1 package OpenILS::WWW::EGCatLoader;
2 use strict; use warnings;
5 use Digest::MD5 qw(md5_hex);
6 use Apache2::Const -compile => qw(OK DECLINED HTTP_INTERNAL_SERVER_ERROR REDIRECT);
7 use OpenSRF::AppSession;
8 use OpenSRF::Utils::Logger qw/$logger/;
9 use OpenILS::Application::AppUtils;
10 use OpenILS::Utils::CStoreEditor qw/:funcs/;
11 use OpenILS::Utils::Fieldmapper;
12 my $U = 'OpenILS::Application::AppUtils';
15 my($class, $apache, $ctx) = @_;
17 my $self = bless({}, ref($class) || $class);
19 $self->apache($apache);
23 OpenILS::Utils::CStoreEditor->init; # just in case
24 $self->editor(new_editor());
30 # current Apache2::RequestRec;
32 my($self, $apache) = @_;
33 $self->{apache} = $apache if $apache;
34 return $self->{apache};
40 $self->{ctx} = $ctx if $ctx;
46 my($self, $editor) = @_;
47 $self->{editor} = $editor if $editor;
48 return $self->{editor};
54 $self->{cgi} = $cgi if $cgi;
59 # load common data, then load page data
63 my $path = $self->apache->path_info;
66 my $stat = $self->load_common;
67 return $stat unless $stat == Apache2::Const::OK;
69 return $self->load_home if $path =~ /opac\/home/;
70 return $self->load_login if $path =~ /opac\/login/;
71 return $self->load_logout if $path =~ /opac\/logout/;
72 return $self->load_rresults if $path =~ /opac\/results/;
73 return $self->load_rdetail if $path =~ /opac\/rdetail/;
74 return $self->load_myopac if $path =~ /opac\/myopac/;
75 return $self->load_place_hold if $path =~ /opac\/place_hold/;
77 return Apache2::Const::OK;
80 # general purpose utility functions added to the environment
82 # find_org_unit : function(id) => aou object
83 # org_tree : function(id) => aou object, top of tree, fleshed
89 # pull the org unit from the cached org tree
90 $self->ctx->{find_org_unit} = sub {
92 return undef unless defined $org_id;
93 return $org_unit_map{$org_id} if defined $org_unit_map{$org_id};
94 my $tree = shift || $self->ctx->{org_tree}->();
95 return $org_unit_map{$org_id} = $tree if $tree->id == $org_id;
96 for my $child (@{$tree->children}) {
97 my $node = $self->ctx->{find_org_unit}->($org_id, $child);
98 return $node if $node;
103 $self->ctx->{org_tree} = sub {
104 unless($cached_org_tree) {
105 $cached_org_tree = $self->editor->search_actor_org_unit([
106 { parent_ou => undef},
108 flesh_fields => {aou => ['children', 'ou_type']},
109 order_by => {aou => 'name'}
113 return $cached_org_tree;
120 # user_status : hash of user circ numbers
124 my $e = $self->editor;
125 my $ctx = $self->ctx;
127 if($e->authtoken($self->cgi->cookie('ses'))) {
131 $ctx->{authtoken} = $e->authtoken;
132 $ctx->{user} = $e->requestor;
133 $ctx->{user_stats} = $U->simplereq(
135 'open-ils.actor.user.opac.vital_stats',
136 $e->authtoken, $e->requestor->id);
140 return $self->load_logout;
144 return Apache2::Const::OK;
149 $self->ctx->{page} = 'home';
150 return Apache2::Const::OK;
156 my $cgi = $self->cgi;
158 $self->ctx->{page} = 'login';
160 my $username = $cgi->param('username');
161 my $password = $cgi->param('password');
163 return Apache2::Const::OK unless $username and $password;
165 my $seed = $U->simplereq(
167 'open-ils.auth.authenticate.init',
170 my $response = $U->simplereq(
172 'open-ils.auth.authenticate.complete',
173 { username => $username,
174 password => md5_hex($seed . md5_hex($password)),
179 # XXX check event, redirect as necessary
181 my $home = $self->apache->unparsed_uri;
182 $home =~ s/\/login/\/home/;
184 $self->apache->print(
186 -url => $cgi->param('origin') || $home,
187 -cookie => $cgi->cookie(
190 -value => $response->{payload}->{authtoken},
191 -expires => CORE::time + $response->{payload}->{authtime}
196 return Apache2::Const::REDIRECT;
202 my $path = $self->apache->uri;
203 $path =~ s/(\/[^\/]+$)/\/home/;
204 my $url = 'http://' . $self->apache->hostname . "$path";
206 $self->apache->print(
207 $self->cgi->redirect(
209 -cookie => $self->cgi->cookie(
218 return Apache2::Const::REDIRECT;
224 # records : list of bre's and copy-count objects
230 my $cgi = $self->cgi;
231 my $ctx = $self->ctx;
232 my $e = $self->editor;
234 $ctx->{page} = 'rresult';
237 $cmf_cache = $e->search_config_metabib_field({id => {'!=' => undef}});
238 $cmc_cache = $e->search_config_metabib_class({name => {'!=' => undef}});
239 $ctx->{metabib_field} = $cmf_cache;
240 $ctx->{metabib_class} = $cmc_cache;
244 my $page = $cgi->param('page') || 0;
245 my $query = $cgi->param('query');
246 my $limit = $cgi->param('limit') || 10; # XXX user settings
248 my $args = {limit => $limit, offset => $page * $limit};
249 my $results = $U->simplereq('open-ils.search',
250 'open-ils.search.biblio.multiclass.query.staff', $args, $query, 1);
252 my $search = OpenSRF::AppSession->create('open-ils.search');
253 my $facet_req = $search->request('open-ils.search.facet_cache.retrieve', $results->{facet_key}, 10);
255 my $rec_ids = [map { $_->[0] } @{$results->{ids}}];
257 $ctx->{page_size} = $limit;
258 $ctx->{hit_count} = $results->{count};
260 my $cstore1 = OpenSRF::AppSession->create('open-ils.cstore');
262 my $bre_req = $cstore1->request(
263 'open-ils.cstore.direct.biblio.record_entry.search', {id => $rec_ids});
266 while(my $resp = $bre_req->recv) {
267 my $bre = $resp->content;
269 my $copy_counts = $e->json_query(
270 {from => ['asset.record_copy_count', 1, $bre->id, 0]})->[0];
275 marc_xml => XML::LibXML->new->parse_string($bre->marc),
276 copy_counts => $copy_counts
283 # shove recs into context in search results order
284 $ctx->{records} = [];
285 for my $rec_id (@$rec_ids) {
288 grep { $_->{bre}->id == $rec_id } @data
292 my $facets = $facet_req->gather(1);
294 for my $cmf_id (keys %$facets) { # quick-n-dirty
295 my ($cmf) = grep { $_->id eq $cmf_id } @$cmf_cache;
296 $facets->{$cmf->label} = $facets->{$cmf_id};
297 delete $facets->{$cmf_id};
299 $ctx->{search_facets} = $facets;
301 return Apache2::Const::OK;
305 # record : bre object
309 $self->ctx->{record} = $self->editor->retrieve_biblio_record_entry([
310 $self->cgi->param('record'),
314 bre => ['call_numbers'],
315 acn => ['copies'] # limit, paging, etc.
320 $self->ctx->{marc_xml} = XML::LibXML->new->parse_string($self->ctx->{record}->marc);
322 return Apache2::Const::OK;
326 # user : au object, fleshed
330 $self->ctx->{user} = $self->editor->retrieve_actor_user([
331 $self->ctx->{user}->id,
341 return Apache2::Const::OK;
345 sub load_place_hold {
347 my $ctx = $self->ctx;
348 my $e = $self->editor;
350 $ctx->{hold_target} = $self->cgi->param('hold_target');
351 $ctx->{hold_type} = $self->cgi->param('hold_type');
352 $ctx->{default_pickup_lib} = $e->requestor->home_ou; # XXX staff
354 if($ctx->{hold_type} eq 'T') {
355 $ctx->{record} = $e->retrieve_biblio_record_entry($ctx->{hold_target});
359 $ctx->{marc_xml} = XML::LibXML->new->parse_string($ctx->{record}->marc);
361 if(my $pickup_lib = $self->cgi->param('pickup_lib')) {
364 patronid => $e->requestor->id,
365 titleid => $ctx->{hold_target}, # XXX
366 pickup_lib => $pickup_lib,
370 my $allowed = $U->simplereq(
372 'open-ils.circ.title_hold.is_possible',
376 if($allowed->{success} == 1) {
377 my $hold = Fieldmapper::action::hold_request->new;
379 $hold->pickup_lib($pickup_lib);
380 $hold->requestor($e->requestor->id);
381 $hold->usr($e->requestor->id); # XXX staff
382 $hold->target($ctx->{hold_target});
383 $hold->hold_type($ctx->{hold_type});
384 # frozen, expired, etc..
386 my $stat = $U->simplereq(
388 'open-ils.circ.holds.create',
392 if($stat and $stat > 0) {
393 $ctx->{hold_success} = 1;
395 $ctx->{hold_failed} = 1; # XXX process the events, etc
399 # place the hold and deliver results
402 return Apache2::Const::OK;