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

(-)a/C4/Auth.pm (-30 / +30 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 POSIX qw/strftime/;
33
use POSIX qw/strftime/;
33
use List::MoreUtils qw/ any /;
34
use List::MoreUtils qw/ any /;
Lines 46-54 BEGIN { Link Here
46
    $debug       = $ENV{DEBUG};
47
    $debug       = $ENV{DEBUG};
47
    @ISA         = qw(Exporter);
48
    @ISA         = qw(Exporter);
48
    @EXPORT      = qw(&checkauth &get_template_and_user &haspermission &get_user_subpermissions);
49
    @EXPORT      = qw(&checkauth &get_template_and_user &haspermission &get_user_subpermissions);
49
    @EXPORT_OK   = qw(&check_api_auth &get_session &check_cookie_auth &checkpw &get_all_subpermissions &get_user_subpermissions
50
    @EXPORT_OK   = qw(&check_api_auth &get_session &check_cookie_auth &checkpw &get_all_subpermissions &get_user_subpermissions);
50
                      ParseSearchHistoryCookie
51
                   );
52
    %EXPORT_TAGS = ( EditPermissions => [qw(get_all_subpermissions get_user_subpermissions)] );
51
    %EXPORT_TAGS = ( EditPermissions => [qw(get_all_subpermissions get_user_subpermissions)] );
53
    $ldap        = C4::Context->config('useldapserver') || 0;
52
    $ldap        = C4::Context->config('useldapserver') || 0;
54
    $cas         = C4::Context->preference('casAuthentication');
53
    $cas         = C4::Context->preference('casAuthentication');
Lines 127-137 Output.pm module. Link Here
127
126
128
=cut
127
=cut
129
128
130
my $SEARCH_HISTORY_INSERT_SQL =<<EOQ;
131
INSERT INTO search_history(userid, sessionid, query_desc, query_cgi, total, time            )
132
VALUES                    (     ?,         ?,          ?,         ?,          ?, FROM_UNIXTIME(?))
133
EOQ
134
135
sub get_template_and_user {
129
sub get_template_and_user {
136
    my $in       = shift;
130
    my $in       = shift;
137
    my $template =
131
    my $template =
Lines 247-267 sub get_template_and_user { Link Here
247
241
248
            # If at least one search has already been performed
242
            # If at least one search has already been performed
249
            if ($sth->fetchrow_array > 0) {
243
            if ($sth->fetchrow_array > 0) {
250
            # We show the link in opac
244
                # We show the link in opac
251
            $template->param(ShowOpacRecentSearchLink => 1);
245
                $template->param( EnableOpacSearchHistory => 1 );
252
            }
246
            }
253
247
254
            # And if there's a cookie with searches performed when the user was not logged in,
248
            # And if there's a cookie with searches performed when the user was not logged in,
255
            # we add them to the logged-in search history
249
            # we add them to the logged-in search history
256
            my @recentSearches = ParseSearchHistoryCookie($in->{'query'});
250
            my @recentSearches = @{
251
                C4::Search::History::get_from_cookie({
252
                    cookie => $in->{'query'}->cookie('KohaOpacRecentSearches')
253
                })
254
            };
257
            if (@recentSearches) {
255
            if (@recentSearches) {
258
                my $sth = $dbh->prepare($SEARCH_HISTORY_INSERT_SQL);
256
                my $dbh = C4::Context->dbh;
257
258
                my $query = q{
259
                    INSERT INTO search_history(userid, sessionid, query_desc, query_cgi, type,  total, time )
260
                    VALUES (?, ?, ?, ?, ?, ?, ?)
261
                };
262
263
                my $sth = $dbh->prepare($query);
259
                $sth->execute( $borrowernumber,
264
                $sth->execute( $borrowernumber,
260
                           $in->{'query'}->cookie("CGISESSID"),
265
                           $in->{query}->cookie("CGISESSID"),
261
                           $_->{'query_desc'},
266
                           $_->{query_desc},
262
                           $_->{'query_cgi'},
267
                           $_->{query_cgi},
263
                           $_->{'total'},
268
                           $_->{type} || 'biblio',
264
                           $_->{'time'},
269
                           $_->{total},
270
                           $_->{time},
265
                        ) foreach @recentSearches;
271
                        ) foreach @recentSearches;
266
272
267
                # And then, delete the cookie's content
273
                # And then, delete the cookie's content
Lines 288-296 sub get_template_and_user { Link Here
288
     # Anonymous opac search history
294
     # Anonymous opac search history
289
     # If opac search history is enabled and at least one search has already been performed
295
     # If opac search history is enabled and at least one search has already been performed
290
     if (C4::Context->preference('EnableOpacSearchHistory')) {
296
     if (C4::Context->preference('EnableOpacSearchHistory')) {
291
        my @recentSearches = ParseSearchHistoryCookie($in->{'query'}); 
297
        my @recentSearches = @{
298
            C4::Search::History::get_from_cookie({
299
                cookie => $in->{'query'}->cookie('KohaOpacRecentSearches')
300
            })
301
        };
292
        if (@recentSearches) {
302
        if (@recentSearches) {
293
            $template->param(ShowOpacRecentSearchLink => 1);
303
            $template->param(EnableOpacSearchHistory => 1);
294
        }
304
        }
295
     }
305
     }
296
306
Lines 1715-1730 sub getborrowernumber { Link Here
1715
    return 0;
1725
    return 0;
1716
}
1726
}
1717
1727
1718
sub ParseSearchHistoryCookie {
1719
    my $input = shift;
1720
    my $search_cookie = $input->cookie('KohaOpacRecentSearches');
1721
    return () unless $search_cookie;
1722
    my $obj = eval { decode_json(uri_unescape($search_cookie)) };
1723
    return () unless defined $obj;
1724
    return () unless ref $obj eq 'ARRAY';
1725
    return @{ $obj };
1726
}
1727
1728
END { }    # module clean-up code here (global destructor)
1728
END { }    # module clean-up code here (global destructor)
1729
1;
1729
1;
1730
__END__
1730
__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
  &SimpleSearch
73
  &SimpleSearch
Lines 2189-2216 sub enabled_staff_search_views Link Here
2189
	);
2188
	);
2190
}
2189
}
2191
2190
2192
sub AddSearchHistory{
2193
	my ($borrowernumber,$session,$query_desc,$query_cgi, $total)=@_;
2194
    my $dbh = C4::Context->dbh;
2195
2196
    # Add the request the user just made
2197
    my $sql = "INSERT INTO search_history(userid, sessionid, query_desc, query_cgi, total, time) VALUES(?, ?, ?, ?, ?, NOW())";
2198
    my $sth   = $dbh->prepare($sql);
2199
    $sth->execute($borrowernumber, $session, $query_desc, $query_cgi, $total);
2200
	return $dbh->last_insert_id(undef, 'search_history', undef,undef,undef);
2201
}
2202
2203
sub GetSearchHistory{
2204
	my ($borrowernumber,$session)=@_;
2205
    my $dbh = C4::Context->dbh;
2206
2207
    # Add the request the user just made
2208
    my $query = "SELECT FROM search_history WHERE (userid=? OR sessionid=?)";
2209
    my $sth   = $dbh->prepare($query);
2210
	$sth->execute($borrowernumber, $session);
2211
    return  $sth->fetchall_hashref({});
2212
}
2213
2214
=head2 z3950_search_args
2191
=head2 z3950_search_args
2215
2192
2216
$arrayref = z3950_search_args($matchpoints)
2193
$arrayref = z3950_search_args($matchpoints)
(-)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 1879-1884 CREATE TABLE IF NOT EXISTS `search_history` ( -- patron's opac search history Link Here
1879
  `sessionid` varchar(32) NOT NULL, -- a system generated session id
1879
  `sessionid` varchar(32) NOT NULL, -- a system generated session id
1880
  `query_desc` varchar(255) NOT NULL, -- the search that was performed
1880
  `query_desc` varchar(255) NOT NULL, -- the search that was performed
1881
  `query_cgi` text NOT NULL, -- the string to append to the search url to rerun the search
1881
  `query_cgi` text NOT NULL, -- the string to append to the search url to rerun the search
1882
  `type` varchar(255) NOT NULL DEFAULT 'biblio', -- search type, must be 'biblio' or 'authority'
1882
  `total` int(11) NOT NULL, -- the total of results found
1883
  `total` int(11) NOT NULL, -- the total of results found
1883
  `time` timestamp NOT NULL default CURRENT_TIMESTAMP, -- the date and time the search was run
1884
  `time` timestamp NOT NULL default CURRENT_TIMESTAMP, -- the date and time the search was run
1884
  KEY `userid` (`userid`),
1885
  KEY `userid` (`userid`),
(-)a/installer/data/mysql/updatedatabase.pl (+14 lines)
Lines 7067-7072 if ( CheckVersion($DBversion) ) { Link Here
7067
    SetVersion($DBversion);
7067
    SetVersion($DBversion);
7068
}
7068
}
7069
7069
7070
7071
7072
7073
7074
7075
7076
7077
$DBversion = "3.13.00.XXX";
7078
if ( CheckVersion($DBversion) ) {
7079
    $dbh->do("ALTER TABLE search_history ADD COLUMN type VARCHAR(255) NOT NULL DEFAULT 'biblio' AFTER query_cgi");
7080
    print "Upgrade to $DBversion done (Bug 10807 - Add db field search_history.type)\n";
7081
    SetVersion($DBversion);
7082
}
7083
7070
=head1 FUNCTIONS
7084
=head1 FUNCTIONS
7071
7085
7072
=head2 TableExists($table)
7086
=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 (-92 / +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-146 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)
38
my ($template, $loggedinuser, $cookie) = get_template_and_user(
40
= get_template_and_user({template_name => "opac-search-history.tmpl",
39
    {
41
                                query => $cgi,
40
        template_name => "opac-search-history.tmpl",
42
                                type => "opac",
41
        query => $cgi,
43
                                authnotrequired => 1,
42
        type => "opac",
44
                                flagsrequired => {borrowers => 1},
43
        authnotrequired => 1,
45
                                debug => 1,
44
        flagsrequired => {borrowers => 1},
46
                                });
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');
47
52
48
# 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
49
if (!$loggedinuser) {
54
unless ( $loggedinuser ) {
50
55
51
    # Deleting search history
56
    # Deleting search history
52
    if ($cgi->param('action') && $cgi->param('action') eq 'delete') {
57
    if ( $action eq 'delete' ) {
53
	# Deleting cookie's content 
58
        # Deleting cookie's content 
54
	my $recentSearchesCookie = $cgi->cookie(
59
        my $current_searches_cookie = C4::Search::History::get_empty_cookie({
55
	    -name => 'KohaOpacRecentSearches',
60
            cgi => $cgi,
56
	    -value => encode_json([]),
61
            name => 'KohaOpacRecentSearches',
57
	    -expires => ''
62
        });
58
	    );
63
59
64
        # Redirecting to this same url with the cookie in the headers so it's deleted immediately
60
	# Redirecting to this same url with the cookie in the headers so it's deleted immediately
65
        my $uri = $cgi->url();
61
	my $uri = $cgi->url();
66
        print $cgi->redirect(
62
	print $cgi->redirect(-uri => $uri,
67
            -uri => $uri,
63
			     -cookie => $recentSearchesCookie);
68
            -cookie => $current_searches_cookie
69
        );
64
70
65
    # Showing search history
71
    # Showing search history
66
    } else {
72
    } else {
67
73
        # Getting the cookie
68
        my @recentSearches = ParseSearchHistoryCookie($cgi);
74
        my @current_searches = @{
69
	    if (@recentSearches) {
75
            C4::Search::History::get_from_cookie({
70
76
                cookie => $cgi->cookie('KohaOpacRecentSearches')
71
		# As the dates are stored as unix timestamps, let's do some formatting
77
            })
72
		foreach my $asearch (@recentSearches) {
78
        };
73
79
74
		    # We create an iso date from the unix timestamp
80
        my @current_biblio_searches = map {
75
		    my $isodate = strftime "%Y-%m-%d", localtime($asearch->{'time'});
81
            $_->{type} eq 'biblio' ? $_ : ()
76
82
        } @current_searches;
77
		    # So we can create a C4::Dates object, to get the date formatted according to the dateformat syspref
83
78
		    my $date = C4::Dates->new($isodate, "iso");
84
        my @current_authority_searches = map {
79
		    my $sysprefdate = $date->output("syspref");
85
            $_->{type} eq 'authority' ? $_ : ()
80
		    
86
        } @current_searches;
81
		    # We also get the time of the day from the unix timestamp
87
82
		    my $time = strftime " %H:%M:%S", localtime($asearch->{'time'});
88
        $template->param(
83
89
            current_biblio_searches => \@current_biblio_searches,
84
		    # And we got our human-readable date : 
90
            current_authority_searches => \@current_authority_searches,
85
		    $asearch->{'time'} = $sysprefdate . $time;
91
        );
86
		}
87
88
		$template->param(recentSearches => \@recentSearches);
89
	    }
90
    }
92
    }
91
} else {
93
} else {
92
# 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
93
   
94
    my $dbh = C4::Context->dbh;
95
    my $dbh = C4::Context->dbh;
95
96
96
    # Deleting search history
97
    # Deleting search history
97
    if ($cgi->param('action') && $cgi->param('action') eq 'delete') {
98
    if ( $action eq 'delete' ) {
98
	my $query = "DELETE FROM search_history WHERE userid = ?";
99
        my $sessionid = defined $previous
99
	my $sth   = $dbh->prepare($query);
100
            ? $cgi->cookie("CGISESSID")
100
	$sth->execute($loggedinuser);
101
            : q{};
101
102
        C4::Search::History::delete(
102
	# Redirecting to this same url so the user won't see the search history link in the header
103
            {
103
	my $uri = $cgi->url();
104
                userid => $loggedinuser,
104
	print $cgi->redirect($uri);
105
                sessionid => $sessionid,
105
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);
106
113
107
    # Showing search history
114
    # Showing search history
108
    } else {
115
    } else {
109
116
        my $current_searches = C4::Search::History::get({
110
	my $date = C4::Dates->new();
117
            userid => $loggedinuser,
111
	my $dateformat = $date->DHTMLcalendar() . " %H:%i:%S"; # Current syspref date format + standard time format
118
            sessionid => $cgi->cookie("CGISESSID")
112
119
        });
113
	# Getting the data with date format work done by mysql
120
        my @current_biblio_searches = map {
114
    my $query = "SELECT userid, sessionid, query_desc, query_cgi, total, time FROM search_history WHERE userid = ? AND sessionid = ?";
121
            $_->{type} eq 'biblio' ? $_ : ()
115
	my $sth   = $dbh->prepare($query);
122
        } @$current_searches;
116
	$sth->execute($loggedinuser, $cgi->cookie("CGISESSID"));
123
117
	my $searches = $sth->fetchall_arrayref({});
124
        my @current_authority_searches = map {
118
	$template->param(recentSearches => $searches);
125
            $_->{type} eq 'authority' ? $_ : ()
119
	
126
        } @$current_searches;
120
	# Getting searches from previous sessions
127
121
	$query = "SELECT COUNT(*) FROM search_history WHERE userid = ? AND sessionid != ?";
128
        my $previous_searches = C4::Search::History::get({
122
	$sth   = $dbh->prepare($query);
129
            userid => $loggedinuser,
123
	$sth->execute($loggedinuser, $cgi->cookie("CGISESSID"));
130
            sessionid => $cgi->cookie("CGISESSID"),
124
131
            previous => 1
125
	# If at least one search from previous sessions has been performed
132
        });
126
        if ($sth->fetchrow_array > 0) {
133
127
        $query = "SELECT userid, sessionid, query_desc, query_cgi, total, time FROM search_history WHERE userid = ? AND sessionid != ?";
134
        my @previous_biblio_searches = map {
128
	    $sth   = $dbh->prepare($query);
135
            $_->{type} eq 'biblio' ? $_ : ()
129
	    $sth->execute($loggedinuser, $cgi->cookie("CGISESSID"));
136
        } @$previous_searches;
130
    	    my $previoussearches = $sth->fetchall_arrayref({});
137
131
    	    $template->param(previousSearches => $previoussearches);
138
        my @previous_authority_searches = map {
132
	
139
            $_->{type} eq 'authority' ? $_ : ()
133
	}
140
        } @$previous_searches;
134
141
135
	$sth->finish;
142
        $template->param(
136
143
            current_biblio_searches => \@current_biblio_searches,
137
144
            current_authority_searches => \@current_authority_searches,
145
            previous_biblio_searches => \@previous_biblio_searches,
146
            previous_authority_searches => \@previous_authority_searches,
147
148
        );
138
    }
149
    }
139
140
}
150
}
141
151
142
$template->param(searchhistoryview => 1);
152
$template->param(searchhistoryview => 1);
143
153
144
output_html_with_http_headers $cgi, $cookie, $template->output;
154
output_html_with_http_headers $cgi, $cookie, $template->output;
145
146
(-)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 617-663 for (my $i=0;$i<@servers;$i++) { Link Here
617
        }
618
        }
618
619
619
        # Opac search history
620
        # Opac search history
620
        my $newsearchcookie;
621
        if (C4::Context->preference('EnableOpacSearchHistory')) {
621
        if (C4::Context->preference('EnableOpacSearchHistory')) {
622
            my @recentSearches = ParseSearchHistoryCookie($cgi);
622
            unless ( $offset ) {
623
623
                my $path_info = $cgi->url(-path_info=>1);
624
            # Adding the new search if needed
624
                my $query_cgi_history = $cgi->url(-query=>1);
625
            my $path_info = $cgi->url(-path_info=>1);
625
                $query_cgi_history =~ s/^$path_info\?//;
626
            my $query_cgi_history = $cgi->url(-query=>1);
626
                $query_cgi_history =~ s/;/&/g;
627
            $query_cgi_history =~ s/^$path_info\?//;
627
                my $query_desc_history = $query_desc;
628
            $query_cgi_history =~ s/;/&/g;
628
                $query_desc_history .= ", $limit_desc"
629
            my $query_desc_history = "$query_desc, $limit_desc";
629
                    if $limit_desc;
630
630
631
            if (!$borrowernumber || $borrowernumber eq '') {
631
                unless ( $borrowernumber ) {
632
                # To a cookie (the user is not logged in)
632
                    my $new_search = C4::Search::History::build_new_cookie_value({
633
                if (!$offset) {
633
                            recent_searches => $cgi->cookie('KohaOpacRecentSearches') || q{},
634
                    push @recentSearches, {
634
                            query_desc => $query_desc_history,
635
                                "query_desc" => Encode::decode_utf8($query_desc_history) || "unknown",
635
                            query_cgi => $query_cgi_history,
636
                                "query_cgi"  => Encode::decode_utf8($query_cgi_history)  || "unknown",
636
                            total => $total,
637
                                "time"       => time(),
637
                            type => "biblio",
638
                                "total"      => $total
638
                    });
639
                              };
640
                    $template->param(ShowOpacRecentSearchLink => 1);
641
                }
642
639
643
                shift @recentSearches if (@recentSearches > 15);
640
                    $cookie = [
644
                # Pushing the cookie back
641
                        $cookie,
645
                $newsearchcookie = $cgi->cookie(
642
                        $cgi->cookie(
646
                            -name => 'KohaOpacRecentSearches',
643
                            -name => 'KohaOpacRecentSearches',
647
                            # We uri_escape the whole serialized structure so we're sure we won't have any encoding problems
644
                            # We uri_escape the whole serialized structure so we're sure we won't have any encoding problems
648
                            -value => uri_escape( encode_json(\@recentSearches) ),
645
                            -value => $new_search,
649
                            -expires => ''
646
                            -expires => ''
650
                );
647
                        )
651
                $cookie = [$cookie, $newsearchcookie];
648
                    ];
652
            }
649
                } else {
653
            else {
650
                    # To the session (the user is logged in)
654
                # To the session (the user is logged in)
651
                    C4::Search::History::add({
655
                if (!$offset) {
652
                        userid => $borrowernumber,
656
                    AddSearchHistory($borrowernumber, $cgi->cookie("CGISESSID"), $query_desc_history, $query_cgi_history, $total);
653
                        sessionid => $cgi->cookie("CGISESSID"),
657
                    $template->param(ShowOpacRecentSearchLink => 1);
654
                        query_desc => $query_desc_history,
655
                        query_cgi => $query_cgi_history,
656
                        total => $total,
657
                        type => "biblio",
658
                    });
658
                }
659
                }
659
            }
660
            }
661
            $template->param( EnableOpacSearchHistory => 1 );
660
        }
662
        }
663
661
        ## If there's just one result, redirect to the detail page
664
        ## If there's just one result, redirect to the detail page
662
        if ($total == 1 && $format ne 'rss2'
665
        if ($total == 1 && $format ne 'rss2'
663
        && $format ne 'opensearchdescription' && $format ne 'atom') {
666
        && $format ne 'opensearchdescription' && $format ne 'atom') {
(-)a/t/Search/History.t (+35 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' );
35
(-)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