[Koha-patches] [PATCH] [SIGNED-OFF] Bug 5668 - star ratings in the OPAC
Nicole C. Engard
nengard at bywatersolutions.com
Sun Aug 21 12:54:40 CEST 2011
From: Robin Sheat <robin at catalyst.net.nz>
This takes the work done by Mason James and tidies it up a bit to work
with master.
This patch allows OPAC users to assign star ratings to biblios, and
other users to see the average of what other people have rated.
Signed-off-by: Nicole C. Engard <nengard at bywatersolutions.com>
---
C4/Auth.pm | 6 +-
C4/Output.pm | 18 +-
C4/Ratings.pm | 145 ++++++++
installer/data/mysql/kohastructure.sql | 16 +
installer/data/mysql/updatedatabase.pl | 20 ++
.../prog/en/modules/admin/preferences/opac.pref | 6 +
koha-tmpl/opac-tmpl/prog/en/css/jquery.rating.css | 12 +
.../prog/en/lib/jquery/plugins/jquery.rating.js | 344 ++++++++++++++++++++
koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 50 +++-
.../opac-tmpl/prog/en/modules/opac-results.tt | 58 ++++
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 | 32 ++
opac/opac-ratings.pl | 104 ++++++
opac/opac-search.pl | 40 ++-
15 files changed, 838 insertions(+), 13 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 100644 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.pl
diff --git a/C4/Auth.pm b/C4/Auth.pm
index 16e908a..6ddf66e 100644
--- a/C4/Auth.pm
+++ b/C4/Auth.pm
@@ -347,6 +347,7 @@ sub get_template_and_user {
LoginFirstname => (C4::Context->userenv?C4::Context->userenv->{"firstname"}:"Bel"),
LoginSurname => C4::Context->userenv?C4::Context->userenv->{"surname"}:"Inconnu",
TagsEnabled => C4::Context->preference("TagsEnabled"),
+ RatingsEnabled => C4::Context->preference("RatingsEnabled"),
hide_marc => C4::Context->preference("hide_marc"),
item_level_itypes => C4::Context->preference('item-level_itypes'),
patronimages => C4::Context->preference("patronimages"),
@@ -975,9 +976,10 @@ sub checkauth {
OpacAuthorities => C4::Context->preference("OpacAuthorities"),
OpacBrowser => C4::Context->preference("OpacBrowser"),
opacheader => C4::Context->preference("opacheader"),
- TagsEnabled => C4::Context->preference("TagsEnabled"),
- OPACUserCSS => C4::Context->preference("OPACUserCSS"),
opacstylesheet => C4::Context->preference("opacstylesheet"),
+ TagsEnabled => C4::Context->preference("TagsEnabled"),
+ RatingsEnabled => C4::Context->preference("RatingsEnabled"),
+ OPACUserCSS => C4::Context->preference("OPACUserCSS"),
intranetcolorstylesheet =>
C4::Context->preference("intranetcolorstylesheet"),
intranetstylesheet => C4::Context->preference("intranetstylesheet"),
diff --git a/C4/Output.pm b/C4/Output.pm
index 98f2d7a..361de95 100644
--- a/C4/Output.pm
+++ b/C4/Output.pm
@@ -44,15 +44,15 @@ BEGIN {
@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_html_with_http_headers)],
- ajax =>[qw(&output_with_http_headers is_ajax)],
+ &output_with_http_headers &output_ajax_with_http_headers &output_html_with_http_headers)],
+ ajax =>[qw(&output_with_http_headers &output_ajax_with_http_headers is_ajax)],
html =>[qw(&output_with_http_headers &output_html_with_http_headers)]
);
push @EXPORT, qw(
&themelanguage &gettemplate setlanguagecookie getlanguagecookie pagination_bar
);
push @EXPORT, qw(
- &output_html_with_http_headers &output_with_http_headers FormatData FormatNumber
+ &output_html_with_http_headers &output_ajax_with_http_headers &output_with_http_headers FormatData FormatNumber
);
}
@@ -478,6 +478,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..ea37301
--- /dev/null
+++ b/C4/Ratings.pm
@@ -0,0 +1,145 @@
+package C4::Ratings;
+
+# Copyright 2010 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.
+
+=head1 C4::Ratings - the Koha API for dealing with star ratings for biblios
+
+This provides an interface to the ratings system, in order to allow them
+to be manipulated or queried.
+
+=cut
+
+use strict;
+use warnings;
+use Carp;
+use Exporter;
+
+use C4::Debug;
+use C4::Context;
+
+#use Smart::Comments '####';
+
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
+
+BEGIN {
+ $VERSION = 3.00;
+ @ISA = qw(Exporter);
+
+ @EXPORT = qw(
+ get_rating add_rating
+ );
+
+ # %EXPORT_TAGS = ();
+}
+
+=head2 get_rating
+
+ get_rating($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.
+
+=head 3 RETURNS
+
+A hashref containing:
+
+=over
+
+=item total - the total number of ratings
+=item avg - the average of the ratings
+=item avgint - the integer form of the average
+=item value - the user's rating
+
+=back
+
+=cut
+
+my ($total_query_sth, $user_query_sth);
+sub get_rating {
+ my ( $biblionumber, $borrowernumber ) = @_;
+ my $dbh = C4::Context->dbh;
+
+ my $total_query = "
+ SELECT AVG(value) AS average,COUNT(value) AS total FROM ratings
+ WHERE biblionumber = ?";
+ $total_query_sth = $total_query_sth || $dbh->prepare($total_query);
+
+ $total_query_sth->execute($biblionumber);
+ my $total_query_res = $total_query_sth->fetchrow_hashref();
+
+ my $user_rating = 0;
+ if ($borrowernumber) {
+ my $user_query = "
+ SELECT value from ratings
+ WHERE biblionumber = ? and borrowernumber = ?";
+ $user_query_sth ||= $dbh->prepare($user_query);
+
+ $user_query_sth->execute( $biblionumber, $borrowernumber );
+ my $user_query_res = $user_query_sth->fetchrow_hashref();
+ $user_rating = $user_query_res->{value} || 0;
+ }
+ my ( $avg, $avgint ) = 0;
+ $avg = $total_query_res->{average} || 0;
+ $avgint = sprintf( "%.0f", $avg );
+
+ my %rating_hash;
+ $rating_hash{total} = $total_query_res->{total} || 0;
+ $rating_hash{avg} = $avg;
+ $rating_hash{avgint} = $avgint;
+ $rating_hash{value} = $user_rating;
+ return \%rating_hash;
+}
+
+=head2 add_rating
+
+ add_rating($biblionumber, $borrowernumber, $value)
+
+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
+
+my ($delete_query_sth, $insert_query_sth);
+sub add_rating {
+ my ( $biblionumber, $borrowernumber, $value ) = @_;
+ if (!defined($biblionumber) || !defined($borrowernumber) ||
+ $value < 0 || $value > 5) {
+ # Seen this happen, want to know about it if it happens again.
+ carp "Invalid input coming in to C4::Ratings::add_rating";
+ return;
+ }
+ if ($borrowernumber == 0) {
+ carp "Attempted to add a rating for borrower number 0";
+ return;
+ }
+ my $dbh = C4::Context->dbh;
+ my $delete_query = "DELETE FROM ratings WHERE borrowernumber = ? AND biblionumber = ? LIMIT 1";
+ my $delete_query_sth ||= $dbh->prepare($delete_query);
+ $delete_query_sth->execute( $borrowernumber, $biblionumber );
+ return if $value == 0; # We don't add a rating for zero
+
+ my $insert_query = "INSERT INTO ratings (borrowernumber,biblionumber,value)
+ VALUES (?,?,?)";
+ $insert_query_sth ||= $dbh->prepare($insert_query);
+ $insert_query_sth->execute( $borrowernumber, $biblionumber, $value );
+}
+
+1;
diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql
index 8b84019..8a7aec0 100644
--- a/installer/data/mysql/kohastructure.sql
+++ b/installer/data/mysql/kohastructure.sql
@@ -2612,6 +2612,22 @@ CREATE TABLE `fieldmapping` (
PRIMARY KEY (`id`)
) 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
+ `value` tinyint(1) NOT NULL, --- the rating, from 1-5
+ `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
+ PRIMARY KEY (`borrowernumber`,`biblionumber`),
+ KEY `ratings_borrowers_fk_1` (`borrowernumber`),
+ KEY `ratings_biblionumber_fk_1` (`biblionumber`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl
index 030897c..dbddaaa 100755
--- a/installer/data/mysql/updatedatabase.pl
+++ b/installer/data/mysql/updatedatabase.pl
@@ -4432,6 +4432,26 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
SetVersion ($DBversion);
}
+$DBversion = 'xxx';
+if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
+ $dbh->do( qq |
+ CREATE TABLE `ratings` (
+ `borrowernumber` int(11) NOT NULL,
+ `biblionumber` int(11) NOT NULL,
+ `value` tinyint(1) NOT NULL,
+ `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
+ PRIMARY KEY (`borrowernumber`,`biblionumber`),
+ KEY `ratings_borrowers_fk_1` (`borrowernumber`),
+ KEY `ratings_biblionumber_fk_1` (`biblionumber`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 | );
+
+ $dbh->do("INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('RatingsEnabled','','Enabled or disables ratings feature in the OPAC',NULL,'YesNo')");
+
+ print "Upgrade to $DBversion done (Added 'ratings' table, and 'RatingsEnabled' syspref\n";
+ SetVersion ($DBversion);
+}
+
+
=head1 FUNCTIONS
=head2 DropAllForeignKeys($table)
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 4a7c652..7f6339c 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
@@ -268,6 +268,12 @@ OPAC:
- pref: numSearchRSSResults
class: long
- search results in the RSS feed.
+ -
+ - pref: RatingsEnabled
+ choices:
+ yes: Show
+ no: "Don't show"
+ - star ratings
Policy:
-
- pref: singleBranchMode
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..5a03d3f
--- /dev/null
+++ b/koha-tmpl/opac-tmpl/prog/en/lib/jquery/plugins/jquery.rating.js
@@ -0,0 +1,344 @@
+/*
+ ### jQuery Star Rating Plugin v3.10 - 2009-03-23 ###
+ * 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 */
+ );
+
+ // loop through each matched element
+ this
+ .not('.star-rating-applied')
+ .addClass('star-rating-applied')
+ .each(function(){
+
+ // Load control parameters / find context / etc
+ var eid = (this.name || 'unnamed-rating').replace(/\[|\]+/g, "_");
+ var context = $(this.form || document.body);
+ var input = $(this);
+ var raters = context.data('rating') || { count:0 };
+ var rater = raters[eid];
+ var control;
+
+ // if rater is available, verify that the control still exists
+ if(rater) control = rater.data('rating');
+
+ if(rater && control){
+ // add star to control if rater is available and the same control still exists
+ control.count++;
+
+ }
+ else{
+ // create new control if first star or control element was removed/replaced
+
+ // Initialize options for this raters
+ 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')) control.readOnly = 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;
+
+ // 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, {
+
+ 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){ // select a value
+ 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');
+ // 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');
+ });
+ }
+ 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
+ if(control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]);// callback event
+ },// $.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 40af8f5..3fa4f12 100644
--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt
@@ -1,6 +1,8 @@
[% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] Catalog › Details for: [% title |html %][% FOREACH subtitl IN subtitle %], [% subtitl.subfield %][% END %]
[% INCLUDE 'doc-head-close.inc' %]
<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.tablesorter.min.js"></script>
+<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.rating.js"></script>
+<link rel="stylesheet" type="text/css" href="[% themelang %]/css/jquery.rating.css" />
<script type="text/JavaScript" language="JavaScript">
//<![CDATA[
$(document).ready(function() {
@@ -47,7 +49,30 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
YAHOO.util.Event.addListener("furthersearches", "click", furthersearchesMenu.show, null, furthersearchesMenu);
YAHOO.widget.Overlay.windowResizeEvent.subscribe(positionfurthersearchesMenu);
});
-
+
+[% IF (RatingsEnabled) %]
+$(document).ready(function() {
+
+$(".auto-submit-star").rating({
+ callback: function(value, link){
+ $.post("/cgi-bin/koha/opac-ratings.pl",
+ { rating: value,
+ biblionumber: "[% biblionumber %]"
+ },
+ function(data){
+ $("#rating_total").html(' ('+data.total+' '+ (data.total==1 ? _('vote') : _('votes'))+')');
+ if (data.value) {
+ $("#rating_user").text(_('your rating added: ')+data.value);
+ } else {
+ $("#rating_user").text('');
+ }
+ }
+ , "json");
+ }
+});
+
+});
+[% END %]
//]]>
</script>
[% IF ( opacuserlogin ) %][% IF ( loggedinusername ) %][% IF ( TagsEnabled ) %]<style type="text/css">
@@ -311,6 +336,29 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
</span>
[% END %][% END %][% END %]
+ [% IF (RatingsEnabled) %]
+ <div class="results_summary">
+ <input class="auto-submit-star" type="radio" name="rating[% biblionumber %]" value="1" [% IF (rating_val_1) %]checked="1"[% END %] [% IF (rating_readonly) %]disabled="disabled"[% END %] />
+ <input class="auto-submit-star" type="radio" name="rating[% biblionumber %]" value="2" [% IF (rating_val_2) %]checked="1"[% END %] [% IF (rating_readonly) %]disabled="disabled"[% END %] />
+ <input class="auto-submit-star" type="radio" name="rating[% biblionumber %]" value="3" [% IF (rating_val_3) %]checked="1"[% END %] [% IF (rating_readonly) %]disabled="disabled"[% END %] />
+ <input class="auto-submit-star" type="radio" name="rating[% biblionumber %]" value="4" [% IF (rating_val_4) %]checked="1"[% END %] [% IF (rating_readonly) %]disabled="disabled"[% END %] />
+ <input class="auto-submit-star" type="radio" name="rating[% biblionumber %]" value="5" [% IF (rating_val_5) %]checked="1"[% END %] [% IF (rating_readonly) %]disabled="disabled"[% END %] />
+
+ <input type="hidden" name='biblionumber' value="[% biblionumber %]" />
+
+ <span id="rating_total" >
+[% IF(rating_total) %] ([% rating_total %] [% IF (rating_total==1) %]vote[% ELSE %]votes[% END %])[% END %]
+</span>
+
+ <span id="rating_user">[% IF (rating_value) %]your rating: [% rating_value %][% END %]</span>
+ [% IF (rating_readonly) %]
+ <span id="rating_login">Log in to add your rating.</span>
+ [% END %]
+</div>
+
+[% 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 bdc4050..78928d1 100644
--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt
@@ -8,6 +8,10 @@
[% 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" />
+<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.rating.js"></script>
+
+<link rel="stylesheet" type="text/css" href="[% themelang %]/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>
@@ -78,6 +82,8 @@ function tagAdded() {
KOHA.Tags.add_multitags_button(bibs, tag);
return false;
}[% END %][% END %]
+
+
[% IF ( OpacHighlightedWords ) %]
var q_array = new Array(); // holds search terms if available
@@ -230,7 +236,32 @@ $(document).ready(function(){
[% END %][% END %]
[% IF OpenLibraryCovers %]KOHA.OpenLibrary.GetCoverFromIsbn();[% END %]
[% IF ( GoogleJackets ) %]KOHA.Google.GetCoverFromIsbn();[% END %]
+
+
+}); // end of $(document).ready
+
+[% IF ( RatingsEnabled ) %]
+$(document).ready(function() {
+ $('.auto-submit-star').rating({
+ callback: function(value, link){
+ var bibnum = this.name.replace(/^rating/, "");
+
+ $.post("/cgi-bin/koha/opac-ratings.pl", {
+ rating: value,
+ biblionumber: bibnum
+ }, function(data){
+ $("#rating_total_"+bibnum).html(" ("+data.total+' '+ (data.total==1 ? _('vote') : _('votes'))+')');
+ if (data.value) {
+ $("#rating_value_"+bibnum).text(_('your rating added: ')+data.value);
+ } else {
+ $("#rating_value_"+bibnum).text('');
+ }
+ }, "json");
+ }
+ });
});
+[% END %]
+
//]]>
</script>
</head>
@@ -504,6 +535,33 @@ $(document).ready(function(){
</div>[% END %]
[% END %]
[% END %][% END %]
+
+[% IF ( RatingsEnabled ) %]
+<div class="results_summary">
+ <form name="ratingform[% SEARCH_RESULT.biblionumber %]" method="post" action="/cgi-bin/koha/opac-ratings.pl">
+ <input class="auto-submit-star" type="radio" name="rating[% SEARCH_RESULT.biblionumber %]" value="1" [% IF ( SEARCH_RESULT.rating_val_1 ) %]checked="1"[% END %] [% IF ( rating_readonly ) %]disabled="disabled"[% END %] />
+ <input class="auto-submit-star" type="radio" name="rating[% SEARCH_RESULT.biblionumber %]" value="2" [% IF ( SEARCH_RESULT.rating_val_2 ) %]checked="1"[% END %] [% IF ( rating_readonly ) %]disabled="disabled"[% END %] />
+ <input class="auto-submit-star" type="radio" name="rating[% SEARCH_RESULT.biblionumber %]" value="3" [% IF ( SEARCH_RESULT.rating_val_3 ) %]checked="1"[% END %] [% IF ( rating_readonly ) %]disabled="disabled"[% END %] />
+ <input class="auto-submit-star" type="radio" name="rating[% SEARCH_RESULT.biblionumber %]" value="4" [% IF ( SEARCH_RESULT.rating_val_4 ) %]checked="1"[% END %] [% IF ( rating_readonly ) %]disabled="disabled"[% END %] />
+ <input class="auto-submit-star" type="radio" name="rating[% SEARCH_RESULT.biblionumber %]" value="5" [% IF ( SEARCH_RESULT.rating_val_5 ) %]checked="1"[% END %] [% IF ( rating_readonly ) %]disabled="disabled"[% END %] />
+ <input type="hidden" name='[% SEARCH_RESULT.biblionumber %]' value="[% SEARCH_RESULT.biblionumber %]" />
+ <span id="rating_total_[% SEARCH_RESULT.biblionumber %]">
+ [% IF (SEARCH_RESULT.rating_total) %]
+ ([% SEARCH_RESULT.rating_total %] [% IF (SEARCH_RESULT.rating_total==1) %]vote[% ELSE %]votes[% END %])
+ [% END %]
+ </span>
+
+ <span id="rating_value_[% SEARCH_RESULT.biblionumber %]">
+ [% IF ( SEARCH_RESULT.rating_value ) %] your rating: [% SEARCH_RESULT.rating_value %][% END %]
+ </span>
+
+ </form>
+ <br />
+</div>
+[% END %]
+
+
+
[% IF ( SEARCH_RESULT.searchhighlightblob ) %]<span class="results_summary"><span class="label">Match:</span> [% SEARCH_RESULT.searchhighlightblob %]</span>[% END %]
<span class="results_summary actions"><span class="label">Actions:</span>
diff --git a/koha-tmpl/opac-tmpl/prog/images/delete.gif b/koha-tmpl/opac-tmpl/prog/images/delete.gif
new file mode 100644
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 at 6Vqe
z at 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 at 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 at DaO@p*l}R7K&xy_%z+DytsIk;xgB`2439K+b7?GbXmoN_5mIg1 at _?b4)vHb2
zW4=iz(~<TC27yT_6CAg$YSazO;JC%ee5xbs^c)q-iOvDjBs>l-D at 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 at 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 at 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 at 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 at nLFbqN;ve
z&H|wp at 2R5NS2`L#KJ=KR(rKEJaLDyUmqb%cL}by=)-=YHmH-A at k7GPXma%d?aC*qL
zh)X7I#x;cnUQ^jS^;|kOFmg at 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 e18e046..99b995a 100755
--- a/opac/opac-detail.pl
+++ b/opac/opac-detail.pl
@@ -37,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;
@@ -46,6 +47,8 @@ use MARC::Record;
use MARC::Field;
use List::MoreUtils qw/any none/;
+#use Smart::Comments '####';
+
BEGIN {
if (C4::Context->preference('BakerTaylorEnabled')) {
require C4::External::BakerTaylor;
@@ -318,6 +321,20 @@ foreach ( @$reviews ) {
$_->{userid} = $borrowerData->{'userid'};
$_->{cardnumber} = $borrowerData->{'cardnumber'};
$_->{datereviewed} = format_date($_->{datereviewed});
+
+
+
+
+# my $value = get_rating_by_review($_->{reviewid});
+ my $rating = get_rating( $biblionumber , $_->{borrowernumber});
+
+ $_->{"borr_rating_val_".$rating->{value}} = 1;
+ $_->{rating} = $rating->{value} ;
+
+ #### $rating
+#### $_
+
+
if ($borrowerData->{'borrowernumber'} eq $borrowernumber) {
$_->{your_comment} = 1;
$loggedincommenter = 1;
@@ -564,6 +581,21 @@ if (C4::Context->preference("OPACURLOpenInNewWindow")) {
$template->param(covernewwindow => 'false');
}
+if (C4::Context->preference('RatingsEnabled') ) {
+my $rating = get_rating( $biblionumber, $borrowernumber );
+$template->param(
+ RatingsShowOnDetail => 1,
+ RatingsEnabled => 1,
+ rating_value => $rating->{'value'},
+ rating_total => $rating->{'total'},
+ rating_avg => $rating->{'avg'},
+ rating_avgint => $rating->{'avgint'},
+ rating_readonly => ( $borrowernumber ? 0 : 1 ),
+ borrowernumber => $borrowernumber,
+ "rating_val_" . "$rating->{'avgint'}" => $rating->{'avgint'},
+ );
+}
+
#Search for title in links
my $marccontrolnumber = GetMarcControlnumber ($record, $marcflavour);
diff --git a/opac/opac-ratings.pl b/opac/opac-ratings.pl
new file mode 100755
index 0000000..2c8b115
--- /dev/null
+++ b/opac/opac-ratings.pl
@@ -0,0 +1,104 @@
+#!/usr/bin/perl
+
+# Copyright 2010 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., 59 Temple Place,
+# Suite 330, Boston, MA 02111-1307 USA
+
+=head1
+
+opac-ratings.pl - API endpoint for setting rating values
+
+This receives a POST containing biblionumber and rating. It
+updates rating for the logged in user.
+
+=cut
+
+use strict;
+use warnings;
+use CGI;
+use CGI::Cookie; # need to check cookies before having CGI parse the POST request
+use JSON;
+
+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 Data::Dumper;
+
+my %ratings = ();
+my %counts = ();
+my @errors = ();
+
+my $is_ajax = is_ajax();
+
+my $query = ($is_ajax) ? &ajax_auth_cgi( {} ) : CGI->new();
+
+my $biblionumber = $query->param('biblionumber');
+my $value;
+
+foreach ( $query->param ) {
+ if (/^rating(.*)/) {
+ $value = $query->param($_);
+ last;
+ }
+}
+
+my ( $template, $loggedinuser, $cookie );
+
+if ($is_ajax) {
+ $loggedinuser = C4::Context->userenv->{'number'};
+ add_rating( $biblionumber, $loggedinuser, $value );
+ my $rating = get_rating($biblionumber, $loggedinuser);
+ my $js_reply = "{total: $rating->{'total'}, value: $rating->{'value'}}";
+
+ output_ajax_with_http_headers( $query, $js_reply );
+ exit;
+} else {
+ # Future enhancements could have this have its own template to
+ # display the users' ratings, or tie in with their reading history
+ # to get them to rate things they read recently.
+ ( $template, $loggedinuser, $cookie ) = get_template_and_user(
+ { template_name => "opac-user.tmpl",
+ query => $query,
+ type => "opac",
+ authnotrequired => 0, # auth required to add ratings
+ debug => 0,
+ }
+ );
+}
+
+my $results = [];
+
+( scalar @errors ) and $template->param( ERRORS => \@errors );
+
+output_html_with_http_headers $query, $cookie, $template->output;
+
+sub ajax_auth_cgi ($) { # returns CGI object
+ 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 );
+ if ( $auth_status ne "ok" ) {
+ output_ajax_with_http_headers $input, "window.alert('Your CGI session cookie ($sessid) is not current. " . "Please refresh the page and try again.');\n";
+ exit 0;
+ }
+ return $input;
+}
+
diff --git a/opac/opac-search.pl b/opac/opac-search.pl
index 81b7ce6..9b76d12 100755
--- a/opac/opac-search.pl
+++ b/opac/opac-search.pl
@@ -36,10 +36,14 @@ use C4::Biblio; # GetBiblioData
use C4::Koha;
use C4::Tags qw(get_tags);
use C4::Branch; # GetBranches
+use C4::Ratings;
+
use POSIX qw(ceil floor strftime);
use URI::Escape;
use Storable qw(thaw freeze);
+#use Smart::Comments '####';
+
my $DisplayMultiPlaceHold = C4::Context->preference("DisplayMultiPlaceHold");
# create a new CGI object
@@ -111,6 +115,7 @@ if (C4::Context->preference('BakerTaylorEnabled')) {
BakerTaylorBookstoreURL => C4::Context->preference('BakerTaylorBookstoreURL'),
);
}
+
if (C4::Context->preference('TagsEnabled')) {
$template->param(TagsEnabled => 1);
foreach (qw(TagsShowOnList TagsInputOnList)) {
@@ -118,6 +123,14 @@ if (C4::Context->preference('TagsEnabled')) {
}
}
+if (C4::Context->preference('RatingsEnabled')) {
+#### $borrowernumber
+ $template->param(rating_readonly => 1) unless $borrowernumber ;
+ $template->param(borrowernumber => $borrowernumber );
+}
+
+
+
## URI Re-Writing
# Deprecated, but preserved because it's interesting :-)
# The same thing can be accomplished with mod_rewrite in
@@ -485,12 +498,26 @@ for (my $i=0;$i<@servers;$i++) {
limit=>$tag_quantity });
}
}
- if (C4::Context->preference('COinSinOPACResults')) {
- foreach (@newresults) {
- $_->{coins} = GetCOinSBiblio($_->{'biblionumber'});
- }
- }
-
+ if (C4::Context->preference('COinSinOPACResults')) {
+ foreach (@newresults) {
+ $_->{coins} = GetCOinSBiblio($_->{'biblionumber'});
+ }
+ }
+
+ if (C4::Context->preference('RatingsEnabled')) {
+ foreach (@newresults) {
+ my $rating = get_rating( $_->{'biblionumber'}, $borrowernumber );
+
+ my $bib = $_->{'biblionumber'};
+ $_->{'rating_user'} = $rating->{'user'};
+ $_->{'rating_total'} = $rating->{'total'};
+ $_->{'rating_avg'} = $rating->{'avg'};
+ $_->{'rating_avgint'} = $rating->{'avgint'};
+ $_->{ 'rating_val_' . $rating->{'avgint'} } = $rating->{'avgint'};
+ $_->{'rating_value'} = $rating->{'value'};
+ }
+ }
+
if ($results_hashref->{$server}->{"hits"}){
$total = $total + $results_hashref->{$server}->{"hits"};
}
@@ -609,7 +636,6 @@ for (my $i=0;$i<@servers;$i++) {
};
}
-
}
# now, show twenty pages, with the current one smack in the middle
else {
--
1.7.2.3
More information about the Koha-patches
mailing list