View | Details | Raw Unified | Return to bug 10807
Collapse All | Expand All

(-)a/C4/Auth.pm (-27 / +29 lines)
Lines 20-26 package C4::Auth; Link Here
20
use strict;
20
use strict;
21
use warnings;
21
use warnings;
22
use Digest::MD5 qw(md5_base64);
22
use Digest::MD5 qw(md5_base64);
23
use JSON qw/encode_json decode_json/;
23
use JSON qw/encode_json/;
24
use URI::Escape;
24
use URI::Escape;
25
use CGI::Session;
25
use CGI::Session;
26
26
Lines 28-33 require Exporter; Link Here
28
use C4::Context;
28
use C4::Context;
29
use C4::Templates;    # to get the template
29
use C4::Templates;    # to get the template
30
use C4::Branch; # GetBranches
30
use C4::Branch; # GetBranches
31
use C4::Search::History;
31
use C4::VirtualShelves;
32
use C4::VirtualShelves;
32
use Koha::AuthUtils qw(hash_password);
33
use Koha::AuthUtils qw(hash_password);
33
use POSIX qw/strftime/;
34
use POSIX qw/strftime/;
Lines 129-139 Output.pm module. Link Here
129
130
130
=cut
131
=cut
131
132
132
my $SEARCH_HISTORY_INSERT_SQL =<<EOQ;
133
INSERT INTO search_history(userid, sessionid, query_desc, query_cgi, total, time            )
134
VALUES                    (     ?,         ?,          ?,         ?,          ?, FROM_UNIXTIME(?))
135
EOQ
136
137
sub get_template_and_user {
133
sub get_template_and_user {
138
134
139
    my $in       = shift;
135
    my $in       = shift;
Lines 256-276 sub get_template_and_user { Link Here
256
252
257
            # If at least one search has already been performed
253
            # If at least one search has already been performed
258
            if ($sth->fetchrow_array > 0) {
254
            if ($sth->fetchrow_array > 0) {
259
            # We show the link in opac
255
                # We show the link in opac
260
            $template->param(ShowOpacRecentSearchLink => 1);
256
                $template->param( EnableOpacSearchHistory => 1 );
261
            }
257
            }
262
258
263
            # And if there's a cookie with searches performed when the user was not logged in,
259
            # And if there's a cookie with searches performed when the user was not logged in,
264
            # we add them to the logged-in search history
260
            # we add them to the logged-in search history
265
            my @recentSearches = ParseSearchHistoryCookie($in->{'query'});
261
            my @recentSearches = @{
262
                C4::Search::History::get_from_cookie({
263
                    cookie => $in->{'query'}->cookie('KohaOpacRecentSearches')
264
                })
265
            };
266
            if (@recentSearches) {
266
            if (@recentSearches) {
267
                my $sth = $dbh->prepare($SEARCH_HISTORY_INSERT_SQL);
267
                my $dbh = C4::Context->dbh;
268
269
                my $query = q{
270
                    INSERT INTO search_history(userid, sessionid, query_desc, query_cgi, type,  total, time )
271
                    VALUES (?, ?, ?, ?, ?, ?, ?)
272
                };
273
274
                my $sth = $dbh->prepare($query);
268
                $sth->execute( $borrowernumber,
275
                $sth->execute( $borrowernumber,
269
                           $in->{'query'}->cookie("CGISESSID"),
276
                           $in->{query}->cookie("CGISESSID"),
270
                           $_->{'query_desc'},
277
                           $_->{query_desc},
271
                           $_->{'query_cgi'},
278
                           $_->{query_cgi},
272
                           $_->{'total'},
279
                           $_->{type} || 'biblio',
273
                           $_->{'time'},
280
                           $_->{total},
281
                           $_->{time},
274
                        ) foreach @recentSearches;
282
                        ) foreach @recentSearches;
275
283
276
                # And then, delete the cookie's content
284
                # And then, delete the cookie's content
Lines 297-305 sub get_template_and_user { Link Here
297
     # Anonymous opac search history
305
     # Anonymous opac search history
298
     # If opac search history is enabled and at least one search has already been performed
306
     # If opac search history is enabled and at least one search has already been performed
299
     if (C4::Context->preference('EnableOpacSearchHistory')) {
307
     if (C4::Context->preference('EnableOpacSearchHistory')) {
300
        my @recentSearches = ParseSearchHistoryCookie($in->{'query'}); 
308
        my @recentSearches = @{
309
            C4::Search::History::get_from_cookie({
310
                cookie => $in->{'query'}->cookie('KohaOpacRecentSearches')
311
            })
312
        };
301
        if (@recentSearches) {
313
        if (@recentSearches) {
302
            $template->param(ShowOpacRecentSearchLink => 1);
314
            $template->param(EnableOpacSearchHistory => 1);
303
        }
315
        }
304
     }
316
     }
305
317
Lines 1760-1775 sub getborrowernumber { Link Here
1760
    return 0;
1772
    return 0;
1761
}
1773
}
1762
1774
1763
sub ParseSearchHistoryCookie {
1764
    my $input = shift;
1765
    my $search_cookie = $input->cookie('KohaOpacRecentSearches');
1766
    return () unless $search_cookie;
1767
    my $obj = eval { decode_json(uri_unescape($search_cookie)) };
1768
    return () unless defined $obj;
1769
    return () unless ref $obj eq 'ARRAY';
1770
    return @{ $obj };
1771
}
1772
1773
END { }    # module clean-up code here (global destructor)
1775
END { }    # module clean-up code here (global destructor)
1774
1;
1776
1;
1775
__END__
1777
__END__
(-)a/C4/Search.pm (-23 lines)
Lines 68-74 This module provides searching functions for Koha's bibliographic databases Link Here
68
  &searchResults
68
  &searchResults
69
  &getRecords
69
  &getRecords
70
  &buildQuery
70
  &buildQuery
71
  &AddSearchHistory
72
  &GetDistinctValues
71
  &GetDistinctValues
73
  &enabled_staff_search_views
72
  &enabled_staff_search_views
74
  &PurgeSearchHistory
73
  &PurgeSearchHistory
Lines 2190-2217 sub enabled_staff_search_views Link Here
2190
	);
2189
	);
2191
}
2190
}
2192
2191
2193
sub AddSearchHistory{
2194
	my ($borrowernumber,$session,$query_desc,$query_cgi, $total)=@_;
2195
    my $dbh = C4::Context->dbh;
2196
2197
    # Add the request the user just made
2198
    my $sql = "INSERT INTO search_history(userid, sessionid, query_desc, query_cgi, total, time) VALUES(?, ?, ?, ?, ?, NOW())";
2199
    my $sth   = $dbh->prepare($sql);
2200
    $sth->execute($borrowernumber, $session, $query_desc, $query_cgi, $total);
2201
	return $dbh->last_insert_id(undef, 'search_history', undef,undef,undef);
2202
}
2203
2204
sub GetSearchHistory{
2205
	my ($borrowernumber,$session)=@_;
2206
    my $dbh = C4::Context->dbh;
2207
2208
    # Add the request the user just made
2209
    my $query = "SELECT FROM search_history WHERE (userid=? OR sessionid=?)";
2210
    my $sth   = $dbh->prepare($query);
2211
	$sth->execute($borrowernumber, $session);
2212
    return  $sth->fetchall_hashref({});
2213
}
2214
2215
sub PurgeSearchHistory{
2192
sub PurgeSearchHistory{
2216
    my ($pSearchhistory)=@_;
2193
    my ($pSearchhistory)=@_;
2217
    my $dbh = C4::Context->dbh;
2194
    my $dbh = C4::Context->dbh;
(-)a/C4/Search/History.pm (+270 lines)
Line 0 Link Here
1
package C4::Search::History;
2
3
use Modern::Perl;
4
5
use C4::Context;
6
use Koha::DateUtils;
7
8
use JSON qw( encode_json decode_json );
9
use URI::Escape;
10
use Encode;
11
12
sub add {
13
    my ( $params ) = @_;
14
    my $userid = $params->{userid};
15
    my $sessionid = $params->{sessionid};
16
    my $query_desc = $params->{query_desc};
17
    my $query_cgi = $params->{query_cgi};
18
    my $total = $params->{total};
19
    my $type = $params->{type} || 'biblio';
20
21
    my $dbh = C4::Context->dbh;
22
23
    # Add the request the user just made
24
    my $query = q{
25
        INSERT INTO search_history(
26
            userid, sessionid, query_desc, query_cgi, type, total, time
27
        ) VALUES(
28
            ?, ?, ?, ?, ?, ?, NOW()
29
        )
30
    };
31
    my $sth = $dbh->prepare($query);
32
    $sth->execute($userid, $sessionid, $query_desc, $query_cgi, $type, $total);
33
}
34
35
sub build_new_cookie_value {
36
    my ( $params ) = @_;
37
    my $recent_searches = $params->{recent_searches};
38
    my $query_desc = Encode::decode_utf8($params->{query_desc}) || "unknown";
39
    my $query_cgi = Encode::decode_utf8($params->{query_cgi}) || "unknown";
40
    my $total = $params->{total};
41
    my $type = $params->{type} || 'biblio';
42
43
    my @recent_searches;
44
    # Getting the (maybe) already sent cookie
45
    if ( $recent_searches ){
46
        $recent_searches = uri_unescape($recent_searches);
47
        if (decode_json($recent_searches)) {
48
            @recent_searches = @{decode_json( $recent_searches )}
49
        }
50
    }
51
52
    # To a cookie (the user is not logged in)
53
    push @recent_searches, {
54
        query_desc => $query_desc,
55
        query_cgi  => $query_cgi,
56
        total      => "$total",
57
        type       => $type,
58
        time       => output_pref( dt_from_string(), 'iso' ),
59
    };
60
61
    shift @recent_searches if (@recent_searches > 15);
62
63
    return uri_escape( encode_json( \@recent_searches ) );
64
}
65
66
sub delete {
67
    my ( $params ) = @_;
68
    my $userid = $params->{userid};
69
    my $sessionid = $params->{sessionid};
70
    my $type = $params->{type} || q{};
71
    my $previous = $params->{previous} || 0;
72
73
    unless ( $userid ) {
74
        warn "ERROR: userid is required for history search";
75
        return;
76
    }
77
78
    my $dbh = C4::Context->dbh;
79
    my $query = q{
80
        DELETE FROM search_history
81
        WHERE userid = ?
82
    };
83
84
    if ( $sessionid ) {
85
        $query .= $previous
86
            ? q{ AND sessionid != ?}
87
            : q{ AND sessionid = ?};
88
    }
89
90
    $query .= q{ AND type = ?}
91
        if $type;
92
93
    $dbh->do(
94
        $query, {},
95
        $userid,
96
        ( $sessionid ? $sessionid : () ),
97
        ( $type ? $type : () )
98
    );
99
}
100
101
sub get {
102
    my ( $params ) = @_;
103
    my $userid = $params->{userid};
104
    my $sessionid = $params->{sessionid};
105
    my $type = $params->{type};
106
    my $previous = $params->{previous};
107
108
    unless ( $userid ) {
109
        warn "ERROR: userid is required for history search";
110
        return;
111
    }
112
113
    my $query = q{
114
        SELECT *
115
        FROM search_history
116
        WHERE userid = ?
117
    };
118
119
    if ( $sessionid ) {
120
        $query .= $previous
121
            ? q{ AND sessionid != ?}
122
            : q{ AND sessionid = ?};
123
    }
124
125
    $query .= q{ AND type = ?}
126
        if $type;
127
128
    my $dbh = C4::Context->dbh;
129
    my $sth = $dbh->prepare( $query );
130
    $sth->execute(
131
        $userid,
132
        ( $sessionid ? $sessionid : () ),
133
        ( $type ? $type : () )
134
    );
135
    return $sth->fetchall_arrayref({});
136
}
137
138
sub get_from_cookie {
139
    my ( $params ) = @_;
140
    my $search_cookie = $params->{cookie};
141
    return [] unless $search_cookie;
142
    my $obj = eval { decode_json(uri_unescape($search_cookie)) };
143
    return [] unless defined $obj;
144
    return [] unless ref $obj eq 'ARRAY';
145
    return $obj;
146
}
147
148
sub get_empty_cookie {
149
    my ( $params ) = @_;
150
    my $cgi = $params->{cgi};
151
    my $name = $params->{name};
152
    $cgi->cookie(
153
        -name => $name,
154
        -value => encode_json([]),
155
        -expires => ''
156
    );
157
}
158
159
1;
160
161
__END__
162
163
=pod
164
165
=head1 NAME
166
167
C4::Search::History - Manage search history
168
169
=head1 DESCRIPTION
170
171
This module provides some routines for the search history management.
172
It deals with cookie or database.
173
174
=head1 ROUTINES
175
176
=head2 add
177
178
    C4::Search::History::add({
179
        userid => $userid,
180
        sessionid => $cgi->cookie("CGIESSID"),
181
        query_desc => $query_desc,
182
        query_cgi => $query_cgi,
183
        total => $total,
184
        type => $type,
185
    });
186
187
type is "biblio" or "authority".
188
189
Add a new search to the user's history.
190
191
=head2 build_new_cookie_value
192
193
    my $value = C4::Search::History::build_new_cookie_value({
194
        cookie => $cookie,
195
        recent_searches => $cgi->cookie('KohaOpacRecentSearches'),
196
        query_desc => $query_desc,
197
        query_cgi => $query_cgi,
198
        total => $total,
199
        type => $type,
200
    });
201
202
Build a new cookie value containing previous search and the last one.
203
204
=head2 delete
205
206
    C4::Search::History::delete({
207
        userid => $loggedinuser,
208
        sessionid => $sessionid,
209
        type => $type,
210
        previous => $previous
211
    });
212
213
Delete searches in the database.
214
If the sessionid is missing all searches for all sessions will be deleted.
215
It is possible to delete searches for current session or all previous sessions using the previous flag.
216
If the type ("biblio" or "authority") is missing, all type will be deleted.
217
To delete *all* searches for a given userid, just pass a userid.
218
219
=head2 get
220
221
    my $searches C4::Search::History::get({
222
        userid => $userid,
223
        sessionsid => $sessionid,
224
        type => $type,
225
        previous => $previous
226
    });
227
228
Return a list of searches for a given userid.
229
If a sessionid is given, searches are limited to the matching session.
230
type and previous follow the same behavior as the delete routine.
231
232
=head2 get_from_cookie
233
234
    my $searches = C4::Search::History::get_from_cookie({
235
        cookie => $cgi->cookie('KohaOpacRecentSearches')
236
    });
237
238
Return all searches present in the given cookie.
239
240
=head2 get_empty_cookie
241
242
    my $cookie = C4::Search::History::get_empty_cookie({
243
        cgi => $cgi,
244
        name => $cookie_name
245
    });
246
247
Return a cookie with no value.
248
249
=head1 AUTHORS
250
251
Jonathan Druart <jonathan.druart@biblibre.com>
252
253
=head1 LICENSE
254
255
Copyright 2013 BibLibre SARL
256
257
This file is part of Koha.
258
259
Koha is free software; you can redistribute it and/or modify it under the
260
terms of the GNU General Public License as published by the Free Software
261
Foundation; either version 2 of the License, or (at your option) any later
262
version.
263
264
Koha is distributed in the hope that it will be useful, but WITHOUT ANY
265
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
266
A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
267
268
You should have received a copy of the GNU General Public License along
269
with Koha; if not, write to the Free Software Foundation, Inc.,
270
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
(-)a/installer/data/mysql/kohastructure.sql (+1 lines)
Lines 1884-1889 CREATE TABLE IF NOT EXISTS `search_history` ( -- patron's opac search history Link Here
1884
  `sessionid` varchar(32) NOT NULL, -- a system generated session id
1884
  `sessionid` varchar(32) NOT NULL, -- a system generated session id
1885
  `query_desc` varchar(255) NOT NULL, -- the search that was performed
1885
  `query_desc` varchar(255) NOT NULL, -- the search that was performed
1886
  `query_cgi` text NOT NULL, -- the string to append to the search url to rerun the search
1886
  `query_cgi` text NOT NULL, -- the string to append to the search url to rerun the search
1887
  `type` varchar(255) NOT NULL DEFAULT 'biblio', -- search type, must be 'biblio' or 'authority'
1887
  `total` int(11) NOT NULL, -- the total of results found
1888
  `total` int(11) NOT NULL, -- the total of results found
1888
  `time` timestamp NOT NULL default CURRENT_TIMESTAMP, -- the date and time the search was run
1889
  `time` timestamp NOT NULL default CURRENT_TIMESTAMP, -- the date and time the search was run
1889
  KEY `userid` (`userid`),
1890
  KEY `userid` (`userid`),
(-)a/installer/data/mysql/updatedatabase.pl (+13 lines)
Lines 7596-7601 if ( CheckVersion($DBversion) ) { Link Here
7596
}
7596
}
7597
7597
7598
7598
7599
7600
7601
7602
7603
7604
7605
$DBversion = "3.13.00.XXX";
7606
if ( CheckVersion($DBversion) ) {
7607
    $dbh->do("ALTER TABLE search_history ADD COLUMN type VARCHAR(255) NOT NULL DEFAULT 'biblio' AFTER query_cgi");
7608
    print "Upgrade to $DBversion done (Bug 10807 - Add db field search_history.type)\n";
7609
    SetVersion($DBversion);
7610
}
7611
7599
=head1 FUNCTIONS
7612
=head1 FUNCTIONS
7600
7613
7601
=head2 TableExists($table)
7614
=head2 TableExists($table)
(-)a/koha-tmpl/opac-tmpl/ccsr/en/includes/top-bar.inc (-1 / +1 lines)
Lines 60-66 Link Here
60
                    <li><span class="members">Welcome, <a href="/cgi-bin/koha/opac-user.pl"><span class="loggedinusername">[% FOREACH USER_INF IN USER_INFO %][% USER_INF.title %] [% USER_INF.firstname %] [% USER_INF.surname %][% END %]</span></a></span></li>
60
                    <li><span class="members">Welcome, <a href="/cgi-bin/koha/opac-user.pl"><span class="loggedinusername">[% FOREACH USER_INF IN USER_INFO %][% USER_INF.title %] [% USER_INF.firstname %] [% USER_INF.surname %][% END %]</span></a></span></li>
61
61
62
                [% END %]
62
                [% END %]
63
                [% IF ( ShowOpacRecentSearchLink ) %]
63
                [% IF ( EnableOpacSearchHistory ) %]
64
                    <li><a href="/cgi-bin/koha/opac-search-history.pl" title="View your search history">Search history</a></li>
64
                    <li><a href="/cgi-bin/koha/opac-search-history.pl" title="View your search history">Search history</a></li>
65
                [% END %]
65
                [% END %]
66
 [% IF ( loggedinusername ) %]<li>[% IF persona %]<a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1" onclick='navigator.id.logout();'>[% ELSE %]<a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1">[% END %]Log Out</a></li>[% END %]
66
 [% IF ( loggedinusername ) %]<li>[% IF persona %]<a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1" onclick='navigator.id.logout();'>[% ELSE %]<a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1">[% END %]Log Out</a></li>[% END %]
(-)a/koha-tmpl/opac-tmpl/ccsr/en/includes/usermenu.inc (-1 / +1 lines)
Lines 12-18 Link Here
12
  [% IF ( OpacPasswordChange ) %]
12
  [% IF ( OpacPasswordChange ) %]
13
    [% IF ( passwdview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-passwd.pl">change my password</a></li>
13
    [% IF ( passwdview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-passwd.pl">change my password</a></li>
14
  [% END %]
14
  [% END %]
15
  [% IF ( ShowOpacRecentSearchLink ) %]
15
  [% IF EnableOpacSearchHistory %]
16
  [% IF ( searchhistoryview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-search-history.pl">my search history</a></li>
16
  [% IF ( searchhistoryview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-search-history.pl">my search history</a></li>
17
  [% END %]
17
  [% END %]
18
  [% IF ( opacreadinghistory ) %]
18
  [% IF ( opacreadinghistory ) %]
(-)a/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc (-1 / +1 lines)
Lines 7-13 Link Here
7
                <li><span class="members">Welcome, <a href="/cgi-bin/koha/opac-user.pl"><span class="loggedinusername">[% FOREACH USER_INF IN USER_INFO %][% USER_INF.title %] [% USER_INF.firstname %] [% USER_INF.surname %][% END %]</span></a></span></li>
7
                <li><span class="members">Welcome, <a href="/cgi-bin/koha/opac-user.pl"><span class="loggedinusername">[% FOREACH USER_INF IN USER_INFO %][% USER_INF.title %] [% USER_INF.firstname %] [% USER_INF.surname %][% END %]</span></a></span></li>
8
8
9
            [% END %]
9
            [% END %]
10
            [% IF ( ShowOpacRecentSearchLink ) %]
10
            [% IF EnableOpacSearchHistory %]
11
                <li><a href="/cgi-bin/koha/opac-search-history.pl" title="View your search history">Search history</a> [<a class="logout" href="/cgi-bin/koha/opac-search-history.pl?action=delete" title="Delete your search history" onclick="return confirm(MSG_DELETE_SEARCH_HISTORY);">x</a>]</li>
11
                <li><a href="/cgi-bin/koha/opac-search-history.pl" title="View your search history">Search history</a> [<a class="logout" href="/cgi-bin/koha/opac-search-history.pl?action=delete" title="Delete your search history" onclick="return confirm(MSG_DELETE_SEARCH_HISTORY);">x</a>]</li>
12
            [% END %]
12
            [% END %]
13
			[% IF ( loggedinusername ) %]<li>[% IF persona %]<a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1" onclick='navigator.id.logout();'>[% ELSE %]<a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1">[% END %]Log Out</a></li>[% END %]
13
			[% IF ( loggedinusername ) %]<li>[% IF persona %]<a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1" onclick='navigator.id.logout();'>[% ELSE %]<a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1">[% END %]Log Out</a></li>[% END %]
(-)a/koha-tmpl/opac-tmpl/prog/en/includes/usermenu.inc (-1 / +1 lines)
Lines 12-18 Link Here
12
  [% IF ( OpacPasswordChange ) %]
12
  [% IF ( OpacPasswordChange ) %]
13
    [% IF ( passwdview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-passwd.pl">change my password</a></li>
13
    [% IF ( passwdview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-passwd.pl">change my password</a></li>
14
  [% END %]
14
  [% END %]
15
  [% IF ( ShowOpacRecentSearchLink ) %]
15
  [% IF EnableOpacSearchHistory %]
16
  [% IF ( searchhistoryview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-search-history.pl">my search history</a></li>
16
  [% IF ( searchhistoryview ) %]<li class="active">[% ELSE %]<li>[% END %]<a href="/cgi-bin/koha/opac-search-history.pl">my search history</a></li>
17
  [% END %]
17
  [% END %]
18
  [% IF ( opacreadinghistory ) %]
18
  [% IF ( opacreadinghistory ) %]
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-search-history.tt (-67 / +157 lines)
Lines 6-24 Link Here
6
[% INCLUDE 'datatables.inc' %]
6
[% INCLUDE 'datatables.inc' %]
7
<script type="text/javascript">
7
<script type="text/javascript">
8
//<![CDATA[
8
//<![CDATA[
9
	var MSG_CONFIRM_DELETE_HISTORY = _("Are you sure you want to delete your search history?");
9
var MSG_CONFIRM_DELETE_HISTORY = _("Are you sure you want to delete your search history?");
10
         $(document).ready(function() {
10
$(document).ready(function() {
11
		// We show table ordered by descending dates by default
11
    // We show table ordered by descending dates by default
12
		// (so that the more recent query is shown first)
12
    // (so that the more recent query is shown first)
13
            $(".historyt").dataTable($.extend(true, {}, dataTablesDefaults, {
13
    $(".historyt").dataTable($.extend(true, {}, dataTablesDefaults, {
14
                "aaSorting": [[ 0, "desc" ]],
14
        "aaSorting": [[ 0, "desc" ]],
15
                "aoColumns": [
15
        "aoColumns": [
16
                    { "sType": "title-string" },
16
            { "sType": "title-string" },
17
                    null,
17
            null,
18
                    null
18
            null
19
                ]
19
        ]
20
            }));
20
    }));
21
        });
21
22
    $('#tabs').tabs();
23
});
22
//]]>
24
//]]>
23
25
24
</script>
26
</script>
Lines 34-101 Link Here
34
   <div id="bd">
36
   <div id="bd">
35
[% INCLUDE 'masthead.inc' %]
37
[% INCLUDE 'masthead.inc' %]
36
38
37
	<div id="yui-main">
39
<div id="yui-main">
38
<div class="yui-b"><div class="yui-g">
40
  <div class="yui-b">
39
        <div id="searchhistory" class="container">
41
    <div class="yui-g">
40
	<h1>Search history</h1>
42
      <h1>Search history</h1>
41
	[% IF ( recentSearches ) %]<form action="/cgi-bin/koha/opac-search-history.pl" method="get"><input type="hidden" name="action" value="delete" /><input type="submit" class="deleteshelf" value="Delete your search history" onclick="return confirm(MSG_CONFIRM_DELETE_HISTORY);" /></form>[% ELSE %][% IF ( previousSearches ) %]<form action="/cgi-bin/koha/opac-search-history.pl" method="get"><input type="hidden" name="action" value="delete" /><input type="submit" class="deleteshelf" value="Delete your search history" onclick="return confirm(MSG_CONFIRM_DELETE_HISTORY);" /></form>[% END %][% END %]
43
      <div id="tabs" class="toptabs">
44
        <ul>
45
          <li><a href="#biblio_tab">Biblio</a></li>
46
          <li><a href="#authority_tab">Authority</a></li>
47
        </ul>
48
        <div id="biblio_tab">
49
          [% IF ( current_biblio_searches ) %]
50
            <h2>Current session</h2>
51
            <form action="/cgi-bin/koha/opac-search-history.pl" method="get">
52
              <input type="hidden" name="action" value="delete" />
53
              <input type="hidden" name="previous" value="0" />
54
              <input type="hidden" name="type" value="biblio" />
55
              <input type="submit" class="deleteshelf" value="Delete your current biblio history" onclick="return confirm(MSG_CONFIRM_DELETE_HISTORY);" />
56
            </form>
57
            <table class="historyt">
58
              <thead>
59
                <tr>
60
                  <th>Date</th>
61
                  <th>Search</th>
62
                  <th>Results</th>
63
                </tr>
64
              </thead>
65
              <tbody>
66
              [% FOREACH s IN current_biblio_searches %]
67
                <tr>
68
                  <td><span title="[% s.time %]">[% s.time |$KohaDates with_hours => 1 %]</span></td>
69
                  <td><a href="/cgi-bin/koha/opac-search.pl?[% s.query_cgi |html %]">[% s.query_desc |html %]</a></td>
70
                  <td>[% s.total %]</td>
71
                </tr>
72
              [% END %]
73
              </tbody>
74
            </table>
75
          [% END %]
76
77
          [% IF ( previous_biblio_searches ) %]
78
            <h2>Previous sessions</h2>
79
            <form action="/cgi-bin/koha/opac-search-history.pl" method="get">
80
              <input type="hidden" name="action" value="delete" />
81
              <input type="hidden" name="previous" value="1" />
82
              <input type="hidden" name="type" value="biblio" />
83
              <input type="submit" class="deleteshelf" value="Delete your previous biblio search history" onclick="return confirm(MSG_CONFIRM_DELETE_HISTORY);" />
84
            </form>
85
            <table class="historyt">
86
              <thead>
87
                <tr>
88
                  <th>Date</th>
89
                  <th>Search</th>
90
                  <th>Results</th>
91
                </tr>
92
              </thead>
93
              <tbody>
94
              [% FOREACH s IN previous_biblio_searches %]
95
                <tr>
96
                  <td><span title="[% s.time %]">[% s.time |$KohaDates with_hours => 1 %]</span></td>
97
                  <td><a href="/cgi-bin/koha/opac-search.pl?[% s.query_cgi |html %]">[% s.query_desc |html %]</a></td>
98
                  <td>[% s.total %]</td>
99
                </tr>
100
              [% END %]
101
              </tbody>
102
            </table>
103
          [% END %]
42
104
43
	    [% IF ( recentSearches ) %]
105
          [% IF !current_biblio_searches && !previous_biblio_searches %]
44
	    <table class="historyt">
106
            <p>Your biblio search history is empty.</p>
45
	    [% IF ( previousSearches ) %]
107
          [% END %]
46
	    <caption>Current session</caption>
108
        </div>
47
	    [% END %]
48
		<thead>
49
		    <tr><th>Date</th><th>Search</th><th>Results</th></tr>
50
		</thead>
51
		<tbody>
52
		    [% FOREACH recentSearche IN recentSearches %]
53
		    <tr>
54
            <td><span title="[% recentSearche.time %]">[% recentSearche.time |$KohaDates with_hours => 1 %]</span></td>
55
			<td><a href="/cgi-bin/koha/opac-search.pl?[% recentSearche.query_cgi |html %]">[% recentSearche.query_desc |html %]</a></td>
56
			<td>[% recentSearche.total %]</td>
57
		    </tr>
58
		    [% END %]
59
		</tbody>
60
	    </table>
61
	    [% END %]
62
109
63
	    [% IF ( previousSearches ) %]
110
        <div id="authority_tab">
64
	    <table class="historyt">
111
          [% IF ( current_authority_searches ) %]
65
	    <caption>Previous sessions</caption>
112
            <h2>Current session</h2>
66
		<thead>
113
            <form action="/cgi-bin/koha/opac-search-history.pl" method="get">
67
		    <tr><th>Date</th><th>Search</th><th>Results</th></tr>
114
              <input type="hidden" name="action" value="delete" />
68
		</thead>
115
              <input type="hidden" name="previous" value="0" />
69
		<tbody>
116
              <input type="hidden" name="type" value="authority" />
70
		    [% FOREACH previousSearche IN previousSearches %]
117
              <input type="submit" class="deleteshelf" value="Delete your current authority search history" onclick="return confirm(MSG_CONFIRM_DELETE_HISTORY);" />
71
		    <tr>
118
            </form>
72
            <td><span title="[% previousSearche.time %]">[% previousSearche.time |$KohaDates with_hours => 1 %]</span></td>
119
            <table class="historyt">
73
			<td><a href="/cgi-bin/koha/opac-search.pl?[% previousSearche.query_cgi |html %]">[% previousSearche.query_desc |html %]</a></td>
120
              <thead>
74
			<td>[% previousSearche.total %]</td>
121
                <tr>
75
		    </tr>
122
                  <th>Date</th>
76
		    [% END %]
123
                  <th>Search</th>
77
		</tbody>
124
                  <th>Results</th>
78
	    </table>
125
                </tr>
79
	    [% END %]
126
              </thead>
127
              <tbody>
128
              [% FOREACH s IN current_authority_searches %]
129
                <tr>
130
                  <td><span title="[% s.time %]">[% s.time |$KohaDates with_hours => 1 %]</span></td>
131
                  <td><a href="/cgi-bin/koha/opac-authorities-home.pl?[% s.query_cgi |html %]">[% s.query_desc |html %]</a></td>
132
                  <td>[% s.total %]</td>
133
                </tr>
134
              [% END %]
135
              </tbody>
136
            </table>
137
          [% END %]
80
138
81
[% IF ( recentSearches ) %][% ELSE %][% IF ( previousSearches ) %][% ELSE %]<p>Your search history is empty.</p>[% END %][% END %]
139
          [% IF ( previous_authority_searches ) %]
140
            <h2>Previous sessions</h2>
141
            <form action="/cgi-bin/koha/opac-search-history.pl" method="get">
142
              <input type="hidden" name="action" value="delete" />
143
              <input type="hidden" name="previous" value="1" />
144
              <input type="hidden" name="type" value="authority" />
145
              <input type="submit" class="deleteshelf" value="Delete your previous authority search history" onclick="return confirm(MSG_CONFIRM_DELETE_HISTORY);" />
146
            </form>
147
            <table class="historyt">
148
              <thead>
149
                <tr>
150
                  <th>Date</th>
151
                  <th>Search</th>
152
                  <th>Results</th>
153
                </tr>
154
              </thead>
155
              <tbody>
156
              [% FOREACH s IN previous_authority_searches %]
157
                <tr>
158
                  <td><span title="[% s.time %]">[% s.time |$KohaDates with_hours => 1 %]</span></td>
159
                  <td><a href="/cgi-bin/koha/opac-authorities-home.pl?[% s.query_cgi |html %]">[% s.query_desc |html %]</a></td>
160
                  <td>[% s.total %]</td>
161
                </tr>
162
              [% END %]
163
              </tbody>
164
            </table>
165
          [% END %]
82
166
83
     </div>
167
          [% IF !current_authority_searches && !previous_authority_searches %]
84
     </div>
168
            <p>Your authority search history is empty.</p>
85
     </div>
169
          [% END %]
86
     </div>
170
        </div>
171
      </div>
172
    </div>
173
  </div>
174
</div>
87
175
88
[% IF ( OpacNav ) %]
176
[% IF ( OpacNav ) %]
89
<div class="yui-b"><div id="leftmenus" class="container">
177
  <div class="yui-b">
90
[% INCLUDE 'navigation.inc' IsPatronPage=1 %]
178
    <div id="leftmenus" class="container">
91
</div></div>
179
      [% INCLUDE 'navigation.inc' IsPatronPage=1 %]
180
    </div>
181
  </div>
92
[% ELSIF ( loggedinusername ) %]
182
[% ELSIF ( loggedinusername ) %]
93
<div class="yui-b"><div id="leftmenus" class="container">
183
  <div class="yui-b">
94
[% INCLUDE 'navigation.inc' IsPatronPage=1 %]
184
    <div id="leftmenus" class="container">
95
</div></div>
185
      [% INCLUDE 'navigation.inc' IsPatronPage=1 %]
96
[% ELSE %]
186
    </div>
187
  </div>
97
[% END %]
188
[% END %]
98
189
99
100
</div>
190
</div>
101
[% INCLUDE 'opac-bottom.inc' %]
191
[% INCLUDE 'opac-bottom.inc' %]
(-)a/opac/opac-authorities-home.pl (+44 lines)
Lines 22-27 use strict; Link Here
22
use warnings;
22
use warnings;
23
23
24
use CGI;
24
use CGI;
25
25
use C4::Auth;
26
use C4::Auth;
26
27
27
use C4::Context;
28
use C4::Context;
Lines 29-34 use C4::Auth; Link Here
29
use C4::Output;
30
use C4::Output;
30
use C4::AuthoritiesMarc;
31
use C4::AuthoritiesMarc;
31
use C4::Koha;    # XXX subfield_is_koha_internal_p
32
use C4::Koha;    # XXX subfield_is_koha_internal_p
33
use C4::Search::History;
32
34
33
my $query        = new CGI;
35
my $query        = new CGI;
34
my $op           = $query->param('op') || '';
36
my $op           = $query->param('op') || '';
Lines 129-134 if ( $op eq "do_search" ) { Link Here
129
        my @usedauths = grep { $_->{used} > 0 } @$results;
131
        my @usedauths = grep { $_->{used} > 0 } @$results;
130
        $results = \@usedauths;
132
        $results = \@usedauths;
131
    }
133
    }
134
135
    # Opac search history
136
    my $newsearchcookie;
137
    if (C4::Context->preference('EnableOpacSearchHistory')) {
138
        unless ( $startfrom ) {
139
            my $path_info = $query->url(-path_info=>1);
140
            my $query_cgi_history = $query->url(-query=>1);
141
            $query_cgi_history =~ s/^$path_info\?//;
142
            $query_cgi_history =~ s/;/&/g;
143
144
            unless ( $loggedinuser ) {
145
                my $new_search = C4::Search::History::build_new_cookie_value({
146
                        cookie => $cookie,
147
                        recent_searches => $query->cookie('KohaOpacRecentSearches') || q{},
148
                        query_desc => $value[0],
149
                        query_cgi => $query_cgi_history,
150
                        total => $total,
151
                        type => "authority",
152
                });
153
154
                $cookie = [
155
                    $cookie,
156
                    $query->cookie(
157
                        -name => 'KohaOpacRecentSearches',
158
                        -value => $new_search,
159
                        -expires => ''
160
                    )
161
                ];
162
            } else {
163
                # To the session (the user is logged in)
164
                C4::Search::History::add({
165
                    userid => $loggedinuser,
166
                    sessionid => $query->cookie("CGISESSID"),
167
                    query_desc => $value[0],
168
                    query_cgi => $query_cgi_history,
169
                    total => $total,
170
                    type => "authority",
171
                });
172
            }
173
        }
174
    }
175
132
    $template->param( result => $results ) if $results;
176
    $template->param( result => $results ) if $results;
133
    $template->param( FIELDS => \@fields );
177
    $template->param( FIELDS => \@fields );
134
    $template->param( orderby => $orderby );
178
    $template->param( orderby => $orderby );
(-)a/opac/opac-search-history.pl (-87 / +100 lines)
Lines 1-6 Link Here
1
#!/usr/bin/perl
1
#!/usr/bin/perl
2
2
3
# Copyright 2009 BibLibre SARL
3
# Copyright 2013 BibLibre SARL
4
#
4
#
5
# This file is part of Koha.
5
# This file is part of Koha.
6
#
6
#
Lines 17-34 Link Here
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
19
20
use strict;
20
use Modern::Perl;
21
use warnings;
22
21
23
use C4::Auth qw(:DEFAULT get_session ParseSearchHistoryCookie);
22
use C4::Auth qw(:DEFAULT get_session);
24
use CGI;
23
use CGI;
25
use JSON qw/decode_json encode_json/;
26
use C4::Context;
24
use C4::Context;
27
use C4::Output;
25
use C4::Output;
28
use C4::Log;
26
use C4::Log;
29
use C4::Items;
27
use C4::Items;
30
use C4::Debug;
28
use C4::Debug;
31
use C4::Dates;
29
use C4::Dates;
30
use C4::Search::History;
32
use URI::Escape;
31
use URI::Escape;
33
use POSIX qw(strftime);
32
use POSIX qw(strftime);
34
33
Lines 36-141 use POSIX qw(strftime); Link Here
36
my $cgi = new CGI;
35
my $cgi = new CGI;
37
36
38
# Getting the template and auth
37
# Getting the template and auth
39
my ($template, $loggedinuser, $cookie)= get_template_and_user({template_name => "opac-search-history.tmpl",
38
my ($template, $loggedinuser, $cookie) = get_template_and_user(
40
                                query => $cgi,
39
    {
41
                                type => "opac",
40
        template_name => "opac-search-history.tmpl",
42
                                authnotrequired => 1,
41
        query => $cgi,
43
                                flagsrequired => {borrowers => 1},
42
        type => "opac",
44
                                debug => 1,
43
        authnotrequired => 1,
45
                                });
44
        flagsrequired => {borrowers => 1},
45
        debug => 1,
46
    }
47
);
48
49
my $type = $cgi->param('type');
50
my $action = $cgi->param('action') || q{};
51
my $previous = $cgi->param('previous');
46
52
47
# If the user is not logged in, we deal with the cookie
53
# If the user is not logged in, we deal with the cookie
48
if (!$loggedinuser) {
54
unless ( $loggedinuser ) {
49
55
50
    # Deleting search history
56
    # Deleting search history
51
    if ($cgi->param('action') && $cgi->param('action') eq 'delete') {
57
    if ( $action eq 'delete' ) {
52
	# Deleting cookie's content 
58
        # Deleting cookie's content
53
	my $recentSearchesCookie = $cgi->cookie(
59
        my $current_searches_cookie = C4::Search::History::get_empty_cookie({
54
	    -name => 'KohaOpacRecentSearches',
60
            cgi => $cgi,
55
	    -value => encode_json([]),
61
            name => 'KohaOpacRecentSearches',
56
	    -expires => ''
62
        });
57
	    );
63
58
64
        # Redirecting to this same url with the cookie in the headers so it's deleted immediately
59
	# Redirecting to this same url with the cookie in the headers so it's deleted immediately
65
        my $uri = $cgi->url();
60
	my $uri = $cgi->url();
66
        print $cgi->redirect(
61
	print $cgi->redirect(-uri => $uri,
67
            -uri => $uri,
62
			     -cookie => $recentSearchesCookie);
68
            -cookie => $current_searches_cookie
69
        );
63
70
64
    # Showing search history
71
    # Showing search history
65
    } else {
72
    } else {
66
73
        # Getting the cookie
67
        my @recentSearches = ParseSearchHistoryCookie($cgi);
74
        my @current_searches = @{
68
	    if (@recentSearches) {
75
            C4::Search::History::get_from_cookie({
69
76
                cookie => $cgi->cookie('KohaOpacRecentSearches')
70
		# As the dates are stored as unix timestamps, let's do some formatting
77
            })
71
		foreach my $asearch (@recentSearches) {
78
        };
72
79
73
		    # We create an iso date from the unix timestamp
80
        my @current_biblio_searches = map {
74
		    my $isodate = strftime "%Y-%m-%d", localtime($asearch->{'time'});
81
            $_->{type} eq 'biblio' ? $_ : ()
75
82
        } @current_searches;
76
		    # We also get the time of the day from the unix timestamp
83
77
		    my $time = strftime " %H:%M:%S", localtime($asearch->{'time'});
84
        my @current_authority_searches = map {
78
85
            $_->{type} eq 'authority' ? $_ : ()
79
		    # And we got our human-readable date : 
86
        } @current_searches;
80
            $asearch->{'time'} = $isodate . $time;
87
81
		}
88
        $template->param(
82
89
            current_biblio_searches => \@current_biblio_searches,
83
		$template->param(recentSearches => \@recentSearches);
90
            current_authority_searches => \@current_authority_searches,
84
	    }
91
        );
85
    }
92
    }
86
} else {
93
} else {
87
# And if the user is logged in, we deal with the database
94
    # And if the user is logged in, we deal with the database
88
   
89
    my $dbh = C4::Context->dbh;
95
    my $dbh = C4::Context->dbh;
90
96
91
    # Deleting search history
97
    # Deleting search history
92
    if ($cgi->param('action') && $cgi->param('action') eq 'delete') {
98
    if ( $action eq 'delete' ) {
93
	my $query = "DELETE FROM search_history WHERE userid = ?";
99
        my $sessionid = defined $previous
94
	my $sth   = $dbh->prepare($query);
100
            ? $cgi->cookie("CGISESSID")
95
	$sth->execute($loggedinuser);
101
            : q{};
96
102
        C4::Search::History::delete(
97
	# Redirecting to this same url so the user won't see the search history link in the header
103
            {
98
	my $uri = $cgi->url();
104
                userid => $loggedinuser,
99
	print $cgi->redirect($uri);
105
                sessionid => $sessionid,
100
106
                type => $type,
107
                previous => $previous
108
            }
109
        );
110
        # Redirecting to this same url so the user won't see the search history link in the header
111
        my $uri = $cgi->url();
112
        print $cgi->redirect($uri);
101
113
102
    # Showing search history
114
    # Showing search history
103
    } else {
115
    } else {
104
116
        my $current_searches = C4::Search::History::get({
105
	my $date = C4::Dates->new();
117
            userid => $loggedinuser,
106
	my $dateformat = $date->DHTMLcalendar() . " %H:%i:%S"; # Current syspref date format + standard time format
118
            sessionid => $cgi->cookie("CGISESSID")
107
119
        });
108
	# Getting the data with date format work done by mysql
120
        my @current_biblio_searches = map {
109
    my $query = "SELECT userid, sessionid, query_desc, query_cgi, total, time FROM search_history WHERE userid = ? AND sessionid = ?";
121
            $_->{type} eq 'biblio' ? $_ : ()
110
	my $sth   = $dbh->prepare($query);
122
        } @$current_searches;
111
	$sth->execute($loggedinuser, $cgi->cookie("CGISESSID"));
123
112
	my $searches = $sth->fetchall_arrayref({});
124
        my @current_authority_searches = map {
113
	$template->param(recentSearches => $searches);
125
            $_->{type} eq 'authority' ? $_ : ()
114
	
126
        } @$current_searches;
115
	# Getting searches from previous sessions
127
116
	$query = "SELECT COUNT(*) FROM search_history WHERE userid = ? AND sessionid != ?";
128
        my $previous_searches = C4::Search::History::get({
117
	$sth   = $dbh->prepare($query);
129
            userid => $loggedinuser,
118
	$sth->execute($loggedinuser, $cgi->cookie("CGISESSID"));
130
            sessionid => $cgi->cookie("CGISESSID"),
119
131
            previous => 1
120
	# If at least one search from previous sessions has been performed
132
        });
121
        if ($sth->fetchrow_array > 0) {
133
122
        $query = "SELECT userid, sessionid, query_desc, query_cgi, total, time FROM search_history WHERE userid = ? AND sessionid != ?";
134
        my @previous_biblio_searches = map {
123
	    $sth   = $dbh->prepare($query);
135
            $_->{type} eq 'biblio' ? $_ : ()
124
	    $sth->execute($loggedinuser, $cgi->cookie("CGISESSID"));
136
        } @$previous_searches;
125
    	    my $previoussearches = $sth->fetchall_arrayref({});
137
126
    	    $template->param(previousSearches => $previoussearches);
138
        my @previous_authority_searches = map {
127
	
139
            $_->{type} eq 'authority' ? $_ : ()
128
	}
140
        } @$previous_searches;
129
141
130
	$sth->finish;
142
        $template->param(
131
143
            current_biblio_searches => \@current_biblio_searches,
132
144
            current_authority_searches => \@current_authority_searches,
145
            previous_biblio_searches => \@previous_biblio_searches,
146
            previous_authority_searches => \@previous_authority_searches,
147
148
        );
133
    }
149
    }
134
135
}
150
}
136
151
137
$template->param(searchhistoryview => 1);
152
$template->param(searchhistoryview => 1);
138
153
139
output_html_with_http_headers $cgi, $cookie, $template->output;
154
output_html_with_http_headers $cgi, $cookie, $template->output;
140
141
(-)a/opac/opac-search.pl (-34 / +37 lines)
Lines 42-50 for ( $searchengine ) { Link Here
42
}
42
}
43
43
44
use C4::Output;
44
use C4::Output;
45
use C4::Auth qw(:DEFAULT get_session ParseSearchHistoryCookie);
45
use C4::Auth qw(:DEFAULT get_session);
46
use C4::Languages qw(getAllLanguages);
46
use C4::Languages qw(getAllLanguages);
47
use C4::Search;
47
use C4::Search;
48
use C4::Search::History;
48
use C4::Biblio;  # GetBiblioData
49
use C4::Biblio;  # GetBiblioData
49
use C4::Koha;
50
use C4::Koha;
50
use C4::Tags qw(get_tags);
51
use C4::Tags qw(get_tags);
Lines 614-660 for (my $i=0;$i<@servers;$i++) { Link Here
614
        }
615
        }
615
616
616
        # Opac search history
617
        # Opac search history
617
        my $newsearchcookie;
618
        if (C4::Context->preference('EnableOpacSearchHistory')) {
618
        if (C4::Context->preference('EnableOpacSearchHistory')) {
619
            my @recentSearches = ParseSearchHistoryCookie($cgi);
619
            unless ( $offset ) {
620
620
                my $path_info = $cgi->url(-path_info=>1);
621
            # Adding the new search if needed
621
                my $query_cgi_history = $cgi->url(-query=>1);
622
            my $path_info = $cgi->url(-path_info=>1);
622
                $query_cgi_history =~ s/^$path_info\?//;
623
            my $query_cgi_history = $cgi->url(-query=>1);
623
                $query_cgi_history =~ s/;/&/g;
624
            $query_cgi_history =~ s/^$path_info\?//;
624
                my $query_desc_history = $query_desc;
625
            $query_cgi_history =~ s/;/&/g;
625
                $query_desc_history .= ", $limit_desc"
626
            my $query_desc_history = "$query_desc, $limit_desc";
626
                    if $limit_desc;
627
627
628
            if (!$borrowernumber || $borrowernumber eq '') {
628
                unless ( $borrowernumber ) {
629
                # To a cookie (the user is not logged in)
629
                    my $new_search = C4::Search::History::build_new_cookie_value({
630
                if (!$offset) {
630
                            recent_searches => $cgi->cookie('KohaOpacRecentSearches') || q{},
631
                    push @recentSearches, {
631
                            query_desc => $query_desc_history,
632
                                "query_desc" => Encode::decode_utf8($query_desc_history) || "unknown",
632
                            query_cgi => $query_cgi_history,
633
                                "query_cgi"  => Encode::decode_utf8($query_cgi_history)  || "unknown",
633
                            total => $total,
634
                                "time"       => time(),
634
                            type => "biblio",
635
                                "total"      => $total
635
                    });
636
                              };
637
                    $template->param(ShowOpacRecentSearchLink => 1);
638
                }
639
636
640
                shift @recentSearches if (@recentSearches > 15);
637
                    $cookie = [
641
                # Pushing the cookie back
638
                        $cookie,
642
                $newsearchcookie = $cgi->cookie(
639
                        $cgi->cookie(
643
                            -name => 'KohaOpacRecentSearches',
640
                            -name => 'KohaOpacRecentSearches',
644
                            # We uri_escape the whole serialized structure so we're sure we won't have any encoding problems
641
                            # We uri_escape the whole serialized structure so we're sure we won't have any encoding problems
645
                            -value => uri_escape( encode_json(\@recentSearches) ),
642
                            -value => $new_search,
646
                            -expires => ''
643
                            -expires => ''
647
                );
644
                        )
648
                $cookie = [$cookie, $newsearchcookie];
645
                    ];
649
            }
646
                } else {
650
            else {
647
                    # To the session (the user is logged in)
651
                # To the session (the user is logged in)
648
                    C4::Search::History::add({
652
                if (!$offset) {
649
                        userid => $borrowernumber,
653
                    AddSearchHistory($borrowernumber, $cgi->cookie("CGISESSID"), $query_desc_history, $query_cgi_history, $total);
650
                        sessionid => $cgi->cookie("CGISESSID"),
654
                    $template->param(ShowOpacRecentSearchLink => 1);
651
                        query_desc => $query_desc_history,
652
                        query_cgi => $query_cgi_history,
653
                        total => $total,
654
                        type => "biblio",
655
                    });
655
                }
656
                }
656
            }
657
            }
658
            $template->param( EnableOpacSearchHistory => 1 );
657
        }
659
        }
660
658
        ## If there's just one result, redirect to the detail page
661
        ## If there's just one result, redirect to the detail page
659
        if ($total == 1 && $format ne 'rss2'
662
        if ($total == 1 && $format ne 'rss2'
660
        && $format ne 'opensearchdescription' && $format ne 'atom') {
663
        && $format ne 'opensearchdescription' && $format ne 'atom') {
(-)a/t/Search/History.t (+34 lines)
Line 0 Link Here
1
#!/usr/bin/env perl
2
3
use Modern::Perl;
4
5
use Test::More tests => 7;
6
use URI::Escape;
7
use JSON qw( decode_json );
8
9
use_ok('Koha::DateUtils');
10
use_ok('C4::Search::History');
11
12
13
# Test cookie
14
my $query_desc = q{first search};
15
my $query_cgi = q{idx=kw&idx=ti&idx=au%2Cwrdl&q=word1é&q=word2è&q=word3à&do=Search&sort_by=author_az};
16
my $total = 42;
17
18
my $first_search = C4::Search::History::build_new_cookie_value({
19
    recent_searches => q{},
20
    query_desc => $query_desc,
21
    query_cgi => $query_cgi,
22
    total => $total,
23
    type => "biblio",
24
});
25
26
my $date = output_pref( dt_from_string(), 'iso' );
27
28
my @values = @{ C4::Search::History::get_from_cookie({cookie => $first_search}) };
29
my $values = shift @values;
30
is( $values->{time}, $date, 'build search time' );
31
is( $values->{query_cgi}, Encode::decode_utf8($query_cgi), 'build search query_cgi' );
32
is( $values->{type}, 'biblio', 'build search type' );
33
is( $values->{total}, '42', 'build search total' );
34
is( $values->{query_desc}, Encode::decode_utf8($query_desc), 'build search query_desc' );
(-)a/t/db_dependent/Auth_ParseSearchHistoryCookie.t (-43 lines)
Lines 1-43 Link Here
1
#!/usr/bin/perl
2
3
use strict;
4
use warnings;
5
6
use Test::More tests => 3;
7
8
use_ok('C4::Auth', qw/ParseSearchHistoryCookie/);
9
10
my $valid_cookie = "%5B%7B%22time%22%3A1374978877%2C%22query_cgi%22%3A%22idx%3D%26q%3Dhistory%26branch_group_limit%3D%22%2C%22total%22%3A2%2C%22query_desc%22%3A%22kw%2Cwrdl%3A%20history%2C%20%22%7D%5D";
11
my $expected_recent_searches = [
12
    {
13
        'time' => 1374978877,
14
        'query_cgi' => 'idx=&q=history&branch_group_limit=',
15
        'total' => 2,
16
        'query_desc' => 'kw,wrdl: history, '
17
    }
18
];
19
20
my $input = CookieSimulator->new($valid_cookie);
21
my @recent_searches = ParseSearchHistoryCookie($input);
22
is_deeply(\@recent_searches, $expected_recent_searches, 'parsed valid search history cookie value');
23
24
# simulate bit of a Storable-based search history cookie
25
my $invalid_cookie = "%04%08%0812345";
26
$input = CookieSimulator->new($invalid_cookie);
27
@recent_searches = ParseSearchHistoryCookie($input);
28
is_deeply(\@recent_searches, [], 'got back empty search history list if given invalid cookie');
29
30
package CookieSimulator;
31
32
sub new {
33
    my ($class, $str) = @_;
34
    my $val = [ $str ];
35
    return bless $val, $class;
36
}
37
38
sub cookie {
39
    my $self = shift;
40
    return $self->[0];
41
}
42
43
1;
(-)a/t/db_dependent/Search/History.t (-1 / +248 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/env perl
2
3
use Modern::Perl;
4
5
use Test::More tests => 16;
6
use URI::Escape;
7
8
use C4::Context;
9
my $dbh = C4::Context->dbh;
10
$dbh->{AutoCommit} = 0;
11
$dbh->{RaiseError} = 1;
12
13
use_ok('Koha::DateUtils');
14
use_ok('C4::Search::History');
15
16
my $userid = 123;
17
my $previous_sessionid = "PREVIOUS_SESSIONID";
18
my $current_sessionid = "CURRENT_SESSIONID";
19
my $total = 42;
20
my $query_cgi_b = q{idx=kw&idx=ti&idx=au%2Cwrdl&q=word1é&q=word2è&q=word3à&do=Search&sort_by=author_az};
21
my $query_cgi_a = q{op=do_search&type=opac&authtypecode=NP&operator=start&value=Harry&marclist=match&and_or=and&orderby=HeadingAsc};
22
23
# add
24
my $added = add( $userid, $current_sessionid, $previous_sessionid, $total, $query_cgi_b, $query_cgi_a );
25
is ( $added, 9, '9 searches are added' );
26
27
# get
28
my $searches_for_userid = C4::Search::History::get({
29
    userid => $userid,
30
});
31
is( scalar(@$searches_for_userid), 9, 'There are 9 searches in all' );
32
33
my $searches_for_current_session = C4::Search::History::get({
34
    userid => $userid,
35
    sessionid => $current_sessionid,
36
});
37
is( scalar(@$searches_for_current_session), 5, 'There are 5 searches for the current session' );
38
39
my $searches_for_previous_sessions = C4::Search::History::get({
40
    userid => $userid,
41
    sessionid => $current_sessionid,
42
    previous => 1,
43
});
44
is( scalar(@$searches_for_previous_sessions), 4, 'There are 4 searches for previous sessions' );
45
46
my $authority_searches_for_current_session = C4::Search::History::get({
47
    userid => $userid,
48
    sessionid => $current_sessionid,
49
    type => 'authority',
50
});
51
is( scalar(@$authority_searches_for_current_session), 3, 'There are 3 authority searches for the current session' );
52
53
my $authority_searches_for_previous_session = C4::Search::History::get({
54
    userid => $userid,
55
    sessionid => $current_sessionid,
56
    type => 'authority',
57
    previous => 1,
58
});
59
is( scalar(@$authority_searches_for_previous_session), 2, 'There are 2 authority searches for previous sessions' );
60
61
my $biblio_searches_for_userid = C4::Search::History::get({
62
    userid => $userid,
63
    type => 'biblio',
64
});
65
is( scalar(@$biblio_searches_for_userid), 4, 'There are 5 searches for the current session' );
66
67
my $authority_searches_for_userid = C4::Search::History::get({
68
    userid => $userid,
69
    type => 'authority',
70
});
71
is( scalar(@$authority_searches_for_userid), 5, 'There are 4 searches for previous sessions' );
72
73
delete_all( $userid );
74
75
# delete
76
add( $userid, $current_sessionid, $previous_sessionid, $total, $query_cgi_b, $query_cgi_a );
77
C4::Search::History::delete({
78
    userid => $userid,
79
    sessionid => $current_sessionid,
80
    type => 'authority',
81
});
82
my $all = C4::Search::History::get({userid => $userid});
83
is( scalar(@$all), 6, 'There are 6 searches in all after deleting current biblio searches' );
84
delete_all( $userid );
85
86
add( $userid, $current_sessionid, $previous_sessionid, $total, $query_cgi_b, $query_cgi_a );
87
C4::Search::History::delete({
88
    userid => $userid,
89
    sessionid => $current_sessionid,
90
    type => 'biblio',
91
    previous => 1,
92
});
93
$all = C4::Search::History::get({userid => $userid});
94
is( scalar(@$all), 7, 'There are 7 searches in all after deleting previous authority searches' );
95
delete_all( $userid );
96
97
add( $userid, $current_sessionid, $previous_sessionid, $total, $query_cgi_b, $query_cgi_a );
98
C4::Search::History::delete({
99
    userid => $userid,
100
    sessionid => $current_sessionid,
101
    previous => 1,
102
});
103
$all = C4::Search::History::get({userid => $userid});
104
is( scalar(@$all), 5, 'There are 5 searches in all after deleting all previous searches' );
105
delete_all( $userid );
106
107
add( $userid, $current_sessionid, $previous_sessionid, $total, $query_cgi_b, $query_cgi_a );
108
C4::Search::History::delete({
109
    userid => $userid,
110
    sessionid => $current_sessionid,
111
});
112
$all = C4::Search::History::get({userid => $userid});
113
is( scalar(@$all), 4, 'There are 5 searches in all after deleting all searches for a sessionid' );
114
delete_all( $userid );
115
116
add( $userid, $current_sessionid, $previous_sessionid, $total, $query_cgi_b, $query_cgi_a );
117
C4::Search::History::delete({
118
    userid => $userid,
119
});
120
$all = C4::Search::History::get({userid => $userid});
121
is( scalar(@$all), 0, 'There are 0 search after deleting all searches for a userid' );
122
delete_all( $userid );
123
124
add( $userid, $current_sessionid, $previous_sessionid, $total, $query_cgi_b, $query_cgi_a );
125
C4::Search::History::delete({});
126
$all = C4::Search::History::get({userid => $userid});
127
is( scalar(@$all), 9, 'There are still 9 searches after calling delete without userid' );
128
delete_all( $userid );
129
130
sub add {
131
    my ( $userid, $current_session_id, $previous_sessionid, $total, $query_cgi_b, $query_cgi_a ) = @_;
132
133
    my $query_desc_b1_p = q{first previous biblio search};
134
    my $first_previous_biblio_search = {
135
        userid => $userid,
136
        sessionid => $previous_sessionid,
137
        query_desc => $query_desc_b1_p,
138
        query_cgi => $query_cgi_b,
139
        total => $total,
140
        type => 'biblio',
141
    };
142
143
    my $query_desc_a1_p = q{first previous authority search};
144
    my $first_previous_authority_search = {
145
        userid => $userid,
146
        sessionid => $previous_sessionid,
147
        query_desc => $query_desc_a1_p,
148
        query_cgi => $query_cgi_a,
149
        total => $total,
150
        type => 'authority',
151
    };
152
153
    my $query_desc_b2_p = q{second previous biblio search};
154
    my $second_previous_biblio_search = {
155
        userid => $userid,
156
        sessionid => $previous_sessionid,
157
        query_desc => $query_desc_b2_p,
158
        query_cgi => $query_cgi_b,
159
        total => $total,
160
        type => 'biblio',
161
    };
162
163
    my $query_desc_a2_p = q{second previous authority search};
164
    my $second_previous_authority_search = {
165
        userid => $userid,
166
        sessionid => $previous_sessionid,
167
        query_desc => $query_desc_a2_p,
168
        query_cgi => $query_cgi_a,
169
        total => $total,
170
        type => 'authority',
171
    };
172
173
174
    my $query_desc_b1_c = q{first current biblio search};
175
176
    my $first_current_biblio_search = {
177
        userid => $userid,
178
        sessionid => $current_sessionid,
179
        query_desc => $query_desc_b1_c,
180
        query_cgi => $query_cgi_b,
181
        total => $total,
182
        type => 'biblio',
183
    };
184
185
    my $query_desc_a1_c = q{first current authority search};
186
    my $first_current_authority_search = {
187
        userid => $userid,
188
        sessionid => $current_sessionid,
189
        query_desc => $query_desc_a1_c,
190
        query_cgi => $query_cgi_a,
191
        total => $total,
192
        type => 'authority',
193
    };
194
195
    my $query_desc_b2_c = q{second current biblio search};
196
    my $second_current_biblio_search = {
197
        userid => $userid,
198
        sessionid => $current_sessionid,
199
        query_desc => $query_desc_b2_c,
200
        query_cgi => $query_cgi_b,
201
        total => $total,
202
        type => 'biblio',
203
    };
204
205
    my $query_desc_a2_c = q{second current authority search};
206
    my $second_current_authority_search = {
207
        userid => $userid,
208
        sessionid => $current_sessionid,
209
        query_desc => $query_desc_a2_c,
210
        query_cgi => $query_cgi_a,
211
        total => $total,
212
        type => 'authority',
213
    };
214
215
    my $query_desc_a3_c = q{third current authority search};
216
    my $third_current_authority_search = {
217
        userid => $userid,
218
        sessionid => $current_sessionid,
219
        query_desc => $query_desc_a3_c,
220
        query_cgi => $query_cgi_a,
221
        total => $total,
222
        type => 'authority',
223
    };
224
225
226
    my $r = 0;
227
    $r += C4::Search::History::add( $first_current_biblio_search );
228
    $r += C4::Search::History::add( $first_current_authority_search );
229
    $r += C4::Search::History::add( $second_current_biblio_search );
230
    $r += C4::Search::History::add( $second_current_authority_search );
231
    $r += C4::Search::History::add( $first_previous_biblio_search );
232
    $r += C4::Search::History::add( $first_previous_authority_search );
233
    $r += C4::Search::History::add( $second_previous_biblio_search );
234
    $r += C4::Search::History::add( $second_previous_authority_search );
235
    $r += C4::Search::History::add( $third_current_authority_search );
236
    return $r;
237
}
238
239
sub delete_all {
240
    my $userid = shift;
241
    C4::Search::History::delete({
242
        userid => $userid,
243
    });
244
}
245
246
$dbh->rollback;
247
248
done_testing;

Return to bug 10807