Bug 24583: Rewrite mandatory/class_sources to YAML
[koha.git] / C4 / Search / History.pm
blob8406f3086bcb204f2919812399ce876031e9e67e
1 package C4::Search::History;
3 use Modern::Perl;
5 use C4::Auth qw( get_session );
6 use C4::Context;
7 use Koha::DateUtils;
9 use JSON qw( encode_json decode_json );
10 use URI::Escape;
11 use Encode;
13 sub add {
14 my ($params) = @_;
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
26 my $query = q{
27 INSERT INTO search_history(
28 userid, sessionid, query_desc, query_cgi, type, total} . ( $time ? ', time' : '' ) . q{
29 ) VALUES(
30 ?, ?, ?, ?, ?, ?} . ( $time ? ', ?' : '' ) . q{
33 my $sth = $dbh->prepare($query);
34 $sth->execute( $userid, $sessionid, $query_desc, $query_cgi, $type,
35 $total, ( $time ? $time : () ) );
38 sub add_to_session {
39 my ($params) = @_;
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,
53 total => "$total",
54 type => $type,
55 time => output_pref( { dt => $now, dateformat => 'iso', timeformat => '24hr' } ),
56 id => $id,
59 shift @recent_searches if ( @recent_searches > 15 );
60 set_to_session( { cgi => $cgi, search_history => \@recent_searches } );
63 sub delete {
64 my ($params) = @_;
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";
78 return;
81 my $dbh = C4::Context->dbh;
82 my $query = q{
83 DELETE FROM search_history
84 WHERE 1
87 $query .= q{ AND id IN ( } . join( q{,}, (q{?}) x @$id ) . q{ )}
88 if @$id;
90 $query .= q{
91 AND userid = ?
92 } if $userid;
94 if ($sessionid) {
95 $query .=
96 $previous
97 ? q{ AND sessionid != ?}
98 : q{ AND sessionid = ?};
101 $query .= q{ AND type = ?}
102 if $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 )}
106 if $interval;
108 $dbh->do(
109 $query, {},
110 ( @$id ? ( @$id ) : () ),
111 ( $userid ? $userid : () ),
112 ( $sessionid ? $sessionid : () ),
113 ( $type ? $type : () ),
114 ( $interval ? $interval : () ),
118 sub delete_from_cookie {
119 my ($params) = @_;
120 my $cookie = $params->{cookie};
121 my $id = $params->{id};
123 return unless $cookie;
125 unless ( ref( $id ) ) {
126 $id = $id ? [ $id ] : [];
128 return unless @$id;
130 my @searches;
131 if ( $cookie ){
132 $cookie = uri_unescape( $cookie );
133 if (decode_json( $cookie )) {
134 @searches = @{decode_json( $cookie )}
138 @searches = map {
139 my $search = $_;
140 ( grep { $_ != $search->{id} } @$id ) ? $search : ()
141 } @searches;
143 return uri_escape( encode_json( \@searches ) );
147 sub get {
148 my ($params) = @_;
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";
161 return;
164 my $query = q{
165 SELECT *
166 FROM search_history
167 WHERE 1
170 $query .= q{ AND id IN ( } . join( q{,}, (q{?}) x @$id ) . q{ )}
171 if @$id;
173 $query .= q{
174 AND userid = ?
175 } if $userid;
177 if ($sessionid) {
178 $query .=
179 $previous
180 ? q{ AND sessionid != ?}
181 : q{ AND sessionid = ?};
184 $query .= q{ AND type = ?}
185 if $type;
187 my $dbh = C4::Context->dbh;
188 my $sth = $dbh->prepare($query);
189 $sth->execute(
190 ( @$id ? ( @$id ) : () ),
191 ( $userid ? $userid : () ),
192 ( $sessionid ? $sessionid : () ),
193 ( $type ? $type : () )
195 return $sth->fetchall_arrayref( {} );
198 sub get_from_session {
199 my ($params) = @_;
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');
205 my $obj =
206 eval { decode_json( uri_unescape( $session->param('search_history') ) ) };
207 return () unless defined $obj;
208 return () unless ref $obj eq 'ARRAY';
209 return @{$obj};
212 sub set_to_session {
213 my ($params) = @_;
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) ) );
226 __END__
228 =pod
230 =head1 NAME
232 C4::Search::History - Manage search history
234 =head1 DESCRIPTION
236 This module provides some routines for the search history management.
237 It deals with session or database.
239 =head1 ROUTINES
241 =head2 add
243 C4::Search::History::add({
244 userid => $userid,
245 sessionid => $cgi->cookie("CGIESSID"),
246 query_desc => $query_desc,
247 query_cgi => $query_cgi,
248 total => $total,
249 type => $type,
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({
259 cgi => $cgi,
260 query_desc => $query_desc,
261 query_cgi => $query_cgi,
262 total => $total,
263 type => $type,
266 Add a search to the session. The number of searches to keep is hardcoded to 15.
268 =head2 delete
270 C4::Search::History::delete({
271 userid => $loggedinuser,
272 sessionid => $sessionid,
273 type => $type,
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.
283 =head2 get
285 my $searches C4::Search::History::get({
286 userid => $userid,
287 sessionsid => $sessionid,
288 type => $type,
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({
299 cgi => $cgi
302 Return all searches present for the given session.
304 =head2 set_to_session
306 C4::Search::History::set_to_session({
307 cgi => $cgi,
308 search_history => $search_history
311 Store searches into the session.
313 =head1 AUTHORS
315 Jonathan Druart <jonathan.druart@biblibre.com>
317 =head1 LICENSE
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>.