From 3f77636acdf7392d9b1cc21b52e8675c01ac6f0b Mon Sep 17 00:00:00 2001 From: kurund Date: Fri, 29 Nov 2013 13:45:31 +0530 Subject: [PATCH] CRM-13809, prevent sending emails to deceased contacts, also code clean up/optimizations ---------------------------------------- * CRM-13809: send email activity: cc may go to wrong contact http://issues.civicrm.org/jira/browse/CRM-13809 --- CRM/Contact/Form/Task/EmailCommon.php | 150 ++++++++++++++-------- templates/CRM/Contact/Form/Task/Email.tpl | 2 +- 2 files changed, 96 insertions(+), 56 deletions(-) diff --git a/CRM/Contact/Form/Task/EmailCommon.php b/CRM/Contact/Form/Task/EmailCommon.php index ca503ddb90..aaf247dc63 100644 --- a/CRM/Contact/Form/Task/EmailCommon.php +++ b/CRM/Contact/Form/Task/EmailCommon.php @@ -42,10 +42,15 @@ class CRM_Contact_Form_Task_EmailCommon { CONST MAX_EMAILS_KILL_SWITCH = 50; public $_contactDetails = array(); - public $_additionalContactDetails = array(); public $_allContactDetails = array(); public $_toContactEmails = array(); + public $_toContactDetails = array(); + public $_allContactIds = array(); + public $_toContactIds = array(); + public $_ccContactIds = array(); + public $_bccContactIds = array(); + static function preProcessFromAddress(&$form) { $form->_single = FALSE; $className = CRM_Utils_System::getClassName($form); @@ -136,42 +141,41 @@ class CRM_Contact_Form_Task_EmailCommon { $cc = $form->add('text', 'cc_id', ts('CC')); $bcc = $form->add('text', 'bcc_id', ts('BCC')); - $elements = array('cc', 'bcc'); + $setDefaults = TRUE; + if (property_exists($form, '_context') && $form->_context == 'standalone') { + $setDefaults = FALSE; + } + + $elements = array('to', 'cc', 'bcc'); foreach ($elements as $element) { if ($$element->getValue()) { - preg_match_all('!"(.*?)"\s+<\s*(.*?)\s*>!', $$element->getValue(), $matches); - $elementValues = array(); - for ($i = 0; $i < count($matches[0]); $i++) { - $name = '"' . $matches[1][$i] . '" <' . $matches[2][$i] . '>'; - $elementValues[] = array( - 'name' => $name, - 'id' => $matches[0][$i], - ); - $id = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_Email', $matches[2][$i] , 'contact_id', 'email'); - $form->_additionalContactDetails[$element][$id] = CRM_Contact_BAO_Contact::displayName($id); + $allEmails = explode(',', $$element->getValue()); + if ($element == 'to') { + $form->_contactIds = array(); } - $var = "{$element}Contact"; - $form->assign($var, json_encode($elementValues)); - } - } - $toSetDefault = TRUE; - if (property_exists($form, '_context') && $form->_context == 'standalone') { - $toSetDefault = FALSE; - } - // when form is submitted recompute contactIds - $allToEmails = array(); - if ($to->getValue()) { - $allToEmails = explode(',', $to->getValue()); - $form->_contactIds = array(); - foreach ($allToEmails as $value) { - list($contactId, $email) = explode('::', $value); - if ($contactId) { - $form->_contactIds[] = $contactId; - $form->_toContactEmails[] = $email; + foreach ($allEmails as $value) { + list($contactId, $email) = explode('::', $value); + if ($contactId) { + switch ($element) { + case 'to': + $form->_contactIds[] = $form->_toContactIds[] = $contactId; + $form->_toContactEmails[] = $email; + break; + case 'cc': + $form->_ccContactIds[] = $contactId; + break; + case 'bcc': + $form->_bccContactIds[] = $contactId; + break; + } + + $form->_allContactIds[] = $contactId; + } } + + $setDefaults = TRUE; } - $toSetDefault = TRUE; } //get the group of contacts as per selected by user in case of Find Activities @@ -180,7 +184,9 @@ class CRM_Contact_Form_Task_EmailCommon { $form->_contactIds = $contact; } - if (is_array($form->_contactIds) && $toSetDefault) { + + // check if we need to setdefaults and check for valid contact emails / communication preferences + if (is_array($form->_contactIds) && $setDefaults) { $returnProperties = array( 'sort_name' => 1, 'email' => 1, @@ -191,7 +197,8 @@ class CRM_Contact_Form_Task_EmailCommon { 'preferred_mail_format' => 1, ); - list($form->_contactDetails) = CRM_Utils_Token::getTokenDetails($form->_contactIds, + // get the details for all selected contacts ( to, cc and bcc contacts ) + list($form->_contactDetails) = CRM_Utils_Token::getTokenDetails($form->_allContactIds, $returnProperties, FALSE, FALSE @@ -200,7 +207,8 @@ class CRM_Contact_Form_Task_EmailCommon { // make a copy of all contact details $form->_allContactDetails = $form->_contactDetails; - foreach ($form->_contactIds as $key => $contactId) { + // perform all validations + foreach ($form->_allContactIds as $key => $contactId) { $value = $form->_contactDetails[$contactId]; if ($value['do_not_email'] || empty($value['email']) || CRM_Utils_Array::value('is_deceased', $value) || $value['on_hold']) { $suppressedEmails++; @@ -210,16 +218,28 @@ class CRM_Contact_Form_Task_EmailCommon { unset($form->_contactDetails[$contactId]); } else { - if (empty($form->_toContactEmails)) { - $email = $value['email']; + $email = $value['email']; + + // build array's which are used to setdefaults + if (in_array($contactId, $form->_toContactIds)) { + $form->_toContactDetails[$contactId] = $form->_contactDetails[$contactId]; + $toArray[] = array( + 'name' => '"' . $value['sort_name'] . '" <' . $email . '>', + 'id' => "$contactId::{$email}", + ); + } + elseif (in_array($contactId, $form->_ccContactIds)) { + $ccArray[] = array( + 'name' => '"' . $value['sort_name'] . '" <' . $email . '>', + 'id' => "$contactId::{$email}", + ); } - else { - $email = $form->_toContactEmails[$key]; + elseif (in_array($contactId, $form->_bccContactIds)) { + $bccArray[] = array( + 'name' => '"' . $value['sort_name'] . '" <' . $email . '>', + 'id' => "$contactId::{$email}", + ); } - $toArray[] = array( - 'name' => '"' . $value['sort_name'] . '" <' . $email . '>', - 'id' => "$contactId::{$email}", - ); } } @@ -229,6 +249,9 @@ class CRM_Contact_Form_Task_EmailCommon { } $form->assign('toContact', json_encode($toArray)); + $form->assign('ccContact', json_encode($ccArray)); + $form->assign('bccContact', json_encode($bccArray)); + $form->assign('suppressedEmails', $suppressedEmails); $form->assign('totalSelectedContacts', count($form->_contactIds)); @@ -321,25 +344,42 @@ class CRM_Contact_Form_Task_EmailCommon { $fromEmail = $formValues['fromEmailAddress']; $from = CRM_Utils_Array::value($fromEmail, $form->_emails); - $cc = CRM_Utils_Array::value('cc_id', $formValues); - $bcc = CRM_Utils_Array::value('bcc_id', $formValues); $subject = $formValues['subject']; - - // CRM-13378: Append CC and BCC information at the end of Activity Details - $elements = array('cc', 'bcc'); + // CRM-13378: Append CC and BCC information at the end of Activity Details and format cc and bcc fields + $elements = array('cc_id', 'bcc_id'); $additionalDetails = NULL; + $ccValues = $bccValues = array(); foreach ($elements as $element) { - if (isset($form->_additionalContactDetails[$element])) { - foreach ($form->_additionalContactDetails[$element] as $id => $display_name) { - $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&force=1&cid={$id}"); - $form->_additionalContactDetails[$element][$id] = "$display_name"; + if (CRM_Utils_Array::value($element, $formValues)) { + $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'][] = '"' . $form->_contactDetails[$contactId]['sort_name'] . '" <' . $email . '>'; + $ccValues['details'][] = "" . $form->_contactDetails[$contactId]['display_name'] . ""; + break; + case 'bcc_id': + $bccValues['email'][]= '"' . $form->_contactDetails[$contactId]['sort_name'] . '" <' . $email . '>'; + $bccValues['details'][] = "" . $form->_contactDetails[$contactId]['display_name'] . ""; + break; + } } - $additionalDetails .= "\n$element : " . implode(", ", $form->_additionalContactDetails[$element]); - unset($form->_additionalContactDetails[$element]); } } + $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($form->_caseId) && is_numeric($form->_caseId)) { $hash = substr(sha1(CIVICRM_SITE_KEY . $form->_caseId), 0, 7); @@ -412,12 +452,12 @@ class CRM_Contact_Form_Task_EmailCommon { $attachments, $cc, $bcc, - array_keys($form->_contactDetails), + array_keys($form->_toContactDetails), $additionalDetails ); if ($sent) { - $count_success = count($form->_contactDetails); + $count_success = count($form->_toContactDetails); CRM_Core_Session::setStatus(ts('One message was sent successfully.', array('plural' => '%count messages were sent successfully.', 'count' => $count_success)), ts('Message Sent', array('plural' => 'Messages Sent', 'count' => $count_success)), 'success'); } diff --git a/templates/CRM/Contact/Form/Task/Email.tpl b/templates/CRM/Contact/Form/Task/Email.tpl index 6d48e932e7..ab3e1d02c3 100644 --- a/templates/CRM/Contact/Form/Task/Email.tpl +++ b/templates/CRM/Contact/Form/Task/Email.tpl @@ -109,7 +109,7 @@ cj('#addbcc').toggle( function() { cj(this).text('Remove BCC'); }); var hintText = "{/literal}{ts escape='js'}Type in a partial or complete name or email address of an existing contact.{/ts}{literal}"; -var sourceDataUrl = "{/literal}{crmURL p='civicrm/ajax/checkemail' h=0 }{literal}"; +var sourceDataUrl = "{/literal}{crmURL p='civicrm/ajax/checkemail' q='id=1' h=0 }{literal}"; var toDataUrl = "{/literal}{crmURL p='civicrm/ajax/checkemail' q='id=1' h=0 }{literal}"; cj( "#to" ).tokenInput( toDataUrl, { prePopulate: toContact, theme: 'facebook', hintText: hintText }); -- 2.25.1