From f66701e3582e319624867071bcba4fa31472d2b2 Mon Sep 17 00:00:00 2001 From: senator Date: Thu, 10 Mar 2011 17:24:08 -0500 Subject: [PATCH] Foundational work for temporary/anon lists and per-user lists (bookbags) There were already some features in EGCatLoader for adding and deleting items from lists, but there's more to do, as that code only dealt with numeric IDs, and we need records avaiable. Also, to avoid search bots creating temporary/anon lists all the time, and just because the following is good practice, our "add to my list" links need to be forms that POST, not links that GET. Etc., etc.; more to come. --- .../src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm | 5 + .../lib/OpenILS/WWW/EGCatLoader/Account.pm | 28 +++-- .../lib/OpenILS/WWW/EGCatLoader/Container.pm | 16 ++- .../perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm | 32 +----- .../perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm | 69 ++++++++++ Open-ILS/web/css/skin/default/opac/semiauto.css | 2 +- Open-ILS/web/css/skin/default/opac/style.css | 9 ++ Open-ILS/web/templates/default/opac/mylist.tt2 | 16 +++ .../web/templates/default/opac/myopac/lists.tt2 | 132 +++++--------------- .../web/templates/default/opac/parts/anon_list.tt2 | 48 +++++++ .../templates/default/opac/parts/result/table.tt2 | 18 ++-- Open-ILS/web/templates/default/opac/results.tt2 | 4 +- 12 files changed, 231 insertions(+), 148 deletions(-) create mode 100644 Open-ILS/web/templates/default/opac/mylist.tt2 create mode 100644 Open-ILS/web/templates/default/opac/parts/anon_list.tt2 diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm index 597bf96..941efa1 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader.pm @@ -84,12 +84,17 @@ sub load { my $path = $self->apache->path_info; + (undef, $self->ctx->{mylist}) = $self->fetch_mylist unless + $path =~ /opac\/my(opac\/lists|list)/; + return $self->load_simple("home") if $path =~ /opac\/home/; return $self->load_simple("advanced") if $path =~ /opac\/advanced/; return $self->load_rresults if $path =~ /opac\/results/; return $self->load_record if $path =~ /opac\/record/; + return $self->load_mylist_add if $path =~ /opac\/mylist\/add/; return $self->load_mylist_del if $path =~ /opac\/mylist\/del/; + return $self->load_mylist if $path =~ /opac\/mylist/; return $self->load_cache_clear if $path =~ /opac\/cache\/clear/; # ---------------------------------------------------------------- diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm index 5adff47..7fcdfa9 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm @@ -489,19 +489,31 @@ sub load_myopac_bookbags { my $self = shift; my $e = $self->editor; my $ctx = $self->ctx; - my $limit = $self->cgi->param('limit') || 0; - my $offset = $self->cgi->param('offset') || 0; - my $args = {order_by => {cbreb => 'name'}}; - $args->{limit} = $limit if $limit; - $args->{offset} = $offset if $offset; + my $rv = $self->load_mylist; + return $rv if $rv ne Apache2::Const::OK; - (undef, $ctx->{mylist}) = $self->fetch_mylist; + my $args = { + order_by => {cbreb => 'name'}, + limit => $self->cgi->param('limit') || 10, + offset => $self->cgi->param('limit') || 0 + }; $ctx->{bookbags} = $e->search_container_biblio_record_entry_bucket([ {owner => $self->editor->requestor->id, btype => 'bookbag'}, - $args - ]); + # XXX what to do about the possibility of really large bookbags here? + {"flesh" => 1, "flesh_fields" => {"cbreb" => ["items"]}, %$args} + ]) or return $e->die_event; + + # get unique record IDs + my %rec_ids = (); + foreach my $bbag (@{$ctx->{bookbags}}) { + foreach my $item_id (map { $_->id } @{$bbag->items}) { + $rec_ids{$item_id} = 1; + } + } + + $ctx->{bookbags_marc_xml} = $self->fetch_marc_xml_by_id(keys %rec_ids); return Apache2::Const::OK; } diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm index 49954e7..5a73fdb 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm @@ -13,7 +13,7 @@ use constant ANON_CACHE_MYLIST => 'mylist'; # Retrieve the users cached records AKA 'My List' # Returns an empty list if there are no cached records sub fetch_mylist { - my $self = shift; + my ($self, $with_marc_xml) = @_; my $list = []; my $cache_key = $self->cgi->cookie(COOKIE_ANON_CACHE); @@ -32,8 +32,12 @@ sub fetch_mylist { } $self->apache->log->info("Found anon-cache list [@$list]"); + my $marc_xml; + if ($with_marc_xml) { + $marc_xml = $self->fetch_marc_xml_by_id($list); + } - return ($cache_key, $list); + return ($cache_key, $list, $marc_xml); } @@ -108,4 +112,12 @@ sub mylist_action_redirect { ); } +sub load_mylist { + my ($self) = shift; + (undef, $self->ctx->{mylist}, $self->ctx->{mylist_marc_xml}) = + $self->fetch_mylist(1); + + return Apache2::Const::OK; +} + 1; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm index e2ea613..84c68a7 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm @@ -26,6 +26,7 @@ sub _prepare_biblio_search_basics { # This stuff probably will need refined or rethought to better handle # the weird things Real Users will surely type in. + $contains = "" unless defined $contains; # silence warning if ($contains eq 'nocontains') { $query =~ s/"//g; $query = ('"' . $query . '"') if index $query, ' '; @@ -138,43 +139,16 @@ sub load_rresults { return Apache2::Const::OK if @$rec_ids == 0; - my $cstore1 = OpenSRF::AppSession->create('open-ils.cstore'); - my $bre_req = $cstore1->request( - 'open-ils.cstore.direct.biblio.record_entry.search', {id => $rec_ids}); - - my $search = OpenSRF::AppSession->create('open-ils.search'); - my $facet_req = $search->request('open-ils.search.facet_cache.retrieve', $results->{facet_key}, 10); - - my @data; - while(my $resp = $bre_req->recv) { - my $bre = $resp->content; - - # XXX farm out to multiple cstore sessions before loop, then collect after - my $copy_counts = $e->json_query( - {from => ['asset.record_copy_count', 1, $bre->id, 0]})->[0]; - - push(@data, - { - bre => $bre, - marc_xml => XML::LibXML->new->parse_string($bre->marc), - copy_counts => $copy_counts - } - ); - } - - $cstore1->kill_me; + my ($facets, @data) = $self->get_records_and_facets($rec_ids, $results->{facet_key}); # shove recs into context in search results order - for my $rec_id (@$rec_ids) { + for my $rec_id (@$rec_ids) { push( @{$ctx->{records}}, grep { $_->{bre}->id == $rec_id } @data ); } - my $facets = $facet_req->gather(1); - - $facets->{$_} = {cmf => $ctx->{find_cmf}->($_), data => $facets->{$_}} for keys %$facets; # quick-n-dirty $ctx->{search_facets} = $facets; return Apache2::Const::OK; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm index 63b5213..a6e408d 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm @@ -137,4 +137,73 @@ sub generic_redirect { return Apache2::Const::REDIRECT; } +sub get_records_and_facets { + my ($self, $rec_ids, $facet_key) = @_; + + my $cstore = OpenSRF::AppSession->create('open-ils.cstore'); + my $bre_req = $cstore->request( + 'open-ils.cstore.direct.biblio.record_entry.search', {id => $rec_ids} + ); + + my $search = OpenSRF::AppSession->create('open-ils.search'); + my $facet_req = $search->request( + 'open-ils.search.facet_cache.retrieve', $facet_key, 10 + ) if $facet_key; + + my @data; + while (my $resp = $bre_req->recv) { + my $bre = $resp->content; + + # XXX farm out to multiple cstore sessions before loop, + # then collect after + my $copy_counts = $self->editor->json_query( + {from => ['asset.record_copy_count', 1, $bre->id, 0]} + )->[0]; + + push @data, { + bre => $bre, + marc_xml => XML::LibXML->new->parse_string($bre->marc), + copy_counts => $copy_counts + }; + } + + $cstore->kill_me; + + my $facets; + if ($facet_key) { + $facets = $facet_req->gather(1); + + $facets->{$_} = { + cmf => $self->ctx->{find_cmf}->($_), + data => $facets->{$_} + } for keys %$facets; # quick-n-dirty + } else { + $facets = undef; + } + + return ($facets, @data); +} + +sub fetch_marc_xml_by_id { + my ($self, $id_list) = @_; + $id_list = [$id_list] unless ref($id_list); + return {} if scalar(grep { defined $_ } @$id_list) < 1; + + # I'm just sure there needs to be some more efficient way to get all of + # this. + my $results = $self->editor->json_query({ + "select" => {"bre" => ["id", "marc"]}, + "from" => {"bre" => {}}, + "where" => {"id" => $id_list} + }) or return $self->editor->die_event; + + my $marc_xml = {}; + for my $r (@$results) { + $marc_xml->{$r->{"id"}} = + (new XML::LibXML)->parse_string($r->{"marc"}); + } + + return $marc_xml; +} + 1; diff --git a/Open-ILS/web/css/skin/default/opac/semiauto.css b/Open-ILS/web/css/skin/default/opac/semiauto.css index f652eaa..84748d0 100644 --- a/Open-ILS/web/css/skin/default/opac/semiauto.css +++ b/Open-ILS/web/css/skin/default/opac/semiauto.css @@ -41,7 +41,7 @@ .bold { font-weight: bold; } .opac-auto-057 { font-weight: bold; padding: 5px; margin: 5px; width: 100%; } .opac-auto-058 { font-weight: bold; padding-left: 10px; } -.opac-auto-059 { font-weight: bold; padding-right: 10px; } +#anon_list_name { font-weight: bold; padding-right: 10px; } .opac-auto-060 { font-weight: normal; } .opac-auto-061 { height: 0px; border-top: 1px solid #b7b7b7; border-bottom: 1px solid #d4d4d4; margin: 15px 0px; } .small-height { height: 10px; } diff --git a/Open-ILS/web/css/skin/default/opac/style.css b/Open-ILS/web/css/skin/default/opac/style.css index 6780de3..324e2ff 100644 --- a/Open-ILS/web/css/skin/default/opac/style.css +++ b/Open-ILS/web/css/skin/default/opac/style.css @@ -940,3 +940,12 @@ div.select-wrapper:hover { padding-left: 5em; background-color: #d7d7d7; margin: 2ex 0; } .row-remover { position: relative; top: 1px; vertical-align: middle; } +.subtle-button { + background-color: #ffffff; + color: #003399; text-decoration: none; + font-size: 12px; + padding: 0; border: 0; margin: 0; + vertical-align: middle; +} +.subtle-button:hover { text-decoration: underline; cursor: pointer; } +.no-dec:hover { text-decoration: none; } diff --git a/Open-ILS/web/templates/default/opac/mylist.tt2 b/Open-ILS/web/templates/default/opac/mylist.tt2 new file mode 100644 index 0000000..f115441 --- /dev/null +++ b/Open-ILS/web/templates/default/opac/mylist.tt2 @@ -0,0 +1,16 @@ +[% PROCESS "default/opac/parts/header.tt2"; + PROCESS "default/opac/parts/marc_misc.tt2"; + WRAPPER "default/opac/parts/base.tt2"; + INCLUDE "default/opac/parts/topnav.tt2"; + ctx.page_title = l("Record Detail") %] +
+ [% INCLUDE "default/opac/parts/utils.tt2" %] + [% INCLUDE "default/opac/parts/searchbar.tt2" %] +
+
+
+ [% INCLUDE "default/opac/parts/anon_list.tt2" %] +
+
+
+[% END %] diff --git a/Open-ILS/web/templates/default/opac/myopac/lists.tt2 b/Open-ILS/web/templates/default/opac/myopac/lists.tt2 index 6d1a6db..3da5062 100644 --- a/Open-ILS/web/templates/default/opac/myopac/lists.tt2 +++ b/Open-ILS/web/templates/default/opac/myopac/lists.tt2 @@ -1,36 +1,10 @@ [% PROCESS "default/opac/parts/header.tt2"; + PROCESS "default/opac/parts/marc_misc.tt2"; WRAPPER "default/opac/parts/base.tt2" + "default/opac/parts/myopac/base.tt2"; myopac_page = "lists" %] -
- - -
-

[% l('Create new list') %]

- [% l('Enter the name of the new list:') %]
- -
- - - - - - -
- [% l('Share this list?') %] - Sharing Help - - [% l('No') %] -
- [% l('Yes') %] -
- [% l('Submit') %] -       - [% l('Cancel') %] -
-
+
-
-
- - - - - -
- [% l('Temporary List') %] - - [% l('Anonymous List Help') %] -
-
-
-
- - - - - - - -
- Title - -
- - -
-

-
+ [% INCLUDE "default/opac/parts/anon_list.tt2" %] + [% IF ctx.bookbags.size %]
@@ -112,7 +46,7 @@ Title - @@ -127,6 +61,7 @@

+ [% END %]
[% l("This will remove the selected bookbag and all items contained within the bookbag. Are you sure you wish to continue?") %] @@ -173,32 +108,6 @@ - - - - - - - - - - - - -
[% l("Create a new Bookbag") %]
- - [% l("Enter the name of the new Bookbag: ") %] - - -
- [% l("Share this Bookbag") %] - [% l("(Help)") %] - [% l("Yes") %] - - [% l("No") %] - - -
@@ -251,4 +160,31 @@ [% l("Bookbag successfully updated") %]
+
+ + +
+

[% l('Create new list') %]

+ [% l('Enter the name of the new list:') %]
+ +
+ + + + + + +
+ [% l('Share this list?') %] + [% l('Sharing Help') %] + + [% l('No') %] +
+ [% l('Yes') %] +
+ [% l('Submit') %] +       + [% l('Cancel') %] +
[% END %] diff --git a/Open-ILS/web/templates/default/opac/parts/anon_list.tt2 b/Open-ILS/web/templates/default/opac/parts/anon_list.tt2 new file mode 100644 index 0000000..2d1d1e3 --- /dev/null +++ b/Open-ILS/web/templates/default/opac/parts/anon_list.tt2 @@ -0,0 +1,48 @@ + [% IF ctx.mylist.size %] +
+
+ + + + + +
+ [% l('Temporary List') %] + + [% l('Anonymous List Help') %] +
+
+
+
+ + + + + + +
+ [% l('Title') %] + +
+ + + [% FOR item IN ctx.mylist; + attrs = {marc_xml => ctx.mylist_marc_xml.$item}; + PROCESS get_marc_attrs args=attrs %] + + + + [% END %] + +
[% attrs.title %]
+

+
+ [% END %] diff --git a/Open-ILS/web/templates/default/opac/parts/result/table.tt2 b/Open-ILS/web/templates/default/opac/parts/result/table.tt2 index 414c8ba..1358ecb 100644 --- a/Open-ILS/web/templates/default/opac/parts/result/table.tt2 +++ b/Open-ILS/web/templates/default/opac/parts/result/table.tt2 @@ -181,26 +181,26 @@
+
+ - add to my list + +
- reviews & more
+ [% IF ctx.mylist.size %]
- View My List
+ [% END %]
[% UNLESS CGI.param('_adv') %]
Sort by
-- 1.7.2.5