1 package C4::Search::History;
5 use C4::Auth qw( get_session );
9 use JSON qw( encode_json decode_json );
15 my $userid = $params->{userid};
16 my $sessionid = $params->{sessionid};
17 my $query_desc = $params->{query_desc};
18 my $query_cgi = $params->{query_cgi};
19 my $total = $params->{total} // 0;
20 my $type = $params->{type} || 'biblio';
21 my $time = $params->{time};
23 my $dbh = C4::Context->dbh;
25 # Add the request the user just made
27 INSERT INTO search_history(
28 userid, sessionid, query_desc, query_cgi, type, total, time
33 my $sth = $dbh->prepare($query);
34 $sth->execute( $userid, $sessionid, $query_desc, $query_cgi, $type,
40 my $cgi = $params->{cgi};
41 my $query_desc = $params->{query_desc} || "unknown";
42 my $query_cgi = $params->{query_cgi} || "unknown";
43 my $total = $params->{total};
44 my $type = $params->{type} || 'biblio';
46 # To a cookie (the user is not logged in)
47 my $now = dt_from_string;
48 my $id = $now->year . $now->month . $now->day . $now->hour . $now->minute . $now->second . int(rand(100));
49 my @recent_searches = get_from_session( { cgi => $cgi } );
50 push @recent_searches, {
51 query_desc => $query_desc,
52 query_cgi => $query_cgi,
55 time => output_pref( { dt => $now, dateformat => 'iso', timeformat => '24hr' } ),
59 shift @recent_searches if ( @recent_searches > 15 );
60 set_to_session( { cgi => $cgi, search_history => \@recent_searches } );
65 my $id = $params->{id};
66 my $userid = $params->{userid};
67 my $sessionid = $params->{sessionid};
68 my $type = $params->{type} || q{};
69 my $previous = $params->{previous} || 0;
70 my $interval = $params->{interval} || 0;
72 unless ( ref( $id ) ) {
73 $id = $id ? [ $id ] : [];
76 unless ( $userid or @$id or $interval ) {
77 warn "ERROR: userid, id or interval is required for history deletion";
81 my $dbh = C4::Context->dbh;
83 DELETE FROM search_history
87 $query .= q{ AND id IN ( } . join( q{,}, (q{?}) x @$id ) . q{ )}
97 ? q{ AND sessionid != ?}
98 : q{ AND sessionid = ?};
101 $query .= q{ AND type = ?}
104 # FIXME DATE_SUB is a Mysql-ism. Postgres uses: datefield - INTERVAL '6 months'
105 $query .= q{ AND time < DATE_SUB( NOW(), INTERVAL ? DAY )}
110 ( @$id ? ( @$id ) : () ),
111 ( $userid ? $userid : () ),
112 ( $sessionid ? $sessionid : () ),
113 ( $type ? $type : () ),
114 ( $interval ? $interval : () ),
118 sub delete_from_cookie {
120 my $cookie = $params->{cookie};
121 my $id = $params->{id};
123 return unless $cookie;
125 unless ( ref( $id ) ) {
126 $id = $id ? [ $id ] : [];
132 $cookie = uri_unescape( $cookie );
133 if (decode_json( $cookie )) {
134 @searches = @{decode_json( $cookie )}
140 ( grep { $_ != $search->{id} } @$id ) ? $search : ()
143 return uri_escape( encode_json( \@searches ) );
149 my $id = $params->{id};
150 my $userid = $params->{userid};
151 my $sessionid = $params->{sessionid};
152 my $type = $params->{type};
153 my $previous = $params->{previous};
155 unless ( ref( $id ) ) {
156 $id = $id ? [ $id ] : [];
159 unless ( $userid or @$id ) {
160 warn "ERROR: userid is required for history search";
170 $query .= q{ AND id IN ( } . join( q{,}, (q{?}) x @$id ) . q{ )}
180 ? q{ AND sessionid != ?}
181 : q{ AND sessionid = ?};
184 $query .= q{ AND type = ?}
187 my $dbh = C4::Context->dbh;
188 my $sth = $dbh->prepare($query);
190 ( @$id ? ( @$id ) : () ),
191 ( $userid ? $userid : () ),
192 ( $sessionid ? $sessionid : () ),
193 ( $type ? $type : () )
195 return $sth->fetchall_arrayref( {} );
198 sub get_from_session {
200 my $cgi = $params->{cgi};
201 my $sessionID = $cgi->cookie('CGISESSID');
202 return () unless $sessionID;
203 my $session = C4::Auth::get_session($sessionID);
204 return () unless $session and $session->param('search_history');
206 eval { decode_json( uri_unescape( $session->param('search_history') ) ) };
207 return () unless defined $obj;
208 return () unless ref $obj eq 'ARRAY';
214 my $cgi = $params->{cgi};
215 my $search_history = $params->{search_history};
216 my $sessionID = $cgi->cookie('CGISESSID');
217 return () unless $sessionID;
218 my $session = C4::Auth::get_session($sessionID);
219 return () unless $session;
220 $session->param( 'search_history',
221 uri_escape( encode_json($search_history) ) );
232 C4::Search::History - Manage search history
236 This module provides some routines for the search history management.
237 It deals with session or database.
243 C4::Search::History::add({
245 sessionid => $cgi->cookie("CGIESSID"),
246 query_desc => $query_desc,
247 query_cgi => $query_cgi,
252 type is "biblio" or "authority".
254 Add a new search to the user's history.
256 =head2 add_to_session
258 my $value = C4::Search::History::add_to_session({
260 query_desc => $query_desc,
261 query_cgi => $query_cgi,
266 Add a search to the session. The number of searches to keep is hardcoded to 15.
270 C4::Search::History::delete({
271 userid => $loggedinuser,
272 sessionid => $sessionid,
274 previous => $previous
277 Delete searches in the database.
278 If the sessionid is missing all searches for all sessions will be deleted.
279 It is possible to delete searches for current session or all previous sessions using the previous flag.
280 If the type ("biblio" or "authority") is missing, all type will be deleted.
281 To delete *all* searches for a given userid, just pass a userid.
285 my $searches C4::Search::History::get({
287 sessionsid => $sessionid,
289 previous => $previous
292 Return a list of searches for a given userid.
293 If a sessionid is given, searches are limited to the matching session.
294 type and previous follow the same behavior as the delete routine.
296 =head2 get_from_session
298 my $searches = C4::Search::History::get_from_session({
302 Return all searches present for the given session.
304 =head2 set_to_session
306 C4::Search::History::set_to_session({
308 search_history => $search_history
311 Store searches into the session.
315 Jonathan Druart <jonathan.druart@biblibre.com>
319 This file is part of Koha.
321 Copyright 2013 BibLibre SARL
323 Koha is free software; you can redistribute it and/or modify it
324 under the terms of the GNU General Public License as published by
325 the Free Software Foundation; either version 3 of the License, or
326 (at your option) any later version.
328 Koha is distributed in the hope that it will be useful, but
329 WITHOUT ANY WARRANTY; without even the implied warranty of
330 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
331 GNU General Public License for more details.
333 You should have received a copy of the GNU General Public License
334 along with Koha; if not, see <http://www.gnu.org/licenses>.