From 1861a80a8a0460a709123dc623fc44be5a0c0057 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 --- 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 ++++++++++ .../data/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 +++ .../prog/en/modules/admin/preferences/opac.pref | 34 + .../intranet-tmpl/prog/en/modules/intranet-main.tt | 12 +- .../prog/en/modules/members/members-update.tt | 140 ++++ .../opac-tmpl/prog/en/includes/opac-bottom.inc | 4 +- koha-tmpl/opac-tmpl/prog/en/includes/usermenu.inc | 2 +- koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt | 6 +- koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt | 2 + .../modules/opac-memberentry-update-submitted.tt | 29 + .../opac-tmpl/prog/en/modules/opac-memberentry.tt | 736 ++++++++++++++++++++ .../en/modules/opac-registration-confirmation.tt | 70 ++ .../en/modules/opac-registration-email-sent.tt | 31 + .../prog/en/modules/opac-registration-invalid.tt | 30 + mainpage.pl | 31 +- members/members-update-do.pl | 64 ++ members/members-update.pl | 65 ++ misc/cronjobs/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 705eda0..4ea03c0 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 71f35d4..16144f9 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 f646241..a585ff8 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 14448e3..671fcdb 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 f381a41..81b014b 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 0000000..f83b61d --- /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 6fa0a54..e6e9df0 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 ddf4b0f..ed673da 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 0cc5a54..2fb5bd4 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 39e4bde..8328192 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 2866f8d..bcf7124 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 4e91e06..e7363b0 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 @@
    [% IF ( ( CAN_user_tools_moderate_comments && pendingcomments ) || ( CAN_user_tools_moderate_tags && pendingtags ) + || ( CAN_user_borrowers && pending_borrower_modifications ) || ( CAN_user_acquisition && pendingsuggestions ) ) %]
    [% IF ( CAN_user_acquisition && pendingsuggestions ) %] @@ -130,9 +131,18 @@ [% pendingtags %]
    [% END %] + + + [% IF ( CAN_user_borrowers && pending_borrower_modifications ) %] +
    + Patrons requesting modifications: + [% pending_borrower_modifications %] +
    + [% END %] +
    - [% END %] + [% END %] [% IF ( IntranetmainUserblock ) %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/members-update.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/members-update.tt new file mode 100644 index 0000000..228ccf2 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/members-update.tt @@ -0,0 +1,140 @@ +[% INCLUDE 'doc-head-open.inc' %] +Koha › Patrons [% IF ( searching ) %]› Search results[% END %] +[% INCLUDE 'doc-head-close.inc' %] + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'patron-search.inc' %] + +[% + SET field_display_names = { + surname => "Surname" + firstname => "First name" + title => "Title" + othernames => "Other names" + initials => "Initials" + streetnumber => "Street number" + streettype => "Street type" + address => "Address" + address2 => "Address 2" + city => "City" + state => "State" + zipcode => "Zip code" + country => "Country" + email => "Email" + phone => "Primary Phone" + mobile => "Primary Mobile Phone" + fax => "Fax" + emailpro => "Secondary email" + phonepro => "Secondary phone" + B_streetnumber => "Alternate address - street number" + B_streettype => "Alternate address - street type" + B_address => "Alternate address" + B_address2 => "Alternate address 2" + B_city => "Alternate address - city" + B_state => "Alternate address - state" + B_zipcode => "Alternate address - zip code" + B_email => "Alternate address - email" + B_phone => "Alertnate address - phone" + dateofbirth => "Date of birth" + contactname => "Contact - last name" + contactfirstname=> "Contact - first name" + contacttitle => "Contact - title" + relationship => "Contact - relationship" + ethnicity => "Ethnicity" + ethnotes => "Ethnicity notes" + sex => "Sex" + altcontactfirstname => "Alternate contact - first name" + altcontactsurname => "Alternate contact - surname" + altcontactaddress1 => "Alternate contact - address" + altcontactaddress2 => "Alternate contact - address 2" + altcontactaddress3 => "Alternate contact - city" + altcontactstate => "Alternate contact - state" + altcontactzipcode => "Alternate contact - zip code" + altcontactcounty => "Alternate contact - county" + altcontactphone => "Alternate contact - phone" + smsalertnumber => "SMS alert number" + } +%] + + +
    + +
    +
    +
    +
    + [% IF PendingModifications %] +
    + + + + + + + + + + + + + + + + + + [% FOREACH pm IN PendingModifications %] + [% SET borrowernumber = pm.borrowernumber %] + + + + + + + + + + [% END %] + +
    ActionPatronChanges
    ApproveDenyIgnore
    + + + + + + + [% borrowers.$borrowernumber.firstname %] [% borrowers.$borrowernumber.surname %] + + + + + + + + + + [% FOREACH key IN pm.keys %] + [% IF field_display_names.$key %] + [% IF ( ( pm.$key OR borrowers.$borrowernumber.$key ) && ( pm.$key != borrowers.$borrowernumber.$key ) ) %] + + + + + + [% END %] + [% END %] + [% END %] +
    FieldFromTo
    [% field_display_names.$key %][% borrowers.$borrowernumber.$key %][% pm.$key %]
    +
    + +

    + +
    + [% ELSE %] +

    There are no pending patron modifications.

    + [% END %] +
    +
    +
    +
    +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/opac-tmpl/prog/en/includes/opac-bottom.inc b/koha-tmpl/opac-tmpl/prog/en/includes/opac-bottom.inc index 295eb5b..3df0221 100644 --- a/koha-tmpl/opac-tmpl/prog/en/includes/opac-bottom.inc +++ b/koha-tmpl/opac-tmpl/prog/en/includes/opac-bottom.inc @@ -1,7 +1,7 @@ [% IF ( opaccredits ) %]
    - [% opaccredits %] -
    + [% opaccredits %] +
    [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/includes/usermenu.inc b/koha-tmpl/opac-tmpl/prog/en/includes/usermenu.inc index 352d6b3..5a07d95 100644 --- a/koha-tmpl/opac-tmpl/prog/en/includes/usermenu.inc +++ b/koha-tmpl/opac-tmpl/prog/en/includes/usermenu.inc @@ -5,7 +5,7 @@ [% IF ( OPACFinesTab ) %] [% IF ( accountview ) %]
  • [% ELSE %]
  • [% END %]my fines
  • [% END %] - [% IF ( userupdateview ) %]
  • [% ELSE %]
  • [% END %]my personal details
  • + [% IF ( userupdateview ) %]
  • [% ELSE %]
  • [% END %]my personal details
  • [% IF ( TagsEnabled ) %] [% IF ( tagsview ) %]
  • [% ELSE %]
  • [% END %]my tags
  • [% 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 a73c8bb..6a6e1ee 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 cc67ff2..1ae7bf5 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 @@
  • + [% IF PatronSelfRegistration && PatronSelfRegistrationDefaultCategory %]
    Don't have an account? Register here.
    [% END %] +
    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 0000000..9183824 --- /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 0000000..ac2cb02 --- /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 %] + +
    + + [% UNLESS + hidden.defined('branchcode') + %] + +
    + + Library +
      + [% UNLESS hidden.defined('branchcode') %] +
    1. + [% IF mandatory.defined('branchcode') %] +
    2. + [% END %] +
    +
    + [% END %] + + [% UNLESS + hidden.defined('title') && hidden.defined('surname') && hidden.defined('firstname') && + hidden.defined('dateofbirth') && hidden.defined('initials') && hidden.defined('othernames') && + hidden.defined('sex') + %] +
    + Identity + +
      + [% UNLESS hidden.defined('title') %] +
    1. + [% IF mandatory.defined('title') %] +
    2. + [% END %] + + [% UNLESS hidden.defined('surname') %] +
    3. + [% IF mandatory.defined('surname') %] +
    4. + [% END %] + + [% UNLESS hidden.defined('firstname') %] +
    5. + [% IF mandatory.defined('firstname') %] +
    6. + [% END %] + + [% UNLESS hidden.defined('dateofbirth') %] +
    7. + [% IF mandatory.defined('dateofbirth') %] +
    8. + [% END %] + + [% UNLESS hidden.defined('initials') %] +
    9. + [% IF mandatory.defined('initials') %] +
    10. + [% END %] + + [% UNLESS hidden.defined('othernames') %] +
    11. + [% IF mandatory.defined('othernames') %] +
    12. + [% END %] + + [% UNLESS hidden.defined('sex') %] +
    13. + + [% IF borrower.sex == 'F' %] + + [% ELSE %] + + [% END %] + + + [% IF borrower.sex == 'M' %] + + [% ELSE %] + + [% END %] + + + [% IF borrower.sex == '' %] + + [% ELSE %] + + [% END %] + + [% IF mandatory.defined('sex') %]Required[% END %] +
    14. + [% END %] +
    +
    + [% END %] + + [% UNLESS + hidden.defined('streetnumber') && hidden.defined('address') && hidden.defined('address2') && + hidden.defined('city') && hidden.defined('state') && hidden.defined('zipcode') && + hidden.defined('country') + %] +
    + Main address + +
      + [% UNLESS hidden.defined('streetnumber') %] +
    1. + [% IF mandatory.defined('streetnumber') %] +
    2. + [% END %] + + [% UNLESS hidden.defined('address') %] +
    3. + [% IF mandatory.defined('address') %] +
    4. + [% END %] + + [% UNLESS hidden.defined('address2') %] +
    5. + [% IF mandatory.defined('address2') %] +
    6. + [% END %] + + [% UNLESS hidden.defined('city') %] +
    7. + [% IF mandatory.defined('city') %] +
    8. + [% END %] + + [% UNLESS hidden.defined('state') %] +
    9. + [% IF mandatory.defined('state') %] +
    10. + [% END %] + + [% UNLESS hidden.defined('zipcode') %] +
    11. + [% IF mandatory.defined('zipcode') %] +
    12. + [% END %] + + [% UNLESS hidden.defined('country') %] +
    13. + [% IF mandatory.defined('country') %] +
    14. + [% END %] + +
    +
    + [% END %] + + [% UNLESS + hidden.defined('phone') && hidden.defined('phonepro') && hidden.defined('mobile') && + hidden.defined('email') && hidden.defined('emailpro') && hidden.defined('fax') + %] +
    + Contact information + +
      + [% UNLESS hidden.defined('phone') %] +
    1. + [% IF mandatory.defined('phone') %] +
    2. + [% END %] + + [% UNLESS hidden.defined('phonepro') %] +
    3. + [% IF mandatory.defined('phonepro') %] +
    4. + [% END %] + + [% UNLESS hidden.defined('mobile') %] +
    5. + [% IF mandatory.defined('mobile') %] +
    6. + [% END %] + + [% UNLESS hidden.defined('email') %] +
    7. + [% IF mandatory.defined('email') %] +
    8. + [% END %] + + [% UNLESS hidden.defined('emailpro') %] +
    9. + [% IF mandatory.defined('emailpro') %] +
    10. + [% END %] + + [% UNLESS hidden.defined('fax') %] +
    11. + [% IF mandatory.defined('fax') %] +
    12. + [% END %] +
    +
    + [% END %] + + [% UNLESS + hidden.defined('B_address') && hidden.defined('B_address2') && hidden.defined('B_city') && + hidden.defined('B_state') && hidden.defined('B_zipcode') && hidden.defined('B_county') && + hidden.defined('B_phone') && hidden.defined('B_email') && hidden.defined('contactnote') + %] +
    + Alternate address + +
      + [% UNLESS hidden.defined('B_address') %] +
    1. + [% IF mandatory.defined('B_address') %] +
    2. + [% END %] + + [% UNLESS hidden.defined('B_address2') %] +
    3. + [% IF mandatory.defined('B_address2') %] +
    4. + [% END %] + + [% UNLESS hidden.defined('B_city') %] +
    5. + [% IF mandatory.defined('B_city') %] +
    6. + [% END %] + + [% UNLESS hidden.defined('B_state') %] +
    7. + [% IF mandatory.defined('B_state') %] +
    8. + [% END %] + + [% UNLESS hidden.defined('B_zipcode') %] +
    9. + [% IF mandatory.defined('B_zipcode') %] +
    10. + [% END %] + + [% UNLESS hidden.defined('B_country') %] +
    11. + [% IF mandatory.defined('B_country') %] +
    12. + [% END %] + + [% UNLESS hidden.defined('B_phone') %] +
    13. + [% IF mandatory.defined('B_phone') %] +
    14. + [% END %] + + [% UNLESS hidden.defined('B_email') %] +
    15. + [% IF mandatory.defined('B_email') %] +
    16. + [% END %] + + [% UNLESS hidden.defined('contactnote') %] +
    17. + [% IF mandatory.defined('contactnote') %] +
    18. + [% END %] + +
    +
    + [% END %] + + [% UNLESS + hidden.defined('altcontactsurname') && hidden.defined('altcontactfirstname') && hidden.defined('altcontactaddress1') && + hidden.defined('altcontactaddress2') && hidden.defined('altcontactaddress3') && hidden.defined('altcontactstate') && + hidden.defined('altcontactzipcode') && hidden.defined('altcontactcountry') && hidden.defined('altcontactphone') + %] +
    + Alternate contact + +
      + [% UNLESS hidden.defined('altcontactsurname') %] +
    1. + [% IF mandatory.defined('altcontactsurname') %] +
    2. + [% END %] + + [% UNLESS hidden.defined('altcontactfirstname') %] +
    3. + [% IF mandatory.defined('altcontactfirstname') %] +
    4. + [% END %] + + [% UNLESS hidden.defined('altcontactaddress1') %] +
    5. + [% IF mandatory.defined('altcontactaddress1') %] +
    6. + [% END %] + + [% UNLESS hidden.defined('altcontactaddress2') %] +
    7. + [% IF mandatory.defined('altcontactaddress2') %] +
    8. + [% END %] + + [% UNLESS hidden.defined('altcontactaddress3') %] +
    9. + [% IF mandatory.defined('altcontactaddress3') %] +
    10. + [% END %] + + [% UNLESS hidden.defined('altcontactstate') %] +
    11. + [% IF mandatory.defined('altcontactstate') %] +
    12. + [% END %] + + [% UNLESS hidden.defined('altcontactzipcode') %] +
    13. + [% IF mandatory.defined('altcontactzipcode') %] +
    14. + [% END %] + + [% UNLESS hidden.defined('altcontactcountry') %] +
    15. + [% IF mandatory.defined('altcontactcountry') %] +
    16. + [% END %] + + [% UNLESS hidden.defined('altcontactphone') %] +
    17. + [% IF mandatory.defined('altcontactphone') %] +
    18. + [% END %] +
    +
    + [% END %] + + [% UNLESS action == 'edit' %] +
    +
      +
    1. + + + + + + Please type this following characters into the preceding box: [% captcha %] +
    2. +
    +
    + [% END %] + + [% IF action == 'edit' %] + [% IF OPACPatronDetails %] + + + [% END %] + [% ELSE %] + + + [% 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 0000000..968faa0 --- /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:

    + +

    + Username: [% borrower.userid %] +
    + Password: [% password_cleartext %] +

    + +

    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 %].

    + +
    [% PatronSelfRegistrationAdditionalInstructions %]
    +
    + + [% IF ( opacuserlogin || OpacNavRight ) %] +
    + [% IF ( opacuserlogin ) %] + [% UNLESS ( loggedinusername ) %] + [% UNLESS ( casAuthentication ) %] +
    +
    + + +
    + Log in to your account: + +
      +
    1. +
    2. +
    + +
    + +
    +
    +
    +
    + [% 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 0000000..bdad739 --- /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 0000000..12dac1d --- /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 78daf38..9085630 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 0000000..e7b7b28 --- /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 0000000..334d83b --- /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 0000000..86f47c5 --- /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 0000000..62816d5 --- /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 0000000..20ec9db --- /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 0000000..682dacb --- /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 05e8133..1c942d5 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; -- 1.7.9.5