From d384ccb4d65b4dba1e23ba400dcfc428b08185dc Mon Sep 17 00:00:00 2001 From: charles Date: Wed, 6 Apr 2016 11:28:04 -0400 Subject: [PATCH] Bug 8000 - Override emails of every message sent from Koha For testing purposes, we do not want emails sent to (legitimate) users. And sometime we also like to actually see what would be generated for the users. This preference will allow to override every message sent by koha with a new (temporary) To address. Leave it empty for normal usage. C4/Letters.pm installer/data/mysql/sysprefs.sql installer/data/mysql/updatedatabase.pl koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref TESTING: 0) Run updatedatabase.pl 1) Enter a valid address for new preference SendAllEmailsTo, something that will be easily identified as NOT the normal destination for the Koha emails. 2) Have koha generate an email to a user. Or any other mean prefered that cause Koha to send email. 3) Validate that the email is NOT sent to the user. 4) Validate that the email IS sent to the overriding address. 5) Clean the preference 6) Redo the test, validate that the email is going to the right address. PS Not sure if those steps are precise enough. Here's one way: a) set AutoEmailOpacUser to true b) create a new user, with an email address c) Normally, a confirmation email is sent to the user. Validate that it goes to the SendAllEmailsTo one. --- C4/Installer/PerlDependencies.pm | 5 ++ C4/Letters.pm | 55 +++++++++++++++++----- basket/sendbasket.pl | 3 ++ .../atomicupdate/bz8000_TestModeForNotices.sql | 6 +++ installer/data/mysql/kohastructure.sql | 1 + installer/data/mysql/sysprefs.sql | 1 + .../prog/en/modules/admin/preferences/admin.pref | 5 ++ misc/cronjobs/runreport.pl | 3 ++ opac/opac-sendbasket.pl | 3 ++ opac/opac-sendshelf.pl | 3 ++ virtualshelves/sendshelf.pl | 3 ++ 11 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bz8000_TestModeForNotices.sql diff --git a/C4/Installer/PerlDependencies.pm b/C4/Installer/PerlDependencies.pm index 5e2f22f..81582c7 100644 --- a/C4/Installer/PerlDependencies.pm +++ b/C4/Installer/PerlDependencies.pm @@ -787,6 +787,11 @@ our $PERL_DEPS = { 'required' => '0', 'min_ver' => '0.56', }, + 'Data::Validate::Email' => { + 'usage' => 'Email validation', + 'required' => '1', + 'min_ver' => '0.04', + }, }; 1; diff --git a/C4/Letters.pm b/C4/Letters.pm index f327890..5fea90d 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -38,6 +38,8 @@ use Encode; use Carp; use Koha::Email; use Koha::DateUtils qw( format_sqldatetime ); +use Data::Validate::Email qw(is_email); +use Email::Valid; use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); @@ -414,7 +416,11 @@ sub SendAlerts { my $alerts = getalert( '', 'issue', $subscriptionid ); foreach (@$alerts) { my $borinfo = C4::Members::GetMember('borrowernumber' => $_->{'borrowernumber'}); - my $email = $borinfo->{email} or next; + my $sendAllEmailsTo = C4::Context->preference('SendAllEmailsTo'); + my $email = $sendAllEmailsTo; + if (!($sendAllEmailsTo && Email::Valid->address($sendAllEmailsTo))){ + $email = $borinfo->{email} or next; + } # warn "sending issues..."; my $userenv = C4::Context->userenv; @@ -528,10 +534,19 @@ sub SendAlerts { # Remove the order tag $letter->{content} =~ s/(.*?)<\/order>/$1/gxms; + # SendAllEmailsTo system preference to override for testing + my $emailsTo = join( ',', @email); + my $emailsCC = join( ',', @cc); + my $sendAllEmailsTo = C4::Context->preference('SendAllEmailsTo'); + if ($sendAllEmailsTo && Email::Valid->address($sendAllEmailsTo) ) { + $emailsTo = $sendAllEmailsTo; + $emailsCC = ''; + } + # ... then send mail my %mail = ( - To => join( ',', @email), - Cc => join( ',', @cc), + To => $emailsTo, + Cc => $emailsCC, From => $userenv->{emailaddress}, Subject => Encode::encode( "UTF-8", "" . $letter->{title} ), Message => $letter->{'is_html'} @@ -583,9 +598,12 @@ sub SendAlerts { ) or return; return { error => "no_email" } unless $externalid->{'emailaddr'}; my $email = Koha::Email->new(); + my $emailaddr = $externalid->{'emailaddr'}; + my $sendAllEmailsTo = C4::Context->preference('SendAllEmailsTo'); + $emailaddr = $sendAllEmailsTo if ($sendAllEmailsTo && Email::Valid->address($sendAllEmailsTo) ); my %mail = $email->create_message_headers( { - to => $externalid->{'emailaddr'}, + to => $emailaddr, from => $library->{branchemail}, replyto => $library->{branchreplyto}, sender => $library->{branchreturnpath}, @@ -1049,7 +1067,7 @@ sub GetQueuedMessages { my $dbh = C4::Context->dbh(); my $statement = << 'ENDSQL'; -SELECT message_id, borrowernumber, subject, content, message_transport_type, status, time_queued +SELECT message_id, borrowernumber, subject, content, message_transport_type, status, time_queued, sentto_address FROM message_queue ENDSQL @@ -1228,15 +1246,19 @@ sub _send_message_by_email { my $member = C4::Members::GetMember( 'borrowernumber' => $message->{'borrowernumber'} ); my $to_address = $message->{'to_address'}; + if (!$to_address && $member) { + $to_address = C4::Members::GetNoticeEmailAddress( $message->{'borrowernumber'} ); + } + my $sendAllEmailsTo = C4::Context->preference('SendAllEmailsTo'); + $to_address = $sendAllEmailsTo if ($sendAllEmailsTo && Email::Valid->address($sendAllEmailsTo) ); unless ($to_address) { - unless ($member) { + if (!$member) { warn "FAIL: No 'to_address' and INVALID borrowernumber ($message->{borrowernumber})"; _set_message_status( { message_id => $message->{'message_id'}, status => 'failed' } ); return; } - $to_address = C4::Members::GetNoticeEmailAddress( $message->{'borrowernumber'} ); - unless ($to_address) { + else { # warn "FAIL: No 'to_address' and no email for " . ($member->{surname} ||'') . ", borrowernumber ($message->{borrowernumber})"; # warning too verbose for this more common case? _set_message_status( { message_id => $message->{'message_id'}, @@ -1281,8 +1303,9 @@ sub _send_message_by_email { _update_message_to_address($message->{'message_id'},$to_address) unless $message->{to_address}; #if initial message address was empty, coming here means that a to address was found and queue should be updated if ( sendmail( %sendmail_params ) ) { - _set_message_status( { message_id => $message->{'message_id'}, - status => 'sent' } ); + _set_message_status( { message_id => $message->{'message_id'}, + status => 'sent', + sentto_address => $to_address } ); return 1; } else { _set_message_status( { message_id => $message->{'message_id'}, @@ -1366,11 +1389,17 @@ sub _set_message_status { return unless exists $params->{ $required_parameter }; } - my $dbh = C4::Context->dbh(); my $statement = 'UPDATE message_queue SET status= ? WHERE message_id = ?'; + my @values; + push @values,$params->{'status'}; + if (exists($params->{'sentto_address'})) { + $statement = 'UPDATE message_queue SET status=?, sentto_address=? WHERE message_id = ?'; + push @values,$params->{'sentto_address'}; + } + push @values,$params->{'message_id'}; + my $dbh = C4::Context->dbh(); my $sth = $dbh->prepare( $statement ); - my $result = $sth->execute( $params->{'status'}, - $params->{'message_id'} ); + my $result = $sth->execute( @values ); return $result; } diff --git a/basket/sendbasket.pl b/basket/sendbasket.pl index 254d9ff..e2e7fa3 100755 --- a/basket/sendbasket.pl +++ b/basket/sendbasket.pl @@ -31,6 +31,7 @@ use C4::Auth; use C4::Output; use C4::Biblio; use Koha::Email; +use Email::Valid; my $query = new CGI; @@ -45,7 +46,9 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user ( ); my $bib_list = $query->param('bib_list'); +my $sendAllEmailsTo = C4::Context->preference('SendAllEmailsTo'); my $email_add = $query->param('email_add'); +$email_add = $sendAllEmailsTo if ($sendAllEmailsTo && Email::Valid->address($sendAllEmailsTo) ); my $dbh = C4::Context->dbh; diff --git a/installer/data/mysql/atomicupdate/bz8000_TestModeForNotices.sql b/installer/data/mysql/atomicupdate/bz8000_TestModeForNotices.sql new file mode 100644 index 0000000..c59f3ac --- /dev/null +++ b/installer/data/mysql/atomicupdate/bz8000_TestModeForNotices.sql @@ -0,0 +1,6 @@ +-- SYSPREF +INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) +VALUES ('SendAllEmailsTo','',NULL,'This email will replace the To address in every message sent by the system. This is meant to help testing and validation only.','Textarea'); + +-- SCHEMA +ALTER TABLE message_queue ADD sentto_address mediumtext AFTER to_address; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 63fefe7..d83e913 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -2599,6 +2599,7 @@ CREATE TABLE `message_queue` ( `status` enum('sent','pending','failed','deleted') NOT NULL default 'pending', `time_queued` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, `to_address` mediumtext, + `sentto_address` mediumtext, `from_address` mediumtext, `content_type` text, PRIMARY KEY `message_id` (`message_id`), diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index e2e3ad2..2ee1097 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -418,6 +418,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('SelfCheckHelpMessage','','70|10','Enter HTML to include under the basic Web-based Self Checkout instructions on the Help page','Textarea'), ('SelfCheckReceiptPrompt','1','NULL','If ON, print receipt dialog pops up when self checkout is finished','YesNo'), ('SelfCheckTimeout','120','','Define the number of seconds before the Web-based Self Checkout times out a patron','Integer'), +('SendAllEmailsTo','',NULL,'This email will replace the To address in every message sent by the system. This is meant to help testing only.','Textarea'), ('SeparateHoldings','0',NULL,'Separate current branch holdings from other holdings','YesNo'), ('SeparateHoldingsBranch','homebranch','homebranch|holdingbranch','Branch used to separate holdings','Choice'), ('SessionRestrictionByIP','1','Check for change in remote IP address for session security. Disable only when remote IP address changes frequently.','','YesNo'), diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref index 0f3b66c..73e83a4 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref @@ -71,6 +71,11 @@ Administration: yes: "logged in library's" no: "all libraries" - rules by default. + - + - Redirect all emails from Koha to + - pref: SendAllEmailsTo + class: email + - instead of their intended user. Login options: - - Automatically log out users after diff --git a/misc/cronjobs/runreport.pl b/misc/cronjobs/runreport.pl index 4602fe7..fe1af4f 100755 --- a/misc/cronjobs/runreport.pl +++ b/misc/cronjobs/runreport.pl @@ -34,6 +34,7 @@ use Text::CSV_XS; use CGI qw ( -utf8 ); use Carp; use Encode; +use Email::Valid; BEGIN { # find Koha's Perl modules @@ -208,6 +209,8 @@ if ($to or $from or $email) { $from or $from = C4::Context->preference('KohaAdminEmailAddress'); $to or $to = C4::Context->preference('KohaAdminEmailAddress'); } +my $sendAllEmailsTo = C4::Context->preference('SendAllEmailsTo'); +$to = $sendAllEmailsTo if ($sendAllEmailsTo && Email::Valid->address($sendAllEmailsTo) ); unless (scalar(@ARGV)) { print STDERR "ERROR: No reportID(s) specified\n"; diff --git a/opac/opac-sendbasket.pl b/opac/opac-sendbasket.pl index 97b64fd..945051b 100755 --- a/opac/opac-sendbasket.pl +++ b/opac/opac-sendbasket.pl @@ -34,6 +34,7 @@ use C4::Output; use C4::Biblio; use C4::Members; use Koha::Email; +use Email::Valid; my $query = new CGI; @@ -47,7 +48,9 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user ( ); my $bib_list = $query->param('bib_list'); +my $sendAllEmailsTo = C4::Context->preference('SendAllEmailsTo'); my $email_add = $query->param('email_add'); +$email_add = $sendAllEmailsTo if ($sendAllEmailsTo && Email::Valid->address($sendAllEmailsTo) ); my $dbh = C4::Context->dbh; diff --git a/opac/opac-sendshelf.pl b/opac/opac-sendshelf.pl index a0682bc..f02046a 100755 --- a/opac/opac-sendshelf.pl +++ b/opac/opac-sendshelf.pl @@ -34,6 +34,7 @@ use C4::Output; use C4::Members; use Koha::Email; use Koha::Virtualshelves; +use Email::Valid; my $query = new CGI; @@ -53,7 +54,9 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user ( ); my $shelfid = $query->param('shelfid'); +my $sendAllEmailsTo = C4::Context->preference('SendAllEmailsTo'); my $email = $query->param('email'); +$email = $sendAllEmailsTo if ($sendAllEmailsTo && Email::Valid->address($sendAllEmailsTo) ); my $dbh = C4::Context->dbh; diff --git a/virtualshelves/sendshelf.pl b/virtualshelves/sendshelf.pl index 02999ea..dc24c30 100755 --- a/virtualshelves/sendshelf.pl +++ b/virtualshelves/sendshelf.pl @@ -33,6 +33,7 @@ use C4::Items; use C4::Output; use Koha::Email; use Koha::Virtualshelves; +use Email::Valid; my $query = new CGI; @@ -47,7 +48,9 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( ); my $shelfid = $query->param('shelfid'); +my $sendAllEmailsTo = C4::Context->preference('SendAllEmailsTo'); my $email = $query->param('email'); +$email = $sendAllEmailsTo if ($sendAllEmailsTo && Email::Valid->address($sendAllEmailsTo) ); my $dbh = C4::Context->dbh; -- 1.9.1