1 package OpenILS::WWW::EGCatLoader;
2 use strict; use warnings;
3 use Apache2::Const -compile => qw(OK FORBIDDEN HTTP_INTERNAL_SERVER_ERROR);
4 use OpenSRF::Utils::Logger qw/$logger/;
5 use OpenILS::Utils::Fieldmapper;
6 use OpenILS::Application::AppUtils;
7 use OpenILS::Utils::CStoreEditor qw/:funcs/;
10 $Data::Dumper::Indent = 0;
11 my $U = 'OpenILS::Application::AppUtils';
17 $ctx->{register} = {};
18 $self->collect_register_validation_settings;
19 $self->collect_requestor_info;
21 # in the home org unit selector, we only want to present
22 # org units to the patron which support self-registration.
23 # all other org units will be disabled
24 $ctx->{register}{valid_orgs} =
25 $self->setting_is_true_for_orgs('opac.allow_pending_user');
27 # just loading the form
28 return Apache2::Const::OK
29 unless $cgi->request_method eq 'POST';
31 my $user = Fieldmapper::staging::user_stage->new;
32 my $addr = Fieldmapper::staging::mailing_address_stage->new;
35 foreach (grep /^stgu\./, $cgi->param) {
36 my $val = $cgi->param($_);
37 $self->inspect_register_value($_, $val);
42 # requestor is logged in, capture who is making this request
43 $user->requesting_usr($ctx->{user}->id) if $ctx->{user};
45 # make sure the selected home org unit is in the list
46 # of valid orgs. This can happen if the selector
47 # defaults to CONS, for example.
48 $ctx->{register}{invalid}{bad_home_ou} = 1 unless
49 grep {$_ eq $user->home_ou} @{$ctx->{register}{valid_orgs}};
53 foreach (grep /^stgma\./, $cgi->param) {
54 my $val = $cgi->param($_);
55 $self->inspect_register_value($_, $val);
61 # if the form contains no address fields, do not
62 # attempt to create a pending address
63 $addr = undef unless $has_addr;
65 # At least one value was invalid. Exit early and re-render.
66 return Apache2::Const::OK if $ctx->{register}{invalid};
68 $self->test_requested_username($user);
70 # user.stage.create will generate a temporary usrname and
71 # link the user and address objects via this username in the DB.
72 my $resp = $U->simplereq(
74 'open-ils.actor.user.stage.create',
78 if (!$resp or ref $resp) {
80 $logger->warn("Patron self-reg failed ".Dumper($resp));
81 $ctx->{register}{error} = 1;
85 $logger->info("Patron self-reg success; usrname $resp");
86 $ctx->{register}{success} = 1;
89 return Apache2::Const::OK;
92 # if the pending account is requested by an existing user account,
93 # load the existing user's data to pre-populate some fields.
94 sub collect_requestor_info {
96 return unless $self->ctx->{user};
98 my $user = $self->editor->retrieve_actor_user([
99 $self->ctx->{user}->id,
100 {flesh => 1, flesh_fields => {
101 au => [qw/mailing_address billing_address/]}
106 my $vhash = $self->ctx->{register}{values} = {};
107 my $addr = $user->mailing_address || $user->billing_address;
108 $vhash->{stgu}{home_ou} = $user->home_ou;
111 $vhash->{stgma}{city} = $addr->city;
112 $vhash->{stgma}{county} = $addr->county;
113 $vhash->{stgma}{state} = $addr->state;
114 $vhash->{stgma}{post_code} = $addr->post_code;
118 # if the username is in use by an actor.usr OR a
119 # pending user treat it as taken and warn the user.
120 sub test_requested_username {
121 my ($self, $user) = @_;
122 my $uname = $user->usrname || return;
123 my $e = $self->editor;
125 my $taken = $e->search_actor_user(
126 {usrname => $uname, deleted => 'f'},
130 $taken = $e->search_staging_user_stage(
133 )->[0] unless $taken;
136 $self->ctx->{register}{username_taken} = 1;
137 $user->clear_usrname;
141 sub collect_register_validation_settings {
143 my $ctx = $self->ctx;
144 my $e = new_editor();
145 my $ctx_org = $ctx->{physical_loc} || $self->_get_search_lib;
146 my $shash = $self->{register}{settings} = {};
148 # retrieve the org unit setting types and values
149 # that are relevant to our validation tasks.
151 my $settings = $e->json_query({
152 select => {coust => ['name']},
154 where => {name => {like => 'ui.patron.edit.%.%.%'}}
157 # load org setting values for all of the regex,
158 # example, show, and require settings
159 for my $set (@$settings) {
161 next unless $set =~ /regex$|show$|require$|example$/;
163 my $val = $ctx->{get_org_setting}->($ctx_org, $set);
164 next unless $val; # no configured org setting
166 # extract the field class, name, and
167 # setting type from the setting name
168 my (undef, undef, undef, $cls, $field, $type) = split(/\./, $set);
170 # translate classes into stage classes
171 my $scls = ($cls eq 'au') ? 'stgu' : 'stgma';
173 $shash->{$scls}{$field}{$type} = $val;
176 # use the generic phone settings where none are provided for day_phone.
178 $shash->{stgu}{day_phone}{example} =
179 $ctx->{get_org_setting}->($ctx_org, 'ui.patron.edit.phone.example')
180 unless $shash->{stgu}{day_phone}{example};
182 $shash->{stgu}{day_phone}{regex} =
183 $ctx->{get_org_setting}->($ctx_org, 'ui.patron.edit.phone.regex')
184 unless $shash->{stgu}{day_phone}{regex};
186 # The regex OUS for username does not match the format of the other
187 # org settings. Wrangle it into place.
188 $shash->{stgu}{usrname}{regex} =
189 $ctx->{get_org_setting}->($ctx_org, 'opac.username_regex');
191 # some fields are assumed to be visible / required even without the
192 # presence of org unit settings. E.g. we obviously want the user to
193 # enter a name, since a name is required for ultimately creating a user
194 # account. We can mimic that by forcing some org unit setting values
196 $shash->{stgu}{first_given_name}{require} = 1
197 unless defined $shash->{stgu}{first_given_name}{require};
198 $shash->{stgu}{second_given_name}{show} = 1
199 unless defined $shash->{stgu}{second_given_name}{show};
200 $shash->{stgu}{family_name}{require} = 1
201 unless defined $shash->{stgu}{family_name}{require};
202 $shash->{stgma}{street1}{require} = 1
203 unless defined $shash->{stgma}{street1}{require};
204 $shash->{stgma}{street2}{show} = 1
205 unless defined $shash->{stgma}{street2}{show};
206 $shash->{stgma}{city}{require} = 1
207 unless defined $shash->{stgma}{city}{require};
208 $shash->{stgma}{post_code}{require} = 1
209 unless defined $shash->{stgma}{post_code}{require};
210 $shash->{stgu}{usrname}{show} = 1
211 unless defined $shash->{stgu}{usrname}{show};
213 $ctx->{register}{settings} = $shash;
215 # laod the page timeout setting
216 $shash->{refresh_timeout} =
217 $ctx->{get_org_setting}->($ctx_org, 'opac.self_register.timeout');
220 # inspects each value and determines, based on org unit settings,
221 # if the value is invalid. Invalid is defined as not providing
222 # a value when one is required or not matching the configured regex.
223 sub inspect_register_value {
224 my ($self, $field_path, $value) = @_;
225 my $ctx = $self->ctx;
226 my ($scls, $field) = split(/\./, $field_path);
230 if ($self->{register}{settings}{$scls}{$field}{require}) {
231 $ctx->{register}{invalid}{$scls}{$field}{require} = 1;
233 $logger->info("patron register field $field ".
234 "requires a value, but none was entered");
239 my $regex = $self->{register}{settings}{$scls}{$field}{regex};
240 return if !$regex or $value =~ /$regex/; # field is valid
242 $logger->info("invalid value was provided for patron ".
243 "register field=$field; pattern=$regex; value=$value");
245 $ctx->{register}{invalid}{$scls}{$field}{regex} = 1;