From 704696b50d5329a39f895485aa26c0a25305c1aa Mon Sep 17 00:00:00 2001 From: eileen Date: Wed, 1 Apr 2020 16:52:20 +1300 Subject: [PATCH] [REF] move all functions associated with the submit function onto the Trait --- CRM/Contact/Form/Task/EmailCommon.php | 10 + CRM/Contact/Form/Task/EmailTrait.php | 239 +++++++++++++++++- .../CRM/Contact/Form/Task/EmailCommonTest.php | 2 +- 3 files changed, 248 insertions(+), 3 deletions(-) diff --git a/CRM/Contact/Form/Task/EmailCommon.php b/CRM/Contact/Form/Task/EmailCommon.php index 6edee67c09..1244b44f3a 100644 --- a/CRM/Contact/Form/Task/EmailCommon.php +++ b/CRM/Contact/Form/Task/EmailCommon.php @@ -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) { diff --git a/CRM/Contact/Form/Task/EmailTrait.php b/CRM/Contact/Form/Task/EmailTrait.php index 3a6076709e..fd24e0423c 100644 --- a/CRM/Contact/Form/Task/EmailTrait.php +++ b/CRM/Contact/Form/Task/EmailTrait.php @@ -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" + $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'][] = "" . $this->_contactDetails[$contactId]['display_name'] . ""; + break; + + case 'bcc_id': + $bccValues['email'][] = '"' . $this->_contactDetails[$contactId]['sort_name'] . '" <' . $email . '>'; + $bccValues['details'][] = "" . $this->_contactDetails[$contactId]['display_name'] . ""; + 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 .= '
' . 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[] = "$displayName" . ($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') . ')'; + 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); + } + } } /** diff --git a/tests/phpunit/CRM/Contact/Form/Task/EmailCommonTest.php b/tests/phpunit/CRM/Contact/Form/Task/EmailCommonTest.php index 1686c32466..10939b6235 100644 --- a/tests/phpunit/CRM/Contact/Form/Task/EmailCommonTest.php +++ b/tests/phpunit/CRM/Contact/Form/Task/EmailCommonTest.php @@ -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', ])); -- 2.25.1