Adding Opac-SearchHistory feature
Enables ppl to store their search history and delete the whole history Adding Storable required by Opac-Search-History Signed-off-by: Galen Charlton <gmcharlt@gmail.com>
This commit is contained in:
parent
7eca37db4f
commit
feeafa8168
65
C4/Auth.pm
65
C4/Auth.pm
|
|
@ -19,6 +19,8 @@ package C4::Auth;
|
|||
|
||||
use strict;
|
||||
use Digest::MD5 qw(md5_base64);
|
||||
use Storable qw(thaw freeze);
|
||||
use URI::Escape;
|
||||
use CGI::Session;
|
||||
|
||||
require Exporter;
|
||||
|
|
@ -225,6 +227,58 @@ sub get_template_and_user {
|
|||
}
|
||||
}
|
||||
}
|
||||
# Logged-in opac search history
|
||||
# If the requested template is an opac one and opac search history is enabled
|
||||
if ($in->{'type'} == "opac" && C4::Context->preference('EnableOpacSearchHistory')) {
|
||||
my $dbh = C4::Context->dbh;
|
||||
my $query = "SELECT COUNT(*) FROM search_history WHERE userid=?";
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute($borrowernumber);
|
||||
|
||||
# If at least one search has already been performed
|
||||
if ($sth->fetchrow_array > 0) {
|
||||
# We show the link in opac
|
||||
$template->param(ShowOpacRecentSearchLink => 1);
|
||||
}
|
||||
|
||||
# And if there's a cookie with searches performed when the user was not logged in,
|
||||
# we add them to the logged-in search history
|
||||
my @recentSearches;
|
||||
my $searchcookie = $in->{'query'}->cookie('KohaOpacRecentSearches');
|
||||
if ($searchcookie){
|
||||
$searchcookie = uri_unescape($searchcookie);
|
||||
if (thaw($searchcookie)) {
|
||||
@recentSearches = @{thaw($searchcookie)};
|
||||
}
|
||||
|
||||
if (@recentSearches > 0) {
|
||||
my $query = "INSERT INTO search_history(userid, sessionid, query_desc, query_cgi, total, time) VALUES";
|
||||
my $icount = 1;
|
||||
foreach my $asearch (@recentSearches) {
|
||||
$query .= "(";
|
||||
$query .= $borrowernumber . ", ";
|
||||
$query .= '"' . $in->{'query'}->cookie("CGISESSID") . "\", ";
|
||||
$query .= '"' . $asearch->{'query_desc'} . "\", ";
|
||||
$query .= '"' . $asearch->{'query_cgi'} . "\", ";
|
||||
$query .= $asearch->{'total'} . ", ";
|
||||
$query .= 'FROM_UNIXTIME(' . $asearch->{'time'} . "))";
|
||||
if ($icount < @recentSearches) { $query .= ", ";}
|
||||
$icount++;
|
||||
}
|
||||
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute;
|
||||
|
||||
# And then, delete the cookie's content
|
||||
my $newsearchcookie = $in->{'query'}->cookie(
|
||||
-name => 'KohaOpacRecentSearches',
|
||||
-value => freeze([]),
|
||||
-expires => ''
|
||||
);
|
||||
$cookie = [$cookie, $newsearchcookie];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else { # if this is an anonymous session, setup to display public lists...
|
||||
|
||||
|
|
@ -250,6 +304,17 @@ sub get_template_and_user {
|
|||
}
|
||||
|
||||
}
|
||||
# Anonymous opac search history
|
||||
# If opac search history is enabled and at least one search has already been performed
|
||||
if (C4::Context->preference('EnableOpacSearchHistory') && $in->{'query'}->cookie('KohaOpacRecentSearches')) {
|
||||
# We show the link in opac
|
||||
if (thaw(uri_unescape($in->{'query'}->cookie('KohaOpacRecentSearches')))) {
|
||||
my @recentSearches = @{thaw(uri_unescape($in->{'query'}->cookie('KohaOpacRecentSearches')))};
|
||||
if (@recentSearches > 0) {
|
||||
$template->param(ShowOpacRecentSearchLink => 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# these template parameters are set the same regardless of $in->{'type'}
|
||||
$template->param(
|
||||
|
|
|
|||
22
C4/Search.pm
22
C4/Search.pm
|
|
@ -61,6 +61,7 @@ This module provides searching functions for Koha's bibliographic databases
|
|||
&getRecords
|
||||
&buildQuery
|
||||
&NZgetRecords
|
||||
&AddSearchHistory
|
||||
);
|
||||
|
||||
# make all your functions, whether exported or not;
|
||||
|
|
@ -2051,6 +2052,27 @@ sub enabled_staff_search_views
|
|||
);
|
||||
}
|
||||
|
||||
sub AddSearchHistory{
|
||||
my ($borrowernumber,$session,$query_desc,$query_cgi, $total)=@_;
|
||||
my $dbh = C4::Context->dbh;
|
||||
|
||||
# Add the request the user just made
|
||||
my $sql = "INSERT INTO search_history(userid, sessionid, query_desc, query_cgi, total, time) VALUES(?, ?, ?, ?, ?, NOW())";
|
||||
my $sth = $dbh->prepare($sql);
|
||||
$sth->execute($borrowernumber, $session, $query_desc, $query_cgi, $total);
|
||||
return $dbh->last_insert_id(undef, 'search_history', undef,undef,undef);
|
||||
}
|
||||
|
||||
sub GetSearchHistory{
|
||||
my ($borrowernumber,$session)=@_;
|
||||
my $dbh = C4::Context->dbh;
|
||||
|
||||
# Add the request the user just made
|
||||
my $query = "SELECT FROM search_history WHERE (userid=? OR sessionid=?)";
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute($borrowernumber, $session);
|
||||
return $sth->fetchall_hashref({});
|
||||
}
|
||||
|
||||
=head2 z3950_search_args
|
||||
|
||||
|
|
|
|||
|
|
@ -593,6 +593,7 @@ WriteMakefile(
|
|||
'POE' => 0.9999,
|
||||
'POSIX' => 1.09,
|
||||
'Schedule::At' => 1.06,
|
||||
'Storable' => 2.21,
|
||||
'SMS::Send' => 0.05, # optional
|
||||
'Term::ANSIColor' => 1.10,
|
||||
'Test' => 1.25,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
#! /usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use C4::Context;
|
||||
my $dbh=C4::Context->dbh;
|
||||
|
||||
$dbh->do("INSERT INTO `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`) VALUES ('EnableOpacSearchHistory', '1', '', 'Enable or disable opac search history', 'YesNo')");
|
||||
|
||||
my $create = << END;
|
||||
CREATE TABLE IF NOT EXISTS `search_history` (
|
||||
`userid` int(11) NOT NULL,
|
||||
`sessionid` varchar(32) NOT NULL,
|
||||
`query_desc` varchar(255) NOT NULL,
|
||||
`query_cgi` varchar(255) NOT NULL,
|
||||
`total` int(11) NOT NULL,
|
||||
`time` timestamp NOT NULL default CURRENT_TIMESTAMP,
|
||||
KEY `userid` (`userid`),
|
||||
KEY `sessionid` (`sessionid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Opac search history results';
|
||||
END
|
||||
|
||||
$dbh->do($create);
|
||||
|
||||
print "Upgrade done (added OPAC search history preference and table)\n";
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<div id="header-wrapper"><div id="members">
|
||||
<!-- TMPL_IF NAME="opacuserlogin" -->
|
||||
<ul><!-- TMPL_IF NAME="loggedinusername" --><li><span class="members">Welcome, <a href="/cgi-bin/koha/opac-user.pl"><span class="loggedinusername"><!-- TMPL_LOOP NAME="USER_INFO" --><!-- TMPL_VAR NAME="title" --> <!-- TMPL_VAR NAME="firstname" --> <!-- TMPL_VAR NAME="surname" --><!-- /TMPL_LOOP --></span></a></span></li><li><a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1">Log Out</a></li><!-- TMPL_ELSE --><li><a href="/cgi-bin/koha/opac-user.pl">Log in to Your Account</a></li><!-- /TMPL_IF -->
|
||||
</ul>
|
||||
<ul><!-- TMPL_IF NAME="loggedinusername" --><li><span class="members">Welcome, <a href="/cgi-bin/koha/opac-user.pl"><span class="loggedinusername"><!-- TMPL_LOOP NAME="USER_INFO" --><!-- TMPL_VAR NAME="title" --> <!-- TMPL_VAR NAME="firstname" --> <!-- TMPL_VAR NAME="surname" --><!-- /TMPL_LOOP --></span></a></span></li><!-- TMPL_IF NAME="ShowOpacRecentSearchLink" --><li><a href="/cgi-bin/koha/opac-search-history.pl" title="View your search history">Search history</a> [<a href="/cgi-bin/koha/opac-search-history.pl?action=delete" title="Delete your search history" onclick="javascript:return confirm(_('Are you sure you want to delete your search history?'));">x</a>]</li> <!-- /TMPL_IF --><li><a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1">Log Out</a></li><!-- TMPL_ELSE --><li><a href="/cgi-bin/koha/opac-user.pl">Log in to Your Account</a></li><!-- /TMPL_IF -->
|
||||
</ul>
|
||||
<!-- /TMPL_IF -->
|
||||
</div>
|
||||
<!-- TMPL_IF NAME="opacheader" -->
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
<!-- TMPL_INCLUDE NAME="doc-head-open.inc" -->
|
||||
<!-- TMPL_IF NAME="LibraryNameTitle" --><!-- TMPL_VAR NAME="LibraryNameTitle" --><!-- TMPL_ELSE -->Koha Online<!-- /TMPL_IF --> Catalog
|
||||
<!-- TMPL_INCLUDE NAME="doc-head-close.inc" -->
|
||||
<script type="text/javascript" src="<!-- TMPL_VAR name="themelang" -->/lib/jquery/plugins/jquery.tablesorter.min.js"></script>
|
||||
<script type="text/JavaScript" language="JavaScript">
|
||||
//<![CDATA[
|
||||
$(document).ready(function() {
|
||||
// We show table ordered by descending dates by default
|
||||
// (so that the more recent query is shown first)
|
||||
$.tablesorter.defaults.sortList = [[0,1]];
|
||||
$("#historyt").tablesorter({<!-- TMPL_IF EXPR="dateformat eq 'metric'" -->
|
||||
dateFormat: 'uk'<!-- /TMPL_IF -->
|
||||
});
|
||||
});
|
||||
//]]>
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- TMPL_IF NAME="OpacNav" --><div id="doc3" class="yui-t1"><!-- TMPL_ELSE --><div id="doc3" class="yui-t7"><!-- /TMPL_IF -->
|
||||
<div id="bd">
|
||||
<!--TMPL_INCLUDE NAME="masthead.inc" -->
|
||||
|
||||
<div id="yui-main">
|
||||
<div class="yui-b"><div class="yui-g">
|
||||
<div class="container">
|
||||
<h1>Search history</h1>
|
||||
<!-- TMPL_IF EXPR="recentSearches || previousSearches" -->
|
||||
<!-- TMPL_IF NAME="recentSearches" -->
|
||||
<!-- TMPL_IF NAME="previousSearches" -->
|
||||
<h2>Current session</h2>
|
||||
<!-- /TMPL_IF -->
|
||||
<table id="historyt">
|
||||
<thead>
|
||||
<tr><th>Date</th><th>Search</th><th>Results</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- TMPL_LOOP NAME="recentSearches" -->
|
||||
<tr>
|
||||
<td><!-- TMPL_VAR NAME="time" --></td>
|
||||
<td><a href="/cgi-bin/koha/opac-search.pl?<!-- TMPL_VAR NAME="query_cgi" -->"><!-- TMPL_VAR NAME="query_desc" --></a></td>
|
||||
<td><!-- TMPL_VAR NAME="total" --></td>
|
||||
</tr>
|
||||
<!-- /TMPL_LOOP -->
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- /TMPL_IF -->
|
||||
|
||||
<!-- TMPL_IF NAME="previousSearches" -->
|
||||
<h2>Previous sessions</h2>
|
||||
<table id="historyt">
|
||||
<thead>
|
||||
<tr><th>Date</th><th>Search</th><th>Results</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- TMPL_LOOP NAME="previousSearches" -->
|
||||
<tr>
|
||||
<td><!-- TMPL_VAR NAME="time" --></td>
|
||||
<td><a href="/cgi-bin/koha/opac-search.pl?<!-- TMPL_VAR NAME="query_cgi" -->"><!-- TMPL_VAR NAME="query_desc" --></a></td>
|
||||
<td><!-- TMPL_VAR NAME="total" --></td>
|
||||
</tr>
|
||||
<!-- /TMPL_LOOP -->
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- /TMPL_IF -->
|
||||
<!-- TMPL_ELSE -->
|
||||
<p>Your search history is now empty.</p>
|
||||
<!-- /TMPL_IF -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- TMPL_IF EXPR="OpacNav||loggedinusername" -->
|
||||
<div class="yui-b"><div class="container">
|
||||
<!--TMPL_INCLUDE NAME="navigation.inc" -->
|
||||
<!--TMPL_INCLUDE NAME="usermenu.inc" -->
|
||||
</div></div></div>
|
||||
<!-- /TMPL_IF -->
|
||||
|
||||
<!-- TMPL_INCLUDE NAME="opac-bottom.inc" -->
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# Copyright 2009 BibLibre SARL
|
||||
#
|
||||
# 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
|
||||
|
||||
use strict;
|
||||
use C4::Auth qw(:DEFAULT get_session);
|
||||
use CGI;
|
||||
use Storable qw(freeze thaw);
|
||||
use C4::Context;
|
||||
use C4::Output;
|
||||
use C4::Log;
|
||||
use C4::Items;
|
||||
use C4::Debug;
|
||||
use C4::Dates;
|
||||
use URI::Escape;
|
||||
use POSIX qw(strftime);
|
||||
|
||||
|
||||
my $cgi = new CGI;
|
||||
|
||||
# Getting the template and auth
|
||||
my ($template, $loggedinuser, $cookie)
|
||||
= get_template_and_user({template_name => "opac-search-history.tmpl",
|
||||
query => $cgi,
|
||||
type => "opac",
|
||||
authnotrequired => 1,
|
||||
flagsrequired => {borrowers => 1},
|
||||
debug => 1,
|
||||
});
|
||||
|
||||
$template->param(dateformat => C4::Context->preference("dateformat"));
|
||||
|
||||
# If the user is not logged in, we deal with the cookie
|
||||
if ($loggedinuser == '') {
|
||||
|
||||
# Deleting search history
|
||||
if ($cgi->param('action') && $cgi->param('action') eq 'delete') {
|
||||
# Deleting cookie's content
|
||||
my $recentSearchesCookie = $cgi->cookie(
|
||||
-name => 'KohaOpacRecentSearches',
|
||||
-value => freeze([]),
|
||||
-expires => ''
|
||||
);
|
||||
|
||||
# Redirecting to this same url with the cookie in the headers so it's deleted immediately
|
||||
my $uri = $cgi->url();
|
||||
print $cgi->redirect(-uri => $uri,
|
||||
-cookie => $recentSearchesCookie);
|
||||
|
||||
# Showing search history
|
||||
} else {
|
||||
|
||||
# Getting the cookie
|
||||
my $searchcookie = $cgi->cookie('KohaOpacRecentSearches');
|
||||
if ($searchcookie && thaw(uri_unescape($searchcookie))) {
|
||||
my @recentSearches = @{thaw(uri_unescape($searchcookie))};
|
||||
if (@recentSearches) {
|
||||
|
||||
# As the dates are stored as unix timestamps, let's do some formatting
|
||||
foreach my $asearch (@recentSearches) {
|
||||
|
||||
# We create an iso date from the unix timestamp
|
||||
my $isodate = strftime "%Y-%m-%d", localtime($asearch->{'time'});
|
||||
|
||||
# So we can create a C4::Dates object, to get the date formatted according to the dateformat syspref
|
||||
my $date = C4::Dates->new($isodate, "iso");
|
||||
my $sysprefdate = $date->output("syspref");
|
||||
|
||||
# We also get the time of the day from the unix timestamp
|
||||
my $time = strftime " %H:%M:%S", localtime($asearch->{'time'});
|
||||
|
||||
# And we got our human-readable date :
|
||||
$asearch->{'time'} = $sysprefdate . $time;
|
||||
}
|
||||
|
||||
$template->param(recentSearches => \@recentSearches);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# And if the user is logged in, we deal with the database
|
||||
|
||||
my $dbh = C4::Context->dbh;
|
||||
|
||||
# Deleting search history
|
||||
if ($cgi->param('action') && $cgi->param('action') eq 'delete') {
|
||||
my $query = "DELETE FROM search_history WHERE userid = ?";
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute($loggedinuser);
|
||||
|
||||
# Redirecting to this same url so the user won't see the search history link in the header
|
||||
my $uri = $cgi->url();
|
||||
print $cgi->redirect($uri);
|
||||
|
||||
|
||||
# Showing search history
|
||||
} else {
|
||||
|
||||
my $date = C4::Dates->new();
|
||||
my $dateformat = $date->DHTMLcalendar() . " %H:%i:%S"; # Current syspref date format + standard time format
|
||||
|
||||
# Getting the data with date format work done by mysql
|
||||
my $query = "SELECT userid, sessionid, query_desc, query_cgi, total, DATE_FORMAT(time, \"$dateformat\") as time FROM search_history WHERE userid = ? AND sessionid = ?";
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute($loggedinuser, $cgi->cookie("CGISESSID"));
|
||||
my $searches = $sth->fetchall_arrayref({});
|
||||
$template->param(recentSearches => $searches);
|
||||
|
||||
# Getting searches from previous sessions
|
||||
$query = "SELECT COUNT(*) FROM search_history WHERE userid = ? AND sessionid != ?";
|
||||
$sth = $dbh->prepare($query);
|
||||
$sth->execute($loggedinuser, $cgi->cookie("CGISESSID"));
|
||||
|
||||
# If at least one search from previous sessions has been performed
|
||||
if ($sth->fetchrow_array > 0) {
|
||||
$query = "SELECT userid, sessionid, query_desc, query_cgi, total, DATE_FORMAT(time, \"$dateformat\") as time FROM search_history WHERE userid = ? AND sessionid != ?";
|
||||
$sth = $dbh->prepare($query);
|
||||
$sth->execute($loggedinuser, $cgi->cookie("CGISESSID"));
|
||||
my $previoussearches = $sth->fetchall_arrayref({});
|
||||
$template->param(previousSearches => $previoussearches);
|
||||
|
||||
}
|
||||
|
||||
$sth->finish;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
output_html_with_http_headers $cgi, $cookie, $template->output;
|
||||
|
||||
|
||||
|
|
@ -15,8 +15,10 @@ use C4::Search;
|
|||
use C4::Biblio; # GetBiblioData
|
||||
use C4::Koha;
|
||||
use C4::Tags qw(get_tags);
|
||||
use POSIX qw(ceil floor strftime);
|
||||
use C4::Branch; # GetBranches
|
||||
use POSIX qw(ceil floor strftime);
|
||||
use URI::Escape;
|
||||
use Storable qw(thaw freeze);
|
||||
|
||||
# create a new CGI object
|
||||
# FIXME: no_undef_params needs to be tested
|
||||
|
|
@ -438,7 +440,54 @@ for (my $i=0;$i<=@servers;$i++) {
|
|||
if ($results_hashref->{$server}->{"hits"}){
|
||||
$total = $total + $results_hashref->{$server}->{"hits"};
|
||||
}
|
||||
## If there's just one result, redirect to the detail page
|
||||
>
|
||||
# Opac search history
|
||||
my $newsearchcookie;
|
||||
if (C4::Context->preference('EnableOpacSearchHistory')) {
|
||||
my @recentSearches;
|
||||
|
||||
# Getting the (maybe) already sent cookie
|
||||
my $searchcookie = $cgi->cookie('KohaOpacRecentSearches');
|
||||
if ($searchcookie){
|
||||
$searchcookie = uri_unescape($searchcookie);
|
||||
if (thaw($searchcookie)) {
|
||||
@recentSearches = @{thaw($searchcookie)};
|
||||
}
|
||||
}
|
||||
|
||||
# Adding the new search if needed
|
||||
if ($borrowernumber eq '') {
|
||||
# To a cookie (the user is not logged in)
|
||||
|
||||
if ($params->{'offset'} eq '') {
|
||||
|
||||
push @recentSearches, {
|
||||
"query_desc" => $query_desc || "unknown",
|
||||
"query_cgi" => $query_cgi || "unknown",
|
||||
"time" => time(),
|
||||
"total" => $total
|
||||
};
|
||||
$template->param(ShowOpacRecentSearchLink => 1);
|
||||
}
|
||||
|
||||
# Pushing the cookie back
|
||||
$newsearchcookie = $cgi->cookie(
|
||||
-name => 'KohaOpacRecentSearches',
|
||||
# We uri_escape the whole freezed structure so we're sure we won't have any encoding problems
|
||||
-value => uri_escape(freeze(\@recentSearches)),
|
||||
-expires => ''
|
||||
);
|
||||
$cookie = [$cookie, $newsearchcookie];
|
||||
}
|
||||
else {
|
||||
# To the session (the user is logged in)
|
||||
if ($params->{'offset'} eq '') {
|
||||
AddSearchHistory($borrowernumber, $cgi->cookie("CGISESSID"), $query_desc, $query_cgi, $total);
|
||||
$template->param(ShowOpacRecentSearchLink => 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
## If there's just one result, redirect to the detail page
|
||||
if ($total == 1) {
|
||||
my $biblionumber=$newresults[0]->{biblionumber};
|
||||
if (C4::Context->preference('BiblioDefaultView') eq 'isbd') {
|
||||
|
|
|
|||
Loading…
Reference in New Issue