From fe52b4f60ce2c21fdd13e89dc4152241b564741e Mon Sep 17 00:00:00 2001
From: David Bourgault <david.bourgault@inlibro.com>
Date: Fri, 15 Sep 2017 15:06:13 -0400
Subject: [PATCH] Bug 8000: Redirect all emails to SendAllEmailsTo

Rebased and squashed after changes to master.
Only difference from previous patches are small adjustements to conflicts in t/db_dependent/Letters.t

Test plan:

1) Apply path
2) Run updatedatabase.pl
3) Clear all SendAllEmailsTo system preference
4) Send mail to a patron of your choosing, email will go to patron's
   email address as usual.
5) Set SendAllEmailsTo to a test email address
6) Send mail to the patron, email will be redirected to the email set
   in the systempreference.
7) Run prove -v t/db_dependent/Letters.t

It does not affect messages in the message_queue.

This patch obsoletes previous patches, because it achieves the same
functionality in a much more centralized way. (4 lines of code!)

Signed-off-by: Ed Veal <eveal@mckinneytexas.org>
Signed-off-by: BWS Sandboxes <ByWaterSandboxes@gmail.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Josef Moravec <josef.moravec@gmail.com>
---
 C4/Letters.pm                                       | 21 ++++++++++++---------
 Koha/Email.pm                                       |  9 +++++++++
 .../Bug8000-SendAllEmailsTo.syspref.sql             |  2 ++
 installer/data/mysql/sysprefs.sql                   |  3 ++-
 .../prog/en/modules/admin/preferences/admin.pref    |  5 +++++
 t/db_dependent/Letters.t                            | 13 ++++++++++++-
 6 files changed, 42 insertions(+), 11 deletions(-)
 create mode 100644 installer/data/mysql/atomicupdate/Bug8000-SendAllEmailsTo.syspref.sql

diff --git a/C4/Letters.pm b/C4/Letters.pm
index 4954067..71c3a02 100644
--- a/C4/Letters.pm
+++ b/C4/Letters.pm
@@ -480,18 +480,21 @@ sub SendAlerts {
 
         # ... then send mail
         my $library = Koha::Libraries->find( $userenv->{branch} );
-        my %mail = (
-            To => join( ',', @email),
-            Cc             => join( ',', @cc),
-            From           => $library->branchemail || C4::Context->preference('KohaAdminEmailAddress'),
-            Subject        => Encode::encode( "UTF-8", "" . $letter->{title} ),
-            Message => $letter->{'is_html'}
+        my $email = Koha::Email->new();
+        my %mail = $email->create_message_headers(
+            {
+                to      => join( ',', @email),
+                cc      => join( ',', @cc),
+                from    => $library->branchemail || C4::Context->preference('KohaAdminEmailAddress'),
+                subject => Encode::encode( "UTF-8", "" . $letter->{title} ),
+                message => $letter->{'is_html'}
                             ? _wrap_html( Encode::encode( "UTF-8", $letter->{'content'} ),
                                           Encode::encode( "UTF-8", "" . $letter->{'title'} ))
                             : Encode::encode( "UTF-8", "" . $letter->{'content'} ),
-            'Content-Type' => $letter->{'is_html'}
+                contenttype => $letter->{'is_html'}
                                 ? 'text/html; charset="utf-8"'
                                 : 'text/plain; charset="utf-8"',
+            }
         );
 
         if ($type eq 'claimacquisition' || $type eq 'claimissues' ) {
@@ -500,7 +503,7 @@ sub SendAlerts {
             $mail{'Sender'} = C4::Context->preference('ReturnpathDefault')
               if C4::Context->preference('ReturnpathDefault');
             $mail{'Bcc'} = $userenv->{emailaddress}
-              if C4::Context->preference("ClaimsBccCopy");
+              if C4::Context->preference("ClaimsBccCopy") and not C4::Context->preference("SendAllEmailsTo");
         }
 
         unless ( Mail::Sendmail::sendmail(%mail) ) {
@@ -1305,7 +1308,7 @@ sub _send_message_by_email {
 
     $sendmail_params{'Auth'} = {user => $username, pass => $password, method => $method} if $username;
     if ( my $bcc = C4::Context->preference('NoticeBcc') ) {
-       $sendmail_params{ Bcc } = $bcc;
+       $sendmail_params{ Bcc } = C4::Context->preference("SendAllEmailsTo") || $bcc;
     }
 
     _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
diff --git a/Koha/Email.pm b/Koha/Email.pm
index fc392a3..b9e3241 100644
--- a/Koha/Email.pm
+++ b/Koha/Email.pm
@@ -18,6 +18,7 @@
 package Koha::Email;
 
 use Modern::Perl;
+use Email::Valid;
 
 use base qw(Class::Accessor);
 use C4::Context;
@@ -49,6 +50,14 @@ sub create_message_headers {
         From    => $params->{from},
         charset => $params->{charset}
     );
+
+    if (C4::Context->preference('SendAllEmailsTo') && Email::Valid->address(C4::Context->preference('SendAllEmailsTo'))) {
+        $mail{'To'} = C4::Context->preference('SendAllEmailsTo');
+    }
+    else {
+        $mail{'Cc'} = $params->{cc};
+    }
+
     if ( C4::Context->preference('ReplytoDefault') ) {
         $params->{replyto} ||= C4::Context->preference('ReplytoDefault');
     }
diff --git a/installer/data/mysql/atomicupdate/Bug8000-SendAllEmailsTo.syspref.sql b/installer/data/mysql/atomicupdate/Bug8000-SendAllEmailsTo.syspref.sql
new file mode 100644
index 0000000..37bdb9c
--- /dev/null
+++ b/installer/data/mysql/atomicupdate/Bug8000-SendAllEmailsTo.syspref.sql
@@ -0,0 +1,2 @@
+INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type)
+VALUES ('SendAllEmailsTo','',NULL,'All emails will be redirected to this email if it is not empty','free');
\ No newline at end of file
diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql
index 0f86627..58b1a5f 100644
--- a/installer/data/mysql/sysprefs.sql
+++ b/installer/data/mysql/sysprefs.sql
@@ -1,4 +1,4 @@
-INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type('SendAllEmailsTo','',NULL,'All emails will be redirected to this email if it is not empty','free'),` ) VALUES
 ('AcqCreateItem','ordering','ordering|receiving|cataloguing','Define when the item is created : when ordering, when receiving, or in cataloguing module','Choice'),
 ('AcqEnableFiles','0',NULL,'If enabled, allows librarians to upload and attach arbitrary files to invoice records.','YesNo'),
 ('AcqItemSetSubfieldsWhenReceiptIsCancelled','', '','Upon cancelling a receipt, update the items subfields if they were created when placing an order (e.g. o=5|a="bar foo")', 'Free'),
@@ -504,6 +504,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
 ('SelfCheckoutByLogin','1',NULL,'Have patrons login into the web-based self checkout system with their username/password or their cardnumber','YesNo'),
 ('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,'All emails will be redirected to this email if it is not empty','free'),
 ('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 2e8dce7..aa0a211 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
@@ -16,6 +16,11 @@ Administration:
               class: email
             - "If you leave this empty, the From address will be used (often defaulting to the admin address)."
         -
+            - "Email to redirect all messages to: "
+            - pref: SendAllEmailsTo
+              class: email
+            - "(Leave this field empty to send messages to their normal recipient)"
+        -
             - "How much debugging information to show in the browser when an internal error occurs: "
             - pref: DebugLevel
               default: 0
diff --git a/t/db_dependent/Letters.t b/t/db_dependent/Letters.t
index a664918..93c503e 100644
--- a/t/db_dependent/Letters.t
+++ b/t/db_dependent/Letters.t
@@ -18,7 +18,7 @@
 # along with Koha; if not, see <http://www.gnu.org/licenses>.
 
 use Modern::Perl;
-use Test::More tests => 65;
+use Test::More tests => 67;
 use Test::MockModule;
 use Test::Warn;
 
@@ -240,6 +240,7 @@ is( $letter14206_c->{message_transport_type}, 'print', 'Bug 14206 - correct mtt
 
 # GetPreparedLetter
 t::lib::Mocks::mock_preference('OPACBaseURL', 'http://thisisatest.com');
+t::lib::Mocks::mock_preference( 'SendAllEmailsTo', '' );
 
 my $sms_content = 'This is a SMS for an <<status>>';
 $dbh->do( q|INSERT INTO letter(branchcode,module,code,name,is_html,title,content,message_transport_type) VALUES (?,'my module','my code','my name',1,'my title',?,'sms')|, undef, $library->{branchcode}, $sms_content );
@@ -488,7 +489,17 @@ $err2 = SendAlerts( 'issue', $serial->{serialid}, 'RLIST' ) }
 is($err2, 1, "Successfully sent serial notification");
 is($mail{'To'}, 'john.smith@test.de', "mailto correct in sent serial notification");
 is($mail{'Message'}, 'Silence in the library,'.$subscriptionid.',No. 0', 'Serial notification text constructed successfully');
+
+t::lib::Mocks::mock_preference( 'SendAllEmailsTo', 'robert.tables@mail.com' );
+
+my $err3;
+warning_is {
+$err3 = SendAlerts( 'issue', $serial->{serialid}, 'RLIST' ) }
+    "Fake sendmail",
+    "SendAlerts is using the mocked sendmail routine";
+is($mail{'To'}, 'robert.tables@mail.com', "mailto address overwritten by SendAllMailsTo preference");
 }
+t::lib::Mocks::mock_preference( 'SendAllEmailsTo', '' );
 
 subtest 'SendAlerts - claimissue' => sub {
     plan tests => 8;
-- 
2.1.4