Bugzilla – Attachment 8704 Details for
Bug 5668
Star ratings in the opac
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 5668 - Star ratings in the opac
Bug-5668---Star-ratings-in-the-opac.patch (text/plain), 58.45 KB, created by
Mason James
on 2012-03-30 03:49:26 UTC
(
hide
)
Description:
Bug 5668 - Star ratings in the opac
Filename:
MIME Type:
Creator:
Mason James
Created:
2012-03-30 03:49:26 UTC
Size:
58.45 KB
patch
obsolete
>From e7abee8804fa0a7591e0f255dfbea0e374c6cefe Mon Sep 17 00:00:00 2001 >From: Mason James <mtj@kohaaloha.com> >Date: Fri, 30 Mar 2012 16:35:29 +1300 >Subject: [PATCH] Bug 5668 - Star ratings in the opac >Content-Type: text/plain; charset="utf-8" >http://koha-community.org > >patch applied to commit eb3dc448d2378e01a524d082fc6389484b0cc7d8 > >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 >--- > C4/Auth.pm | 4 +- > C4/Output.pm | 34 ++- > C4/Ratings.pm | 249 +++++++++++++ > installer/data/mysql/kohastructure.sql | 15 + > installer/data/mysql/sysprefs.sql | 1 + > installer/data/mysql/updatedatabase.pl | 22 ++ > koha-tmpl/intranet-tmpl/prog/en/modules/about.tt | 6 + > .../prog/en/modules/admin/preferences/opac.pref | 12 + > koha-tmpl/opac-tmpl/prog/en/css/jquery.rating.css | 12 + > .../prog/en/lib/jquery/plugins/jquery.rating.js | 392 ++++++++++++++++++++ > koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 81 ++++- > .../opac-tmpl/prog/en/modules/opac-results.tt | 40 ++- > koha-tmpl/opac-tmpl/prog/images/delete.gif | Bin 0 -> 752 bytes > koha-tmpl/opac-tmpl/prog/images/star.gif | Bin 0 -> 815 bytes > opac/opac-detail.pl | 22 +- > opac/opac-ratings-ajax.pl | 115 ++++++ > opac/opac-ratings.pl | 65 ++++ > opac/opac-search.pl | 24 ++- > t/db_dependent/Ratings.t | 63 ++++ > 19 files changed, 1137 insertions(+), 20 deletions(-) > create mode 100644 C4/Ratings.pm > create mode 100644 koha-tmpl/opac-tmpl/prog/en/css/jquery.rating.css > create mode 100644 koha-tmpl/opac-tmpl/prog/en/lib/jquery/plugins/jquery.rating.js > create mode 100755 koha-tmpl/opac-tmpl/prog/images/delete.gif > create mode 100644 koha-tmpl/opac-tmpl/prog/images/star.gif > create mode 100755 opac/opac-ratings-ajax.pl > create mode 100755 opac/opac-ratings.pl > create mode 100755 t/db_dependent/Ratings.t > >diff --git a/C4/Auth.pm b/C4/Auth.pm >index 0b737e7..e22da24 100644 >--- a/C4/Auth.pm >+++ b/C4/Auth.pm >@@ -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__ >diff --git a/C4/Output.pm b/C4/Output.pm >index 9087075..359662a 100644 >--- a/C4/Output.pm >+++ b/C4/Output.pm >@@ -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)] >- ); >+ >+ @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 > >@@ -306,6 +310,18 @@ sub output_html_with_http_headers ($$$;$) { > output_with_http_headers( $query, $cookie, $data, 'html', $status ); > } > >+ >+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; >diff --git a/C4/Ratings.pm b/C4/Ratings.pm >new file mode 100644 >index 0000000..a01182b >--- /dev/null >+++ b/C4/Ratings.pm >@@ -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__ >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index fda0bac..2b4de74 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -2809,6 +2809,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 */; >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index e8c22ee..e106fb1 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -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'); >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index ddc288c..fba0031 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -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); > } > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt >index 302e7bd..a3d5248 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/about.tt >@@ -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 © 2008 <a href="http://www.fyneworks.com/">Fyneworks.com</a></p> >+ > </div> > > <div id="translations"> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref >index ae6b620..8083e4d 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref >@@ -6,6 +6,10 @@ OPAC: > choices: opac-templates > - theme on the OPAC. > - >+ >+ >+ >+ > - "The OPAC is located at http://" > - pref: OPACBaseURL > class: url >@@ -22,6 +26,14 @@ OPAC: > 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: > yes: Show >diff --git a/koha-tmpl/opac-tmpl/prog/en/css/jquery.rating.css b/koha-tmpl/opac-tmpl/prog/en/css/jquery.rating.css >new file mode 100644 >index 0000000..e89096b >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/prog/en/css/jquery.rating.css >@@ -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 */ >diff --git a/koha-tmpl/opac-tmpl/prog/en/lib/jquery/plugins/jquery.rating.js b/koha-tmpl/opac-tmpl/prog/en/lib/jquery/plugins/jquery.rating.js >new file mode 100644 >index 0000000..a500e2c >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/prog/en/lib/jquery/plugins/jquery.rating.js >@@ -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 #*/ >diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt >index a5be324..f44133e 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt >+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt >@@ -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,6 +86,45 @@ > [% 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(); >+ >+ >+$(".auto-submit-star").rating({ >+ callback: function (value, link) { >+ $.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"); >+ } >+}); >+// ----------------------------------------------------- >+ > }); > > >@@ -215,7 +257,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 +529,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 ) %] <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> >diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt >index eda2015..3a68685 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt >+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt >@@ -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 %]&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> >@@ -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,8 +503,35 @@ $(document).ready(function(){ > [% END %] > </span> > [% END %] >- [% IF ( LibraryThingForLibrariesID ) %]<div class="ltfl_reviews"></div>[% END %] >- [% IF ( opacuserlogin ) %][% IF ( TagsEnabled ) %] >+ >+ >+ [% 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 ) %] > [% IF ( SEARCH_RESULT.TagLoop.size ) %] > <div class="results_summary"><span class="label">Tags:</span> >diff --git a/koha-tmpl/opac-tmpl/prog/images/delete.gif b/koha-tmpl/opac-tmpl/prog/images/delete.gif >new file mode 100755 >index 0000000000000000000000000000000000000000..43c6ca8763d79bde87bcf437e497af00c8be562d >GIT binary patch >literal 752 >zcmZ?wbhEHb6kt$bc*el6GthYN-n}zt&b)vB{*)<GZZDnssVwQ*wQJ8pz3-M6ef|3N >zTw?I^BRjWl-THaiqIb<TR|-<zzkh%9=+U)n*M2*H{@2X5mq}6Aa+CK)+kfaTd)M9Y >zW&YeVXU=?m_V93u_p1$S-kmu7EY$ycOu&bh{H05m9`-kWR9EwH&eRVR>i+-#|NQy$ >zABXln&Q1FL`t{#CH*SY|{oJwc*Qz;h;)0))7aYq9ewP~fc2e)_P3vAY)$9wl{IzJp >zy{ydlr;a^HiGHwZ{*SH8FZkJhE{gei`OM?;ir*_{?@ji478&@mD*tSH_`A&5@6Vqe >z@G<&xeCOwiq-WvY-<q?(PpbX8Zpp{q%CC#&{pc>eS5f?;vgCP8#IHGBw=+^cY}xvy >zx8c*8mDl2ff1W;kCeZrNm9vlQYJg5<pbb#`$->Caki?(^G9DBs4DA0KlA4-ZT3fl8 >z8F_gb*}2-1v>0WWwY1oIg_&Emc-aM+Wn|bpRc1GF^$N-etzA1qr9X*XNNWw_j-BjG >zGEKc(x)1gUF{(82E@ad^eMXp9hUxg0Q)f<}lVRDncBb&%dq*yAR+(|<o-jL$(28?2 >zo;??45^QExc`no~#IC}^-ui`UvIUER!h-n=LseJ=rYP`FI@~V6z4by;((yhm^C*W! >z21kx@DaO@p*l}R7K&xy_%z+DytsIk;xgB`2439K+b7?GbXmoN_5mIg1@_?b4)vHb2 >zW4=iz(~<TC27yT_6CAg$YSazO;JC%ee5xbs^c)q-iOvDjBs>l-D@bZwvw%g)cL7VG >z)An_f*+XqOetkIP*eg{wS7K(+qJ{-x0ue3?v&y~1d1To>MqD_2keNGNE=Pc|!BJ7b >fV_(F^#N=Z_Jo9)pKRPly^YODPxtB<AFjxZs(@{iI > >literal 0 >HcmV?d00001 > >diff --git a/koha-tmpl/opac-tmpl/prog/images/star.gif b/koha-tmpl/opac-tmpl/prog/images/star.gif >new file mode 100644 >index 0000000000000000000000000000000000000000..d0948a70843bf01952d1f81dcfcdadc92976a04a >GIT binary patch >literal 815 >zcmZ?wbhEHb6ksr5c*el6(A@m!(W5UnOP^`reSRqFN=wUy;^KSv?mbz*{y;*);~mc5 >z-|RUW6m;#{wMW}bp6pHg_U+rN({8s`u6+0I-Q5+MAMeb%w`<p%^ObAe+`hkj`DTyO >z+d~E~k2$_RJM(N#&bNn2U+&-kax?1Vx!~u|pC6Bkx;a<%e0BBpNt3?6-n!q(>5!M# >z{q=^=j}*N*e*EQepZ7;K-(U6l^W*)qy-uI5Mx04YJ9FmD@2@w0e|`3BzvYV!svmDJ >zy1UBt<DL4wUS5~`l~&o?KiTc|?y&dMwH9wLt^WW2|BarW%QZD$t~tCq+4%9S{-+DB >zU+=}f+^q2P-MdfMLf>A9dUx3IVz=bW<9TmSpMHPB|LHc1x92?H@6~*NPV?1P?R#4d >zPbMV1-s|#ytJ9}D;U7+0e!n;8#jahi&$Zv4GUd&Fk1akv*Jf&ey1!wEi_7<GUO*ce >zC<BT=Ss2+FvKVwg#(?64f&G6&R#S79fN)Dk2QP1DuW+|=Z&!EEq$XuvcJ`T_!n3+( >zPg$TWFniYgMJuxwEHYhZ+HLC6v}WVFjRGxe*Yle0Y?-ll&zz2hYr8v-tu*bNVmfR6 >znT~Z6o0Ux&=T2&$rVu=>gU#eYv#yB=$CE4*Ha3+f942mV(XO4k$!yUkYI4!<crrvB >zCM=xaSm|bCkl=8r*<OezWJO^_0~=?DVCaekf*U&*6uTK@`5X*vJ?{A5Yn6wikt>^v >z(7()>%8M?Gl%7kx>Gn`^RAQF96>H<Z$Y)U-PmqX3BO7nCe5XmDq6#B(gG-`HBtv>~ >zqm`q-QcY~aQ7_g~!8sNO9r=2u3Mlqi#CWtc9T(=ypIRf>c$iT@(<;xV@nLFbqN;ve >z&H|wp@2R5NS2`L#KJ=KR(rKEJaLDyUmqb%cL}by=)-=YHmH-A@k7GPXma%d?aC*qL >zh)X7I#x;cnUQ^jS^;|kOFmg@Nv0U}W!=<5%L(6DYL1B*CL?*3JjSUV#i&`dVbSiW! >SUO9NY!6jXVS5kz7!5RQ<r+B^q > >literal 0 >HcmV?d00001 > >diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl >index 923f3ff..e57dace 100755 >--- a/opac/opac-detail.pl >+++ b/opac/opac-detail.pl >@@ -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; >@@ -548,7 +550,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}, >@@ -558,6 +560,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) { >@@ -628,6 +631,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 >@@ -639,6 +646,8 @@ foreach ( @$reviews ) { > } > $_->{userid} = $borrowerData->{'userid'}; > $_->{cardnumber} = $borrowerData->{'cardnumber'}; >+ $_->{datereviewed} = format_date($_->{datereviewed}); >+ > if ($borrowerData->{'borrowernumber'} eq $borrowernumber) { > $_->{your_comment} = 1; > $loggedincommenter = 1; >@@ -907,6 +916,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 ); >diff --git a/opac/opac-ratings-ajax.pl b/opac/opac-ratings-ajax.pl >new file mode 100755 >index 0000000..88f2634 >--- /dev/null >+++ b/opac/opac-ratings-ajax.pl >@@ -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; >+} >diff --git a/opac/opac-ratings.pl b/opac/opac-ratings.pl >new file mode 100755 >index 0000000..b2bcf6f >--- /dev/null >+++ b/opac/opac-ratings.pl >@@ -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"); >diff --git a/opac/opac-search.pl b/opac/opac-search.pl >index ea0cb98..c61e503 100755 >--- a/opac/opac-search.pl >+++ b/opac/opac-search.pl >@@ -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; >diff --git a/t/db_dependent/Ratings.t b/t/db_dependent/Ratings.t >new file mode 100755 >index 0000000..23bde86 >--- /dev/null >+++ b/t/db_dependent/Ratings.t >@@ -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 >-- >1.7.2.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 5668
:
3034
|
3035
|
5097
|
5098
|
5136
|
5137
|
5792
|
5794
|
5833
|
7116
|
7165
|
7166
|
7215
|
7604
|
7798
|
8027
|
8199
|
8202
|
8312
|
8326
|
8359
|
8459
|
8514
|
8537
|
8548
|
8613
|
8704
|
8705
|
8706
|
9159
|
9163
|
9164