]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Container.pm
LP#1721575: Batch Actions In the Public Catalog
[Evergreen.git] / Open-ILS / src / perlmods / lib / OpenILS / WWW / EGCatLoader / Container.pm
1 package OpenILS::WWW::EGCatLoader;
2 use strict; use warnings;
3 use Apache2::Const -compile => qw(OK DECLINED FORBIDDEN HTTP_INTERNAL_SERVER_ERROR REDIRECT HTTP_BAD_REQUEST);
4 use OpenSRF::Utils::Logger qw/$logger/;
5 use OpenILS::Utils::CStoreEditor qw/:funcs/;
6 use OpenILS::Utils::Fieldmapper;
7 use OpenILS::Application::AppUtils;
8 my $U = 'OpenILS::Application::AppUtils';
9
10 # Retrieve the users cached records AKA 'My List'
11 # Returns an empty list if there are no cached records
12 sub fetch_mylist {
13     my ($self, $with_marc_xml, $skip_sort) = @_;
14
15     my $list = [];
16     my $cache_key = $self->cgi->cookie((ref $self)->COOKIE_CART_CACHE);
17
18     if($cache_key) {
19
20         $list = $U->simplereq(
21             'open-ils.actor',
22             'open-ils.actor.anon_cache.get_value', 
23             $cache_key, (ref $self)->CART_CACHE_MYLIST);
24
25         if(!$list) {
26             $cache_key = undef;
27             $list = [];
28         }
29     }
30
31     {   # sanitize
32         no warnings qw/numeric/;
33         $list = [map { int $_ } @$list];
34         $list = [grep { $_ > 0} @$list];
35     };
36
37     my $marc_xml;
38     if ($with_marc_xml) {
39         my $ctx = $self->ctx;
40
41         # capture pref_ou for callnumber filter/display
42         $ctx->{pref_ou} = $self->_get_pref_lib() || $ctx->{search_ou};
43
44         # search for local callnumbers for display
45         my $focus_ou = $ctx->{physical_loc} || $ctx->{pref_ou};
46
47         my (undef, @recs) = $self->get_records_and_facets(
48             $list, undef, {
49                 flesh => '{mra,holdings_xml,acp,exclude_invisible_acn}',
50                 flesh_depth => 1,
51                 site => $ctx->{get_aou}->($focus_ou)->shortname,
52                 pref_lib => $ctx->{pref_ou}
53             }
54         );
55
56         # make it look like the caller is expecting
57         $marc_xml = { map {$_->{id} => $_->{marc_xml}} @recs };
58     }
59
60     # Leverage QueryParser to sort the items by values of config.metabib_fields
61     # from the items' marc records.
62     if (@$list && !$skip_sort) {
63         my ($sorter, $modifier) = $self->_get_bookbag_sort_params("anonsort");
64         my $query = $self->_prepare_anonlist_sorting_query($list, $sorter, $modifier);
65         my $args = {
66             "limit" => 1000,
67             "offset" => 0
68         };
69         $list = $U->bib_record_list_via_search($query, $args) or
70             return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
71     }
72
73     return ($cache_key, $list, $marc_xml);
74 }
75
76 sub load_api_mylist_retrieve {
77     my $self = shift;
78
79     # this has the effect of instantiating an empty one if need be
80     my ($cache_key, $list) = $self->fetch_mylist(0, 1);
81
82     $self->ctx->{json_response} = {
83         mylist => [ map { 0 + $_ } @$list ], # force integers
84     };
85     $self->ctx->{json_reponse_cookie} =
86         $self->cgi->cookie(
87             -name => (ref $self)->COOKIE_CART_CACHE,
88             -path => '/',
89             -value => ($cache_key) ? $cache_key : '',
90             -expires => ($cache_key) ? undef : '-1h'
91         );
92
93     return Apache2::Const::OK;
94 }
95
96 sub load_api_mylist_clear {
97     my $self = shift;
98
99     $self->clear_anon_cache;
100
101     # and return fresh, empty cart
102     return $self->load_api_mylist_retrieve();
103 }
104
105 # Adds a record (by id) to My List, creating a new anon cache + list if necessary.
106 sub load_mylist_add {
107     my $self = shift;
108
109     my ($cache_key, $list) = $self->_do_mylist_add();
110
111     # Check if we need to warn patron about adding to a "temporary"
112     # list:
113     if ($self->check_for_temp_list_warning) {
114         return $self->mylist_warning_redirect($cache_key);
115     }
116
117     return $self->mylist_action_redirect($cache_key);
118 }
119
120 sub load_api_mylist_add {
121     my $self = shift;
122
123     my ($cache_key, $list) = $self->_do_mylist_add();
124
125     $self->ctx->{json_response} = {
126         mylist => [ map { 0 + $_ } @$list ], # force integers
127     };
128     $self->ctx->{json_reponse_cookie} =
129         $self->cgi->cookie(
130             -name => (ref $self)->COOKIE_CART_CACHE,
131             -path => '/',
132             -value => ($cache_key) ? $cache_key : '',
133             -expires => ($cache_key) ? undef : '-1h'
134         );
135
136     return Apache2::Const::OK;
137 }
138
139 sub _do_mylist_add {
140     my $self = shift;
141     my @rec_ids = $self->cgi->param('record');
142
143     my ($cache_key, $list) = $self->fetch_mylist(0, 1);
144     push(@$list, @rec_ids);
145
146     $cache_key = $U->simplereq(
147         'open-ils.actor',
148         'open-ils.actor.anon_cache.set_value', 
149         $cache_key, (ref $self)->CART_CACHE_MYLIST, $list);
150
151     return ($cache_key, $list);
152 }
153
154 sub load_mylist_delete {
155     my $self = shift;
156
157     my ($cache_key, $list) = $self->_do_mylist_delete;
158
159     return $self->mylist_action_redirect($cache_key);
160 }
161
162 sub load_api_mylist_delete {
163     my $self = shift;
164
165     my ($cache_key, $list) = $self->_do_mylist_delete();
166
167     $self->ctx->{json_response} = {
168         mylist => [ map { 0 + $_ } @$list ], # force integers
169     };
170     $self->ctx->{json_reponse_cookie} =
171         $self->cgi->cookie(
172             -name => (ref $self)->COOKIE_CART_CACHE,
173             -path => '/',
174             -value => ($cache_key) ? $cache_key : '',
175             -expires => ($cache_key) ? undef : '-1h'
176         );
177
178     return Apache2::Const::OK;
179 }
180
181 sub _do_mylist_delete {
182     my $self = shift;
183     my @rec_ids = $self->cgi->param('record');
184
185     my ($cache_key, $list) = $self->fetch_mylist(0, 1);
186     foreach my $rec_id (@rec_ids) {
187         $list = [ grep { $_ ne $rec_id } @$list ];
188     }
189
190     $cache_key = $U->simplereq(
191         'open-ils.actor',
192         'open-ils.actor.anon_cache.set_value', 
193         $cache_key, (ref $self)->CART_CACHE_MYLIST, $list);
194
195     return ($cache_key, $list);
196 }
197
198 sub load_mylist_print {
199     my $self = shift;
200
201     my $cache_key = shift // $self->cgi->cookie((ref $self)->COOKIE_CART_CACHE);
202
203     if (!$cache_key) {
204         return $self->generic_redirect;
205     }
206
207     my $url = sprintf(
208         "%s://%s%s/record/print/%s",
209         $self->ctx->{proto},
210         $self->ctx->{hostname},
211         $self->ctx->{opac_root},
212         $cache_key,
213     );
214
215     my $redirect = $self->cgi->param('redirect_to');
216     $url .= '?redirect_to=' . uri_escape_utf8($redirect);
217     my $clear_cart = $self->cgi->param('clear_cart');
218     $url .= '&is_list=1';
219     $url .= '&clear_cart=1' if $clear_cart;
220
221     return $self->generic_redirect($url);
222 }
223
224 sub load_mylist_email {
225     my $self = shift;
226
227     my $cache_key = shift // $self->cgi->cookie((ref $self)->COOKIE_CART_CACHE);
228
229     if (!$cache_key) {
230         return $self->generic_redirect;
231     }
232
233     my $url = sprintf(
234         "%s://%s%s/record/email/%s",
235         $self->ctx->{proto},
236         $self->ctx->{hostname},
237         $self->ctx->{opac_root},
238         $cache_key,
239     );
240
241     my $redirect = $self->cgi->param('redirect_to');
242     $url .= '?redirect_to=' . uri_escape_utf8($redirect);
243     my $clear_cart = $self->cgi->param('clear_cart');
244     $url .= '&is_list=1';
245     $url .= '&clear_cart=1' if $clear_cart;
246
247     return $self->generic_redirect($url);
248 }
249
250 sub _stash_record_list_in_anon_cache {
251     my $self = shift;
252     my @rec_ids = @_;
253
254     my $cache_key = $U->simplereq(
255         'open-ils.actor',
256         'open-ils.actor.anon_cache.set_value',
257         undef, (ref $self)->CART_CACHE_MYLIST, [ @rec_ids ]);
258     return $cache_key;
259 }
260
261 sub load_mylist_move {
262     my $self = shift;
263     my @rec_ids = $self->cgi->param('record');
264     my $action = $self->cgi->param('action') || '';
265
266     my ($cache_key, $list) = $self->fetch_mylist;
267
268     unless ((scalar(@rec_ids) > 0) ||
269         ($self->cgi->param('entire_list') && scalar(@$list) > 0)) {
270         my $url = $self->ctx->{referer};
271         $url .= ($url =~ /\?/ ? '&' : '?') . 'cart_none_selected=1';
272         return $self->generic_redirect($url);
273     }
274
275     if ($action eq 'place_hold') {
276         if ($self->cgi->param('entire_list')) {
277             @rec_ids = @$list;
278         }
279         return $self->load_myopac_bookbag_update('place_hold', undef, @rec_ids);
280     }
281     if ($action eq 'print') {
282         my $temp_cache_key = $self->_stash_record_list_in_anon_cache(@rec_ids);
283         return $self->load_mylist_print($temp_cache_key);
284     }
285     if ($action eq 'email') {
286         my $temp_cache_key = $self->_stash_record_list_in_anon_cache(@rec_ids);
287         return $self->load_mylist_email($temp_cache_key);
288     }
289     if ($action eq 'new_list') {
290         my $url = $self->apache->unparsed_uri;
291         $url =~ s!/mylist/move!/myopac/lists!;
292         return $self->generic_redirect($url);
293     }
294
295     return $self->mylist_action_redirect unless $cache_key;
296
297     my @keep;
298     foreach my $id (@$list) { push(@keep, $id) unless grep { $id eq $_ } @rec_ids; }
299
300     $cache_key = $U->simplereq(
301         'open-ils.actor',
302         'open-ils.actor.anon_cache.set_value', 
303         $cache_key, (ref $self)->CART_CACHE_MYLIST, \@keep
304     );
305
306     if ($action eq 'delete' && scalar(@keep) == 0) {
307         my $url = $self->cgi->param('orig_referrer') // $self->ctx->{referer};
308         return $self->generic_redirect($url);
309     }
310
311     if ($self->ctx->{user} and $action =~ /^\d+$/) {
312         # in this case, action becomes list_id
313         $self->load_myopac_bookbag_update('add_rec', $self->cgi->param('action'));
314         # XXX TODO: test for failure of above
315     }
316
317     return $self->mylist_action_redirect($cache_key);
318 }
319
320 sub load_cache_clear {
321     my $self = shift;
322     $self->clear_anon_cache;
323     return $self->mylist_action_redirect;
324 }
325
326 # Wipes the entire anonymous cache, including My List
327 sub clear_anon_cache {
328     my $self = shift;
329     my $field = shift;
330
331     my $cache_key = $self->cgi->cookie((ref $self)->COOKIE_CART_CACHE) or return;
332
333     $U->simplereq(
334         'open-ils.actor',
335         'open-ils.actor.anon_cache.delete_session', $cache_key)
336         if $cache_key;
337
338 }
339
340 # Called after an anon-cache / My List action occurs.  Redirect
341 # to the redirect_url (cgi param) or referrer or home.
342 sub mylist_action_redirect {
343     my $self = shift;
344     my $cache_key = shift;
345
346     my $url;
347     if( my $anchor = $self->cgi->param('anchor') ) {
348         # on the results page, we want to redirect 
349         # back to record that was affected
350         $url = $self->cgi->param('redirect_to') // $self->ctx->{referer};
351         $url =~ s/#.*|$/#$anchor/;
352     } else {
353         $url = $self->cgi->param('redirect_to') // $self->ctx->{referer};
354     }
355
356     return $self->generic_redirect(
357         $url,
358         $self->cgi->cookie(
359             -name => (ref $self)->COOKIE_CART_CACHE,
360             -path => '/',
361             -value => ($cache_key) ? $cache_key : '',
362             -expires => ($cache_key) ? undef : '-1h'
363         )
364     );
365 }
366
367 # called after an anon-cache / my list addition when we are configured
368 # to show a warning to the user.
369
370 sub mylist_warning_redirect {
371     my $self = shift;
372     my $cache_key = shift;
373
374     my $base_url = sprintf(
375         "%s://%s%s/temp_warn",
376         $self->ctx->{proto},
377         $self->ctx->{hostname},
378         $self->ctx->{opac_root}
379     );
380
381     my $redirect = $self->ctx->{referer};
382     if (my $anchor = $self->cgi->param('anchor')) {
383         $redirect =~ s/#.*|$/#$anchor/;
384     }
385
386     $base_url .= '?redirect_to=' . uri_escape_utf8($redirect);
387
388     return $self->generic_redirect(
389         $base_url,
390         $self->cgi->cookie(
391             -name => (ref $self)->COOKIE_CART_CACHE,
392             -path => '/',
393             -value => ($cache_key) ? $cache_key : '',
394             -expires => ($cache_key) ? undef : '-1h'
395         )
396     );
397 }
398
399 sub load_mylist {
400     my ($self) = shift;
401     (undef, $self->ctx->{mylist}, $self->ctx->{mylist_marc_xml}) =
402         $self->fetch_mylist(1);
403
404     # get list of bookbags in case user wants to move cart contents to
405     # one
406     if ($self->ctx->{user}) {
407         $self->_load_lists_and_settings;
408     }
409
410     return Apache2::Const::OK;
411 }
412
413 sub load_temp_warn_post {
414     my $self = shift;
415     my $url = $self->cgi->param('redirect_to');
416     return $self->generic_redirect(
417         $url,
418         $self->cgi->cookie(
419             -name => 'no_temp_list_warn',
420             -path => '/',
421             -value => ($self->cgi->param('no_temp_list_warn')) ? '1' : '',
422             -expires => ($self->cgi->param('no_temp_list_warn')) ? undef : '-1h'
423         )
424     );
425 }
426
427 sub load_temp_warn {
428     my $self = shift;
429     $self->ctx->{'redirect_to'} = $self->cgi->param('redirect_to');
430     return Apache2::Const::OK;
431 }
432
433 1;