[Koha-patches] [PATCH] Bug 6772 - recommendation system
Robin Sheat
robin at catalyst.net.nz
Thu Aug 25 08:38:42 CEST 2011
From: Chris Cormack <chris at bigballofwax.co.nz>
This allows Koha to link similar books to provide recommendations to
users. It provides a cron job that should be run regularly (daily or
weekly perhaps) to build a recommendation index. When viewing books in
the OPAC, those items with the closest match will be displayed.
Author: Chris Cormack <chris at bigballofwax.co.nz>
Author: Robin Sheat <robin at catalyst.net.nz>
---
C4/Recommendations.pm | 204 ++++++++++++++++++++
debian/koha-common.cron.daily | 4 +
installer/data/mysql/de-DE/mandatory/sysprefs.sql | 2 +-
installer/data/mysql/en/mandatory/sysprefs.sql | 1 +
.../1-Obligatoire/unimarc_standard_systemprefs.sql | 1 +
installer/data/mysql/it-IT/necessari/sysprefs.sql | 1 +
installer/data/mysql/kohastructure.sql | 11 +
.../data/mysql/nb-NO/1-Obligatorisk/sysprefs.sql | 1 +
installer/data/mysql/pl-PL/mandatory/sysprefs.sql | 1 +
...m_preferences_full_optimal_for_install_only.sql | 1 +
...m_preferences_full_optimal_for_install_only.sql | 1 +
installer/data/mysql/updatedatabase.pl | 17 ++
.../prog/en/modules/admin/preferences/opac.pref | 6 +
koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 11 +
misc/cronjobs/recommendations.pl | 53 +++++
opac/opac-detail.pl | 8 +
16 files changed, 322 insertions(+), 1 deletions(-)
create mode 100644 C4/Recommendations.pm
create mode 100755 misc/cronjobs/recommendations.pl
diff --git a/C4/Recommendations.pm b/C4/Recommendations.pm
new file mode 100644
index 0000000..0cd0e00
--- /dev/null
+++ b/C4/Recommendations.pm
@@ -0,0 +1,204 @@
+package C4::Recommendations;
+
+# Copyright 2009,2011 Catalyst IT
+#
+# 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 NAME
+
+ C4::Recommendations - Koha module for producing reading recommendations
+
+=head1 SYNOPSIS
+
+ use C4::Recommendations;
+
+ build_recommendations();
+
+ my $recommended_books = get_recommendations($biblio);
+
+=head1 DESCRIPTION
+
+This looks at the issue history, and counts how many times each particular book
+has been taken out by someone who also has taken out another particular book,
+recording that as a hit for each pair.
+
+For example, if 3 people have taken out book A and book B, then this is
+recorded as three "hits" for that combination, and so it'll show as a
+recommendation with that strength.
+
+=head1 EXPORT
+
+None by default, however C<build_recommendations> and C<get_recommendations>
+can be imported optionally.
+
+=head1 FUNCTIONS
+
+=cut
+
+use strict;
+use warnings;
+use C4::Context;
+
+require Exporter;
+
+our @ISA = qw(Exporter);
+
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
+our @EXPORT_OK = qw(
+ build_recommendations
+ get_recommendations
+);
+
+our $VERSION = '0.01';
+
+=head2 build_recommendations
+
+ build_recommendations
+
+This runs through all the issues and generates the tables of recommendations.
+Note that it'll likely take a long time to run, and put stress on the database,
+so do it at a low peak time.
+
+=cut
+
+sub build_recommendations {
+ my $dbh = C4::Context->dbh;
+ $dbh->do("TRUNCATE recommendations");
+ my $all_issues_query = qq/
+SELECT biblio.biblionumber,borrowernumber
+FROM old_issues,biblio,items
+WHERE old_issues.itemnumber=items.itemnumber
+AND items.biblionumber=biblio.biblionumber
+ /;
+ my $all_issues_sth = $dbh->prepare($all_issues_query);
+ my $borrower_issues_query = qq/
+SELECT biblio.biblionumber,borrowernumber
+FROM old_issues,biblio,items
+WHERE old_issues.itemnumber=items.itemnumber
+AND items.biblionumber=biblio.biblionumber
+AND old_issues.borrowernumber = ?
+AND items.biblionumber > ?
+ /;
+ my $borrower_issues_sth = $dbh->prepare($borrower_issues_query);
+ my $recommendations_select = $dbh->prepare(qq/
+SELECT * FROM recommendations
+WHERE biblio_one = ? AND
+biblio_two = ?
+ /);
+ my $recommendations_update = $dbh->prepare(qq/
+UPDATE recommendations
+SET hit_count = ?
+WHERE biblio_one = ?
+AND biblio_two = ?
+ /);
+ my $recommendations_insert = $dbh->prepare(qq/
+INSERT INTO recommendations (biblio_one,biblio_two,hit_count) VALUES (?,?,?)
+ /);
+
+ $all_issues_sth->execute();
+ while ( my $issue = $all_issues_sth->fetchrow_hashref() ) {
+# warn $issue->{'borrowernumber'};
+ $borrower_issues_sth->execute( $issue->{'borrowernumber'}, $issue->{biblionumber} );
+ while ( my $borrowers_issue = $borrower_issues_sth->fetchrow_hashref() ) {
+# warn $borrowers_issue->{'biblionumber'};
+ $recommendations_select->execute( $issue->{'biblionumber'},
+ $borrowers_issue->{'biblionumber'} );
+ if ( my $recommendation = $recommendations_select->fetchrow_hashref() ) {
+ $recommendation->{'hit_count'}++;
+ $recommendations_update->execute(
+ $recommendation->{'hit_count'},
+ $issue->{'biblionumber'},
+ $borrowers_issue->{'biblionumber'}
+ );
+ } else {
+ $recommendations_insert->execute(
+ $issue->{'biblionumber'},
+ $borrowers_issue->{'biblionumber'},
+ 1
+ );
+ }
+ }
+
+ }
+}
+
+=head2 get_recommendations
+
+ my $recommendations = get_recommendations($biblionumber, $limit)
+ foreach my $rec (@$recommendations) {
+ print $rec->{biblionumber}.": ".$rec->{title}."\n";
+ }
+
+This gets the recommendations for a particular biblio, returning an array of
+hashes containing C<biblionumber> and C<title>. The array is ordered from
+most-recommended to least.
+
+C<$limit> restrictes the amount of results returned. If it's not supplied,
+it defaults to 100.
+
+=cut
+
+sub get_recommendations {
+ my ($biblionumber, $limit) = @_;
+ $limit ||= 100;
+
+ my $dbh = C4::Context->dbh();
+
+ # Two parts: first get the biblio_one side, then get the
+ # biblio_two side. I'd love to know how to squish this into one query.
+ my $sth = $dbh->prepare(qq/
+SELECT biblio.biblionumber,biblio.title, hit_count
+FROM biblio,recommendations
+WHERE biblio.biblionumber = biblio_two
+AND biblio_one = ?
+ORDER BY hit_count DESC
+LIMIT ?
+ /);
+ $sth->execute($biblionumber, $limit);
+ my $res = $sth->fetchall_arrayref({});
+
+ $sth = $dbh->prepare(qq/
+SELECT biblio.biblionumber,biblio.title, hit_count
+FROM biblio,recommendations
+WHERE biblio.biblionumber = biblio_one
+AND biblio_two = ?
+ORDER BY hit_count DESC
+LIMIT ?
+ /);
+ $sth->execute($biblionumber, $limit);
+ push @{ $res }, @{$sth->fetchall_arrayref({})};
+
+ $res = \@{ @{$res}[0..$limit] } if (@$res > $limit);
+
+ my @res = sort { $b->{hit_count} <=> $a->{hit_count} } @$res;
+ return \@res;
+}
+
+1;
+__END__
+
+=head1 AUTHOR
+
+=over
+
+=item Chris Cormack, E<lt>chrisc at catalyst.net.nzE<gt>
+
+=item Robin Sheat, E<lt>robin at catalyst.net.nzE<gt>
+
+=back
+
diff --git a/debian/koha-common.cron.daily b/debian/koha-common.cron.daily
index e2c7a80..86a7fe5 100644
--- a/debian/koha-common.cron.daily
+++ b/debian/koha-common.cron.daily
@@ -23,3 +23,7 @@ koha-foreach --enabled /usr/share/koha/bin/cronjobs/services_throttle.pl > /dev/
koha-foreach --enabled /usr/share/koha/bin/cronjobs/cleanup_database.pl --sessions --zebraqueue 10
koha-foreach --enabled --noemail /usr/share/koha/bin/cronjobs/cleanup_database.pl --mail
koha-run-backups --days 2 --output /var/spool/koha
+
+# If recommendations are enabled, this may take a while to run. However, it'll
+# stop pretty much immediately if it doesn't need to do anything.
+koha-foreach --enabled /usr/share/koha/bin/cronjobs/recommendations.pl
diff --git a/installer/data/mysql/de-DE/mandatory/sysprefs.sql b/installer/data/mysql/de-DE/mandatory/sysprefs.sql
index 6df6a9f..1107703 100755
--- a/installer/data/mysql/de-DE/mandatory/sysprefs.sql
+++ b/installer/data/mysql/de-DE/mandatory/sysprefs.sql
@@ -317,4 +317,4 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES (
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('BasketConfirmations', '1', 'When closing or reopening a basket,', 'always ask for confirmation.|do not ask for confirmation.', 'Choice');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('MARCAuthorityControlField008', '|| aca||aabn | a|a d', NULL, NULL, 'Textarea');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpenLibraryCovers',0, 'If ON Openlibrary book covers will be show',NULL,'YesNo');
-
+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('ShowRecommendations',0,'If ON recommendation information will be generated and displayed',NULL,'YesNo');
diff --git a/installer/data/mysql/en/mandatory/sysprefs.sql b/installer/data/mysql/en/mandatory/sysprefs.sql
index 8407505..3d17252 100755
--- a/installer/data/mysql/en/mandatory/sysprefs.sql
+++ b/installer/data/mysql/en/mandatory/sysprefs.sql
@@ -317,3 +317,4 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES (
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('BasketConfirmations', '1', 'When closing or reopening a basket,', 'always ask for confirmation.|do not ask for confirmation.', 'Choice');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('MARCAuthorityControlField008', '|| aca||aabn | a|a d', NULL, NULL, 'Textarea');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpenLibraryCovers',0,'If ON Openlibrary book covers will be show',NULL,'YesNo');
+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('ShowRecommendations',0,'If ON recommendation information will be generated and displayed',NULL,'YesNo');
diff --git a/installer/data/mysql/fr-FR/1-Obligatoire/unimarc_standard_systemprefs.sql b/installer/data/mysql/fr-FR/1-Obligatoire/unimarc_standard_systemprefs.sql
index d46502c..d13cc73 100755
--- a/installer/data/mysql/fr-FR/1-Obligatoire/unimarc_standard_systemprefs.sql
+++ b/installer/data/mysql/fr-FR/1-Obligatoire/unimarc_standard_systemprefs.sql
@@ -318,4 +318,5 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES (
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('BasketConfirmations', '1', 'When closing or reopening a basket,', 'always ask for confirmation.|do not ask for confirmation.', 'Choice');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('MARCAuthorityControlField008', '|| aca||aabn | a|a d', NULL, NULL, 'Textarea');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpenLibraryCovers',0,'If ON Openlibrary book covers will be show',NULL,'YesNo');
+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('ShowRecommendations',0,'If ON recommendation information will be generated and displayed',NULL,'YesNo');
diff --git a/installer/data/mysql/it-IT/necessari/sysprefs.sql b/installer/data/mysql/it-IT/necessari/sysprefs.sql
index 3448738..17cc120 100755
--- a/installer/data/mysql/it-IT/necessari/sysprefs.sql
+++ b/installer/data/mysql/it-IT/necessari/sysprefs.sql
@@ -304,4 +304,5 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES (
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('BasketConfirmations', '1', 'When closing or reopening a basket,', 'always ask for confirmation.|do not ask for confirmation.', 'Choice');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('MARCAuthorityControlField008', '|| aca||aabn | a|a d', NULL, NULL, 'Textarea');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpenLibraryCovers',0,'If ON Openlibrary book covers will be show',NULL,'YesNo');
+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('ShowRecommendations',0,'If ON recommendation information will be generated and displayed',NULL,'YesNo');
diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql
index 8b84019..3a7f4d3 100644
--- a/installer/data/mysql/kohastructure.sql
+++ b/installer/data/mysql/kohastructure.sql
@@ -2612,6 +2612,17 @@ CREATE TABLE `fieldmapping` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+DROP TABLE IF EXISTS `recommendations`;
+CREATE TABLE `recommendations` (
+ `id` int(11) NOT NULL auto_increment,
+ `biblio_one` int(11),
+ `biblio_two` int(11),
+ `hit_count` int(11),
+ PRIMARY KEY (`id`),
+ KEY `biblio_one_idx` (`biblio_one`),
+ KEY `biblio_two_idx` (`biblio_two`)
+) 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/nb-NO/1-Obligatorisk/sysprefs.sql b/installer/data/mysql/nb-NO/1-Obligatorisk/sysprefs.sql
index ac4c3e2..37eca0f 100644
--- a/installer/data/mysql/nb-NO/1-Obligatorisk/sysprefs.sql
+++ b/installer/data/mysql/nb-NO/1-Obligatorisk/sysprefs.sql
@@ -324,3 +324,4 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES (
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('BasketConfirmations', '1', 'When closing or reopening a basket,', 'always ask for confirmation.|do not ask for confirmation.', 'Choice');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('MARCAuthorityControlField008', '|| aca||aabn | a|a d', NULL, NULL, 'Textarea');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpenLibraryCovers',0,'If ON Openlibrary book covers will be show',NULL,'YesNo');
+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('ShowRecommendations',0,'If ON recommendation information will be generated and displayed',NULL,'YesNo');
diff --git a/installer/data/mysql/pl-PL/mandatory/sysprefs.sql b/installer/data/mysql/pl-PL/mandatory/sysprefs.sql
index 3087f3c..6e9a72a 100755
--- a/installer/data/mysql/pl-PL/mandatory/sysprefs.sql
+++ b/installer/data/mysql/pl-PL/mandatory/sysprefs.sql
@@ -316,3 +316,4 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES (
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('BasketConfirmations', '1', 'When closing or reopening a basket,', 'always ask for confirmation.|do not ask for confirmation.', 'Choice');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('MARCAuthorityControlField008', '|| aca||aabn | a|a d', NULL, NULL, 'Textarea');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpenLibraryCovers',0, 'If ON Openlibrary book covers will be show',NULL,'YesNo');
+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('ShowRecommendations',0,'If ON recommendation information will be generated and displayed',NULL,'YesNo');
diff --git a/installer/data/mysql/ru-RU/mandatory/system_preferences_full_optimal_for_install_only.sql b/installer/data/mysql/ru-RU/mandatory/system_preferences_full_optimal_for_install_only.sql
index c0912ba..8e82624 100755
--- a/installer/data/mysql/ru-RU/mandatory/system_preferences_full_optimal_for_install_only.sql
+++ b/installer/data/mysql/ru-RU/mandatory/system_preferences_full_optimal_for_install_only.sql
@@ -371,3 +371,4 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES (
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('BasketConfirmations', '1', 'When closing or reopening a basket,', 'always ask for confirmation.|do not ask for confirmation.', 'Choice');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('MARCAuthorityControlField008', '|| aca||aabn | a|a d', NULL, NULL, 'Textarea');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpenLibraryCovers',0,'If ON Openlibrary book covers will be show',NULL,'YesNo');
+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('ShowRecommendations',0,'If ON recommendation information will be generated and displayed',NULL,'YesNo');
diff --git a/installer/data/mysql/uk-UA/mandatory/system_preferences_full_optimal_for_install_only.sql b/installer/data/mysql/uk-UA/mandatory/system_preferences_full_optimal_for_install_only.sql
index d334469..afc93e7 100755
--- a/installer/data/mysql/uk-UA/mandatory/system_preferences_full_optimal_for_install_only.sql
+++ b/installer/data/mysql/uk-UA/mandatory/system_preferences_full_optimal_for_install_only.sql
@@ -396,4 +396,5 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES (
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('BasketConfirmations', '1', 'When closing or reopening a basket,', 'always ask for confirmation.|do not ask for confirmation.', 'Choice');
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('MARCAuthorityControlField008', '|| aca||aabn | a|a d', NULL, NULL, 'Textarea');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpenLibraryCovers',0, 'If ON Openlibrary book covers will be show',NULL,'YesNo');
+INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('ShowRecommendations',0,'If ON recommendation information will be generated and displayed',NULL,'YesNo');
diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl
index 030897c..264759f 100755
--- a/installer/data/mysql/updatedatabase.pl
+++ b/installer/data/mysql/updatedatabase.pl
@@ -4432,6 +4432,23 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
SetVersion ($DBversion);
}
+$DBversion = "xxx";
+if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
+ $dbh->do(qq/
+ CREATE TABLE `recommendations` (
+ `id` int(11) NOT NULL auto_increment,
+ `biblio_one` int(11),
+ `biblio_two` int(11),
+ `hit_count` int(11),
+ PRIMARY KEY (`id`),
+ KEY `biblio_one_idx` (`biblio_one`),
+ KEY `biblio_two_idx` (`biblio_two`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8
+ qq/);
+ $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('ShowRecommendations',0,'If ON recommendation information will be generated and displayed',NULL,'YesNo');");
+ print "Add table and syspref track the recommended reading data.\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..cd00daa 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: ShowRecommendations
+ choices:
+ yes: Do
+ no: "Don't"
+ - "generate and display reading recommendations in the OPAC. <i>(Notes: this requires the <tt>recommendations.pl</tt> cron job to be configured to run regularly. This cron job will take a long time to run on catalogs with a sizable circulation history.)</i>"
Policy:
-
- pref: singleBranchMode
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..e5243af 100644
--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt
@@ -363,6 +363,7 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
[% IF ( OPACFRBRizeEditions ) %][% IF ( XISBNS ) %]<li><a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblionumber %]#editions">Editions</a></li>[% END %][% END %]
[% IF ( OPACAmazonEnabled ) %][% IF ( OPACAmazonReviews ) %]<li><a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblionumber %]#amazonreviews">Amazon Reviews</a></li>[% END %][% END %]
+ [% IF ( Recommendations ) %]<li><a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblionumber %]#recommendations">Recommendations</a></li>[% END %]
[% IF ( Babeltheque ) %]<li><a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% biblionumber %]#babeltheque">Babelthèque</a></li>[% END %]
[% IF ( serialcollection ) %]
@@ -728,6 +729,16 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
</div>
[% END %]
+[% IF (Recommendations) %]
+<div id="recommendations">
+<table>
+[% FOREACH recommendation IN recommendation_loop %]
+<tr><td><a href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% recommendation.biblionumber %]">[% recommendation.title | html %]</a></td></tr>
+[% END %]
+</table>
+</div>
+[% END %]
+
[% IF ( OPACFRBRizeEditions ) %][% IF ( XISBNS ) %]
<div id="editions">
diff --git a/misc/cronjobs/recommendations.pl b/misc/cronjobs/recommendations.pl
new file mode 100755
index 0000000..d2b114f
--- /dev/null
+++ b/misc/cronjobs/recommendations.pl
@@ -0,0 +1,53 @@
+#!/usr/bin/perl
+
+# Copyright 2009,2011 Catalyst IT Ltd.
+#
+# 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 NAME
+
+recommendations.pl - cron script to populate the recommendations table
+
+=head1 SYNOPSIS
+
+./recommendations.pl
+
+or, in crontab:
+0 1 * * * recommendations.pl
+
+=head1 DESCRIPTION
+
+=cut
+
+use strict;
+use warnings;
+BEGIN {
+ # find Koha's Perl modules
+ # test carefully before changing this
+ use FindBin;
+ eval { require "$FindBin::Bin/../kohalib.pl" };
+}
+
+use C4::Context;
+use C4::Recommendations qw/ build_recommendations /;
+
+if (C4::Context->preference('ShowRecommendations')) {
+ build_recommendations();
+}
+
+1;
+
+__END__
diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl
index e18e046..b17d77a 100755
--- a/opac/opac-detail.pl
+++ b/opac/opac-detail.pl
@@ -42,6 +42,7 @@ use C4::VirtualShelves;
use C4::XSLT;
use C4::ShelfBrowser;
use C4::Charset;
+use C4::Recommendations qw/ get_recommendations /;
use MARC::Record;
use MARC::Field;
use List::MoreUtils qw/any none/;
@@ -66,6 +67,13 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
my $biblionumber = $query->param('biblionumber') || $query->param('bib');
+if ( C4::Context->preference('ShowRecommendations')){
+ my $recommendations = get_recommendations($biblionumber);
+ $template->param('Recommendations' => 1,
+ 'recommendation_loop' => $recommendations
+ );
+}
+
$template->param( 'AllowOnShelfHolds' => C4::Context->preference('AllowOnShelfHolds') );
$template->param( 'ItemsIssued' => CountItemsIssued( $biblionumber ) );
--
1.7.4.1
More information about the Koha-patches
mailing list