Ensure a default FROM address is used when sending email confirmations
authoreileen <emcnaughton@wikimedia.org>
Fri, 18 Oct 2019 22:27:23 +0000 (11:27 +1300)
committereileen <emcnaughton@wikimedia.org>
Fri, 18 Oct 2019 23:46:33 +0000 (12:46 +1300)
CRM/Contribute/Form/AdditionalPayment.php
CRM/Core/BAO/MessageTemplate.php
CRM/Financial/BAO/Payment.php
api/v3/Payment.php
tests/phpunit/CRM/Contribute/Form/AdditionalPaymentTest.php
tests/phpunit/api/v3/PaymentTest.php

index 10219870fc62503ee79ae3dab2d31bbad4e5d8d3..7dfac4da9449e641df6234149ecca913c0333298 100644 (file)
@@ -67,8 +67,6 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
 
   protected $fromEmailId = NULL;
 
-  protected $_fromEmails = NULL;
-
   protected $_view = NULL;
 
   public $_action = NULL;
@@ -94,18 +92,14 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
       CRM_Utils_System::setTitle($title);
       return;
     }
-    $this->_fromEmails = CRM_Core_BAO_Email::getFromEmail();
-
     $entityType = 'contribution';
     if ($this->_component == 'event') {
       $entityType = 'participant';
       $this->_contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_id, 'contribution_id', 'participant_id');
       $eventId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_id, 'event_id', 'id');
-      $this->_fromEmails = CRM_Event_BAO_Event::getFromEmailIds($eventId);
     }
     else {
       $this->_contributionId = $this->_id;
-      $this->_fromEmails['from_email_id'] = CRM_Core_BAO_Email::getFromEmail();
     }
 
     $paymentInfo = CRM_Core_BAO_FinancialTrxn::getPartialPaymentWithType($this->_id, $entityType);
@@ -222,7 +216,11 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
     //add receipt for offline contribution
     $this->addElement('checkbox', 'is_email_receipt', ts('Send Receipt?'));
 
-    $this->add('select', 'from_email_address', ts('Receipt From'), $this->_fromEmails['from_email_id']);
+    if ($this->_component === 'event') {
+      $eventID = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_id, 'event_id', 'id');
+    }
+
+    $this->add('select', 'from_email_address', ts('Receipt From'), CRM_Financial_BAO_Payment::getValidFromEmailsForPayment($eventID));
 
     $this->add('textarea', 'receipt_text', ts('Confirmation Message'));
 
@@ -330,8 +328,10 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
 
   /**
    * Process Payments.
+   *
    * @param array $submittedValues
    *
+   * @throws \CiviCRM_API3_Exception
    */
   public function submit($submittedValues) {
     $this->_params = $submittedValues;
@@ -375,7 +375,7 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
     $statusMsg = ts('The payment record has been processed.');
     // send email
     if (!empty($paymentID) && !empty($this->_params['is_email_receipt'])) {
-      $sendResult = civicrm_api3('Payment', 'sendconfirmation', ['id' => $paymentID])['values'][$paymentID];
+      $sendResult = civicrm_api3('Payment', 'sendconfirmation', ['id' => $paymentID, 'from' => $submittedValues['from_email_address']])['values'][$paymentID];
       if ($sendResult['is_sent']) {
         $statusMsg .= ' ' . ts('A receipt has been emailed to the contributor.');
       }
index 4b81879706d30b8f65adb8c8e3bf30afd1379a55..3c28a5a4aea4e4fe6a1831dd620a8330e02337cd 100644 (file)
@@ -385,7 +385,7 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate {
     ];
     $params = array_merge($defaults, $params);
 
-    // Core#644 - handle contact ID passed as "From".
+    // Core#644 - handle Email ID passed as "From".
     if (isset($params['from'])) {
       $params['from'] = CRM_Utils_Mail::formatFromAddress($params['from']);
     }
index ccc65c2dd83206ad12998df80a81d4beeec053af..ac9e83b521aa0a69d804ee48278f5c3e4f063426 100644 (file)
@@ -196,9 +196,35 @@ class CRM_Financial_BAO_Payment {
       'toEmail' => $entities['contact']['email'],
       'tplParams' => self::getConfirmationTemplateParameters($entities),
     ];
+    if (!empty($params['from']) && !empty($params['check_permissions'])) {
+      // Filter from against permitted emails.
+      $validEmails = self::getValidFromEmailsForPayment($entities['event']['id'] ?? NULL);
+      if (!isset($validEmails[$params['from']])) {
+        // Ignore unpermitted parameter.
+        unset($params['from']);
+      }
+    }
+    $sendTemplateParams['from'] = $params['from'] ?? key(CRM_Core_BAO_Email::domainEmails());
     return CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
   }
 
+  /**
+   * Get valid from emails for payment.
+   *
+   * @param int $eventID
+   *
+   * @return array
+   */
+  public static function getValidFromEmailsForPayment($eventID = NULL) {
+    if ($eventID) {
+      $emails = CRM_Event_BAO_Event::getFromEmailIds($eventID);
+    }
+    else {
+      $emails['from_email_id'] = CRM_Core_BAO_Email::getFromEmail();
+    }
+    return $emails['from_email_id'];
+  }
+
   /**
    * Load entities related to the current payment id.
    *
index 4ec6647c22d3aa4f455d7588f9debd577e4f0bde..cdbfbc98c20e88e19909783fb7c1974ffe9a7817 100644 (file)
@@ -273,12 +273,9 @@ function _civicrm_api3_payment_cancel_spec(&$params) {
  */
 function civicrm_api3_payment_sendconfirmation($params) {
   $allowedParams = [
-    'receipt_from_email',
-    'receipt_from_name',
-    'cc_receipt',
-    'bcc_receipt',
-    'receipt_text',
+    'from',
     'id',
+    'check_permissions',
   ];
   $input = array_intersect_key($params, array_flip($allowedParams));
   // use either the contribution or membership receipt, based on whether it’s a membership-related contrib or not
@@ -307,4 +304,8 @@ function _civicrm_api3_payment_sendconfirmation_spec(&$params) {
     'title' => ts('Payment ID'),
     'type' => CRM_Utils_Type::T_INT,
   ];
+  $params['from_email_address'] = [
+    'title' => ts('From email; an email string or the id of a valid email'),
+    'type' => CRM_Utils_Type::T_STRING,
+  ];
 }
index 48973291f848deb483f482690a2981a09e3aa5ca..0f294a7b868344862bcb5dfc60ded4ca42925164 100644 (file)
@@ -138,6 +138,7 @@ class CRM_Contribute_Form_AdditionalPaymentTest extends CiviUnitTestCase {
     $this->checkResults([30, 70], 2);
     $mut->assertSubjects(['Payment Receipt -']);
     $mut->checkMailLog([
+      'From: site@something.com',
       'Dear Anthony,',
       'Payment Details',
       'Total Fees: $ 100.00',
index d1dfd72357103b7cacc19cca4c75c63e865d189b..69f237428843ffef608cee212c0e3231dac59175 100644 (file)
@@ -181,6 +181,7 @@ class api_v3_PaymentTest extends CiviUnitTestCase {
     $this->callAPISuccess('Payment', 'sendconfirmation', ['id' => $payment['id']]);
     $mut->assertSubjects(['Payment Receipt - Annual CiviCRM meet']);
     $mut->checkMailLog([
+      'From: "FIXME" <info@EXAMPLE.ORG>',
       'Dear Anthony,',
       'Total Fees: $ 300.00',
       'This Payment Amount: $ 50.00',
@@ -204,6 +205,7 @@ class api_v3_PaymentTest extends CiviUnitTestCase {
    */
   public function testPaymentEmailReceiptFullyPaid() {
     $mut = new CiviMailUtils($this);
+    CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviContribute', 'edit contributions', 'access CiviCRM'];
     list($lineItems, $contribution) = $this->createParticipantWithContribution();
 
     $params = [
@@ -212,9 +214,12 @@ class api_v3_PaymentTest extends CiviUnitTestCase {
     ];
     $payment = $this->callAPISuccess('payment', 'create', $params);
 
-    $this->callAPISuccess('Payment', 'sendconfirmation', ['id' => $payment['id']]);
+    // Here we set the email to an  invalid email & use check_permissions, domain email should be used.
+    $email = $this->callAPISuccess('Email', 'create', ['contact_id' => 1, 'email' => 'bob@example.com']);
+    $this->callAPISuccess('Payment', 'sendconfirmation', ['id' => $payment['id'], 'from' => $email['id'], 'check_permissions' => 1]);
     $mut->assertSubjects(['Payment Receipt - Annual CiviCRM meet', 'Registration Confirmation - Annual CiviCRM meet']);
     $mut->checkMailLog([
+      'From: "FIXME" <info@EXAMPLE.ORG>',
       'Dear Anthony,',
       'A payment has been received.',
       'Total Fees: $ 300.00',