[REF] move all functions associated with the submit function onto the Trait
authoreileen <emcnaughton@wikimedia.org>
Wed, 1 Apr 2020 03:52:20 +0000 (16:52 +1300)
committereileen <emcnaughton@wikimedia.org>
Sun, 12 Apr 2020 21:44:06 +0000 (09:44 +1200)
CRM/Contact/Form/Task/EmailCommon.php
CRM/Contact/Form/Task/EmailTrait.php
tests/phpunit/CRM/Contact/Form/Task/EmailCommonTest.php

index 6edee67c09175d41e93212c9b4efd1ee63e59d08..1244b44f3a0db7d23f2d55c09b09349e48e98bbf 100644 (file)
@@ -356,6 +356,8 @@ class CRM_Contact_Form_Task_EmailCommon {
    * @throws \Civi\API\Exception\UnauthorizedException
    */
   public static function postProcess(&$form) {
+    CRM_Core_Error::deprecatedFunctionWarning('This code is no longer used in core and will be removed');
+
     self::bounceIfSimpleMailLimitExceeded(count($form->_contactIds));
 
     // check and ensure that
@@ -376,6 +378,8 @@ class CRM_Contact_Form_Task_EmailCommon {
    * @throws \Civi\API\Exception\UnauthorizedException
    */
   public static function submit(&$form, $formValues) {
+    CRM_Core_Error::deprecatedFunctionWarning('This code is no longer used in core and will be removed');
+
     self::saveMessageTemplate($formValues);
 
     $from = $formValues['from_email_address'] ?? NULL;
@@ -559,6 +563,8 @@ class CRM_Contact_Form_Task_EmailCommon {
    * @throws \Civi\API\Exception\UnauthorizedException
    */
   protected static function saveMessageTemplate($formValues) {
+    CRM_Core_Error::deprecatedFunctionWarning('This code is no longer used in core and will be removed');
+
     if (!empty($formValues['saveTemplate']) || !empty($formValues['updateTemplate'])) {
       $messageTemplate = [
         'msg_text' => $formValues['text_message'],
@@ -587,6 +593,8 @@ class CRM_Contact_Form_Task_EmailCommon {
    *  The number of emails the user is attempting to send
    */
   public static function bounceIfSimpleMailLimitExceeded($count) {
+    CRM_Core_Error::deprecatedFunctionWarning('This code is no longer used in core and will be removed');
+
     $limit = Civi::settings()->get('simple_mail_limit');
     if ($count > $limit) {
       CRM_Core_Error::statusBounce(ts('Please do not use this task to send a lot of emails (greater than %1). Many countries have legal requirements when sending bulk emails and the CiviMail framework has opt out functionality and domain tokens to help meet these.',
@@ -603,6 +611,8 @@ class CRM_Contact_Form_Task_EmailCommon {
    * @return array
    */
   protected static function getEmails($element): array {
+    CRM_Core_Error::deprecatedFunctionWarning('This code is no longer used in core and will be removed');
+
     $allEmails = explode(',', $element->getValue());
     $return = [];
     foreach ($allEmails as $value) {
index 3a6076709e3104f94d9e5b64337288ed915fe757..fd24e0423c845687c46c7271dbb814a8b3cc6992 100644 (file)
@@ -145,7 +145,7 @@ trait CRM_Contact_Form_Task_EmailTrait {
     if (count($this->_contactIds) > 1) {
       $this->_single = FALSE;
     }
-    CRM_Contact_Form_Task_EmailCommon::bounceIfSimpleMailLimitExceeded(count($this->_contactIds));
+    $this->bounceIfSimpleMailLimitExceeded(count($this->_contactIds));
 
     $emailAttributes = [
       'class' => 'huge',
@@ -371,7 +371,242 @@ trait CRM_Contact_Form_Task_EmailTrait {
    * @throws \Civi\API\Exception\UnauthorizedException
    */
   public function postProcess() {
-    CRM_Contact_Form_Task_EmailCommon::postProcess($this);
+    $this->bounceIfSimpleMailLimitExceeded(count($this->_contactIds));
+
+    // check and ensure that
+    $formValues = $this->controller->exportValues($this->getName());
+    $this->submit($formValues);
+  }
+
+  /**
+   * Bounce if there are more emails than permitted.
+   *
+   * @param int $count
+   *  The number of emails the user is attempting to send
+   */
+  protected function bounceIfSimpleMailLimitExceeded($count) {
+    $limit = Civi::settings()->get('simple_mail_limit');
+    if ($count > $limit) {
+      CRM_Core_Error::statusBounce(ts('Please do not use this task to send a lot of emails (greater than %1). Many countries have legal requirements when sending bulk emails and the CiviMail framework has opt out functionality and domain tokens to help meet these.',
+        [1 => $limit]
+      ));
+    }
+  }
+
+  /**
+   * Submit the form values.
+   *
+   * This is also accessible for testing.
+   *
+   * @param array $formValues
+   *
+   * @throws \CRM_Core_Exception
+   * @throws \CiviCRM_API3_Exception
+   * @throws \Civi\API\Exception\UnauthorizedException
+   */
+  public function submit($formValues) {
+    $this->saveMessageTemplate($formValues);
+
+    $from = $formValues['from_email_address'] ?? NULL;
+    // dev/core#357 User Emails are keyed by their id so that the Signature is able to be added
+    // If we have had a contact email used here the value returned from the line above will be the
+    // numerical key where as $from for use in the sendEmail in Activity needs to be of format of "To Name" <toemailaddress>
+    $from = CRM_Utils_Mail::formatFromAddress($from);
+    $subject = $formValues['subject'];
+
+    // CRM-13378: Append CC and BCC information at the end of Activity Details and format cc and bcc fields
+    $elements = ['cc_id', 'bcc_id'];
+    $additionalDetails = NULL;
+    $ccValues = $bccValues = [];
+    foreach ($elements as $element) {
+      if (!empty($formValues[$element])) {
+        $allEmails = explode(',', $formValues[$element]);
+        foreach ($allEmails as $value) {
+          list($contactId, $email) = explode('::', $value);
+          $contactURL = CRM_Utils_System::url('civicrm/contact/view', "reset=1&force=1&cid={$contactId}", TRUE);
+          switch ($element) {
+            case 'cc_id':
+              $ccValues['email'][] = '"' . $this->_contactDetails[$contactId]['sort_name'] . '" <' . $email . '>';
+              $ccValues['details'][] = "<a href='{$contactURL}'>" . $this->_contactDetails[$contactId]['display_name'] . "</a>";
+              break;
+
+            case 'bcc_id':
+              $bccValues['email'][] = '"' . $this->_contactDetails[$contactId]['sort_name'] . '" <' . $email . '>';
+              $bccValues['details'][] = "<a href='{$contactURL}'>" . $this->_contactDetails[$contactId]['display_name'] . "</a>";
+              break;
+          }
+        }
+      }
+    }
+
+    $cc = $bcc = '';
+    if (!empty($ccValues)) {
+      $cc = implode(',', $ccValues['email']);
+      $additionalDetails .= "\ncc : " . implode(", ", $ccValues['details']);
+    }
+    if (!empty($bccValues)) {
+      $bcc = implode(',', $bccValues['email']);
+      $additionalDetails .= "\nbcc : " . implode(", ", $bccValues['details']);
+    }
+
+    // CRM-5916: prepend case id hash to CiviCase-originating emails’ subjects
+    if (isset($this->_caseId) && is_numeric($this->_caseId)) {
+      $hash = substr(sha1(CIVICRM_SITE_KEY . $this->_caseId), 0, 7);
+      $subject = "[case #$hash] $subject";
+    }
+
+    $attachments = [];
+    CRM_Core_BAO_File::formatAttachment($formValues,
+      $attachments,
+      NULL, NULL
+    );
+
+    // format contact details array to handle multiple emails from same contact
+    $formattedContactDetails = [];
+    $tempEmails = [];
+    foreach ($this->_contactIds as $key => $contactId) {
+      // if we dont have details on this contactID, we should ignore
+      // potentially this is due to the contact not wanting to receive email
+      if (!isset($this->_contactDetails[$contactId])) {
+        continue;
+      }
+      $email = $this->_toContactEmails[$key];
+      // prevent duplicate emails if same email address is selected CRM-4067
+      // we should allow same emails for different contacts
+      $emailKey = "{$contactId}::{$email}";
+      if (!in_array($emailKey, $tempEmails)) {
+        $tempEmails[] = $emailKey;
+        $details = $this->_contactDetails[$contactId];
+        $details['email'] = $email;
+        unset($details['email_id']);
+        $formattedContactDetails[] = $details;
+      }
+    }
+
+    $contributionIds = [];
+    if ($this->getVar('_contributionIds')) {
+      $contributionIds = $this->getVar('_contributionIds');
+    }
+
+    // send the mail
+    list($sent, $activityId) = CRM_Activity_BAO_Activity::sendEmail(
+      $formattedContactDetails,
+      $subject,
+      $formValues['text_message'],
+      $formValues['html_message'],
+      NULL,
+      NULL,
+      $from,
+      $attachments,
+      $cc,
+      $bcc,
+      array_keys($this->_toContactDetails),
+      $additionalDetails,
+      $contributionIds,
+      CRM_Utils_Array::value('campaign_id', $formValues),
+      $this->getVar('_caseId')
+    );
+
+    $followupStatus = '';
+    if ($sent) {
+      $followupActivity = NULL;
+      if (!empty($formValues['followup_activity_type_id'])) {
+        $params['followup_activity_type_id'] = $formValues['followup_activity_type_id'];
+        $params['followup_activity_subject'] = $formValues['followup_activity_subject'];
+        $params['followup_date'] = $formValues['followup_date'];
+        $params['target_contact_id'] = $this->_contactIds;
+        $params['followup_assignee_contact_id'] = explode(',', $formValues['followup_assignee_contact_id']);
+        $followupActivity = CRM_Activity_BAO_Activity::createFollowupActivity($activityId, $params);
+        $followupStatus = ts('A followup activity has been scheduled.');
+
+        if (Civi::settings()->get('activity_assignee_notification')) {
+          if ($followupActivity) {
+            $mailToFollowupContacts = [];
+            $assignee = [$followupActivity->id];
+            $assigneeContacts = CRM_Activity_BAO_ActivityAssignment::getAssigneeNames($assignee, TRUE, FALSE);
+            foreach ($assigneeContacts as $values) {
+              $mailToFollowupContacts[$values['email']] = $values;
+            }
+
+            $sentFollowup = CRM_Activity_BAO_Activity::sendToAssignee($followupActivity, $mailToFollowupContacts);
+            if ($sentFollowup) {
+              $followupStatus .= '<br />' . ts("A copy of the follow-up activity has also been sent to follow-up assignee contacts(s).");
+            }
+          }
+        }
+      }
+
+      $count_success = count($this->_toContactDetails);
+      CRM_Core_Session::setStatus(ts('One message was sent successfully. ', [
+        'plural' => '%count messages were sent successfully. ',
+        'count' => $count_success,
+      ]) . $followupStatus, ts('Message Sent', ['plural' => 'Messages Sent', 'count' => $count_success]), 'success');
+    }
+
+    // Display the name and number of contacts for those email is not sent.
+    // php 5.4 throws out a notice since the values of these below arrays are arrays.
+    // the behavior is not documented in the php manual, but it does the right thing
+    // suppressing the notices to get things in good shape going forward
+    $emailsNotSent = @array_diff_assoc($this->_allContactDetails, $this->_contactDetails);
+
+    if ($emailsNotSent) {
+      $not_sent = [];
+      foreach ($emailsNotSent as $contactId => $values) {
+        $displayName = $values['display_name'];
+        $email = $values['email'];
+        $contactViewUrl = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid=$contactId");
+        $not_sent[] = "<a href='$contactViewUrl' title='$email'>$displayName</a>" . ($values['on_hold'] ? '(' . ts('on hold') . ')' : '');
+      }
+      $status = '(' . ts('because no email address on file or communication preferences specify DO NOT EMAIL or Contact is deceased or Primary email address is On Hold') . ')<ul><li>' . implode('</li><li>', $not_sent) . '</li></ul>';
+      CRM_Core_Session::setStatus($status, ts('One Message Not Sent', [
+        'count' => count($emailsNotSent),
+        'plural' => '%count Messages Not Sent',
+      ]), 'info');
+    }
+
+    if (isset($this->_caseId)) {
+      // if case-id is found in the url, create case activity record
+      $cases = explode(',', $this->_caseId);
+      foreach ($cases as $key => $val) {
+        if (is_numeric($val)) {
+          $caseParams = [
+            'activity_id' => $activityId,
+            'case_id' => $val,
+          ];
+          CRM_Case_BAO_Case::processCaseActivity($caseParams);
+        }
+      }
+    }
+  }
+
+  /**
+   * Save the template if update selected.
+   *
+   * @param array $formValues
+   *
+   * @throws \CiviCRM_API3_Exception
+   * @throws \Civi\API\Exception\UnauthorizedException
+   */
+  protected function saveMessageTemplate($formValues) {
+    if (!empty($formValues['saveTemplate']) || !empty($formValues['updateTemplate'])) {
+      $messageTemplate = [
+        'msg_text' => $formValues['text_message'],
+        'msg_html' => $formValues['html_message'],
+        'msg_subject' => $formValues['subject'],
+        'is_active' => TRUE,
+      ];
+
+      if (!empty($formValues['saveTemplate'])) {
+        $messageTemplate['msg_title'] = $formValues['saveTemplateName'];
+        CRM_Core_BAO_MessageTemplate::add($messageTemplate);
+      }
+
+      if (!empty($formValues['template']) && !empty($formValues['updateTemplate'])) {
+        $messageTemplate['id'] = $formValues['template'];
+        unset($messageTemplate['msg_title']);
+        CRM_Core_BAO_MessageTemplate::add($messageTemplate);
+      }
+    }
   }
 
   /**
index 1686c3246694692ab60036f8069af180fdf3429d..10939b6235829cea9b297f9ed15a2dea085201f3 100644 (file)
@@ -82,7 +82,7 @@ class CRM_Contact_Form_Task_EmailCommonTest extends CiviUnitTestCase {
     $form->registerRule('maxfilesize', 'callback', '_ruleCheckMaxFileSize', 'HTML_QuickForm_file');
     CRM_Contact_Form_Task_EmailCommon::preProcessFromAddress($form);
     $form->buildQuickForm();
-    CRM_Contact_Form_Task_EmailCommon::submit($form, array_merge($form->_defaultValues, [
+    $form->submit(array_merge($form->_defaultValues, [
       'from_email_address' => $loggedInEmail['id'],
       'subject' => 'Really interesting stuff',
     ]));