Lines 20-25
use Modern::Perl;
Link Here
|
20 |
use CGI qw ( -utf8 ); |
20 |
use CGI qw ( -utf8 ); |
21 |
use Digest::MD5 qw( md5_base64 md5_hex ); |
21 |
use Digest::MD5 qw( md5_base64 md5_hex ); |
22 |
use Encode qw( encode ); |
22 |
use Encode qw( encode ); |
|
|
23 |
use List::MoreUtils qw( each_array uniq ); |
23 |
use String::Random qw( random_string ); |
24 |
use String::Random qw( random_string ); |
24 |
|
25 |
|
25 |
use C4::Auth; |
26 |
use C4::Auth; |
Lines 86-91
$template->param(
Link Here
|
86 |
OPACPatronDetails => C4::Context->preference('OPACPatronDetails'), |
87 |
OPACPatronDetails => C4::Context->preference('OPACPatronDetails'), |
87 |
); |
88 |
); |
88 |
|
89 |
|
|
|
90 |
my $attributes = ParsePatronAttributes($cgi); |
91 |
my $conflicting_attribute = 0; |
92 |
|
93 |
foreach my $attr (@$attributes) { |
94 |
unless ( C4::Members::Attributes::CheckUniqueness($attr->{code}, $attr->{value}, $borrowernumber) ) { |
95 |
my $attr_info = C4::Members::AttributeTypes->fetch($attr->{code}); |
96 |
$template->param( |
97 |
extended_unique_id_failed_code => $attr->{code}, |
98 |
extended_unique_id_failed_value => $attr->{value}, |
99 |
extended_unique_id_failed_description => $attr_info->description() |
100 |
); |
101 |
$conflicting_attribute = 1; |
102 |
} |
103 |
} |
104 |
|
89 |
if ( $action eq 'create' ) { |
105 |
if ( $action eq 'create' ) { |
90 |
|
106 |
|
91 |
my %borrower = ParseCgiForBorrower($cgi); |
107 |
my %borrower = ParseCgiForBorrower($cgi); |
Lines 102-108
if ( $action eq 'create' ) {
Link Here
|
102 |
$cardnumber_error_code = checkcardnumber( $borrower{cardnumber}, $borrower{borrowernumber} ); |
118 |
$cardnumber_error_code = checkcardnumber( $borrower{cardnumber}, $borrower{borrowernumber} ); |
103 |
} |
119 |
} |
104 |
|
120 |
|
105 |
if ( @empty_mandatory_fields || @$invalidformfields || $cardnumber_error_code ) { |
121 |
if ( @empty_mandatory_fields || @$invalidformfields || $cardnumber_error_code || $conflicting_attribute ) { |
106 |
if ( $cardnumber_error_code == 1 ) { |
122 |
if ( $cardnumber_error_code == 1 ) { |
107 |
$template->param( cardnumber_already_exists => 1 ); |
123 |
$template->param( cardnumber_already_exists => 1 ); |
108 |
} elsif ( $cardnumber_error_code == 2 ) { |
124 |
} elsif ( $cardnumber_error_code == 2 ) { |
Lines 114-119
if ( $action eq 'create' ) {
Link Here
|
114 |
invalid_form_fields => $invalidformfields, |
130 |
invalid_form_fields => $invalidformfields, |
115 |
borrower => \%borrower |
131 |
borrower => \%borrower |
116 |
); |
132 |
); |
|
|
133 |
$template->param( patron_attribute_classes => GeneratePatronAttributesForm( undef, $attributes ) ); |
117 |
} |
134 |
} |
118 |
elsif ( |
135 |
elsif ( |
119 |
md5_base64( uc( $cgi->param('captcha') ) ) ne $cgi->param('captcha_digest') ) |
136 |
md5_base64( uc( $cgi->param('captcha') ) ) ne $cgi->param('captcha_digest') ) |
Lines 122-127
if ( $action eq 'create' ) {
Link Here
|
122 |
failed_captcha => 1, |
139 |
failed_captcha => 1, |
123 |
borrower => \%borrower |
140 |
borrower => \%borrower |
124 |
); |
141 |
); |
|
|
142 |
$template->param( patron_attribute_classes => GeneratePatronAttributesForm( undef, $attributes ) ); |
125 |
} |
143 |
} |
126 |
else { |
144 |
else { |
127 |
if ( |
145 |
if ( |
Lines 182-187
if ( $action eq 'create' ) {
Link Here
|
182 |
C4::Context->preference('OpacPasswordChange') ); |
200 |
C4::Context->preference('OpacPasswordChange') ); |
183 |
|
201 |
|
184 |
my ( $borrowernumber, $password ) = AddMember_Opac(%borrower); |
202 |
my ( $borrowernumber, $password ) = AddMember_Opac(%borrower); |
|
|
203 |
C4::Members::Attributes::SetBorrowerAttributes( $borrowernumber, $attributes ); |
185 |
C4::Form::MessagingPreferences::handle_form_action($cgi, { borrowernumber => $borrowernumber }, $template, 1, C4::Context->preference('PatronSelfRegistrationDefaultCategory') ) if $borrowernumber && C4::Context->preference('EnhancedMessagingPreferences'); |
204 |
C4::Form::MessagingPreferences::handle_form_action($cgi, { borrowernumber => $borrowernumber }, $template, 1, C4::Context->preference('PatronSelfRegistrationDefaultCategory') ) if $borrowernumber && C4::Context->preference('EnhancedMessagingPreferences'); |
186 |
|
205 |
|
187 |
$template->param( password_cleartext => $password ); |
206 |
$template->param( password_cleartext => $password ); |
Lines 225-230
elsif ( $action eq 'update' ) {
Link Here
|
225 |
secret => md5_base64( Encode::encode( 'UTF-8', C4::Context->config('pass') ) ), |
244 |
secret => md5_base64( Encode::encode( 'UTF-8', C4::Context->config('pass') ) ), |
226 |
}), |
245 |
}), |
227 |
); |
246 |
); |
|
|
247 |
$template->param( patron_attribute_classes => GeneratePatronAttributesForm( undef, $attributes ) ); |
228 |
|
248 |
|
229 |
$template->param( action => 'edit' ); |
249 |
$template->param( action => 'edit' ); |
230 |
} |
250 |
} |
Lines 272-285
elsif ( $action eq 'update' ) {
Link Here
|
272 |
elsif ( $action eq 'edit' ) { #Display logged in borrower's data |
292 |
elsif ( $action eq 'edit' ) { #Display logged in borrower's data |
273 |
my $borrower = GetMember( borrowernumber => $borrowernumber ); |
293 |
my $borrower = GetMember( borrowernumber => $borrowernumber ); |
274 |
|
294 |
|
275 |
if (C4::Context->preference('ExtendedPatronAttributes')) { |
|
|
276 |
my $attributes = C4::Members::Attributes::GetBorrowerAttributes($borrowernumber, 'opac'); |
277 |
if (scalar(@$attributes) > 0) { |
278 |
$borrower->{ExtendedPatronAttributes} = 1; |
279 |
$borrower->{patron_attributes} = $attributes; |
280 |
} |
281 |
} |
282 |
|
283 |
$template->param( |
295 |
$template->param( |
284 |
borrower => $borrower, |
296 |
borrower => $borrower, |
285 |
guarantor => scalar Koha::Patrons->find($borrowernumber)->guarantor(), |
297 |
guarantor => scalar Koha::Patrons->find($borrowernumber)->guarantor(), |
Lines 295-300
elsif ( $action eq 'edit' ) { #Display logged in borrower's data
Link Here
|
295 |
$template->param( display_patron_image => 1 ) if $patron_image; |
307 |
$template->param( display_patron_image => 1 ) if $patron_image; |
296 |
} |
308 |
} |
297 |
|
309 |
|
|
|
310 |
$template->param( patron_attribute_classes => GeneratePatronAttributesForm( $borrower ) ); |
311 |
} else { |
312 |
$template->param( patron_attribute_classes => GeneratePatronAttributesForm() ); |
298 |
} |
313 |
} |
299 |
|
314 |
|
300 |
my $captcha = random_string("CCCCC"); |
315 |
my $captcha = random_string("CCCCC"); |
Lines 448-450
sub DelEmptyFields {
Link Here
|
448 |
|
463 |
|
449 |
return %borrower; |
464 |
return %borrower; |
450 |
} |
465 |
} |
451 |
- |
466 |
|
|
|
467 |
sub GeneratePatronAttributesForm { |
468 |
my ( $borrower, $entered_attributes ) = @_; |
469 |
|
470 |
# Get all attribute types and the values for this patron (if applicable) |
471 |
my @types = C4::Members::AttributeTypes::GetAttributeTypes(); |
472 |
|
473 |
if (scalar(@types) == 0) { |
474 |
return []; |
475 |
} |
476 |
|
477 |
my %attr_values = (); |
478 |
|
479 |
if ( $borrower ) { |
480 |
my $attributes = C4::Members::Attributes::GetBorrowerAttributes($borrowernumber); |
481 |
|
482 |
# Remap the patron's attributes into a hash of arrayrefs per attribute (depends on |
483 |
# autovivification) |
484 |
foreach my $attr (@$attributes) { |
485 |
push @{ $attr_values{ $attr->{code} } }, $attr; |
486 |
} |
487 |
} |
488 |
|
489 |
if ( $entered_attributes ) { |
490 |
foreach my $attr (@$entered_attributes) { |
491 |
push @{ $attr_values{ $attr->{code} } }, $attr; |
492 |
} |
493 |
} |
494 |
|
495 |
# Find all existing classes |
496 |
my @classes = uniq( map { $_->{class} } @types ); |
497 |
@classes = sort @classes; |
498 |
my %items_by_class; |
499 |
|
500 |
foreach my $attr_type_desc (@types) { |
501 |
my $attr_type = C4::Members::AttributeTypes->fetch( $attr_type_desc->{code} ); |
502 |
# Make sure this attribute should be displayed in the OPAC |
503 |
next unless ( $attr_type->opac_display() ); |
504 |
# Then, make sure it either has values or is editable |
505 |
next unless ( $attr_values{ $attr_type->code() } || $attr_type->opac_editable() ); |
506 |
|
507 |
push @{ $items_by_class{ $attr_type->class() } }, { |
508 |
type => $attr_type, |
509 |
# If editable, make sure there's at least one empty entry, to make the template's job easier |
510 |
values => $attr_values{ $attr_type->code() } || [{}] |
511 |
}; |
512 |
} |
513 |
|
514 |
# Finally, build a list of containing classes |
515 |
my @class_loop; |
516 |
foreach my $class (@classes) { |
517 |
next unless ( $items_by_class{$class} ); |
518 |
|
519 |
my $av = Koha::AuthorisedValues->search({ category => 'PA_CLASS', authorised_value => $class }); |
520 |
my $lib = $av->count ? $av->next->opac_description : $class; |
521 |
|
522 |
push @class_loop, { |
523 |
class => $class, |
524 |
items => $items_by_class{$class}, |
525 |
lib => $lib, |
526 |
}; |
527 |
} |
528 |
|
529 |
return \@class_loop; |
530 |
} |
531 |
|
532 |
sub ParsePatronAttributes { |
533 |
my ( $cgi ) = @_; |
534 |
|
535 |
my @codes = $cgi->param('patron_attribute_code'); |
536 |
my @values = $cgi->param('patron_attribute_value'); |
537 |
my @passwords = $cgi->param('patron_attribute_password'); |
538 |
|
539 |
my $ea = each_array( @codes, @values, @passwords ); |
540 |
my @attributes; |
541 |
my %dups = (); |
542 |
|
543 |
while ( my ( $code, $value, $password ) = $ea->() ) { |
544 |
next unless defined($value) and $value ne ''; |
545 |
next if exists $dups{$code}->{$value}; |
546 |
$dups{$code}->{$value} = 1; |
547 |
|
548 |
push @attributes, { code => $code, value => $value, password => $password }; |
549 |
} |
550 |
|
551 |
return \@attributes; |
552 |
} |