Bug 5668 - Star ratings in the opac

patch applied to commit eb3dc448d2

Signed-off-by: Nicole C. Engard <nengard@bywatersolutions.com>

Turned on star ratings in the opac on details and results
Searched for titles - saw the stars
Clicked on a title
Clicked on the stars
Clicked on the stars to change my rating
Logged out
Tried to click on stars
Logged in as different user
Rated items that were rated already and saw average change
Changed preference to show only on detail and repeated tests
Changed preference to now show stars

All above tests passed. Signing off.

Rebased 3-19-12 by Ian Walls

Signed-off-by: Paul Poulain <paul.poulain@biblibre.com>
This commit is contained in:
Mason James 2012-03-30 16:35:29 +13:00 committed by Paul Poulain
parent f12a3cc7e7
commit 7eef4c8c70
19 changed files with 1147 additions and 22 deletions

View File

@ -41,8 +41,7 @@ BEGIN {
if ( psgi_env ) { die 'psgi:exit' }
else { exit }
}
$VERSION = 3.02; # set version for version checking
$VERSION = 3.02; # set version for version checking
$debug = $ENV{DEBUG};
@ISA = qw(Exporter);
@EXPORT = qw(&checkauth &get_template_and_user &haspermission &get_user_subpermissions);
@ -1665,6 +1664,7 @@ sub getborrowernumber {
return 0;
}
END { } # module clean-up code here (global destructor)
1;
__END__

View File

@ -39,18 +39,22 @@ BEGIN {
# set the version for version checking
$VERSION = 3.03;
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(&is_ajax ajax_fail); # More stuff should go here instead
%EXPORT_TAGS = ( all =>[qw(&pagination_bar
&output_with_http_headers &output_html_with_http_headers)],
ajax =>[qw(&output_with_http_headers is_ajax)],
html =>[qw(&output_with_http_headers &output_html_with_http_headers)]
);
push @EXPORT, qw(
&output_html_with_http_headers &output_with_http_headers FormatData FormatNumber pagination_bar
);
}
@ISA = qw(Exporter);
@EXPORT_OK = qw(&is_ajax ajax_fail); # More stuff should go here instead
%EXPORT_TAGS = ( all =>[qw(&themelanguage &gettemplate setlanguagecookie pagination_bar
&output_with_http_headers &output_ajax_with_http_headers &output_html_with_http_headers)],
ajax =>[qw(&output_with_http_headers &output_ajax_with_http_headers is_ajax)],
html =>[qw(&output_with_http_headers &output_html_with_http_headers)]
);
push @EXPORT, qw(
&themelanguage &gettemplate setlanguagecookie getlanguagecookie pagination_bar
);
push @EXPORT, qw(
&output_html_with_http_headers &output_ajax_with_http_headers &output_with_http_headers FormatData FormatNumber
);
}
=head1 NAME
@ -306,7 +310,19 @@ sub output_html_with_http_headers ($$$;$) {
output_with_http_headers( $query, $cookie, $data, 'html', $status );
}
sub is_ajax () {
sub output_ajax_with_http_headers {
my ( $query, $js ) = @_;
print $query->header(
-type => 'text/javascript',
-charset => 'UTF-8',
-Pragma => 'no-cache',
-'Cache-Control' => 'no-cache',
-expires => '-1d',
), $js;
}
sub is_ajax {
my $x_req = $ENV{HTTP_X_REQUESTED_WITH};
return ( $x_req and $x_req =~ /XMLHttpRequest/i ) ? 1 : 0;
}

249
C4/Ratings.pm Normal file
View File

@ -0,0 +1,249 @@
package C4::Ratings;
# Copyright 2011 KohaAloha, NZ
# Parts copyright 2011, Catalyst IT, NZ.
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
use strict;
use warnings;
use Carp;
use Exporter;
use POSIX;
use C4::Debug;
use C4::Context;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
BEGIN {
$VERSION = 3.00;
@ISA = qw(Exporter);
@EXPORT = qw(
&GetRating
&AddRating
&ModRating
&DelRating
);
}
=head1 NAME
C4::Ratings - a module to manage user ratings of Koha biblios
=head1 DESCRIPTION
Ratings.pm provides simple functionality for a user to 'rate' a biblio, and to retrieve a biblio's rating info
the 4 subroutines allow a user to add, delete modify and retrieve rating info for a biblio.
The rating can be from 1 to 5 stars, (5 stars being the highest rating)
=head1 SYNOPSIS
Get a rating for a bib
my $rating_hashref = GetRating( $biblionumber, undef );
my $rating_hashref = GetRating( $biblionumber, $borrowernumber );
Add a rating for a bib
my $rating_hashref = AddRating( $biblionumber, $borrowernumber, $rating_value );
Mod a rating for a bib
my $rating_hashref = ModRating( $biblionumber, $borrowernumber, $rating_value );
Delete a rating for a bib
my $rating_hashref = DelRating( $biblionumber, $borrowernumber );
All subroutines in Ratings.pm return a hashref which contain 4 keys
for example, after executing this statment below...
my $rating_hashref = GetRating ( $biblionumber, $borrowernumber ) ;
$rating_hashref now contains a hashref that looks like this...
$rating = {
rating_avg => '2',
rating_avg_int => '2.3',
rating_total => '432',
rating_value => '5'
}
they 4 keys returned in the hashref are...
rating_avg: average rating of a biblio
rating_avg_int: average rating of a biblio, rounded to 1dp
rating_total: total number of ratings of a biblio
rating_value: logged-in user's rating of a biblio
=head1 BUGS
Please use bugs.koha-community.org for tracking bugs.
=head1 SOURCE AVAILABILITY
The source is available from the koha-community.org git server
L<http://git.koha-community.org>
=head1 AUTHOR
Original code: Mason James <mtj@kohaaloha.com>
=head1 COPYRIGHT
Copyright (c) 2011 Mason James <mtj@kohaaloha.com>
=head1 LICENSE
C4::Ratings is free software. You can redistribute it and/or
modify it under the same terms as Koha itself.
=head1 CREDITS
Mason James <mtj@kohaaloha.com>
Koha Dev Team <http://koha-community.org>
=head2 GetRating
GetRating($biblionumber, [$borrowernumber])
Get a rating for a bib
my $rating_hashref = GetRating( $biblionumber, undef );
my $rating_hashref = GetRating( $biblionumber, $borrowernumber );
This returns the rating for the supplied biblionumber. It will also return
the rating that the supplied user gave to the provided biblio. If a particular
value can't be supplied, '0' is returned for that value.
=head3 RETURNS
A hashref containing:
=over
=item * rating_avg - average rating of a biblio
=item * rating_avg_int - average rating of a biblio, rounded to 1dp
=item * rating_total - total number of ratings of a biblio
=item * rating_value - logged-in user's rating of a biblio
=back
=cut
sub GetRating {
my ( $biblionumber, $borrowernumber ) = @_;
my $query = qq| SELECT COUNT(*) AS total, SUM(rating_value) AS sum
FROM ratings WHERE biblionumber = ? |;
my $sth = C4::Context->dbh->prepare($query);
$sth->execute($biblionumber);
my $res = $sth->fetchrow_hashref();
my ( $avg, $avg_int ) = 0;
if ( $res->{sum} and $res->{total} ) {
eval { $avg = $res->{sum} / $res->{total} };
}
$avg_int = sprintf( "%.1f", $avg );
$avg = sprintf( "%.0f", $avg );
my %rating_hash;
$rating_hash{rating_total} = $res->{total} || 0;
$rating_hash{rating_avg} = $avg || 0;
$rating_hash{rating_avg_int} = $avg_int ||0;
if ($borrowernumber) {
my $q2 = qq|
SELECT rating_value FROM ratings WHERE biblionumber = ? AND borrowernumber = ?|;
my $sth1 = C4::Context->dbh->prepare($q2);
$sth1->execute( $biblionumber, $borrowernumber );
my $res1 = $sth1->fetchrow_hashref();
$rating_hash{'rating_value'} = $res1->{"rating_value"};
}
else {
$rating_hash{rating_borrowernumber} = undef;
$rating_hash{rating_value} = undef;
}
#### %rating_hash
return \%rating_hash;
}
=head2 AddRating
my $rating_hashref = AddRating( $biblionumber, $borrowernumber, $rating_value );
Add a rating for a bib
This adds or updates a rating for a particular user on a biblio. If the value
is 0, then the rating will be deleted. If the value is out of the range of
0-5, nothing will happen.
=cut
sub AddRating {
my ( $biblionumber, $borrowernumber, $rating_value ) = @_;
my $query =
qq| INSERT INTO ratings (borrowernumber,biblionumber,rating_value)
VALUES (?,?,?)|;
my $sth = C4::Context->dbh->prepare($query);
$sth->execute( $borrowernumber, $biblionumber, $rating_value );
my $rating = GetRating( $biblionumber, $borrowernumber );
return $rating;
}
=head2 ModRating
my $rating_hashref = ModRating( $biblionumber, $borrowernumber, $rating_value );
Mod a rating for a bib
=cut
sub ModRating {
my ( $biblionumber, $borrowernumber, $rating_value ) = @_;
my $query =
qq|UPDATE ratings SET rating_value = ? WHERE borrowernumber = ? AND biblionumber = ?|;
my $sth = C4::Context->dbh->prepare($query);
$sth->execute( $rating_value, $borrowernumber, $biblionumber );
my $rating = GetRating( $biblionumber, $borrowernumber );
return $rating;
}
=head2 DelRating
my $rating_hashref = DelRating( $biblionumber, $borrowernumber );
Delete a rating for a bib
=cut
sub DelRating {
my ( $biblionumber, $borrowernumber ) = @_;
my $dbh = C4::Context->dbh;
my $query =
"delete from ratings where borrowernumber = ? and biblionumber = ?";
my $sth = C4::Context->dbh->prepare($query);
my $rv = $sth->execute( $borrowernumber, $biblionumber );
my $rating = GetRating( $biblionumber, undef );
return $rating;
}
1;
__END__

View File

@ -2813,6 +2813,21 @@ CREATE TABLE IF NOT EXISTS `social_data` (
PRIMARY KEY (`isbn`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- 'Ratings' table. This tracks the star ratings set by borrowers.
--
DROP TABLE IF EXISTS ratings;
CREATE TABLE ratings (
borrowernumber int(11) NOT NULL, --- the borrower this rating is for
biblionumber int(11) NOT NULL, --- the biblio it's for
rating_value tinyint(1) NOT NULL, --- the rating, from 1-5
timestamp timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (borrowernumber,biblionumber),
CONSTRAINT ratings_ibfk_1 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT ratings_ibfk_2 FOREIGN KEY (biblionumber) REFERENCES biblio (biblionumber) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;

View File

@ -360,3 +360,4 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('SocialNetworks','1','Enable/Disable social networks links in opac detail pages','','YesNo');
INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES('SubscriptionDuplicateDroppedInput','','','List of fields which must not be rewritten when a subscription is duplicated (Separated by pipe |)','Free');
INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('AutoResumeSuspendedHolds', '1', NULL , 'Allow suspended holds to be automatically resumed by a set date.', 'YesNo');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('OpacStarRatings','all',NULL,'disable|all|details','Choice');

View File

@ -4929,6 +4929,28 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('AllowPKIAuth','None','Use the field from a client-side SSL certificate to look a user in the Koha database','None|Common Name|emailAddress','Choice');
});
print "Upgrade to $DBversion done (Bug 6296 New System preference AllowPKIAuth)\n";
}
$DBversion = "3.07.00.XXX";
if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) {
$dbh->do(
q | CREATE TABLE ratings (
borrowernumber int(11) NOT NULL,
biblionumber int(11) NOT NULL,
rating_value tinyint(1) NOT NULL,
timestamp timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (borrowernumber,biblionumber),
CONSTRAINT ratings_ibfk_1 FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT ratings_ibfk_2 FOREIGN KEY (biblionumber) REFERENCES biblio (biblionumber) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
);
$dbh->do(
q /INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('OpacStarRatings','disable',NULL,'disable|all|details','Choice') /
);
print
"Upgrade to $DBversion done (Add 'ratings' table and 'OpacStarRatings' syspref)\n";
SetVersion($DBversion);
}

View File

@ -342,6 +342,12 @@
<a rel="license" href="http://creativecommons.org/licenses/by-sa/2.5/">Creative Commons Attribution-ShareAlike 2.5 License</a>
by the Bridge Consortium of Carleton College and St. Olaf College.</li>
</ul>
<h2>jQuery Star Rating Plugin</h2>
<p>jQuery Star Rating Plugin v3.14 by <a href="http://www.fyneworks.com/">Fyneworks.com</a> is licensed under the <a target="_blank" href="http://en.wikipedia.org/wiki/MIT_License">MIT License</a> and the <a target="_blank" href="http://creativecommons.org/licenses/GPL/2.0/">GPL License</a>.</p>
<p>Copyright &copy; 2008 <a href="http://www.fyneworks.com/">Fyneworks.com</a></p>
</div>
<div id="translations">

View File

@ -6,6 +6,10 @@ OPAC:
choices: opac-templates
- theme on the OPAC.
-
- "The OPAC is located at http://"
- pref: OPACBaseURL
class: url
@ -21,6 +25,14 @@ OPAC:
yes: Enable
no: Disable
- "Koha OPAC as public. Private OPAC requires authentification before accessing the OPAC."
-
- "Show star-ratings on"
- pref: OpacStarRatings
choices:
all: "results and details"
disable: "no"
details: "only details"
- "pages."
-
- pref: OpacMaintenance
choices:

View File

@ -0,0 +1,12 @@
/* jQuery.Rating Plugin CSS - http://www.fyneworks.com/jquery/star-rating/ */
div.rating-cancel,div.star-rating{float:left;width:15px;height:15px;text-indent:-999em;cursor:pointer;display:block;background:transparent;overflow:hidden}
div.rating-cancel,div.rating-cancel a{background:url(../../images/delete.gif) no-repeat 0 -16px}
div.star-rating,div.star-rating a{background:url(../../images/star.gif) no-repeat 0 0px}
div.rating-cancel a,div.star-rating a{display:block;width:16px;height:100%;background-position:0 0px;border:0}
div.star-rating-on a{background-position:0 -32px!important}
div.star-rating-hover a{background-position:0 -16px}
/* Read Only CSS */
div.star-rating-readonly a{cursor:default !important}
/* Partial Star CSS */
div.star-rating{background:transparent!important;overflow:hidden!important}
/* END jQuery.Rating Plugin CSS */

View File

@ -0,0 +1,392 @@
/*
### jQuery Star Rating Plugin v3.14 - 2012-01-26 ###
* Home: http://www.fyneworks.com/jquery/star-rating/
* Code: http://code.google.com/p/jquery-star-rating-plugin/
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
###
*/
/*# AVOID COLLISIONS #*/
;if(window.jQuery) (function($){
/*# AVOID COLLISIONS #*/
// IE6 Background Image Fix
if ($.browser.msie) try { document.execCommand("BackgroundImageCache", false, true)} catch(e) { };
// Thanks to http://www.visualjquery.com/rating/rating_redux.html
// plugin initialization
$.fn.rating = function(options){
if(this.length==0) return this; // quick fail
// Handle API methods
if(typeof arguments[0]=='string'){
// Perform API methods on individual elements
if(this.length>1){
var args = arguments;
return this.each(function(){
$.fn.rating.apply($(this), args);
});
};
// Invoke API method handler
$.fn.rating[arguments[0]].apply(this, $.makeArray(arguments).slice(1) || []);
// Quick exit...
return this;
};
// Initialize options for this call
var options = $.extend(
{}/* new object */,
$.fn.rating.options/* default options */,
options || {} /* just-in-time options */
);
// Allow multiple controls with the same name by making each call unique
$.fn.rating.calls++;
// loop through each matched element
this
.not('.star-rating-applied')
.addClass('star-rating-applied')
.each(function(){
// Load control parameters / find context / etc
var control, input = $(this);
var eid = (this.name || 'unnamed-rating').replace(/\[|\]/g, '_').replace(/^\_+|\_+$/g,'');
var context = $(this.form || document.body);
// FIX: http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=23
var raters = context.data('rating');
if(!raters || raters.call!=$.fn.rating.calls) raters = { count:0, call:$.fn.rating.calls };
var rater = raters[eid];
// if rater is available, verify that the control still exists
if(rater) control = rater.data('rating');
if(rater && control)//{// save a byte!
// add star to control if rater is available and the same control still exists
control.count++;
//}// save a byte!
else{
// create new control if first star or control element was removed/replaced
// Initialize options for this rater
control = $.extend(
{}/* new object */,
options || {} /* current call options */,
($.metadata? input.metadata(): ($.meta?input.data():null)) || {}, /* metadata options */
{ count:0, stars: [], inputs: [] }
);
// increment number of rating controls
control.serial = raters.count++;
// create rating element
rater = $('<span class="star-rating-control"/>');
input.before(rater);
// Mark element for initialization (once all stars are ready)
rater.addClass('rating-to-be-drawn');
// Accept readOnly setting from 'disabled' property
if(input.attr('disabled') || input.hasClass('disabled')) control.readOnly = true;
// Accept required setting from class property (class='required')
if(input.hasClass('required')) control.required = true;
// Create 'cancel' button
rater.append(
control.cancel = $('<div class="rating-cancel"><a title="' + control.cancel + '">' + control.cancelValue + '</a></div>')
.mouseover(function(){
$(this).rating('drain');
$(this).addClass('star-rating-hover');
//$(this).rating('focus');
})
.mouseout(function(){
$(this).rating('draw');
$(this).removeClass('star-rating-hover');
//$(this).rating('blur');
})
.click(function(){
$(this).rating('select');
})
.data('rating', control)
);
}; // first element of group
// insert rating star
var star = $('<div class="star-rating rater-'+ control.serial +'"><a title="' + (this.title || this.value) + '">' + this.value + '</a></div>');
rater.append(star);
// inherit attributes from input element
if(this.id) star.attr('id', this.id);
if(this.className) star.addClass(this.className);
// Half-stars?
if(control.half) control.split = 2;
// Prepare division control
if(typeof control.split=='number' && control.split>0){
var stw = ($.fn.width ? star.width() : 0) || control.starWidth;
var spi = (control.count % control.split), spw = Math.floor(stw/control.split);
star
// restrict star's width and hide overflow (already in CSS)
.width(spw)
// move the star left by using a negative margin
// this is work-around to IE's stupid box model (position:relative doesn't work)
.find('a').css({ 'margin-left':'-'+ (spi*spw) +'px' })
};
// readOnly?
if(control.readOnly)//{ //save a byte!
// Mark star as readOnly so user can customize display
star.addClass('star-rating-readonly');
//} //save a byte!
else//{ //save a byte!
// Enable hover css effects
star.addClass('star-rating-live')
// Attach mouse events
.mouseover(function(){
$(this).rating('fill');
$(this).rating('focus');
})
.mouseout(function(){
$(this).rating('draw');
$(this).rating('blur');
})
.click(function(){
$(this).rating('select');
})
;
//}; //save a byte!
// set current selection
if(this.checked) control.current = star;
// set current select for links
if(this.nodeName=="A"){
if($(this).hasClass('selected'))
control.current = star;
};
// hide input element
input.hide();
// backward compatibility, form element to plugin
input.change(function(){
$(this).rating('select');
});
// attach reference to star to input element and vice-versa
star.data('rating.input', input.data('rating.star', star));
// store control information in form (or body when form not available)
control.stars[control.stars.length] = star[0];
control.inputs[control.inputs.length] = input[0];
control.rater = raters[eid] = rater;
control.context = context;
input.data('rating', control);
rater.data('rating', control);
star.data('rating', control);
context.data('rating', raters);
}); // each element
// Initialize ratings (first draw)
$('.rating-to-be-drawn').rating('draw').removeClass('rating-to-be-drawn');
return this; // don't break the chain...
};
/*--------------------------------------------------------*/
/*
### Core functionality and API ###
*/
$.extend($.fn.rating, {
// Used to append a unique serial number to internal control ID
// each time the plugin is invoked so same name controls can co-exist
calls: 0,
focus: function(){
var control = this.data('rating'); if(!control) return this;
if(!control.focus) return this; // quick fail if not required
// find data for event
var input = $(this).data('rating.input') || $( this.tagName=='INPUT' ? this : null );
// focus handler, as requested by focusdigital.co.uk
if(control.focus) control.focus.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]);
}, // $.fn.rating.focus
blur: function(){
var control = this.data('rating'); if(!control) return this;
if(!control.blur) return this; // quick fail if not required
// find data for event
var input = $(this).data('rating.input') || $( this.tagName=='INPUT' ? this : null );
// blur handler, as requested by focusdigital.co.uk
if(control.blur) control.blur.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]);
}, // $.fn.rating.blur
fill: function(){ // fill to the current mouse position.
var control = this.data('rating'); if(!control) return this;
// do not execute when control is in read-only mode
if(control.readOnly) return;
// Reset all stars and highlight them up to this element
this.rating('drain');
this.prevAll().andSelf().filter('.rater-'+ control.serial).addClass('star-rating-hover');
},// $.fn.rating.fill
drain: function() { // drain all the stars.
var control = this.data('rating'); if(!control) return this;
// do not execute when control is in read-only mode
if(control.readOnly) return;
// Reset all stars
control.rater.children().filter('.rater-'+ control.serial).removeClass('star-rating-on').removeClass('star-rating-hover');
},// $.fn.rating.drain
draw: function(){ // set value and stars to reflect current selection
var control = this.data('rating'); if(!control) return this;
// Clear all stars
this.rating('drain');
// Set control value
if(control.current){
control.current.data('rating.input').attr('checked','checked');
control.current.prevAll().andSelf().filter('.rater-'+ control.serial).addClass('star-rating-on');
}
else
$(control.inputs).removeAttr('checked');
// Show/hide 'cancel' button
control.cancel[control.readOnly || control.required?'hide':'show']();
// Add/remove read-only classes to remove hand pointer
this.siblings()[control.readOnly?'addClass':'removeClass']('star-rating-readonly');
},// $.fn.rating.draw
select: function(value,wantCallBack){ // select a value
// ***** MODIFICATION *****
// Thanks to faivre.thomas - http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=27
//
// ***** LIST OF MODIFICATION *****
// ***** added Parameter wantCallBack : false if you don't want a callback. true or undefined if you want postback to be performed at the end of this method'
// ***** recursive calls to this method were like : ... .rating('select') it's now like .rating('select',undefined,wantCallBack); (parameters are set.)
// ***** line which is calling callback
// ***** /LIST OF MODIFICATION *****
var control = this.data('rating'); if(!control) return this;
// do not execute when control is in read-only mode
if(control.readOnly) return;
// clear selection
control.current = null;
// programmatically (based on user input)
if(typeof value!='undefined'){
// select by index (0 based)
if(typeof value=='number')
return $(control.stars[value]).rating('select',undefined,wantCallBack);
// select by literal value (must be passed as a string
if(typeof value=='string')
//return
$.each(control.stars, function(){
if($(this).data('rating.input').val()==value) $(this).rating('select',undefined,wantCallBack);
});
}
else
control.current = this[0].tagName=='INPUT' ?
this.data('rating.star') :
(this.is('.rater-'+ control.serial) ? this : null);
// Update rating control state
this.data('rating', control);
// Update display
this.rating('draw');
// find data for event
var input = $( control.current ? control.current.data('rating.input') : null );
// click callback, as requested here: http://plugins.jquery.com/node/1655
// **** MODIFICATION *****
// Thanks to faivre.thomas - http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=27
//
//old line doing the callback :
//if(control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]);// callback event
//
//new line doing the callback (if i want :)
if((wantCallBack ||wantCallBack == undefined) && control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]);// callback event
//to ensure retro-compatibility, wantCallBack must be considered as true by default
// **** /MODIFICATION *****
},// $.fn.rating.select
readOnly: function(toggle, disable){ // make the control read-only (still submits value)
var control = this.data('rating'); if(!control) return this;
// setread-only status
control.readOnly = toggle || toggle==undefined ? true : false;
// enable/disable control value submission
if(disable) $(control.inputs).attr("disabled", "disabled");
else $(control.inputs).removeAttr("disabled");
// Update rating control state
this.data('rating', control);
// Update display
this.rating('draw');
},// $.fn.rating.readOnly
disable: function(){ // make read-only and never submit value
this.rating('readOnly', true, true);
},// $.fn.rating.disable
enable: function(){ // make read/write and submit value
this.rating('readOnly', false, false);
}// $.fn.rating.select
});
/*--------------------------------------------------------*/
/*
### Default Settings ###
eg.: You can override default control like this:
$.fn.rating.options.cancel = 'Clear';
*/
$.fn.rating.options = { //$.extend($.fn.rating, { options: {
cancel: 'Cancel Rating', // advisory title for the 'cancel' link
cancelValue: '', // value to submit when user click the 'cancel' link
split: 0, // split the star into how many parts?
// Width of star image in case the plugin can't work it out. This can happen if
// the jQuery.dimensions plugin is not available OR the image is hidden at installation
starWidth: 16//,
//NB.: These don't need to be pre-defined (can be undefined/null) so let's save some code!
//half: false, // just a shortcut to control.split = 2
//required: false, // disables the 'cancel' button so user can only select one of the specified values
//readOnly: false, // disable rating plugin interaction/ values cannot be changed
//focus: function(){}, // executed when stars are focused
//blur: function(){}, // executed when stars are focused
//callback: function(){}, // executed when a star is clicked
}; //} });
/*--------------------------------------------------------*/
/*
### Default implementation ###
The plugin will attach itself to file inputs
with the class 'multi' when the page loads
*/
$(function(){
$('input[type=radio].star').rating();
});
/*# AVOID COLLISIONS #*/
})(jQuery);
/*# AVOID COLLISIONS #*/

View File

@ -9,6 +9,9 @@
{lang: '[% lang %]'}
</script>
[% END %]
<script type="text/javascript" src="/opac-tmpl/prog/en/lib/jquery/plugins/jquery.rating.js"></script>
<link rel="stylesheet" type="text/css" href="/opac-tmpl/prog/en/css/jquery.rating.css" />
<script type="text/JavaScript" language="JavaScript">
//<![CDATA[
[% IF ( busc ) %]
@ -83,8 +86,55 @@
[% END %]
$(".branch-info-tooltip-trigger").tooltip({delay: 100, position: "top right"});
});
// -----------------------------------------------------
// star-ratings code
// -----------------------------------------------------
// hide 'rate' button if javascript enabled
$('input[name="rate_button"]').remove();
$(function () {
$(".auto-submit-star").rating({
callback: function (value, link) {
// if the new value equals the old value, dont execute callback...
// just do nothing!
if ($("#rating_value").attr("value") != value) {
$(function () {
$.post("/cgi-bin/koha/opac-ratings-ajax.pl", {
rating_old_value: $("#rating_value").attr("value"),
borrowernumber: "[% borrowernumber %]",
biblionumber: "[% biblionumber %]",
rating_value: value,
auth_error: value,
}, function (data) {
if (data.auth_status != 'ok') {
window.alert('Your CGI session cookie is not current. Please refresh the page and try again.');
} else {
$("#rating_value").val(data.rating_value);
if (data.rating_value) {
$("#rating_value_text").text('your rating: ' + data.rating_value + ', ');
} else {
$("#rating_value_text").text('');
}
$("#rating_text").text('average rating: ' + data.rating_avg_int + ' (' + data.rating_total + ' votes)');
}
}, "json");
});
};
}
});
});
// -----------------------------------------------------
});
[% IF ( busc ) %]
@ -215,7 +265,6 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
YAHOO.util.Event.addListener("furthersearches", "click", furthersearchesMenu.show, null, furthersearchesMenu);
YAHOO.widget.Overlay.windowResizeEvent.subscribe(positionfurthersearchesMenu);
});
//]]>
</script>
[% IF ( opacuserlogin ) %][% IF ( loggedinusername ) %][% IF ( TagsEnabled ) %]<style type="text/css">
@ -488,6 +537,44 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
</span>
[% END %][% END %][% END %]
[% IF ( OpacStarRatings != 'disable' ) %]
<form method="post" action="/cgi-bin/koha/opac-ratings.pl">
<div class="results_summary">
[% FOREACH i IN [ 1 2 3 4 5 ] %]
[% IF rating_avg == i && borrowernumber %]
<input class="auto-submit-star" type="radio" name="rating" value="[% i %]" checked="checked" />
[% ELSIF rating_avg == i %]
<input class="auto-submit-star" type="radio" name="rating" value="[% i %]" checked="checked" disabled="disabled" />
[% ELSIF borrowernumber %]
<input class="auto-submit-star" type="radio" name="rating" value="[% i %]" />
[% ELSE %]
<input class="auto-submit-star" type="radio" name="rating" value="[% i %]" disabled="disabled" />
[% END %]
[% END %]
<!-- define some hidden vars for ratings -->
<input type="hidden" name='biblionumber' value="[% biblionumber %]" />
<input type="hidden" name='borrowernumber' value="[% borrowernumber %]" />
<input type="hidden" name='rating_value' id='rating_value' value="[% rating_value %]" />
<input type="hidden" name='rating_total' id='rating_total' value="[% rating_total %]" />
<input type="hidden" name='rating_avg_int' id='rating_avg_int' value="[% rating_avg_int %]" />
[% UNLESS ( rating_readonly ) %]&nbsp; <INPUT name="rate_button" type="submit" value="Rate me">[% END %]&nbsp;
[% IF ( rating_value ) %]
<span id="rating_value_text">your rating: [% rating_value %], </span>
[% ELSE %]
<span id="rating_value_text"></span>
[% END %]
<span id="rating_text">average rating: [% rating_avg_int %] ([% rating_total %] votes)</span>
</div>
</FORM>
[% END %]
[% IF ( BakerTaylorContentURL ) %]
<span class="results_summary">
<span class="label">Enhanced content: </span>

View File

@ -6,8 +6,10 @@
You did not specify any search criteria.
[% END %]
[% INCLUDE 'doc-head-close.inc' %]
<link rel="alternate" type="application/rss+xml" title="[% LibraryName |html %] Search RSS Feed" href="[% OPACBaseURL %]/cgi-bin/koha/opac-search.pl?[% query_cgi |html %][% limit_cgi |html %]&amp;count=[% countrss |html %]&amp;sort_by=acqdate_dsc&amp;format=rss2" />
<link rel="alternate" type="application/rss+xml" title="[% LibraryName |html %] Search RSS Feed" href="[% OPACBaseurl %]/cgi-bin/koha/opac-search.pl?[% query_cgi |html %][% limit_cgi |html %]&amp;count=[% countrss |html %]&amp;sort_by=acqdate_dsc&amp;format=rss2" />
<script type="text/javascript" src="/opac-tmpl/prog/en/lib/jquery/jquery.js"></script>
<script type="text/javascript" src="/opac-tmpl/prog/en/lib/jquery/plugins/jquery.rating.js"></script>
<link rel="stylesheet" type="text/css" href="/opac-tmpl/prog/en/css/jquery.rating.css" />
<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
[% IF ( OpacHighlightedWords ) %]<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.highlight-3.js"></script>
@ -234,6 +236,7 @@ $(document).ready(function(){
[% IF OPACLocalCoverImages %]KOHA.LocalCover.GetCoverFromBibnumber(false);[% END %]
[% IF ( GoogleJackets ) %]KOHA.Google.GetCoverFromIsbn();[% END %]
});
//]]>
</script>
</head>
@ -481,8 +484,8 @@ $(document).ready(function(){
[% IF ( SEARCH_RESULT.intransitcount ) %] In transit ([% SEARCH_RESULT.intransitcount %]),[% END %]
</span>
</span>
[% END %]
[% IF ( SEARCH_RESULT.score_avg ) %]
<span class="result_summary">
<img src="[% themelang %]/../images/Star[% SEARCH_RESULT.score_int %].gif" title="" style="max-height: 15px;"/> <span style="font-size: 85%;">[% SEARCH_RESULT.score_avg %] / 5 (on [% SEARCH_RESULT.num_scores %] rates)</span>
@ -500,6 +503,33 @@ $(document).ready(function(){
[% END %]
</span>
[% END %]
[% IF ( OpacStarRatings == 'all' ) %]
<div class="results_summary">
[% FOREACH i IN [ 1 2 3 4 5 ] %]
[% IF ( SEARCH_RESULT.rating_avg == i ) %]
<input class="star" type="radio" name="rating-[% SEARCH_RESULT.biblionumber %]" value="[% i %]" checked="checked" disabled="disabled" />
[% ELSE %]
<input class="star" type="radio" name="rating-[% SEARCH_RESULT.biblionumber %]" value="[% i %]" disabled="disabled" />
[% END %]
[% END %]
<input type="hidden" name='biblionumber' value="[% SEARCH_RESULT.biblionumber %]" />
<input type="hidden" name='loggedinuser' value="[% loggedinuser %]" />
[% IF ( SEARCH_RESULT.rating_total ) > 0 %]
<span id="rating_total_[% SEARCH_RESULT.biblionumber %]">&nbsp;&nbsp;([% SEARCH_RESULT.rating_total %] votes)</span>
[% ELSE %]
</br>
[% END %]
</div>
[% END %]
[% IF ( LibraryThingForLibrariesID ) %]<div class="ltfl_reviews"></div>[% END %]
[% IF ( opacuserlogin ) %][% IF ( TagsEnabled ) %]
[% IF ( TagsShowOnList ) %]

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 815 B

View File

@ -2,6 +2,7 @@
# Copyright 2000-2002 Katipo Communications
# Copyright 2010 BibLibre
# Copyright 2011 KohaAloha, NZ
#
# This file is part of Koha.
#
@ -36,6 +37,7 @@ use C4::XISBN qw(get_xisbns get_biblionumber_from_isbn);
use C4::External::Amazon;
use C4::External::Syndetics qw(get_syndetics_index get_syndetics_summary get_syndetics_toc get_syndetics_excerpt get_syndetics_reviews get_syndetics_anotes );
use C4::Review;
use C4::Ratings;
use C4::Members;
use C4::VirtualShelves;
use C4::XSLT;
@ -549,7 +551,7 @@ my $subtitle = GetRecordValue('subtitle', $record, GetFrameworkCode($bib
MARCAUTHORS => $marcauthorsarray,
MARCSERIES => $marcseriesarray,
MARCURLS => $marcurlsarray,
MARCHOSTS => $marchostsarray,
MARCHOSTS => $marchostsarray,
norequests => $norequests,
RequestOnOpac => C4::Context->preference("RequestOnOpac"),
itemdata_ccode => $itemfields{ccode},
@ -559,6 +561,7 @@ my $subtitle = GetRecordValue('subtitle', $record, GetFrameworkCode($bib
itemdata_itemnotes => $itemfields{itemnotes},
authorised_value_images => $biblio_authorised_value_images,
subtitle => $subtitle,
OpacStarRatings => C4::Context->preference("OpacStarRatings"),
);
if (C4::Context->preference("AlternateHoldingsField") && scalar @items == 0) {
@ -629,6 +632,10 @@ if ( C4::Context->preference('ShowReviewer') and C4::Context->preference('ShowRe
my $reviews = getreviews( $biblionumber, 1 );
my $loggedincommenter;
foreach ( @$reviews ) {
my $borrowerData = GetMember('borrowernumber' => $_->{borrowernumber});
# setting some borrower info into this hash
@ -640,6 +647,8 @@ foreach ( @$reviews ) {
}
$_->{userid} = $borrowerData->{'userid'};
$_->{cardnumber} = $borrowerData->{'cardnumber'};
$_->{datereviewed} = format_date($_->{datereviewed});
if ($borrowerData->{'borrowernumber'} eq $borrowernumber) {
$_->{your_comment} = 1;
$loggedincommenter = 1;
@ -908,6 +917,17 @@ my $OpacExportOptions=C4::Context->preference("OpacExportOptions");
my @export_options = split(/\|/,$OpacExportOptions);
$template->{VARS}->{'export_options'} = \@export_options;
if ( C4::Context->preference('OpacStarRatings') !~ /disable/ ) {
my $rating = GetRating( $biblionumber, $borrowernumber );
$template->param(
rating_value => $rating->{'rating_value'},
rating_total => $rating->{'rating_total'},
rating_avg => $rating->{'rating_avg'},
rating_avg_int => $rating->{'rating_avg_int'},
borrowernumber => $borrowernumber
);
}
#Search for title in links
my $marccontrolnumber = GetMarcControlnumber ($record, $marcflavour);
my $marcissns = GetMarcISSN ( $record, $marcflavour );

115
opac/opac-ratings-ajax.pl Executable file
View File

@ -0,0 +1,115 @@
#!/usr/bin/perl
# Copyright 2011 KohaAloha, NZ
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
=head1 DESCRIPTION
A script that takes an ajax json query, and then inserts or modifies a star-rating.
=cut
use strict;
use warnings;
use CGI;
use CGI::Cookie; # need to check cookies before having CGI parse the POST request
use C4::Auth qw(:DEFAULT check_cookie_auth);
use C4::Context;
use C4::Debug;
use C4::Output 3.02 qw(:html :ajax pagination_bar);
use C4::Ratings;
use JSON;
my $is_ajax = is_ajax();
my ( $query, $auth_status );
if ($is_ajax) {
( $query, $auth_status ) = &ajax_auth_cgi( {} );
}
else {
$query = CGI->new();
}
my $biblionumber = $query->param('biblionumber');
my $rating_value = $query->param('rating_value');
my $rating_old_value = $query->param('rating_old_value');
my ( $template, $loggedinuser, $cookie );
if ($is_ajax) {
$loggedinuser = C4::Context->userenv->{'number'};
}
else {
( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => "opac-detail.tt",
query => $query,
type => "opac",
authnotrequired => 0, # auth required to add tags
debug => 1,
}
);
}
my $rating;
undef $rating_value if $rating_value eq '';
if ( !$rating_value ) {
#### delete
$rating = DelRating( $biblionumber, $loggedinuser );
}
elsif ( $rating_value and !$rating_old_value ) {
#### insert
$rating = AddRating( $biblionumber, $loggedinuser, $rating_value );
}
elsif ( $rating_value ne $rating_old_value ) {
#### mod
$rating = ModRating( $biblionumber, $loggedinuser, $rating_value );
}
my %js_reply = (
rating_total => $rating->{'rating_total'},
rating_avg => $rating->{'rating_avg'},
rating_avg_int => $rating->{'rating_avg_int'},
rating_value => $rating->{'rating_value'},
auth_status => $auth_status,
);
my $json_reply = JSON->new->encode( \%js_reply );
#### $rating
#### %js_reply
#### $json_reply
output_ajax_with_http_headers( $query, $json_reply );
exit;
# a ratings specific ajax return sub, returns CGI object, and an 'auth_success' value
sub ajax_auth_cgi {
my $needed_flags = shift;
my %cookies = fetch CGI::Cookie;
my $input = CGI->new;
my $sessid = $cookies{'CGISESSID'}->value || $input->param('CGISESSID');
my ( $auth_status, $auth_sessid ) =
check_cookie_auth( $sessid, $needed_flags );
return $input, $auth_status;
}

65
opac/opac-ratings.pl Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/perl
# Copyright 2011 KohaAloha, NZ
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Koha; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
=head1
A non-javascript method to add/modify a biblio's rating, called from opac-detail.pl
note: there is currently no 'delete rating' functionality in this script
=cut
use strict;
use warnings;
use CGI;
use CGI::Cookie;
use C4::Auth qw(:DEFAULT check_cookie_auth);
use C4::Context;
use C4::Output;
use C4::Dates qw(format_date);
use C4::Biblio;
use C4::Ratings;
use C4::Debug;
my $query = CGI->new();
my $a = $query->Vars;
#### $a
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
{
template_name => "",
query => $query,
type => "opac",
authnotrequired => 0, # auth required to add tags
debug => 0,
}
);
my $biblionumber = $query->param('biblionumber');
my $rating_old_value = $query->param('rating_value');
my $rating_value = $query->param('rating');
my $rating;
if ( !$rating_old_value ) {
$rating = AddRating( $biblionumber, $loggedinuser, $rating_value );
}
else {
$rating = ModRating( $biblionumber, $loggedinuser, $rating_value );
}
print $query->redirect(
"/cgi-bin/koha/opac-detail.pl?biblionumber=$biblionumber");

View File

@ -1,7 +1,8 @@
#!/usr/bin/perl
# Copyright 2008 Garry Collum and the Koha Koha Development team
# Copyright 2008 Garry Collum and the Koha Development team
# Copyright 2010 BibLibre
# Copyright 2011 KohaAloha, NZ
#
# This file is part of Koha.
#
@ -37,12 +38,13 @@ use C4::Koha;
use C4::Tags qw(get_tags);
use C4::Branch; # GetBranches
use C4::SocialData;
use C4::Ratings;
use POSIX qw(ceil floor strftime);
use URI::Escape;
use Storable qw(thaw freeze);
use Business::ISBN;
my $DisplayMultiPlaceHold = C4::Context->preference("DisplayMultiPlaceHold");
# create a new CGI object
# FIXME: no_undef_params needs to be tested
@ -113,6 +115,9 @@ elsif (C4::Context->preference("marcflavour") eq "MARC21" ) {
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
$template->param( 'OPACNoResultsFound' => C4::Context->preference('OPACNoResultsFound') );
$template->param(
OpacStarRatings => C4::Context->preference("OpacStarRatings") );
if (C4::Context->preference('BakerTaylorEnabled')) {
$template->param(
BakerTaylorEnabled => 1,
@ -121,6 +126,7 @@ if (C4::Context->preference('BakerTaylorEnabled')) {
BakerTaylorBookstoreURL => C4::Context->preference('BakerTaylorBookstoreURL'),
);
}
if (C4::Context->preference('TagsEnabled')) {
$template->param(TagsEnabled => 1);
foreach (qw(TagsShowOnList TagsInputOnList)) {
@ -520,6 +526,7 @@ for (my $i=0;$i<@servers;$i++) {
}
}
my $tag_quantity;
if (C4::Context->preference('TagsEnabled') and
$tag_quantity = C4::Context->preference('TagsShowOnList')) {
@ -530,6 +537,7 @@ for (my $i=0;$i<@servers;$i++) {
limit=>$tag_quantity });
}
}
if (C4::Context->preference('COinSinOPACResults')) {
foreach (@newresults) {
my $record = GetMarcBiblio($_->{'biblionumber'});
@ -551,6 +559,17 @@ for (my $i=0;$i<@servers;$i++) {
}
}
if ( C4::Context->preference('OpacStarRatings') eq 'all' ) {
foreach my $res (@newresults) {
my $rating = GetRating( $res->{'biblionumber'}, $borrowernumber );
$res->{'rating_value'} = $rating->{'rating_value'};
$res->{'rating_total'} = $rating->{'rating_total'};
$res->{'rating_avg'} = $rating->{'rating_avg'};
$res->{'rating_avg_int'} = $rating->{'rating_avg_int'};
}
}
if ($results_hashref->{$server}->{"hits"}){
$total = $total + $results_hashref->{$server}->{"hits"};
}
@ -773,4 +792,5 @@ if (C4::Context->preference('GoogleIndicTransliteration')) {
$template->param('GoogleIndicTransliteration' => 1);
}
$template->param( borrowernumber => $borrowernumber);
output_with_http_headers $cgi, $cookie, $template->output, $content_type;

63
t/db_dependent/Ratings.t Executable file
View File

@ -0,0 +1,63 @@
#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 12;
use C4::Members;
BEGIN {
use FindBin;
use C4::Ratings;
use_ok('C4::Ratings');
DelRating( 1, 901 );
DelRating( 1, 902 );
my $rating5 = GetRating( 1, undef );
ok( defined $rating5, 'get a rating, without borrowernumber' );
my $borrower102 = GetMember( borrowernumber => 102);
my $borrower103 = GetMember( borrowernumber => 103);
SKIP: {
skip 'Missing test borrowers, skipping specific tests', 10 unless ( defined $borrower102 && defined $borrower103 );
my $rating1 = AddRating( 1, 102, 3 );
my $rating2 = AddRating( 1, 103, 4 );
my $rating3 = ModRating( 1, 102, 5 );
my $rating4 = GetRating( 1, 103 );
my $rating6 = DelRating( 1, 102 );
my $rating7 = DelRating( 1, 103 );
ok( defined $rating1, 'add a rating' );
ok( defined $rating2, 'add another rating' );
ok( defined $rating3, 'update a rating' );
ok( defined $rating4, 'get a rating, with borrowernumber' );
ok( defined $rating6, 'delete a rating' );
ok( defined $rating7, 'delete another rating' );
ok( $rating3->{'rating_avg'} == '4', "get a bib's average(float) rating" );
ok( $rating3->{'rating_avg_int'} == 4.5, "get a bib's average(int) rating" );
ok( $rating3->{'rating_total'} == 2, "get a bib's total number of ratings" );
ok( $rating3->{'rating_value'} == 5, "verify user's bib rating" );
}
}
=c
mason@xen1:~/g/head$ perl t/db_dependent/Ratings.t
1..12
ok 1 - use C4::Ratings;
ok 2 - add a rating
ok 3 - add another rating
ok 4 - update a rating
ok 5 - get a rating, with borrowernumber
ok 6 - get a rating, without borrowernumber
ok 7 - get a bib's average(float) rating
ok 8 - get a bib's average(int) rating
ok 9 - get a bib's total number of ratings
ok 10 - verify user's bib rating
ok 11 - delete a rating
ok 12 - delete another rating
=cut