@@ -, +, @@ history lines --- C4/Search/History.pm | 45 +-- catalogue/search-history.pl | 92 +++--- .../prog/en/modules/catalogue/search-history.tt | 285 ++++++++--------- .../bootstrap/en/modules/opac-search-history.tt | 351 ++++++++++----------- opac/opac-search-history.pl | 172 +++++----- 5 files changed, 469 insertions(+), 476 deletions(-) --- a/C4/Search/History.pm +++ a/C4/Search/History.pm @@ -162,37 +162,44 @@ sub get { } my $query = q{ - SELECT * - FROM search_history + SELECT sh.* , s.a_session + FROM search_history sh + LEFT JOIN sessions s ON (sh.sessionid = s.id) WHERE 1 }; - $query .= q{ AND id IN ( } . join( q{,}, (q{?}) x @$id ) . q{ )} - if @$id; + my @bind_params; - $query .= q{ - AND userid = ? - } if $userid; + if (@$id) { + $query .= q{ AND sh.id IN ( } . join( q{,}, (q{?}) x @$id ) . q{ )}; + push @bind_params, @$id; + } + + if ($userid) { + $query .= q{ AND sh.userid = ? }; + push @bind_params, $userid; + } if ($sessionid) { - $query .= - $previous - ? q{ AND sessionid != ?} - : q{ AND sessionid = ?}; + if (defined $previous) { + $query .= + $previous + ? q{ AND sh.sessionid != ?} + : q{ AND sh.sessionid = ?}; + push @bind_params, $sessionid; + } } - $query .= q{ AND type = ?} - if $type; + if ($type) { + $query .= q{ AND sh.type = ?}; + push @bind_params, $type; + } my $dbh = C4::Context->dbh; my $sth = $dbh->prepare($query); - $sth->execute( - ( @$id ? ( @$id ) : () ), - ( $userid ? $userid : () ), - ( $sessionid ? $sessionid : () ), - ( $type ? $type : () ) - ); + $sth->execute(@bind_params); return $sth->fetchall_arrayref( {} ); + } sub get_from_session { --- a/catalogue/search-history.pl +++ a/catalogue/search-history.pl @@ -20,8 +20,11 @@ use Modern::Perl; use CGI qw ( -utf8 ); +use URI::Escape; use C4::Auth; +use C4::Languages; +use C4::Search; use C4::Search::History; use C4::Output; @@ -37,61 +40,76 @@ my ($template, $loggedinuser, $cookie) = get_template_and_user({ my $type = $cgi->param('type'); my $action = $cgi->param('action') || q{list}; -my $previous = $cgi->param('previous'); -# Deleting search history -if ( $action eq 'delete' ) { - my $sessionid = defined $previous - ? $cgi->cookie("CGISESSID") - : q{}; +if ( $action eq 'search' ) { + # Start a new search + + my @ids = $cgi->multi_param('id'); + my @nots = $cgi->multi_param('not'); + my $searches = C4::Search::History::get({ + userid => $loggedinuser, + id => \@ids, + }); + my @ccl_queries; + foreach my $search (@$searches) { + my $scgi = new CGI($search->{query_cgi}); + my @operators = map uri_unescape($_), $scgi->multi_param('op'); + my @indexes = map uri_unescape($_), $scgi->multi_param('idx'); + my @operands = map uri_unescape($_), $scgi->multi_param('q'); + my @limits = map uri_unescape($_), $scgi->multi_param('limit'); + my @sort_by = $scgi->param('sort_by'); + my $scan = $scgi->param('scan'); + my $lang = C4::Languages::getlanguage($cgi); + my ( $error, $query ) = + buildQuery( \@operators, \@operands, \@indexes, \@limits, \@sort_by, + $scan, $lang ); + + if (grep {$_ == $search->{id}} @nots) { + $query = "allrecords,alwaysmatches='' not ($query)"; + } + + push @ccl_queries, $query; + } + my $join = ($cgi->param('join') eq 'or') ? 'or' : 'and'; + my $query = 'ccl=(' . join(") $join (", @ccl_queries) . ')'; + print $cgi->redirect("/cgi-bin/koha/catalogue/search.pl?q=$query"); + exit; +} elsif ( $action eq 'delete' ) { C4::Search::History::delete( { userid => $loggedinuser, - id => [ $cgi->param('id') ], + id => [ $cgi->multi_param('id') ], } ); # Redirecting to this same url so the user won't see the search history link in the header print $cgi->redirect('/cgi-bin/koha/catalogue/search-history.pl'); - -# Showing search history + exit; } else { - my $current_searches = C4::Search::History::get({ + # Showing search history + my $searches = C4::Search::History::get({ userid => $loggedinuser, sessionid => $cgi->cookie("CGISESSID") }); - my @current_biblio_searches = map { - $_->{type} eq 'biblio' ? $_ : () - } @$current_searches; - - my @current_authority_searches = map { - $_->{type} eq 'authority' ? $_ : () - } @$current_searches; - - my $previous_searches = C4::Search::History::get({ - userid => $loggedinuser, - sessionid => $cgi->cookie("CGISESSID"), - previous => 1 - }); - - my @previous_biblio_searches = map { + foreach my $row (@$searches) { + if ($row->{a_session}) { + $row->{session} = YAML::Load($row->{a_session}); + $row->{session}->{session_ctime} = $row->{session}->{_SESSION_CTIME}; + $row->{session}->{session_id} = $row->{session}->{_SESSION_ID}; + } + } + my @biblio_searches = map { $_->{type} eq 'biblio' ? $_ : () - } @$previous_searches; + } @$searches; - my @previous_authority_searches = map { + my @authority_searches = map { $_->{type} eq 'authority' ? $_ : () - } @$previous_searches; + } @$searches; $template->param( - current_biblio_searches => \@current_biblio_searches, - current_authority_searches => \@current_authority_searches, - previous_biblio_searches => \@previous_biblio_searches, - previous_authority_searches => \@previous_authority_searches, - + biblio_searches => \@biblio_searches, + authority_searches => \@authority_searches, + sessionid => $cgi->cookie("CGISESSID"), ); } - -$template->param( -); - output_html_with_http_headers $cgi, $cookie, $template->output; --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/search-history.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/search-history.tt @@ -1,6 +1,88 @@ -[% INCLUDE 'doc-head-open.inc' %] [% USE Koha %] [% USE KohaDates %] +[% USE date %] + +[% BLOCK search_history_table %] +
+ [%# Search from multiple lines is only enabled for biblios %] + [% IF type == 'biblio' %] +
+ Start a new search + + New search: + + + Cancel + +
+ [% END %] +
+ Select all visible rows + | + Clear selection on visible rows + | + + Select searches to: + Delete + +
+ + + + + + + + + + + + + + [% FOREACH s IN searches %] + + + + + + [% IF type == 'biblio' %] + [% search_url = '/cgi-bin/koha/catalogue/search.pl' %] + [% ELSE %] + [% search_url = '/cgi-bin/koha/authorities/authorities-home.pl' %] + [% END %] + + + + [% END %] + +
NotSession dateDateSearchResults
+ + + [% IF s.session %] + [% session_ctime = date.format(s.session.session_ctime, '%Y-%m-%d %H:%M:%S') %] + + [% IF s.session.session_id == sessionid %] + + [% END %] + [% session_ctime | $KohaDates %] + [% IF s.session.session_id == sessionid %] + + [% END %] + + [% ELSE %] + Unknown + [% END %] + [% s.time |$KohaDates with_hours => 1 %][% s.query_desc |html %][% s.total %]
+
+[% END %] + +[% INCLUDE 'doc-head-open.inc' %] Koha › Catalog › Search history [% INCLUDE 'doc-head-close.inc' %] @@ -12,10 +94,11 @@ $(document).ready(function() { // We show table ordered by descending dates by default // (so that the more recent query is shown first) $(".historyt").dataTable($.extend(true, {}, dataTablesDefaults, { - "aaSorting": [[ 1, "desc" ]], + "aaSorting": [[ 3, "desc" ]], "aoColumnDefs": [ - { "aTargets": [ 0 ], "bSortable": false, "bSearchable": false }, - { "aTargets": [ 1 ], "sType": "title-string" }, + { "aTargets": [ 0, 1 ], "bSortable": false, "bSearchable": false }, + { "aTargets": [ 2, 3 ], "sType": "title-string" }, + { "aTargets": [ 1 ], "bVisible": false } ], "sPaginationType": "full_numbers" })); @@ -34,7 +117,7 @@ $(document).ready(function() { var new_form = $('
') .attr('action', form.attr('action')) .attr('method', form.attr('method')); - form.find('input[type="hidden"]') + form.find('input[type="hidden"],select') .add(table.$('input:checkbox:checked')) .each(function() { var input = $('') @@ -81,10 +164,42 @@ $(document).ready(function() { } if ( confirm(msg) ) { + form.find('input[name="action"]').val('delete'); form.submit(); } return false; }); + $(".action_search").click(function() { + var $form = $(this).parents('form'); + var table = $form.find('table').dataTable(); + var $checked = table.$('input:checkbox:checked'); + $(this).hide(); + $('.search_options').show(); + table.fnSetColumnVis(1, true); + return false; + }); + + $('.search_options button[type="submit"]').click(function() { + var $form = $(this).parents('form'); + var table = $form.find('table').dataTable(); + var $checked = table.$('input:checkbox:checked'); + if ($checked.length) { + $form.find('input[name="action"]').val('search'); + $form.submit(); + } else { + alert(_("You have to select searches first")); + } + return false; + }); + + $('.action_search_cancel').click(function() { + var form = $(this).parents('form').first(); + var table = form.find('table').dataTable(); + $('.action_search').show(); + $('.search_options').hide(); + table.fnSetColumnVis(1, false); + return false; + }).click(); $('#tabs form').each(function() { enableCheckboxActions($(this)); @@ -133,161 +248,21 @@ function enableCheckboxActions(form){
  • Authority
  • - [% IF ( current_biblio_searches ) %] -

    Current session

    - -
    - Select all visible rows - | - Clear selection on visible rows - | - - Select searches to: - Delete - -
    - - - - - - - - - - - - [% FOREACH s IN current_biblio_searches %] - - - - - - - [% END %] - -
    DateSearchResults
    [% s.time |$KohaDates with_hours => 1 %][% s.query_desc |html %][% s.total %]
    - - [% END %] - - [% IF ( previous_biblio_searches ) %] -

    Previous sessions

    -
    -
    - Select all visible rows - | - Clear selection on visible rows - | - - Select searches to: - Delete - -
    - - - - - - - - - - - - [% FOREACH s IN previous_biblio_searches %] - - - - - - - [% END %] - -
    DateSearchResults
    [% s.time |$KohaDates with_hours => 1 %][% s.query_desc |html %][% s.total %]
    -
    - [% END %] - - [% IF !current_biblio_searches && !previous_biblio_searches %] + [% IF ( biblio_searches ) %] + [% INCLUDE search_history_table + searches = biblio_searches + type = 'biblio' %] + [% ELSE %]

    Your catalog search history is empty.

    [% END %]
    - [% IF ( current_authority_searches ) %] -

    Current session

    -
    -
    - Select all visible rows - | - Clear selection on visible rows - | - - Select searches to: - Delete - -
    - - - - - - - - - - - - [% FOREACH s IN current_authority_searches %] - - - - - - - [% END %] - -
    DateSearchResults
    [% s.time |$KohaDates with_hours => 1 %][% s.query_desc |html %][% s.total %]
    -
    - [% END %] - - [% IF ( previous_authority_searches ) %] -

    Previous sessions

    -
    -
    - Select all visible rows - | - Clear selection on visible rows - | - - Select searches to: - Delete - -
    - - - - - - - - - - - - [% FOREACH s IN previous_authority_searches %] - - - - - - - [% END %] - -
    DateSearchResults
    [% s.time |$KohaDates with_hours => 1 %][% s.query_desc |html %][% s.total %]
    -
    - [% END %] - - [% IF !current_authority_searches && !previous_authority_searches %] + [% IF ( authority_searches ) %] + [% INCLUDE search_history_table + searches = authority_searches + type = 'authority' %] + [% ELSE %]

    Your authority search history is empty.

    [% END %]
    --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-search-history.tt +++ a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-search-history.tt @@ -1,5 +1,101 @@ [% USE Koha %] [% USE KohaDates %] +[% USE date %] + +[% BLOCK search_history_table %] +
    +
    + [% IF type == 'biblio' %] + Start a new search + + New search: + + + Cancel + +   + [% END %] +
    +
    + Select all + Clear all + | + + Select searches to: + Delete + +
    + + + + + + + [% IF hide_session_column %] + + [% ELSE %] + + [% END %] + + + + + + + [% FOREACH s IN searches %] + + + + [% IF hide_session_column %] + + + [% IF type == 'biblio' %] + [% search_url = '/cgi-bin/koha/opac-search.pl' %] + [% ELSIF type == 'authority' %] + [% search_url = '/cgi-bin/koha/opac-authorities-home.pl' %] + [% END %] + + + + [% END %] + +
    NotSession dateSession dateDateSearchResults
    + + + [% ELSE %] + + [% END %] + [% IF s.session %] + [% session_ctime = date.format(s.session.session_ctime, '%Y-%m-%d %H:%M:%S') %] + + [% IF s.session.session_id == sessionid %] + + [% END %] + [% session_ctime | $KohaDates %] + [% IF s.session.session_id == sessionid %] + + [% END %] + + [% ELSE %] + Unknown + [% END %] + [% s.time |$KohaDates with_hours => 1 %] + [% IF type == 'biblio' %] + + Subscribe to this search + + [% END %] + [% s.query_desc |html %][% s.total %]
    + +
    +[% END %] + [% INCLUDE 'doc-head-open.inc' %] [% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog › Your search history [% INCLUDE 'doc-head-close.inc' %] @@ -31,186 +127,39 @@
    [% END %]
    -

    Search history

    - [% IF Koha.Preference( 'OpacAuthorities' ) == 1 %] -
    - +

    Search history

    + [% IF Koha.Preference( 'OpacAuthorities' ) == 1 %] +
    + + [% END %] +
    + [% IF ( biblio_searches ) %] + [% INCLUDE search_history_table + searches = biblio_searches + type = 'biblio' %] + [% ELSE %] +

    Your catalog search history is empty.

    [% END %] -
    -
    - [% IF ( current_biblio_searches ) %] -

    Current session

    -
    -
    - Select all - Clear all - | - - Select searches to: - Delete - -
    - - - - - - - - - - - - [% FOREACH s IN current_biblio_searches %] - - - - - - - [% END %] - -
    DateSearchResults
    [% s.time |$KohaDates with_hours => 1 %]Subscribe to this search [% s.query_desc |html %][% s.total %]
    - -
    - [% END # IF ( current_biblio_searches ) %] -
    - -
    - [% IF ( previous_biblio_searches ) %] -

    Previous sessions

    -
    -
    - Select all - Clear all - | - - Select searches to: - Delete - -
    - - - - - - - - - - - - - [% FOREACH s IN previous_biblio_searches %] - - - - - - - [% END %] - -
    DateSearchResults
    [% s.time |$KohaDates with_hours => 1 %]Subscribe to this search [% s.query_desc |html %][% s.total %]
    - -
    - [% END # IF ( previous_biblio_searches ) %] -
    - - [% IF !current_biblio_searches && !previous_biblio_searches %] -

    Your catalog search history is empty.

    - [% END %] -
    +
    - [% IF Koha.Preference( 'OpacAuthorities' ) == 1 %] -
    - [% IF ( current_authority_searches ) %] -

    Current session

    -
    -
    - Select all - Clear all - | - - Select searches to: - Delete - -
    - - - - - - - - - - - - [% FOREACH s IN current_authority_searches %] - - - - - - - [% END %] - -
    DateSearchResults
    [% s.time |$KohaDates with_hours => 1 %][% s.query_desc |html %][% s.total %]
    - -
    - [% END # / IF ( current_authority_searches ) %] - - [% IF ( previous_authority_searches ) %] -

    Previous sessions

    -
    -
    - Select all - Clear all - | - - Select searches to: - Delete - -
    - - - - - - - - - - - - [% FOREACH s IN previous_authority_searches %] - - - - - - - [% END %] - -
    DateSearchResults
    [% s.time |$KohaDates with_hours => 1 %][% s.query_desc |html %][% s.total %]
    - -
    - [% END # / IF ( previous_authority_searches )%] - - [% IF !current_authority_searches && !previous_authority_searches %] -

    Your authority search history is empty.

    - [% END %] -
    - [% END # / IF Koha.Preference( 'OpacAuthorities' ) %] -
    -
    -
    -
    - - + [% IF Koha.Preference( 'OpacAuthorities' ) == 1 %] +
    + [% IF ( authority_searches ) %] + [% INCLUDE search_history_table + searches = authority_searches + type = 'authority' %] + [% ELSE %] +

    Your authority search history is empty.

    + [% END %] +
    + [% END %] + + + + [% INCLUDE 'opac-bottom.inc' %] [% BLOCK jsinclude %] @@ -220,14 +169,14 @@ //param('type'); my $action = $cgi->param('action') || q{}; -my $previous = $cgi->param('previous'); -# If the user is not logged in, we deal with the session -unless ( $loggedinuser ) { - # Deleting search history - if ( $action eq 'delete') { - # Deleting session's search history - my @id = $cgi->multi_param('id'); - my $all = not scalar( @id ); - - my $type = $cgi->param('type'); - my @searches = (); - unless ( $all ) { - @searches = C4::Search::History::get_from_session({ cgi => $cgi }); - if ( $type ) { - @searches = map { $_->{type} ne $type ? $_ : () } @searches; - } - if ( @id ) { - @searches = map { my $search = $_; ( grep {/^$search->{id}$/} @id ) ? () : $_ } @searches; - } - } - C4::Search::History::set_to_session({ cgi => $cgi, search_history => \@searches }); +if ( $action eq 'search' ) { + # Start a new search - # Redirecting to this same url so the user won't see the search history link in the header - print $cgi->redirect(-uri => '/cgi-bin/koha/opac-search-history.pl'); - # Showing search history + my @ids = $cgi->multi_param('id'); + my @nots = $cgi->multi_param('not'); + my @searches; + if ($loggedinuser) { + @searches = @{ C4::Search::History::get({ + userid => $loggedinuser, + id => \@ids, + }) }; } else { - # Getting the searches from session - my @current_searches = C4::Search::History::get_from_session({ - cgi => $cgi, - }); - - my @current_biblio_searches = map { - $_->{type} eq 'biblio' ? $_ : () - } @current_searches; - - my @current_authority_searches = map { - $_->{type} eq 'authority' ? $_ : () - } @current_searches; - - $template->param( - current_biblio_searches => \@current_biblio_searches, - current_authority_searches => \@current_authority_searches, - ); + @searches = C4::Search::History::get_from_session({ cgi => $cgi }); + if ( @ids ) { + @searches = map { + my $search = $_; + ( grep {/^$search->{id}$/} @ids ) ? $_ : () + } @searches; + } } -} else { - # And if the user is logged in, we deal with the database - my $dbh = C4::Context->dbh; + my @ccl_queries; + foreach my $search (@searches) { + my $scgi = new CGI($search->{query_cgi}); + my @operators = map uri_unescape($_), $scgi->multi_param('op'); + my @indexes = map uri_unescape($_), $scgi->multi_param('idx'); + my @operands = map uri_unescape($_), $scgi->multi_param('q'); + my @limits = map uri_unescape($_), $scgi->multi_param('limit'); + my @sort_by = $scgi->multi_param('sort_by'); + my $scan = $scgi->param('scan'); + my $lang = C4::Languages::getlanguage($cgi); + my ( $error, $query ) = + buildQuery( \@operators, \@operands, \@indexes, \@limits, \@sort_by, + $scan, $lang ); + + if (grep {$_ == $search->{id}} @nots) { + $query = "allrecords,alwaysmatches='' not ($query)"; + } + push @ccl_queries, $query; + } + my $join = ($cgi->param('join') eq 'or') ? 'or' : 'and'; + my $query = 'ccl=(' . join(") $join (", @ccl_queries) . ')'; + print $cgi->redirect("/cgi-bin/koha/opac-search.pl?q=$query"); + exit; +} elsif ( $action eq 'delete' ) { # Deleting search history - if ( $action eq 'delete' ) { - my @id = $cgi->multi_param('id'); + my @id = $cgi->multi_param('id'); + if ($loggedinuser) { if ( @id ) { C4::Search::History::delete( { userid => $loggedinuser, - id => [ $cgi->param('id') ], + id => \@id, } ); } else { @@ -114,45 +112,61 @@ unless ( $loggedinuser ) { } ); } - # Redirecting to this same url so the user won't see the search history link in the header - print $cgi->redirect(-uri => '/cgi-bin/koha/opac-search-history.pl'); - - # Showing search history } else { - my $current_searches = C4::Search::History::get({ + # Deleting session's search history + my $type = $cgi->param('type'); + my @searches = (); + if ( scalar @id ) { + @searches = C4::Search::History::get_from_session({ cgi => $cgi }); + if ( $type ) { + @searches = map { $_->{type} ne $type ? $_ : () } @searches; + } + if ( @id ) { + @searches = map { my $search = $_; ( grep {/^$search->{id}$/} @id ) ? () : $_ } @searches; + } + } + C4::Search::History::set_to_session({ cgi => $cgi, search_history => \@searches }); + } + # Redirecting to this same url so the user won't see the search history link in the header + print $cgi->redirect(-uri => '/cgi-bin/koha/opac-search-history.pl'); + exit; +} else { + # Showing search history + my @searches; + if ($loggedinuser) { + @searches = @{ C4::Search::History::get({ userid => $loggedinuser, sessionid => $cgi->cookie("CGISESSID") + }) }; + foreach my $row (@searches) { + if ($row->{a_session}) { + $row->{session} = YAML::Load($row->{a_session}); + $row->{session}->{session_ctime} = $row->{session}->{_SESSION_CTIME}; + $row->{session}->{session_id} = $row->{session}->{_SESSION_ID}; + } + } + } else { + # Getting the searches from session + @searches = C4::Search::History::get_from_session({ + cgi => $cgi, }); - my @current_biblio_searches = map { - $_->{type} eq 'biblio' ? $_ : () - } @$current_searches; - - my @current_authority_searches = map { - $_->{type} eq 'authority' ? $_ : () - } @$current_searches; - - my $previous_searches = C4::Search::History::get({ - userid => $loggedinuser, - sessionid => $cgi->cookie("CGISESSID"), - previous => 1 - }); + $template->param(hide_session_column => 1); + } - my @previous_biblio_searches = map { - $_->{type} eq 'biblio' ? $_ : () - } @$previous_searches; - my @previous_authority_searches = map { - $_->{type} eq 'authority' ? $_ : () - } @$previous_searches; + my @biblio_searches = map { + $_->{type} eq 'biblio' ? $_ : () + } @searches; - $template->param( - current_biblio_searches => \@current_biblio_searches, - current_authority_searches => \@current_authority_searches, - previous_biblio_searches => \@previous_biblio_searches, - previous_authority_searches => \@previous_authority_searches, + my @authority_searches = map { + $_->{type} eq 'authority' ? $_ : () + } @searches; - ); - } + $template->param( + biblio_searches => \@biblio_searches, + authority_searches => \@authority_searches, + sessionid => $cgi->cookie('CGISESSID'), + ); } $template->param(searchhistoryview => 1); --