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);
return 0;
}
+
END { } # module clean-up code here (global destructor)
1;
__END__
# 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)]
- );
+
+ @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(
- &output_html_with_http_headers &output_with_http_headers FormatData FormatNumber pagination_bar
+ &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
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;
}
--- /dev/null
+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__
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 */;
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');
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);
}
<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 © 2008 <a href="http://www.fyneworks.com/">Fyneworks.com</a></p>
+
</div>
<div id="translations">
choices: opac-templates
- theme on the OPAC.
-
+
+
+
+
- "The OPAC is located at http://"
- pref: OPACBaseURL
class: url
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:
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ ### 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 #*/
{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 ) %]
[% 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 ) %]
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">
</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 ) %] <INPUT name="rate_button" type="submit" value="Rate me">[% END %]
+
+ [% 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>
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 %]&count=[% countrss |html %]&sort_by=acqdate_dsc&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 %]&count=[% countrss |html %]&sort_by=acqdate_dsc&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>
[% IF OPACLocalCoverImages %]KOHA.LocalCover.GetCoverFromBibnumber(false);[% END %]
[% IF ( GoogleJackets ) %]KOHA.Google.GetCoverFromIsbn();[% END %]
});
+
//]]>
</script>
</head>
[% 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>
[% 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 %]"> ([% 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 ) %]
# Copyright 2000-2002 Katipo Communications
# Copyright 2010 BibLibre
+# Copyright 2011 KohaAloha, NZ
#
# This file is part of Koha.
#
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;
MARCAUTHORS => $marcauthorsarray,
MARCSERIES => $marcseriesarray,
MARCURLS => $marcurlsarray,
- MARCHOSTS => $marchostsarray,
+ MARCHOSTS => $marchostsarray,
norequests => $norequests,
RequestOnOpac => C4::Context->preference("RequestOnOpac"),
itemdata_ccode => $itemfields{ccode},
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) {
my $reviews = getreviews( $biblionumber, 1 );
my $loggedincommenter;
+
+
+
+
foreach ( @$reviews ) {
my $borrowerData = GetMember('borrowernumber' => $_->{borrowernumber});
# setting some borrower info into this hash
}
$_->{userid} = $borrowerData->{'userid'};
$_->{cardnumber} = $borrowerData->{'cardnumber'};
+ $_->{datereviewed} = format_date($_->{datereviewed});
+
if ($borrowerData->{'borrowernumber'} eq $borrowernumber) {
$_->{your_comment} = 1;
$loggedincommenter = 1;
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 );
--- /dev/null
+#!/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;
+}
--- /dev/null
+#!/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");
#!/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.
#
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
$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,
BakerTaylorBookstoreURL => C4::Context->preference('BakerTaylorBookstoreURL'),
);
}
+
if (C4::Context->preference('TagsEnabled')) {
$template->param(TagsEnabled => 1);
foreach (qw(TagsShowOnList TagsInputOnList)) {
}
}
+
my $tag_quantity;
if (C4::Context->preference('TagsEnabled') and
$tag_quantity = C4::Context->preference('TagsShowOnList')) {
limit=>$tag_quantity });
}
}
+
if (C4::Context->preference('COinSinOPACResults')) {
foreach (@newresults) {
my $record = GetMarcBiblio($_->{'biblionumber'});
}
}
+
+ 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"};
}
$template->param('GoogleIndicTransliteration' => 1);
}
+ $template->param( borrowernumber => $borrowernumber);
output_with_http_headers $cgi, $cookie, $template->output, $content_type;
--- /dev/null
+#!/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