From 92782d38328e712ddde5c7f879473c6cb46aaef3 Mon Sep 17 00:00:00 2001
From: Kyle M Hall
Date: Tue, 31 Jul 2012 10:07:04 -0400
Subject: [PATCH] Bug 7067 - OPAC Borrower Self Registration
This development will add the ability for a new patron to register
himself or herself. The self-registration will attempt to match this
newly inputted data to any existing patrons and if any possible matches
are found, ask if the patron is sure he or she doesn't already have an
account at the library. A system preference may be set to prevent patron
self-registration if the system detects the possibility that the person
may already have an account.
Once the patron has registered, passing a captcha (or similar
bot-stopper), the patron will then be optionally verified a second time
via email. At this point, the patron will be able to print a temporary
library card (optional by system preference), and will be provided any
details necessary to access electronic resources (this body of text
would be a template in the slips and notices system). At the library's
choice, this new patron would either be set to a temporary patron status
(patron type set via system preference), or a fully-fledged patron
(allow patron type to be determined by age and/or other attributes).
Assuming the library uses temporary patron types for OPAC registrations,
this patron will next enter a queue and would need to physically enter
the library to verify himself and become a fully-fledged patron (most
likely by bringing in physical proof of address, etc.). The librarian
would look up the patron record and modify the patron type. If a
temporary patron has not been verified within a certain time frame
(defined by a system preference), the patron record will be deleted
from the system via a cron job.
For registered patrons, the system will allow each person to also
update his or her personal data via the OPAC. When a patron updates his
or her information, the changes will be entered into a queue to be
verified by a librarian (preventing a patron from inputting obviously
bogus data). The staff client home page will display the number of
patron records with changes awaiting approval. A librarian would then be
able to click through a list of modification requests, and approve or
deny each (with approval and denial alerts being sent to the patron via
the standard messaging system).
NEW SYSTEM PREFERENCES
* PatronSelfRegistration
* PatronSelfRegistrationDetectDuplicates
* PatronSelfRegistrationVerifyByEmail
* PatronSelfRegistrationPrintTemporaryCard
* PatronSelfRegistrationUseTemporaryStatus
* PatronSelfRegistrationExpireTemporaryAccountsDelay
NEW NOTICE
* Verify by email notice
NEW SLIP
* Temporary card slip
NEW CRON JOB
* delete_expired_opac_registrations.pl
- Deletes patrons that have not been upgraded from the temporary
status within the specified delay
* delete_unverified_opac_registrations.pl
- Deletes the unverified patrons based on the length of time specified
in the PatronSelfRegistrationExpireTemporaryAccountsDelay
The patron will register from self_registration.pl, linked off opac-main.pl if enabled. The registration page will be translatable to other languages in the same way that existing templates are.
Test Plan:
1) Enable PatronSelfRegistration
2) Set PatronSelfRegistrationExpireTemporaryAccountsDelay to a number
of days
3) Create a self-registered borrower category
4) Set PatronSelfRegistrationUseTemporaryStatus
5) Set PatronSelfRegistrationVerifyByEmail to "Don't require"
6) Go to OPAC, log out if logged in.
7) You should see the "Register here" link below the login box
8) Attempt to register yourself
9) Verify you can log in with your temporary password.
10) Set PatronSelfRegistrationVerifyByEmail to "Require"
11) Attempt another self-registration
12) Check the messages table, you should see a new message with a
verification link.
13) Copy and paste the link into a web browser to verify the registration
14) Log in with the given credentials to verify the account was created.
Test Plan - Part 2 - Borrower Modifications
1) Log in to OPAC, go to "my personal details" tab.
2) Make some modifications to your details.
3) Repeat steps 1 and 2 for two more borrowers.
4) Log in to Koha intranet with a user that can modify borrowers.
5) At the bottom of mainpage.pl, you should see:
Patrons requesting modifications: 3
6) Click the link
7) Approve one change, deny a different one, and ignore the third, then
submit.
8) Check the records, you should see the changes take affect on the
approved one, and no changes to the other two. You should also see
"Patrons requesting modifications: 1" at the bottom of mainpage.pl
now.
Signed-off-by: Jonathan Druart
Signed-off-by: Owen Leonard
Bug 7067 - OPAC Borrower Self Registration - Followup
* Rename PatronSelfRegistrationUseTemporaryStatus to PatronSelfRegistrationDefaultCategory
* Hide register link unless PatronSelfRegistrationDefaultCategory is set.
* Add invalid token page
* Add documentation and switches to cron scripts
* Add required fields check for editing exiting patrons
* Don't force require email address for existing patrons when
PatronSelfRegistrationVerifyByEmail is enabled.
Signed-off-by: Owen Leonard
Passed-QA-by: Jonathan Druart
Signed-off-by: Jared Camins-Esakov
---
C4/Auth.pm | 11 +-
C4/Installer/PerlDependencies.pm | 5 +
C4/Letters.pm | 30 +-
C4/Log.pm | 1 +
C4/Members.pm | 42 +-
Koha/Borrower/Modifications.pm | 369 +++++++++
.../mysql/en/mandatory/sample_notices.sql | 12 +
installer/data/mysql/kohastructure.sql | 78 ++
installer/data/mysql/sysprefs.sql | 7 +
installer/data/mysql/updatedatabase.pl | 104 +++
.../en/modules/admin/preferences/opac.pref | 34 +
.../prog/en/modules/intranet-main.tt | 12 +-
.../prog/en/modules/members/members-update.tt | 140 ++++
.../prog/en/includes/opac-bottom.inc | 4 +-
.../opac-tmpl/prog/en/includes/usermenu.inc | 2 +-
.../opac-tmpl/prog/en/modules/opac-auth.tt | 6 +-
.../opac-tmpl/prog/en/modules/opac-main.tt | 2 +
.../opac-memberentry-update-submitted.tt | 29 +
.../prog/en/modules/opac-memberentry.tt | 736 ++++++++++++++++++
.../modules/opac-registration-confirmation.tt | 70 ++
.../modules/opac-registration-email-sent.tt | 31 +
.../en/modules/opac-registration-invalid.tt | 30 +
mainpage.pl | 31 +-
members/members-update-do.pl | 64 ++
members/members-update.pl | 65 ++
.../delete_expired_opac_registrations.pl | 80 ++
.../delete_unverified_opac_registrations.pl | 70 ++
opac/opac-memberentry.pl | 303 +++++++
opac/opac-registration-verify.pl | 82 ++
opac/opac-user.pl | 2 +-
30 files changed, 2412 insertions(+), 40 deletions(-)
create mode 100644 Koha/Borrower/Modifications.pm
create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/members-update.tt
create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-memberentry-update-submitted.tt
create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-memberentry.tt
create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-registration-confirmation.tt
create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-registration-email-sent.tt
create mode 100644 koha-tmpl/opac-tmpl/prog/en/modules/opac-registration-invalid.tt
create mode 100755 members/members-update-do.pl
create mode 100755 members/members-update.pl
create mode 100755 misc/cronjobs/delete_expired_opac_registrations.pl
create mode 100755 misc/cronjobs/delete_unverified_opac_registrations.pl
create mode 100755 opac/opac-memberentry.pl
create mode 100755 opac/opac-registration-verify.pl
diff --git a/C4/Auth.pm b/C4/Auth.pm
index 705eda01c3..4ea03c0462 100644
--- a/C4/Auth.pm
+++ b/C4/Auth.pm
@@ -462,6 +462,8 @@ sub get_template_and_user {
SyndeticsSeries => C4::Context->preference("SyndeticsSeries"),
SyndeticsCoverImageSize => C4::Context->preference("SyndeticsCoverImageSize"),
OPACLocalCoverImages => C4::Context->preference("OPACLocalCoverImages"),
+ PatronSelfRegistration => C4::Context->preference("PatronSelfRegistration"),
+ PatronSelfRegistrationDefaultCategory => C4::Context->preference("PatronSelfRegistrationDefaultCategory"),
);
$template->param(OpacPublic => '1') if ($user || C4::Context->preference("OpacPublic"));
@@ -967,10 +969,9 @@ sub checkauth {
OpacAuthorities => C4::Context->preference("OpacAuthorities"),
OpacBrowser => C4::Context->preference("OpacBrowser"),
opacheader => C4::Context->preference("opacheader"),
- TagsEnabled => C4::Context->preference("TagsEnabled"),
+ TagsEnabled => C4::Context->preference("TagsEnabled"),
OPACUserCSS => C4::Context->preference("OPACUserCSS"),
- intranetcolorstylesheet =>
- C4::Context->preference("intranetcolorstylesheet"),
+ intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"),
intranetstylesheet => C4::Context->preference("intranetstylesheet"),
intranetbookbag => C4::Context->preference("intranetbookbag"),
IntranetNav => C4::Context->preference("IntranetNav"),
@@ -978,7 +979,9 @@ sub checkauth {
intranetuserjs => C4::Context->preference("intranetuserjs"),
IndependantBranches=> C4::Context->preference("IndependantBranches"),
AutoLocation => C4::Context->preference("AutoLocation"),
- wrongip => $info{'wrongip'},
+ wrongip => $info{'wrongip'},
+ PatronSelfRegistration => C4::Context->preference("PatronSelfRegistration"),
+ PatronSelfRegistrationDefaultCategory => C4::Context->preference("PatronSelfRegistrationDefaultCategory"),
);
$template->param( OpacPublic => C4::Context->preference("OpacPublic"));
diff --git a/C4/Installer/PerlDependencies.pm b/C4/Installer/PerlDependencies.pm
index 71f35d4f7e..16144f943d 100644
--- a/C4/Installer/PerlDependencies.pm
+++ b/C4/Installer/PerlDependencies.pm
@@ -629,6 +629,11 @@ our $PERL_DEPS = {
'required' => '0',
'min_ver' => '1.09',
},
+ 'String::Random' => {
+ 'usage' => 'OpacSelfRegistration',
+ 'required' => '0',
+ 'min_ver' => '1.4',
+ },
};
1;
diff --git a/C4/Letters.pm b/C4/Letters.pm
index f646241e8e..a585ff88d5 100644
--- a/C4/Letters.pm
+++ b/C4/Letters.pm
@@ -540,6 +540,9 @@ sub GetProcessedLetter {
}
}
+ my $OPACBaseURL = C4::Context->preference('OPACBaseURL');
+ $letter->{content} =~ s/<>/$OPACBaseURL/go;
+
if ($want_librarian) {
# parsing librarian name
my $userenv = C4::Context->userenv;
@@ -638,18 +641,19 @@ sub _parseletter_sth {
# check cache first
(defined $handles{$table}) and return $handles{$table};
my $query =
- ($table eq 'biblio' ) ? "SELECT * FROM $table WHERE biblionumber = ?" :
- ($table eq 'biblioitems' ) ? "SELECT * FROM $table WHERE biblionumber = ?" :
- ($table eq 'items' ) ? "SELECT * FROM $table WHERE itemnumber = ?" :
- ($table eq 'issues' ) ? "SELECT * FROM $table WHERE itemnumber = ?" :
- ($table eq 'old_issues' ) ? "SELECT * FROM $table WHERE itemnumber = ? ORDER BY timestamp DESC LIMIT 1" :
- ($table eq 'reserves' ) ? "SELECT * FROM $table WHERE borrowernumber = ? and biblionumber = ?" :
- ($table eq 'borrowers' ) ? "SELECT * FROM $table WHERE borrowernumber = ?" :
- ($table eq 'branches' ) ? "SELECT * FROM $table WHERE branchcode = ?" :
- ($table eq 'suggestions' ) ? "SELECT * FROM $table WHERE suggestionid = ?" :
- ($table eq 'aqbooksellers') ? "SELECT * FROM $table WHERE id = ?" :
- ($table eq 'aqorders' ) ? "SELECT * FROM $table WHERE ordernumber = ?" :
- ($table eq 'opac_news' ) ? "SELECT * FROM $table WHERE idnew = ?" :
+ ($table eq 'biblio' ) ? "SELECT * FROM $table WHERE biblionumber = ?" :
+ ($table eq 'biblioitems' ) ? "SELECT * FROM $table WHERE biblionumber = ?" :
+ ($table eq 'items' ) ? "SELECT * FROM $table WHERE itemnumber = ?" :
+ ($table eq 'issues' ) ? "SELECT * FROM $table WHERE itemnumber = ?" :
+ ($table eq 'old_issues' ) ? "SELECT * FROM $table WHERE itemnumber = ? ORDER BY timestamp DESC LIMIT 1" :
+ ($table eq 'reserves' ) ? "SELECT * FROM $table WHERE borrowernumber = ? and biblionumber = ?" :
+ ($table eq 'borrowers' ) ? "SELECT * FROM $table WHERE borrowernumber = ?" :
+ ($table eq 'branches' ) ? "SELECT * FROM $table WHERE branchcode = ?" :
+ ($table eq 'suggestions' ) ? "SELECT * FROM $table WHERE suggestionid = ?" :
+ ($table eq 'aqbooksellers') ? "SELECT * FROM $table WHERE id = ?" :
+ ($table eq 'aqorders' ) ? "SELECT * FROM $table WHERE ordernumber = ?" :
+ ($table eq 'opac_news' ) ? "SELECT * FROM $table WHERE idnew = ?" :
+ ($table eq 'borrower_modifications') ? "SELECT * FROM $table WHERE borrowernumber = ? OR verification_token =?":
undef ;
unless ($query) {
warn "ERROR: No _parseletter_sth query for table '$table'";
@@ -756,7 +760,7 @@ sub EnqueueLetter {
my $params = shift or return;
return unless exists $params->{'letter'};
- return unless exists $params->{'borrowernumber'};
+# return unless exists $params->{'borrowernumber'};
return unless exists $params->{'message_transport_type'};
my $content = $params->{letter}->{content};
diff --git a/C4/Log.pm b/C4/Log.pm
index 14448e3ca5..671fcdb8a4 100644
--- a/C4/Log.pm
+++ b/C4/Log.pm
@@ -73,6 +73,7 @@ sub logaction {
# the scalar '0'.
my $userenv = C4::Context->userenv();
my $usernumber = (ref($userenv) eq 'HASH') ? $userenv->{'number'} : 0;
+ $usernumber ||= 0;
my $dbh = C4::Context->dbh;
my $sth=$dbh->prepare("Insert into action_logs (timestamp,user,module,action,object,info) values (now(),?,?,?,?,?)");
diff --git a/C4/Members.pm b/C4/Members.pm
index f381a41745..81b014b91e 100644
--- a/C4/Members.pm
+++ b/C4/Members.pm
@@ -25,6 +25,7 @@ use strict;
use C4::Context;
use C4::Dates qw(format_date_in_iso format_date);
use Digest::MD5 qw(md5_base64);
+use String::Random qw( random_string );
use Date::Calc qw/Today Add_Delta_YM check_date Date_to_Days/;
use C4::Log; # logaction
use C4::Overdues;
@@ -118,6 +119,7 @@ BEGIN {
#Insert data
push @EXPORT, qw(
&AddMember
+ &AddMember_Opac
&add_member_orgs
&MoveMemberToDeleted
&ExtendMemberSubscriptionTo
@@ -751,11 +753,25 @@ Returns as undef upon any db error without further processing
sub AddMember {
my (%data) = @_;
my $dbh = C4::Context->dbh;
- # generate a proper login if none provided
- $data{'userid'} = Generate_Userid($data{'borrowernumber'}, $data{'firstname'}, $data{'surname'}) if $data{'userid'} eq '';
- # create a disabled account if no password provided
- $data{'password'} = ($data{'password'})? md5_base64($data{'password'}) : '!';
- $data{'borrowernumber'}=InsertInTable("borrowers",\%data);
+
+ # generate a proper login if none provided
+ $data{'userid'} = Generate_Userid($data{'borrowernumber'}, $data{'firstname'}, $data{'surname'}) if $data{'userid'} eq '';
+
+ # add expiration date if it isn't already there
+ unless ( $data{'dateexpiry'} ) {
+ $data{'dateexpiry'} = GetExpiryDate( $data{'categorycode'}, C4::Dates->new()->output("iso") );
+ }
+
+ # add enrollment date if it isn't already there
+ unless ( $data{'dateenrolled'} ) {
+ $data{'dateenrolled'} = C4::Dates->new()->output("iso");
+ }
+
+ # create a disabled account if no password provided
+ $data{'password'} = ($data{'password'})? md5_base64($data{'password'}) : '!';
+ $data{'borrowernumber'}=InsertInTable("borrowers",\%data);
+
+
# mysql_insertid is probably bad. not necessarily accurate and mysql-specific at best.
logaction("MEMBERS", "CREATE", $data{'borrowernumber'}, "") if C4::Context->preference("BorrowersLog");
@@ -2379,6 +2395,22 @@ sub GetBorrowersWithEmail {
return @result;
}
+sub AddMember_Opac {
+ my ( %borrower ) = @_;
+
+ $borrower{'categorycode'} = C4::Context->preference('PatronSelfRegistrationDefaultCategory');
+
+ my $sr = new String::Random;
+ $sr->{'A'} = [ 'A'..'Z', 'a'..'z' ];
+ my $password = $sr->randpattern("AAAAAAAAAA");
+ $borrower{'password'} = $password;
+
+ $borrower{'cardnumber'} = fixup_cardnumber();
+
+ my $borrowernumber = AddMember(%borrower);
+
+ return ( $borrowernumber, $password );
+}
END { } # module clean-up code here (global destructor)
diff --git a/Koha/Borrower/Modifications.pm b/Koha/Borrower/Modifications.pm
new file mode 100644
index 0000000000..f83b61d922
--- /dev/null
+++ b/Koha/Borrower/Modifications.pm
@@ -0,0 +1,369 @@
+package Koha::Borrower::Modifications;
+
+# Copyright 2012 ByWater Solutions
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+=head1 NAME
+
+C4::Borrowers::Modifications
+
+=cut
+
+use Modern::Perl;
+
+use C4::Context;
+use C4::Debug;
+use C4::SQLHelper qw(InsertInTable UpdateInTable);
+
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
+
+BEGIN {
+
+ # set the version for version checking
+ $VERSION = 0.01;
+ require Exporter;
+ @ISA = qw(Exporter);
+ @EXPORT = qw(
+
+ );
+
+ my $debug = C4::Context->preference("DebugLevel");
+}
+
+sub new {
+ my ( $class, %args ) = @_;
+ my $self = bless( {}, $class );
+
+ $self->{'verification_token'} = $args{'verification_token'};
+ $self->{'borrowernumber'} = $args{'borrowernumber'};
+
+ return $self;
+}
+
+=head AddModifications
+
+Koha::Borrower::Modifications->AddModifications( %data );
+
+Adds or updates modifications for a borrower.
+
+Requires either the key borrowernumber, or verification_token
+to be part of the passed in hash.
+
+=cut
+
+sub AddModifications {
+ my ( $self, %data ) = @_;
+
+ if ( $self->{'borrowernumber'} ) {
+ delete $data{'borrowernumber'};
+
+ if ( keys %data ) {
+ $data{'borrowernumber'} = $self->{'borrowernumber'};
+ my $dbh = C4::Context->dbh;
+
+ my $query = "
+ SELECT COUNT(*) AS count
+ FROM borrower_modifications
+ WHERE borrowernumber = ?
+ ";
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute( $self->{'borrowernumber'} );
+ my $result = $sth->fetchrow_hashref();
+
+ if ( $result->{'count'} ) {
+ $data{'verification_token'} = q{};
+ return UpdateInTable( "borrower_modifications", \%data );
+ }
+ else {
+ return InsertInTable( "borrower_modifications", \%data );
+ }
+ }
+
+ }
+ elsif ( $self->{'verification_token'} ) {
+ delete $data{'borrowernumber'};
+ $data{'verification_token'} = $self->{'verification_token'};
+
+ return InsertInTable( "borrower_modifications", \%data );
+ }
+ else {
+ return;
+ }
+}
+
+=head Verify
+
+$verified = Koha::Borrower::Modifications->Verify( $verification_token );
+
+Returns true if the passed in token is valid.
+
+=cut
+
+sub Verify {
+ my ( $self, $verification_token ) = @_;
+
+ if ( ref($self) ) {
+ $verification_token =
+ ($verification_token)
+ ? $verification_token
+ : $self->{'verification_token'};
+ }
+
+ my $dbh = C4::Context->dbh;
+ my $query = "
+ SELECT COUNT(*) AS count
+ FROM borrower_modifications
+ WHERE verification_token = ?
+ ";
+ my $sth = $dbh->prepare($query);
+ $sth->execute($verification_token);
+ my $result = $sth->fetchrow_hashref();
+
+ return $result->{'count'};
+}
+
+=head GetPendingModificationsCount
+
+$count = Koha::Borrower::Modifications->GetPendingModificationsCount();
+
+Returns the number of pending modifications for existing borrowers.
+=cut
+
+sub GetPendingModificationsCount {
+ my ( $self, $branchcode ) = @_;
+
+ my $dbh = C4::Context->dbh;
+ my $query = "
+ SELECT COUNT(*) AS count
+ FROM borrower_modifications, borrowers
+ WHERE borrower_modifications.borrowernumber > 0
+ AND borrower_modifications.borrowernumber = borrowers.borrowernumber
+ ";
+
+ my @params;
+ if ($branchcode) {
+ $query .= " AND borrowers.branchcode = ? ";
+ push( @params, $branchcode );
+ }
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute(@params);
+ my $result = $sth->fetchrow_hashref();
+
+ return $result->{'count'};
+}
+
+=head GetPendingModifications
+
+$arrayref = Koha::Borrower::Modifications->GetPendingModifications();
+
+Returns an arrayref of hashrefs for all pending modifications for existing borrowers.
+
+=cut
+
+sub GetPendingModifications {
+ my ( $self, $branchcode ) = @_;
+
+ my $dbh = C4::Context->dbh;
+ my $query = "
+ SELECT borrower_modifications.*
+ FROM borrower_modifications, borrowers
+ WHERE borrower_modifications.borrowernumber > 0
+ AND borrower_modifications.borrowernumber = borrowers.borrowernumber
+ ";
+
+ my @params;
+ if ($branchcode) {
+ $query .= " AND borrowers.branchcode = ? ";
+ push( @params, $branchcode );
+ }
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute(@params);
+
+ my @m;
+ while ( my $row = $sth->fetchrow_hashref() ) {
+ foreach my $key ( keys %$row ) {
+ delete $row->{$key} unless defined $row->{$key};
+ }
+
+ push( @m, $row );
+ }
+
+ return \@m;
+}
+
+=head ApproveModifications
+
+Koha::Borrower::Modifications->ApproveModifications( $borrowernumber );
+
+Commits the pending modifications to the borrower record and removes
+them from the modifications table.
+
+=cut
+
+sub ApproveModifications {
+ my ( $self, $borrowernumber ) = @_;
+
+ if ( ref($self) ) {
+ $borrowernumber =
+ ($borrowernumber) ? $borrowernumber : $self->{'borrowernumber'};
+ }
+
+ return unless $borrowernumber;
+
+ my $data = $self->GetModifications( borrowernumber => $borrowernumber );
+
+ if ( UpdateInTable( "borrowers", $data ) ) {
+ $self->DelModifications( borrowernumber => $borrowernumber );
+ }
+}
+
+=head DenyModifications
+
+Koha::Borrower::Modifications->DenyModifications( $borrowernumber );
+
+Removes the modifications from the table for the given borrower,
+without commiting the changes to the borrower record.
+
+=cut
+
+sub DenyModifications {
+ my ( $self, $borrowernumber ) = @_;
+
+ if ( ref($self) ) {
+ $borrowernumber =
+ ($borrowernumber) ? $borrowernumber : $self->{'borrowernumber'};
+ }
+
+ return unless $borrowernumber;
+
+ return $self->DelModifications( borrowernumber => $borrowernumber );
+}
+
+=head DelModifications
+
+Koha::Borrower::Modifications->DelModifications(
+ [ borrowernumber => $borrowernumber ],
+ [ verification_token => $verification_token ]
+);
+
+Deletes the modifications for the given borrowernumber or verification token.
+
+=cut
+
+sub DelModifications {
+ my ( $self, %params ) = @_;
+
+ my ( $field, $value );
+
+ if ( $params{'borrowernumber'} ) {
+ $field = 'borrowernumber';
+ $value = $params{'borrowernumber'};
+ }
+ elsif ( $params{'verification_token'} ) {
+ $field = 'verification_token';
+ $value = $params{'verification_token'};
+ }
+
+ if ( ref($self) && !$value ) {
+ if ( $self->{'borrowernumber'} ) {
+ $field = 'borrowernumber';
+ $value = $self->{'borrowernumber'};
+ }
+ elsif ( $self->{'verification_token'} ) {
+ $field = 'verification_token';
+ $value = $self->{'verification_token'};
+ }
+ }
+
+ return unless $value;
+
+ my $dbh = C4::Context->dbh;
+
+ $field = $dbh->quote_identifier($field);
+
+ my $query = "
+ DELETE
+ FROM borrower_modifications
+ WHERE $field = ?
+ ";
+
+ my $sth = $dbh->prepare($query);
+ return $sth->execute($value);
+}
+
+=head GetModifications
+
+$hashref = Koha::Borrower::Modifications->GetModifications(
+ [ borrowernumber => $borrowernumber ],
+ [ verification_token => $verification_token ]
+);
+
+Gets the modifications for the given borrowernumber or verification token.
+
+=cut
+
+sub GetModifications {
+ my ( $self, %params ) = @_;
+
+ my ( $field, $value );
+
+ if ( $params{'borrowernumber'} ) {
+ $field = 'borrowernumber';
+ $value = $params{'borrowernumber'};
+ }
+ elsif ( $params{'verification_token'} ) {
+ $field = 'verification_token';
+ $value = $params{'verification_token'};
+ }
+
+ if ( ref($self) && !$value ) {
+ if ( $self->{'borrowernumber'} ) {
+ $field = 'borrowernumber';
+ $value = $self->{'borrowernumber'};
+ }
+ elsif ( $self->{'verification_token'} ) {
+ $field = 'verification_token';
+ $value = $self->{'verification_token'};
+ }
+ }
+
+ return unless $value;
+
+ my $dbh = C4::Context->dbh;
+
+ $field = $dbh->quote_identifier($field);
+
+ my $query = "
+ SELECT *
+ FROM borrower_modifications
+ WHERE $field = ?
+ ";
+
+ my $sth = $dbh->prepare($query);
+ $sth->execute($value);
+ my $data = $sth->fetchrow_hashref();
+
+ foreach my $key ( keys %$data ) {
+ delete $data->{$key} unless ( defined( $data->{$key} ) );
+ }
+
+ return $data;
+}
+
+1;
diff --git a/installer/data/mysql/en/mandatory/sample_notices.sql b/installer/data/mysql/en/mandatory/sample_notices.sql
index 6fa0a5400a..e6e9df08fb 100644
--- a/installer/data/mysql/en/mandatory/sample_notices.sql
+++ b/installer/data/mysql/en/mandatory/sample_notices.sql
@@ -105,3 +105,15 @@ Date due: <>
<>
<>
', 1);
+
+
+INSERT INTO `letter` (`module`,`code`,`branchcode`,`name`,`is_html`,`title`,`content`)
+VALUES (
+'members', 'OPAC_REG_VERIFY', '', 'Opac Self-Registration Verification Email', '1', 'Verify Your Account', 'Hello!
+
+Your library account has been created. Please verify your email address by clicking this link to complete the signup process:
+
+http://<>/cgi-bin/koha/opac-registration-verify.pl?token=<>
+
+If you did not initiate this request, you may safely ignore this one-time message. The request will expire shortly.'
+);
\ No newline at end of file
diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql
index ddf4b0fb7c..ed673da455 100644
--- a/installer/data/mysql/kohastructure.sql
+++ b/installer/data/mysql/kohastructure.sql
@@ -2977,6 +2977,84 @@ CREATE TABLE borrower_attribute_types_branches( -- association table between bor
FOREIGN KEY (b_branchcode) REFERENCES branches(branchcode) ON DELETE CASCADE
) ENGINE=INNODB DEFAULT CHARSET=utf8;
+--
+-- Table structure for table `borrower_modifications`
+--
+
+CREATE TABLE IF NOT EXISTS `borrower_modifications` (
+ `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `verification_token` varchar(255) NOT NULL DEFAULT '',
+ `borrowernumber` int(11) NOT NULL DEFAULT '0',
+ `cardnumber` varchar(16) DEFAULT NULL,
+ `surname` mediumtext,
+ `firstname` text,
+ `title` mediumtext,
+ `othernames` mediumtext,
+ `initials` text,
+ `streetnumber` varchar(10) DEFAULT NULL,
+ `streettype` varchar(50) DEFAULT NULL,
+ `address` mediumtext,
+ `address2` text,
+ `city` mediumtext,
+ `state` text,
+ `zipcode` varchar(25) DEFAULT NULL,
+ `country` text,
+ `email` mediumtext,
+ `phone` text,
+ `mobile` varchar(50) DEFAULT NULL,
+ `fax` mediumtext,
+ `emailpro` text,
+ `phonepro` text,
+ `B_streetnumber` varchar(10) DEFAULT NULL,
+ `B_streettype` varchar(50) DEFAULT NULL,
+ `B_address` varchar(100) DEFAULT NULL,
+ `B_address2` text,
+ `B_city` mediumtext,
+ `B_state` text,
+ `B_zipcode` varchar(25) DEFAULT NULL,
+ `B_country` text,
+ `B_email` text,
+ `B_phone` mediumtext,
+ `dateofbirth` date DEFAULT NULL,
+ `branchcode` varchar(10) DEFAULT NULL,
+ `categorycode` varchar(10) DEFAULT NULL,
+ `dateenrolled` date DEFAULT NULL,
+ `dateexpiry` date DEFAULT NULL,
+ `gonenoaddress` tinyint(1) DEFAULT NULL,
+ `lost` tinyint(1) DEFAULT NULL,
+ `debarred` date DEFAULT NULL,
+ `debarredcomment` varchar(255) DEFAULT NULL,
+ `contactname` mediumtext,
+ `contactfirstname` text,
+ `contacttitle` text,
+ `guarantorid` int(11) DEFAULT NULL,
+ `borrowernotes` mediumtext,
+ `relationship` varchar(100) DEFAULT NULL,
+ `ethnicity` varchar(50) DEFAULT NULL,
+ `ethnotes` varchar(255) DEFAULT NULL,
+ `sex` varchar(1) DEFAULT NULL,
+ `password` varchar(30) DEFAULT NULL,
+ `flags` int(11) DEFAULT NULL,
+ `userid` varchar(75) DEFAULT NULL,
+ `opacnote` mediumtext,
+ `contactnote` varchar(255) DEFAULT NULL,
+ `sort1` varchar(80) DEFAULT NULL,
+ `sort2` varchar(80) DEFAULT NULL,
+ `altcontactfirstname` varchar(255) DEFAULT NULL,
+ `altcontactsurname` varchar(255) DEFAULT NULL,
+ `altcontactaddress1` varchar(255) DEFAULT NULL,
+ `altcontactaddress2` varchar(255) DEFAULT NULL,
+ `altcontactaddress3` varchar(255) DEFAULT NULL,
+ `altcontactstate` text,
+ `altcontactzipcode` varchar(50) DEFAULT NULL,
+ `altcontactcountry` text,
+ `altcontactphone` varchar(50) DEFAULT NULL,
+ `smsalertnumber` varchar(50) DEFAULT NULL,
+ `privacy` int(11) DEFAULT NULL,
+ PRIMARY KEY (`verification_token`,`borrowernumber`),
+ KEY `verification_token` (`verification_token`),
+ KEY `borrowernumber` (`borrowernumber`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql
index 0cc5a54ec0..2fb5bd450c 100644
--- a/installer/data/mysql/sysprefs.sql
+++ b/installer/data/mysql/sysprefs.sql
@@ -388,3 +388,10 @@ INSERT INTO systempreferences (variable, value, options, explanation, type) VALU
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('HoldsToPullStartDate','2','Set the default start date for the Holds to pull list to this many days ago',NULL,'Integer');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('alphabet','A B C D E F G H I J K L M N O P Q R S T U V W X Y Z','Alphabet than can be expanded into browse links, e.g. on Home > Patrons',NULL,'free');
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('RefundLostItemFeeOnReturn', '1', 'If enabled, the lost item fee charged to a borrower will be refunded when the lost item is returned.', NULL, 'YesNo');
+INSERT INTO systempreferences (`variable`, `value`, `options`, `explanation`, `type`) VALUES
+('PatronSelfRegistration', '0', NULL, 'If enabled, patrons will be able to register themselves via the OPAC.', 'YesNo'),
+('PatronSelfRegistrationVerifyByEmail', '0', NULL, 'If enabled, any patron attempting to register themselves via the OPAC will be required to verify themselves via email to activate his or her account.', 'YesNo'),
+('PatronSelfRegistrationDefaultCategory', '', '', 'A patron registered via the OPAC will receive a borrower category code set in this system preference.', 'free'),
+('PatronSelfRegistrationExpireTemporaryAccountsDelay', '0', NULL, 'If PatronSelfRegistrationDefaultCategory is enabled, this system preference controls how long a patron can have a temporary status before the account is deleted automatically. It is an integer value representing a number of days to wait before deleting a temporary patron account. Setting it to 0 disables the deleting of temporary accounts.', 'Integer'),
+('PatronSelfRegistrationBorrowerMandatoryField', 'surname|firstname', NULL , 'Choose the mandatory fields for a patron''s account, when registering via the OPAC.', 'free'),
+('PatronSelfRegistrationBorrowerUnwantedField', '', NULL , 'Name the fields you don''t want to display when registering a new patron via the OPAC.', 'free');
diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl
index 39e4bde404..8328192738 100755
--- a/installer/data/mysql/updatedatabase.pl
+++ b/installer/data/mysql/updatedatabase.pl
@@ -5714,6 +5714,110 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
) ENGINE=InnoDB DEFAULT CHARSET=utf8");
print "Upgrade to $DBversion done (creating `transport_cost` table; adding UseTransportCostMatrix systempref, in circulation)\n";
+ SetVersion($DBversion);
+}
+
+$DBversion = '3.09.00.XXX';
+if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
+ $dbh->do("
+ CREATE TABLE IF NOT EXISTS `borrower_modifications` (
+ `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `verification_token` varchar(255) NOT NULL DEFAULT '',
+ `borrowernumber` int(11) NOT NULL DEFAULT '0',
+ `cardnumber` varchar(16) DEFAULT NULL,
+ `surname` mediumtext,
+ `firstname` text,
+ `title` mediumtext,
+ `othernames` mediumtext,
+ `initials` text,
+ `streetnumber` varchar(10) DEFAULT NULL,
+ `streettype` varchar(50) DEFAULT NULL,
+ `address` mediumtext,
+ `address2` text,
+ `city` mediumtext,
+ `state` text,
+ `zipcode` varchar(25) DEFAULT NULL,
+ `country` text,
+ `email` mediumtext,
+ `phone` text,
+ `mobile` varchar(50) DEFAULT NULL,
+ `fax` mediumtext,
+ `emailpro` text,
+ `phonepro` text,
+ `B_streetnumber` varchar(10) DEFAULT NULL,
+ `B_streettype` varchar(50) DEFAULT NULL,
+ `B_address` varchar(100) DEFAULT NULL,
+ `B_address2` text,
+ `B_city` mediumtext,
+ `B_state` text,
+ `B_zipcode` varchar(25) DEFAULT NULL,
+ `B_country` text,
+ `B_email` text,
+ `B_phone` mediumtext,
+ `dateofbirth` date DEFAULT NULL,
+ `branchcode` varchar(10) DEFAULT NULL,
+ `categorycode` varchar(10) DEFAULT NULL,
+ `dateenrolled` date DEFAULT NULL,
+ `dateexpiry` date DEFAULT NULL,
+ `gonenoaddress` tinyint(1) DEFAULT NULL,
+ `lost` tinyint(1) DEFAULT NULL,
+ `debarred` date DEFAULT NULL,
+ `debarredcomment` varchar(255) DEFAULT NULL,
+ `contactname` mediumtext,
+ `contactfirstname` text,
+ `contacttitle` text,
+ `guarantorid` int(11) DEFAULT NULL,
+ `borrowernotes` mediumtext,
+ `relationship` varchar(100) DEFAULT NULL,
+ `ethnicity` varchar(50) DEFAULT NULL,
+ `ethnotes` varchar(255) DEFAULT NULL,
+ `sex` varchar(1) DEFAULT NULL,
+ `password` varchar(30) DEFAULT NULL,
+ `flags` int(11) DEFAULT NULL,
+ `userid` varchar(75) DEFAULT NULL,
+ `opacnote` mediumtext,
+ `contactnote` varchar(255) DEFAULT NULL,
+ `sort1` varchar(80) DEFAULT NULL,
+ `sort2` varchar(80) DEFAULT NULL,
+ `altcontactfirstname` varchar(255) DEFAULT NULL,
+ `altcontactsurname` varchar(255) DEFAULT NULL,
+ `altcontactaddress1` varchar(255) DEFAULT NULL,
+ `altcontactaddress2` varchar(255) DEFAULT NULL,
+ `altcontactaddress3` varchar(255) DEFAULT NULL,
+ `altcontactstate` text,
+ `altcontactzipcode` varchar(50) DEFAULT NULL,
+ `altcontactcountry` text,
+ `altcontactphone` varchar(50) DEFAULT NULL,
+ `smsalertnumber` varchar(50) DEFAULT NULL,
+ `privacy` int(11) DEFAULT NULL,
+ PRIMARY KEY (`verification_token`,`borrowernumber`),
+ KEY `verification_token` (`verification_token`),
+ KEY `borrowernumber` (`borrowernumber`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+");
+
+ $dbh->do("
+ INSERT INTO systempreferences (`variable`, `value`, `options`, `explanation`, `type`) VALUES
+ ('PatronSelfRegistration', '0', NULL, 'If enabled, patrons will be able to register themselves via the OPAC.', 'YesNo'),
+ ('PatronSelfRegistrationVerifyByEmail', '0', NULL, 'If enabled, any patron attempting to register themselves via the OPAC will be required to verify themselves via email to activate his or her account.', 'YesNo'),
+ ('PatronSelfRegistrationDefaultCategory', '', '', 'A patron registered via the OPAC will receive a borrower category code set in this system preference.', 'free'),
+ ('PatronSelfRegistrationExpireTemporaryAccountsDelay', '0', NULL, 'If PatronSelfRegistrationDefaultCategory is enabled, this system preference controls how long a patron can have a temporary status before the account is deleted automatically. It is an integer value representing a number of days to wait before deleting a temporary patron account. Setting it to 0 disables the deleting of temporary accounts.', 'Integer'),
+ ('PatronSelfRegistrationBorrowerMandatoryField', 'surname|firstname', NULL , 'Choose the mandatory fields for a patron''s account, when registering via the OPAC.', 'free'),
+ ('PatronSelfRegistrationBorrowerUnwantedField', '', NULL , 'Name the fields you don''t want to display when registering a new patron via the OPAC.', 'free');
+ ");
+
+ $dbh->do("
+ INSERT INTO letter ( `module`, `code`, `branchcode`, `name`, `is_html`, `title`, `content` )
+ VALUES ( 'members', 'OPAC_REG_VERIFY', '', 'Opac Self-Registration Verification Email', '1', 'Verify Your Account', 'Hello!
+
+ Your library account has been created. Please verify your email address by clicking this link to complete the signup process:
+
+ http://<>/cgi-bin/koha/opac-registration-verify.pl?token=<>
+
+ If you did not initiate this request, you may safely ignore this one-time message. The request will expire shortly.'
+ )");
+
+ print "Upgrade to $DBversion done (Add Patron Self Registration)\n";
SetVersion ($DBversion);
}
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref
index 2866f8d3d2..bcf712428b 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref
@@ -527,3 +527,37 @@ OPAC:
yes: Use
no: "Don't use"
- "the item collection code when finding items for the shelf browser."
+
+ Self Registration:
+ -
+ - pref: PatronSelfRegistration
+ choices:
+ yes: Allow
+ no: "Don't allow"
+ - "library patrons to register an account via the OPAC."
+ -
+ - pref: PatronSelfRegistrationVerifyByEmail
+ choices:
+ yes: Require
+ no: "Don't require"
+ - "that a self-registering patron verify his or herself via email."
+ -
+ - "Use the patron category code"
+ - pref: PatronSelfRegistrationDefaultCategory
+ class: short
+ - "as the default patron category for patrons registered via the OPAC."
+ -
+ - "Delete patrons registered via the OPAC, but not yet verified after"
+ - pref: PatronSelfRegistrationExpireTemporaryAccountsDelay
+ class: integer
+ - "days."
+ -
+ - "The following database columns must be filled in on the patron entry screen:"
+ - pref: PatronSelfRegistrationBorrowerMandatoryField
+ class: multi
+ - (separate columns with |)
+ -
+ - "The following database columns will not appear on the patron entry screen:"
+ - pref: PatronSelfRegistrationBorrowerUnwantedField
+ class: multi
+ - (separate columns with |)
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
index 4e91e06758..e7363b01b9 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
@@ -107,6 +107,7 @@
[% END %]
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt
index a73c8bbad8..6a6e1ee995 100644
--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt
@@ -84,8 +84,10 @@ please choose against which one you would like to authenticate:
-
Don't have a password yet?
If you don't have a password yet, stop by the circulation desk the next time you're in the library. We'll happily set one up for you.
-
Don't have a library card?
If you don't have a library card, stop by your local library to sign up.
+
+
Don't have a password yet?
If you don't have a password yet, stop by the circulation desk the next time you're in the library. We'll happily set one up for you.
+
Don't have a library card?
If you don't have a library card, stop by your local library to sign up[% IF PatronSelfRegistration && PatronSelfRegistrationDefaultCategory %] or register here[% END %].
+
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt
index cc67ff2b18..1ae7bf5df8 100644
--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt
@@ -56,6 +56,8 @@
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-memberentry-update-submitted.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-memberentry-update-submitted.tt
new file mode 100644
index 0000000000..91838245f0
--- /dev/null
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-memberentry-update-submitted.tt
@@ -0,0 +1,29 @@
+[% INCLUDE 'doc-head-open.inc' %]
+[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog
+[% INCLUDE 'doc-head-close.inc' %]
+
+
+[% IF ( OpacNav ) %]
[% ELSE %]
[% END %]
+
+[% INCLUDE 'masthead.inc' %]
+
+
+
+
+
+
+
Your updates have been submitted. A librarian will now review you updates before applying them.
+
+
+
+
+
+
+[% IF ( OpacNav ) %]
+
+ [% INCLUDE 'navigation.inc' %]
+
+[% END %]
+
+
+[% INCLUDE 'opac-bottom.inc' %]
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-memberentry.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-memberentry.tt
new file mode 100644
index 0000000000..ac2cb02a81
--- /dev/null
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-memberentry.tt
@@ -0,0 +1,736 @@
+[% USE KohaDates %]
+[% SET userupdateview = 1 %]
+
+ [% INCLUDE 'doc-head-open.inc' %]
+ [% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog › Your fines and charges
+ [% INCLUDE 'doc-head-close.inc' %]
+
+
+
+
+
+
+
+ [% INCLUDE 'masthead.inc' %]
+
+
+
+
+
+ [% UNLESS OPACPatronDetails %]
+
To make changes to your record please contact the library.
+ [% END %]
+
+ [% IF empty_mandatory_fields %]
+
You have not filled out all required fields. Please fill in all missing fields and resubmit.
+ [% END %]
+
+ [% IF failed_captcha %]
+
You typed in the wrong characters in the box before submitting. Please try again.
+ [% END %]
+
+
+
+
+
+
+
+
+
+
+ [% INCLUDE 'navigation.inc' IsPatronPage=1 %]
+
+
+
+[% INCLUDE 'opac-bottom.inc' %]
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-registration-confirmation.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-registration-confirmation.tt
new file mode 100644
index 0000000000..968faa00c7
--- /dev/null
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-registration-confirmation.tt
@@ -0,0 +1,70 @@
+[% INCLUDE 'doc-head-open.inc' %]
+[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog
+[% INCLUDE 'doc-head-close.inc' %]
+
+
+[% IF ( OpacNav ) %]
[% ELSE %]
[% END %]
+
+[% INCLUDE 'masthead.inc' %]
+
+
+
+
+
+
Registration Complete!
+
+
You have successfully registered your new account. To log in, use the following credentials:
For your convenience, the login box on this page has been pre-filled with this data. Please log in[% IF OpacPasswordChange %] and change your password[% END %].
+ [% END %]
+ [% END %]
+ [% END %]
+
+ [% IF ( OpacNavRight ) %]
[% OpacNavRight %]
[% END %]
+
+ [% END %]
+
+
+
+
+[% IF ( OpacNav ) %]
+
+ [% INCLUDE 'navigation.inc' %]
+
+[% END %]
+
+
+[% INCLUDE 'opac-bottom.inc' %]
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-registration-email-sent.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-registration-email-sent.tt
new file mode 100644
index 0000000000..bdad739780
--- /dev/null
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-registration-email-sent.tt
@@ -0,0 +1,31 @@
+[% INCLUDE 'doc-head-open.inc' %]
+[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog
+[% INCLUDE 'doc-head-close.inc' %]
+
+
+[% IF ( OpacNav ) %]
[% ELSE %]
[% END %]
+
+[% INCLUDE 'masthead.inc' %]
+
+
+
+
+
+
Please Confirm Registration
+
+
A confirmation email has been sent to the email address [% email %].
+
+
Your account will not be activated until you follow the link provided in the confirmation email.
+
+
+
+
+
+[% IF ( OpacNav ) %]
+
+ [% INCLUDE 'navigation.inc' %]
+
+[% END %]
+
+
+[% INCLUDE 'opac-bottom.inc' %]
diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-registration-invalid.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-registration-invalid.tt
new file mode 100644
index 0000000000..12dac1dce3
--- /dev/null
+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-registration-invalid.tt
@@ -0,0 +1,30 @@
+[% INCLUDE 'doc-head-open.inc' %]
+[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog
+[% INCLUDE 'doc-head-close.inc' %]
+
+
+[% IF ( OpacNav ) %]
[% ELSE %]
[% END %]
+
+[% INCLUDE 'masthead.inc' %]
+
+
+
+
+
+
Registration invalid!
+
+
There were problems processing your registration. Please contact your library for help.
+
+
+
+
+
+
+[% IF ( OpacNav ) %]
+
+ [% INCLUDE 'navigation.inc' %]
+
+[% END %]
+
+
+[% INCLUDE 'opac-bottom.inc' %]
diff --git a/mainpage.pl b/mainpage.pl
index 78daf3887d..9085630e69 100755
--- a/mainpage.pl
+++ b/mainpage.pl
@@ -28,17 +28,17 @@ use C4::NewsChannels;
use C4::Review qw/numberofreviews/;
use C4::Suggestions qw/CountSuggestion/;
use C4::Tags qw/get_count_by_tag_status/;
-my $query = new CGI;
+use Koha::Borrower::Modifications;
-my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
+my $query = new CGI;
+
+my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user(
{
template_name => "intranet-main.tmpl",
query => $query,
type => "intranet",
authnotrequired => 0,
- flagsrequired => {
- catalogue => 1,
- },
+ flagsrequired => { catalogue => 1, },
}
);
@@ -50,14 +50,23 @@ $template->param(
koha_news_count => $koha_news_count
);
-my $pendingcomments = numberofreviews(0);
-my $pendingtags = get_count_by_tag_status(0);
-my $pendingsuggestions = CountSuggestion("ASKED");
+my $branch =
+ C4::Context->preference("IndependantBranches")
+ && !$flags->{'superlibrarian'}
+ ? C4::Context->userenv()->{'branch'}
+ : undef;
+
+my $pendingcomments = numberofreviews(0);
+my $pendingtags = get_count_by_tag_status(0);
+my $pendingsuggestions = CountSuggestion("ASKED");
+my $pending_borrower_modifications =
+ Koha::Borrower::Modifications->GetPendingModificationsCount( $branch );
$template->param(
- pendingcomments => $pendingcomments,
- pendingtags => $pendingtags,
- pendingsuggestions => $pendingsuggestions
+ pendingcomments => $pendingcomments,
+ pendingtags => $pendingtags,
+ pendingsuggestions => $pendingsuggestions,
+ pending_borrower_modifications => $pending_borrower_modifications,
);
#
diff --git a/members/members-update-do.pl b/members/members-update-do.pl
new file mode 100755
index 0000000000..e7b7b2872b
--- /dev/null
+++ b/members/members-update-do.pl
@@ -0,0 +1,64 @@
+#!/usr/bin/perl
+
+# Parts Copyright Biblibre 2010
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use strict;
+use warnings;
+
+use CGI;
+use C4::Auth;
+use C4::Output;
+use C4::Context;
+use C4::Members;
+use C4::Branch;
+use C4::Category;
+use Koha::Borrower::Modifications;
+
+my $query = new CGI;
+
+my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
+ {
+ template_name => "about.tmpl",
+ query => $query,
+ type => "intranet",
+ authnotrequired => 0,
+ flagsrequired => { borrowers => 1 },
+ debug => 1,
+ }
+);
+
+my @params = $query->param;
+
+foreach my $param (@params) {
+ if ( $param =~ "^modify_" ) {
+ my (undef, $borrowernumber) = split( /_/, $param );
+
+ my $action = $query->param($param);
+
+ if ( $action eq 'approve' ) {
+ Koha::Borrower::Modifications->ApproveModifications( $borrowernumber );
+ }
+ elsif ( $action eq 'deny' ) {
+ Koha::Borrower::Modifications->DenyModifications( $borrowernumber );
+ }
+ elsif ( $action eq 'ignore' ) {
+
+ }
+ }
+}
+
+print $query->redirect("/cgi-bin/koha/members/members-update.pl");
diff --git a/members/members-update.pl b/members/members-update.pl
new file mode 100755
index 0000000000..334d83b5ee
--- /dev/null
+++ b/members/members-update.pl
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+
+# Parts Copyright Biblibre 2010
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use strict;
+use warnings;
+
+use CGI;
+use C4::Auth;
+use C4::Output;
+use C4::Context;
+use C4::Members;
+use C4::Branch;
+use C4::Category;
+use Koha::Borrower::Modifications;
+
+my $query = new CGI;
+
+my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user(
+ {
+ template_name => "members/members-update.tmpl",
+ query => $query,
+ type => "intranet",
+ authnotrequired => 0,
+ flagsrequired => { borrowers => 1 },
+ debug => 1,
+ }
+);
+
+my $branch =
+ C4::Context->preference("IndependantBranches")
+ && !$flags->{'superlibrarian'}
+ ? C4::Context->userenv()->{'branch'}
+ : undef;
+
+my $pending_modifications =
+ Koha::Borrower::Modifications->GetPendingModifications($branch);
+
+my $borrowers;
+foreach my $pm (@$pending_modifications) {
+ $borrowers->{ $pm->{'borrowernumber'} } =
+ GetMember( borrowernumber => $pm->{'borrowernumber'} );
+
+}
+
+$template->param(
+ PendingModifications => $pending_modifications,
+ borrowers => $borrowers,
+);
+
+output_html_with_http_headers $query, $cookie, $template->output;
diff --git a/misc/cronjobs/delete_expired_opac_registrations.pl b/misc/cronjobs/delete_expired_opac_registrations.pl
new file mode 100755
index 0000000000..86f47c5ae0
--- /dev/null
+++ b/misc/cronjobs/delete_expired_opac_registrations.pl
@@ -0,0 +1,80 @@
+#!/usr/bin/perl
+
+# Copyright 2009-2010 Kyle Hall
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+use Getopt::Long;
+
+BEGIN {
+
+ # find Koha's Perl modules
+ # test carefully before changing this
+ use FindBin;
+ eval { require "$FindBin::Bin/../kohalib.pl" };
+}
+
+use C4::Context;
+use C4::Members qw/ DelMember /;
+
+my $help;
+my $confirm;
+
+GetOptions(
+ 'h|help' => \$help,
+ 'c|confirm' => \$confirm,
+);
+my $usage = << 'ENDUSAGE';
+
+This script remove confirmed OPAC based patron registrations
+that have not been changed from the patron category specified
+in the system preference PatronSelfRegistrationDefaultCategory
+within the required time period.
+
+This script has the following parameters :
+ -h --help: This message
+
+ -c --confirm: Without this flag set, this script will do nothing.
+ENDUSAGE
+
+if ( $help || !$confirm ) {
+ print $usage;
+ exit;
+}
+
+## Delete accounts that haven't been upgraded from the 'temporary' category code'
+my $delay =
+ C4::Context->preference('PatronSelfRegistrationExpireTemporaryAccountsDelay');
+my $category_code =
+ C4::Context->preference('PatronSelfRegistrationDefaultCategory');
+
+my $query = "
+ SELECT borrowernumber
+ FROM borrowers
+ WHERE
+ categorycode = ?
+ AND
+ DATEDIFF( DATE( NOW() ), DATE(dateenrolled) ) = ? )
+";
+
+my $dbh = C4::Context->dbh;
+my $sth = $dbh->prepare($query);
+$sth->execute( $category_code, $delay );
+
+while ( my ($borrowernumber) = $sth->fetchrow_array() ) {
+ DelMember($borrowernumber);
+}
diff --git a/misc/cronjobs/delete_unverified_opac_registrations.pl b/misc/cronjobs/delete_unverified_opac_registrations.pl
new file mode 100755
index 0000000000..62816d5553
--- /dev/null
+++ b/misc/cronjobs/delete_unverified_opac_registrations.pl
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+
+# Copyright 2009-2010 Kyle Hall
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+use Getopt::Long;
+
+BEGIN {
+
+ # find Koha's Perl modules
+ # test carefully before changing this
+ use FindBin;
+ eval { require "$FindBin::Bin/../kohalib.pl" };
+}
+
+use C4::Context;
+use C4::Members qw/ DelMember /;
+
+my $help;
+my $confirm;
+my $hours = 24;
+
+GetOptions(
+ 'h|help' => \$help,
+ 'c|confirm' => \$confirm,
+ 't|time=i' => \$hours,
+);
+my $usage = << 'ENDUSAGE';
+
+This script removes unconfirmed OPAC based patron registrations
+that have not been confirmed within the required time period.
+
+This script has the following parameters :
+ -h --help: This message
+
+ -t --time: The length in hours to wait before removing an unconfirmed registration.
+ Defaults to 24 hours if not set.
+
+ -c --confirm: Without this flag set, this script will do nothing.
+ENDUSAGE
+
+if ( $help || !$confirm ) {
+ print $usage;
+ exit;
+}
+
+my $dbh = C4::Context->dbh;
+
+$dbh->do( "
+ DELETE FROM borrower_modifications
+ WHERE
+ borrowernumber = 0
+ AND
+ TIME_TO_SEC( TIMEDIFF( NOW(), timestamp )) / 3600 > ?
+", undef, $hours );
diff --git a/opac/opac-memberentry.pl b/opac/opac-memberentry.pl
new file mode 100755
index 0000000000..20ec9dbdd8
--- /dev/null
+++ b/opac/opac-memberentry.pl
@@ -0,0 +1,303 @@
+#!/usr/bin/perl
+
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use CGI;
+use Digest::MD5 qw( md5_base64 md5_hex );
+use String::Random qw( random_string );
+
+use C4::Auth;
+use C4::Output;
+use C4::Members;
+use Koha::Borrower::Modifications;
+use C4::Branch qw(GetBranchesLoop);
+
+my $cgi = new CGI;
+my $dbh = C4::Context->dbh;
+
+my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
+ {
+ template_name => "opac-memberentry.tmpl",
+ type => "opac",
+ query => $cgi,
+ authnotrequired => 1,
+ }
+);
+
+unless ( C4::Context->preference('PatronSelfRegistration') || $borrowernumber )
+{
+ print $cgi->redirect("/cgi-bin/koha/opac-main.pl");
+ exit;
+}
+
+my $action = $cgi->param('action') || q{};
+if ( $action eq q{} ) {
+ if ($borrowernumber) {
+ $action = 'edit';
+ }
+ else {
+ $action = 'new';
+ }
+}
+
+$template->param(
+ action => $action,
+ hidden => GetHiddenFields(),
+ mandatory => GetMandatoryFields($action),
+ member_titles => GetTitles(),
+ branches => GetBranchesLoop(),
+ OPACPatronDetails => C4::Context->preference('OPACPatronDetails'),
+);
+
+if ( $action eq 'create' ) {
+
+ my %borrower = ParseCgiForBorrower($cgi);
+
+ %borrower = DelEmptyFields(%borrower);
+
+ my @empty_mandatory_fields = CheckMandatoryFields( \%borrower, $action );
+
+ if (@empty_mandatory_fields) {
+ $template->param(
+ empty_mandatory_fields => \@empty_mandatory_fields,
+ borrower => \%borrower
+ );
+ }
+ elsif (
+ md5_base64( $cgi->param('captcha') ) ne $cgi->param('captcha_digest') )
+ {
+ $template->param(
+ failed_captcha => 1,
+ borrower => \%borrower
+ );
+ }
+ else {
+ if (
+ C4::Context->boolean_preference(
+ 'PatronSelfRegistrationVerifyByEmail')
+ )
+ {
+ ( $template, $borrowernumber, $cookie ) = get_template_and_user(
+ {
+ template_name => "opac-registration-email-sent.tmpl",
+ type => "opac",
+ query => $cgi,
+ authnotrequired => 1,
+ }
+ );
+ $template->param( 'email' => $borrower{'email'} );
+
+ my $verification_token = md5_hex( \%borrower );
+ $borrower{'password'} = random_string("..........");
+
+ Koha::Borrower::Modifications->new(
+ verification_token => $verification_token )
+ ->AddModifications(%borrower);
+
+ #Send verification email
+ my $letter = C4::Letters::GetPreparedLetter(
+ module => 'members',
+ letter_code => 'OPAC_REG_VERIFY',
+ tables => {
+ borrower_modifications =>
+ [ $verification_token, $verification_token ],
+ },
+ );
+
+ C4::Letters::EnqueueLetter(
+ {
+ letter => $letter,
+ message_transport_type => 'email',
+ to_address => $borrower{'email'},
+ from_address =>
+ C4::Context->preference('KohaAdminEmailAddress'),
+ }
+ );
+ }
+ else {
+ ( $template, $borrowernumber, $cookie ) = get_template_and_user(
+ {
+ template_name => "opac-registration-confirmation.tmpl",
+ type => "opac",
+ query => $cgi,
+ authnotrequired => 1,
+ }
+ );
+
+ $template->param( OpacPasswordChange =>
+ C4::Context->preference('OpacPasswordChange') );
+
+ my ( $borrowernumber, $password ) = AddMember_Opac(%borrower);
+
+ $template->param( password_cleartext => $password );
+ $template->param(
+ borrower => GetMember( borrowernumber => $borrowernumber ) );
+ $template->param(
+ PatronSelfRegistrationAdditionalInstructions =>
+ C4::Context->preference(
+ 'PatronSelfRegistrationAdditionalInstructions')
+ );
+ }
+ }
+}
+elsif ( $action eq 'update' ) {
+
+ my %borrower = ParseCgiForBorrower($cgi);
+
+ my %borrower_changes = DelEmptyFields(%borrower);
+ my @empty_mandatory_fields =
+ CheckMandatoryFields( \%borrower_changes, $action );
+
+ if (@empty_mandatory_fields) {
+ $template->param(
+ empty_mandatory_fields => \@empty_mandatory_fields,
+ borrower => \%borrower
+ );
+
+ $template->param( action => 'edit' );
+ }
+ else {
+ ( $template, $borrowernumber, $cookie ) = get_template_and_user(
+ {
+ template_name => "opac-memberentry-update-submitted.tmpl",
+ type => "opac",
+ query => $cgi,
+ authnotrequired => 1,
+ }
+ );
+
+ my %borrower_changes = DelUnchangedFields( $borrowernumber, %borrower );
+
+ my $m =
+ Koha::Borrower::Modifications->new(
+ borrowernumber => $borrowernumber );
+
+ $m->DelModifications;
+ $m->AddModifications(%borrower_changes);
+ }
+}
+elsif ( $action eq 'edit' ) { #Display logged in borrower's data
+ $template->param(
+ borrower => GetMember( borrowernumber => $borrowernumber ), );
+}
+
+my $captcha = random_string("CCCCC");
+
+$template->param(
+ captcha => $captcha,
+ captcha_digest => md5_base64($captcha)
+);
+
+output_html_with_http_headers $cgi, $cookie, $template->output;
+
+sub GetHiddenFields {
+ my %hidden_fields;
+
+ my $BorrowerUnwantedField =
+ C4::Context->preference("PatronSelfRegistrationBorrowerUnwantedField");
+
+ my @fields = split( /\|/, $BorrowerUnwantedField );
+ foreach (@fields) {
+ next unless m/\w/o;
+ $hidden_fields{$_} = 1;
+ }
+
+ return \%hidden_fields;
+}
+
+sub GetMandatoryFields {
+ my ($action) = @_;
+
+ my %mandatory_fields;
+
+ my $BorrowerMandatoryField =
+ C4::Context->preference("PatronSelfRegistrationBorrowerMandatoryField");
+
+ my @fields = split( /\|/, $BorrowerMandatoryField );
+
+ foreach (@fields) {
+ $mandatory_fields{$_} = 1;
+ }
+
+ if ( $action eq 'create' || $action eq 'new' ) {
+ $mandatory_fields{'email'} = 1
+ if C4::Context->boolean_preference(
+ 'PatronSelfRegistrationVerifyByEmail');
+ }
+
+ return \%mandatory_fields;
+}
+
+sub CheckMandatoryFields {
+ my ( $borrower, $action ) = @_;
+
+ my @empty_mandatory_fields;
+
+ my $mandatory_fields = GetMandatoryFields($action);
+ delete $mandatory_fields->{'cardnumber'};
+
+ foreach my $key ( keys %$mandatory_fields ) {
+ push( @empty_mandatory_fields, $key )
+ unless ( defined( $borrower->{$key} ) && $borrower->{$key} );
+ }
+
+ return @empty_mandatory_fields;
+}
+
+sub ParseCgiForBorrower {
+ my ($cgi) = @_;
+
+ my %borrower;
+
+ foreach ( $cgi->param ) {
+ if ( $_ =~ '^borrower_' ) {
+ my ($key) = substr( $_, 9 );
+ $borrower{$key} = $cgi->param($_);
+ }
+ }
+
+ $borrower{'dateofbirth'} =
+ C4::Dates->new( $borrower{'dateofbirth'} )->output("iso")
+ if ( defined( $borrower{'dateofbirth'} ) );
+
+ return %borrower;
+}
+
+sub DelUnchangedFields {
+ my ( $borrowernumber, %new_data ) = @_;
+
+ my $current_data = GetMember( borrowernumber => $borrowernumber );
+
+ foreach my $key ( keys %new_data ) {
+ if ( $current_data->{$key} eq $new_data{$key} ) {
+ delete $new_data{$key};
+ }
+ }
+
+ return %new_data;
+}
+
+sub DelEmptyFields {
+ my (%borrower) = @_;
+
+ foreach my $key ( keys %borrower ) {
+ delete $borrower{$key} unless $borrower{$key};
+ }
+
+ return %borrower;
+}
diff --git a/opac/opac-registration-verify.pl b/opac/opac-registration-verify.pl
new file mode 100755
index 0000000000..682dacb1a7
--- /dev/null
+++ b/opac/opac-registration-verify.pl
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use CGI;
+
+use C4::Auth;
+use C4::Output;
+use C4::Members;
+use Koha::Borrower::Modifications;
+
+my $cgi = new CGI;
+my $dbh = C4::Context->dbh;
+
+unless ( C4::Context->preference('PatronSelfRegistration') ) {
+ print $cgi->redirect("/cgi-bin/koha/opac-main.pl");
+ exit;
+}
+
+my $token = $cgi->param('token');
+my $m = Koha::Borrower::Modifications->new( verification_token => $token );
+
+my ( $template, $borrowernumber, $cookie );
+if ( $m->Verify() ) {
+ ( $template, $borrowernumber, $cookie ) = get_template_and_user(
+ {
+ template_name => "opac-registration-confirmation.tmpl",
+ type => "opac",
+ query => $cgi,
+ authnotrequired => 1,
+ }
+ );
+
+ $template->param(
+ OpacPasswordChange => C4::Context->preference('OpacPasswordChange') );
+
+ my $borrower = $m->GetModifications();
+
+ my $password;
+ ( $borrowernumber, $password ) = AddMember_Opac(%$borrower);
+
+ if ($borrowernumber) {
+ $m->DelModifications();
+
+ $template->param( password_cleartext => $password );
+ $template->param(
+ borrower => GetMember( borrowernumber => $borrowernumber ) );
+ $template->param(
+ PatronSelfRegistrationAdditionalInstructions =>
+ C4::Context->preference(
+ 'PatronSelfRegistrationAdditionalInstructions')
+ );
+ }
+
+}
+else {
+ ( $template, $borrowernumber, $cookie ) = get_template_and_user(
+ {
+ template_name => "opac-registration-invalid.tmpl",
+ type => "opac",
+ query => $cgi,
+ authnotrequired => 1,
+ }
+ );
+}
+
+output_html_with_http_headers $cgi, $cookie, $template->output;
diff --git a/opac/opac-user.pl b/opac/opac-user.pl
index 05e8133d68..1c942d5bcd 100755
--- a/opac/opac-user.pl
+++ b/opac/opac-user.pl
@@ -368,7 +368,7 @@ $template->param(
$template->param( DHTMLcalendar_dateformat => C4::Dates->DHTMLcalendar() );
$template->param(
SuspendHoldsOpac => C4::Context->preference('SuspendHoldsOpac'),
- AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds') ,
+ AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
);
output_html_with_http_headers $query, $cookie, $template->output;
--
2.39.2