From beac1417a7d3dc34deebbe5fc6e19067d09e4cc5 Mon Sep 17 00:00:00 2001 From: Matthew Wire Date: Fri, 29 Sep 2017 23:48:54 +0100 Subject: [PATCH] Deduplicate from email address code and add a setting to disable sending from contact email addresses --- CRM/Admin/Form/Setting/Smtp.php | 5 ++ CRM/Contact/BAO/Contact/Location.php | 30 +++------ CRM/Contact/Form/Domain.php | 56 ---------------- CRM/Contact/Form/Task/EmailCommon.php | 66 ++++--------------- CRM/Contact/Form/Task/PDFLetterCommon.php | 3 + CRM/Contribute/BAO/Contribution.php | 2 +- CRM/Contribute/Form/Contribution.php | 2 +- CRM/Contribute/Form/Task/Invoice.php | 53 ++------------- CRM/Contribute/Form/Task/PDF.php | 8 +-- CRM/Contribute/Form/Task/PDFLetterCommon.php | 3 + CRM/Core/BAO/Domain.php | 19 ++++-- CRM/Core/BAO/Email.php | 32 ++++++--- CRM/Event/Cart/Form/Checkout/Payment.php | 12 +--- CRM/Mailing/BAO/Mailing.php | 2 +- CRM/Member/Form/Membership.php | 2 +- api/v3/Mailing.php | 2 +- settings/Mailing.setting.php | 13 ++++ templates/CRM/Admin/Form/Setting/Smtp.hlp | 31 +++++++++ templates/CRM/Admin/Form/Setting/Smtp.tpl | 27 ++++++-- templates/CRM/Contact/Form/Domain.hlp | 15 ----- templates/CRM/Contact/Form/Domain.tpl | 14 ---- templates/CRM/Contact/Form/Task/Email.tpl | 8 +-- .../CRM/Contact/Form/Task/PDFLetterCommon.tpl | 4 ++ .../CRM/Contribute/Form/Task/Invoice.hlp | 10 --- .../CRM/Contribute/Form/Task/Invoice.tpl | 13 ++-- templates/CRM/Contribute/Form/Task/PDF.tpl | 5 +- .../CRM/Contribute/Form/Task/PDFLetter.tpl | 4 ++ templates/CRM/Member/Form/Membership.hlp | 9 +++ templates/CRM/Member/Form/Membership.tpl | 4 +- .../CRM/Member/Form/MembershipRenewal.tpl | 2 +- .../CRM/Contact/Form/Task/EmailCommonTest.php | 2 +- .../Form/Task/PDFLetterCommonTest.php | 1 + 32 files changed, 184 insertions(+), 275 deletions(-) create mode 100644 templates/CRM/Admin/Form/Setting/Smtp.hlp diff --git a/CRM/Admin/Form/Setting/Smtp.php b/CRM/Admin/Form/Setting/Smtp.php index 84c8728287..4bfa646424 100644 --- a/CRM/Admin/Form/Setting/Smtp.php +++ b/CRM/Admin/Form/Setting/Smtp.php @@ -52,6 +52,7 @@ class CRM_Admin_Form_Setting_Smtp extends CRM_Admin_Form_Setting { $this->addRadio('outBound_option', ts('Select Mailer'), $outBoundOption); CRM_Utils_System::setTitle(ts('Settings - Outbound Mail')); + $this->add('checkbox', 'allow_mail_from_logged_in_contact', ts('Allow Mail to be sent from logged in contact\'s email address')); $this->add('text', 'sendmail_path', ts('Sendmail Path')); $this->add('text', 'sendmail_args', ts('Sendmail Argument')); $this->add('text', 'smtpServer', ts('SMTP Server')); @@ -79,6 +80,9 @@ class CRM_Admin_Form_Setting_Smtp extends CRM_Admin_Form_Setting { $formValues = $this->controller->exportValues($this->_name); + Civi::settings()->set('allow_mail_from_logged_in_contact', (!empty($formValues['allow_mail_from_logged_in_contact']))); + unset($formValues['allow_mail_from_logged_in_contact']); + $buttonName = $this->controller->getButtonName(); // check if test button if ($buttonName == $this->_testButtonName) { @@ -259,6 +263,7 @@ class CRM_Admin_Form_Setting_Smtp extends CRM_Admin_Form_Setting { } } } + $this->_defaults['allow_mail_from_logged_in_contact'] = Civi::settings()->get('allow_mail_from_logged_in_contact'); return $this->_defaults; } diff --git a/CRM/Contact/BAO/Contact/Location.php b/CRM/Contact/BAO/Contact/Location.php index 7405537b44..a06971c9c8 100644 --- a/CRM/Contact/BAO/Contact/Location.php +++ b/CRM/Contact/BAO/Contact/Location.php @@ -45,29 +45,19 @@ class CRM_Contact_BAO_Contact_Location { * Array of display_name, email, location type and location id if found, or (null,null,null, null) */ public static function getEmailDetails($id, $isPrimary = TRUE, $locationTypeID = NULL) { - $primaryClause = NULL; + $params = array( + 'location_type_id' => $locationTypeID, + 'contact_id' => $id, + 'return' => array('contact_id.display_name', 'email', 'location_type_id', 'id'), + ); if ($isPrimary) { - $primaryClause = " AND civicrm_email.is_primary = 1"; + $params['is_primary'] = 1; } + $emails = civicrm_api3('Email', 'get', $params); - $locationClause = NULL; - if ($locationTypeID) { - $locationClause = " AND civicrm_email.location_type_id = $locationTypeID"; - } - - $sql = " -SELECT civicrm_contact.display_name, - civicrm_email.email, - civicrm_email.location_type_id, - civicrm_email.id -FROM civicrm_contact -LEFT JOIN civicrm_email ON ( civicrm_contact.id = civicrm_email.contact_id {$primaryClause} {$locationClause} ) -WHERE civicrm_contact.id = %1"; - - $params = array(1 => array($id, 'Integer')); - $dao = CRM_Core_DAO::executeQuery($sql, $params); - if ($dao->fetch()) { - return array($dao->display_name, $dao->email, $dao->location_type_id, $dao->id); + if ($emails['count'] > 0) { + $email = reset($emails['values']); + return array($email['contact_id.display_name'], $email['email'], $email['location_type_id'], $email['id']); } return array(NULL, NULL, NULL, NULL); } diff --git a/CRM/Contact/Form/Domain.php b/CRM/Contact/Form/Domain.php index c041cef4c6..cd3d2ec7f9 100644 --- a/CRM/Contact/Form/Domain.php +++ b/CRM/Contact/Form/Domain.php @@ -118,19 +118,6 @@ class CRM_Contact_Form_Domain extends CRM_Core_Form { $params['id'] = $this->_id; CRM_Core_BAO_Domain::retrieve($params, $domainDefaults); $this->_contactId = $domainDefaults['contact_id']; - //get the default domain from email address. fix CRM-3552 - $optionValues = array(); - $grpParams['name'] = 'from_email_address'; - CRM_Core_OptionValue::getValues($grpParams, $optionValues); - foreach ($optionValues as $Id => $value) { - if ($value['is_default'] && $value['is_active']) { - $this->_fromEmailId = $Id; - $list = explode('"', $value['label']); - $domainDefaults['email_name'] = CRM_Utils_Array::value(1, $list); - $domainDefaults['email_address'] = CRM_Utils_Mail::pluckEmailFromHeader($value['label']); - break; - } - } unset($params['id']); $locParams = array('contact_id' => $domainDefaults['contact_id']); @@ -156,9 +143,6 @@ class CRM_Contact_Form_Domain extends CRM_Core_Form { public function buildQuickForm() { $this->addField('name', array('label' => ts('Organization Name')), TRUE); $this->addField('description', array('label' => ts('Description'), 'size' => 30)); - $this->add('text', 'email_name', ts('FROM Name'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_Email', 'email'), TRUE); - $this->add('text', 'email_address', ts('FROM Email Address'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_Email', 'email'), TRUE); - $this->addRule('email_address', ts('Domain Email Address must use a valid email address format (e.g. \'info@example.org\').'), 'email'); //build location blocks. CRM_Contact_Form_Location::buildQuickForm($this); @@ -207,16 +191,6 @@ class CRM_Contact_Form_Domain extends CRM_Core_Form { $errors = array(); } - //fix for CRM-3552, - //as we use "fromName" format for domain email. - if (strpos($fields['email_name'], '"') !== FALSE) { - $errors['email_name'] = ts('Double quotes are not allow in from name.'); - } - - // Check for default from email address and organization (domain) name. Force them to change it. - if ($fields['email_address'] == 'info@EXAMPLE.ORG') { - $errors['email_address'] = ts('Please enter a valid default FROM email address for system-generated emails.'); - } if ($fields['name'] == 'Default Domain Name') { $errors['name'] = ts('Please enter the name of the organization or entity which owns this CiviCRM site.'); } @@ -275,36 +249,6 @@ class CRM_Contact_Form_Domain extends CRM_Core_Form { CRM_Core_BAO_Domain::edit($params, $this->_id); - //set domain from email address, CRM-3552 - $emailName = '"' . $params['email_name'] . '" <' . $params['email_address'] . '>'; - - $emailParams = array( - 'label' => $emailName, - 'description' => $params['description'], - 'is_active' => 1, - 'is_default' => 1, - ); - - $groupParams = array('name' => 'from_email_address'); - - //get the option value wt. - if ($this->_fromEmailId) { - $action = $this->_action; - $emailParams['weight'] = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue', $this->_fromEmailId, 'weight'); - } - else { - //add from email address. - $action = CRM_Core_Action::ADD; - $grpId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', 'from_email_address', 'id', 'name'); - $fieldValues = array('option_group_id' => $grpId); - $emailParams['weight'] = CRM_Utils_Weight::getDefaultWeight('CRM_Core_DAO_OptionValue', $fieldValues); - } - - //reset default within domain. - $emailParams['reset_default_for'] = array('domain_id' => CRM_Core_Config::domainID()); - - CRM_Core_OptionValue::addOptionValue($emailParams, $groupParams, $action, $this->_fromEmailId); - CRM_Core_Session::setStatus(ts("Domain information for '%1' has been saved.", array(1 => $domain->name)), ts('Saved'), 'success'); $session = CRM_Core_Session::singleton(); $session->replaceUserContext(CRM_Utils_System::url('civicrm/admin', 'reset=1')); diff --git a/CRM/Contact/Form/Task/EmailCommon.php b/CRM/Contact/Form/Task/EmailCommon.php index 88be4a082b..e57efd9d01 100644 --- a/CRM/Contact/Form/Task/EmailCommon.php +++ b/CRM/Contact/Form/Task/EmailCommon.php @@ -44,21 +44,16 @@ class CRM_Contact_Form_Task_EmailCommon { public $_toContactEmails = array(); /** - * Generate an array of Domain email addresses. + * @deprecated Generate an array of Domain email addresses. * @return array $domainEmails; */ public static function domainEmails() { - $domainEmails = array(); - $domainFrom = CRM_Core_OptionGroup::values('from_email_address'); - foreach (array_keys($domainFrom) as $k) { - $domainEmail = $domainFrom[$k]; - $domainEmails[$domainEmail] = htmlspecialchars($domainEmail); - } - return $domainEmails; + Civi::log()->warning('Deprecated function, use CRM_Core_BAO_Email::domainEmails()', array('civi.tag' => 'deprecated')); + return CRM_Core_BAO_Email::domainEmails(); } /** - * Pre Process Form Addresses to be used in QUickfomr + * Pre Process Form Addresses to be used in Quickform * @param CRM_Core_Form $form * @param bool $bounce determine if we want to throw a status bounce. */ @@ -72,60 +67,27 @@ class CRM_Contact_Form_Task_EmailCommon { $form->_single = TRUE; } - $form->_emails = $emails = array(); + $form->_emails = array(); $contactID = CRM_Core_Session::singleton()->getLoggedInContactID(); - $fromDisplayName = CRM_Core_Session::singleton()->getLoggedInContactDisplayName(); - $form->_contactIds = array($contactID); - $contactEmails = CRM_Core_BAO_Email::allEmails($contactID); - $form->_onHold = array(); + $fromEmailValues = CRM_Core_BAO_Email::getFromEmail(); - foreach ($contactEmails as $emailId => $item) { - $email = $item['email']; - if (!$email && (count($emails) < 1)) { - // set it if no emails are present at all - $form->_noEmails = TRUE; - } - else { - if ($email) { - if (in_array($email, $emails)) { - // CRM-3624 - continue; - } - - $emails[$emailId] = '"' . $fromDisplayName . '" <' . $email . '> '; - $form->_onHold[$emailId] = $item['on_hold']; - $form->_noEmails = FALSE; - } - } - if (!empty($email)) { - $form->_emails[$emailId] = $emails[$emailId]; - $emails[$emailId] .= $item['locationType']; - - if ($item['is_primary']) { - $emails[$emailId] .= ' ' . ts('(preferred)'); - } - $emails[$emailId] = htmlspecialchars($emails[$emailId]); - } + $form->_noEmails = FALSE; + if (empty($fromEmailValues)) { + $form->_noEmails = TRUE; } - $form->assign('noEmails', $form->_noEmails); if ($bounce) { if ($form->_noEmails) { - CRM_Core_Error::statusBounce(ts('Your user record does not have a valid email address')); + CRM_Core_Error::statusBounce(ts('Your user record does not have a valid email address and no from addresses have been configured.')); } } - // now add domain from addresses - $domainEmails = self::domainEmails(); - foreach ($domainEmails as $domainEmail => $email) { - $form->_emails[$domainEmail] = $domainEmail; - } - $form->_fromEmails = CRM_Utils_Array::crmArrayMerge($emails, $domainEmails); - $form->_fromEmails = array_filter($form->_fromEmails); + $form->_emails = $fromEmailValues; + $form->_fromEmails = $fromEmailValues; if (is_numeric(key($form->_fromEmails))) { // Add signature $defaultEmail = civicrm_api3('email', 'getsingle', array('id' => key($form->_fromEmails))); @@ -287,7 +249,7 @@ class CRM_Contact_Form_Task_EmailCommon { $form->add('text', 'subject', ts('Subject'), 'size=50 maxlength=254', TRUE); - $form->add('select', 'fromEmailAddress', ts('From'), $form->_fromEmails, TRUE, array('class' => 'crm-select2 huge')); + $form->add('select', 'from_email_address', ts('From'), $form->_fromEmails, TRUE); CRM_Mailing_BAO_Mailing::commonCompose($form); @@ -427,7 +389,7 @@ class CRM_Contact_Form_Task_EmailCommon { public static function submit(&$form, $formValues) { self::saveMessageTemplate($formValues); - $from = CRM_Utils_Array::value($formValues['fromEmailAddress'], $form->_emails); + $from = CRM_Utils_Array::value('from_email_address', $formValues); $subject = $formValues['subject']; // CRM-13378: Append CC and BCC information at the end of Activity Details and format cc and bcc fields diff --git a/CRM/Contact/Form/Task/PDFLetterCommon.php b/CRM/Contact/Form/Task/PDFLetterCommon.php index ae6d83ef53..d1ef15e2d1 100644 --- a/CRM/Contact/Form/Task/PDFLetterCommon.php +++ b/CRM/Contact/Form/Task/PDFLetterCommon.php @@ -58,6 +58,7 @@ class CRM_Contact_Form_Task_PDFLetterCommon { * @param CRM_Core_Form $form */ public static function preProcess(&$form) { + CRM_Contact_Form_Task_EmailCommon::preProcessFromAddress($form); $messageText = array(); $messageSubject = array(); $dao = new CRM_Core_BAO_MessageTemplate(); @@ -104,6 +105,8 @@ class CRM_Contact_Form_Task_PDFLetterCommon { FALSE ); + $form->add('select', 'from_email_address', ts('From Email Address'), $form->_fromEmails, TRUE); + $form->add('static', 'pdf_format_header', NULL, ts('Page Format: %1', array(1 => ''))); $form->addSelect('format_id', array( 'label' => ts('Select Format'), diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index 8d57b4cb10..e4eabc997f 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -4736,7 +4736,7 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) * @return array */ public static function generateFromEmailAndName($input, $contribution) { - // Use input valuse if supplied. + // Use input value if supplied. if (!empty($input['receipt_from_email'])) { return array(CRM_Utils_array::value('receipt_from_name', $input, ''), $input['receipt_from_email']); } diff --git a/CRM/Contribute/Form/Contribution.php b/CRM/Contribute/Form/Contribution.php index 04310298e8..4910937982 100644 --- a/CRM/Contribute/Form/Contribution.php +++ b/CRM/Contribute/Form/Contribution.php @@ -1685,7 +1685,7 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP $formValues += CRM_Contribute_BAO_ContributionSoft::getSoftContribution($contribution->id); // to get 'from email id' for send receipt - $this->fromEmailId = $formValues['from_email_address']; + $this->fromEmailId = CRM_Utils_Array::value('from_email_address', $formValues); if (CRM_Contribute_Form_AdditionalInfo::emailReceipt($this, $formValues)) { $this->statusMessage[] = ts('A receipt has been emailed to the contributor.'); } diff --git a/CRM/Contribute/Form/Task/Invoice.php b/CRM/Contribute/Form/Task/Invoice.php index 03ec061b5e..8f2a406dff 100644 --- a/CRM/Contribute/Form/Task/Invoice.php +++ b/CRM/Contribute/Form/Task/Invoice.php @@ -129,6 +129,7 @@ class CRM_Contribute_Form_Task_Invoice extends CRM_Contribute_Form_Task { $this->_selectedOutput = CRM_Utils_Request::retrieve('select', 'String', $this); $this->assign('selectedOutput', $this->_selectedOutput); + CRM_Contact_Form_Task_EmailCommon::preProcessFromAddress($this); if ($this->_selectedOutput == 'email') { CRM_Utils_System::setTitle(ts('Email Invoice')); } @@ -141,36 +142,12 @@ class CRM_Contribute_Form_Task_Invoice extends CRM_Contribute_Form_Task { * Build the form object. */ public function buildQuickForm() { - $session = CRM_Core_Session::singleton(); $this->preventAjaxSubmit(); if (CRM_Core_Permission::check('administer CiviCRM')) { $this->assign('isAdmin', 1); } - $contactID = $session->get('userID'); - $contactEmails = CRM_Core_BAO_Email::allEmails($contactID); - $emails = array(); - $fromDisplayName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', - $contactID, 'display_name' - ); - foreach ($contactEmails as $emailId => $item) { - $email = $item['email']; - if ($email) { - $emails[$emailId] = '"' . $fromDisplayName . '" <' . $email . '> '; - } - if (isset($emails[$emailId])) { - $emails[$emailId] .= $item['locationType']; - if ($item['is_primary']) { - $emails[$emailId] .= ' ' . ts('(preferred)'); - } - $emails[$emailId] = htmlspecialchars($emails[$emailId]); - } - } - $fromEmailAddress = CRM_Core_OptionGroup::values('from_email_address'); - foreach ($fromEmailAddress as $key => $email) { - $fromEmailAddress[$key] = htmlspecialchars($fromEmailAddress[$key]); - } - $fromEmail = CRM_Utils_Array::crmArrayMerge($emails, $fromEmailAddress); - $this->add('select', 'from_email_address', ts('From Email Address'), array('' => '- select -') + $fromEmail); + + $this->add('select', 'from_email_address', ts('From'), $this->_fromEmails, TRUE); if ($this->_selectedOutput != 'email') { $this->addElement('radio', 'output', NULL, ts('Email Invoice'), 'email_invoice'); $this->addElement('radio', 'output', NULL, ts('PDF Invoice'), 'pdf_invoice'); @@ -479,30 +456,8 @@ class CRM_Contribute_Form_Task_Invoice extends CRM_Contribute_Form_Task { 'tplParams' => $tplParams, 'PDFFilename' => $pdfFileName, ); - $session = CRM_Core_Session::singleton(); - $contactID = $session->get('userID'); - //CRM-16319 - we dont store in userID in case the user is doing multiple - //transactions etc - if (empty($contactID)) { - $contactID = $session->get('transaction.userID'); - } - // Fix Invoice email doesnot send out when completed payment using Paypal - if (empty($contactID)) { - $contactID = current($contactIds); - } - $contactEmails = CRM_Core_BAO_Email::allEmails($contactID); - $emails = array(); - $fromDisplayName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', - $contactID, 'display_name' - ); - foreach ($contactEmails as $emailId => $item) { - $email = $item['email']; - if ($email) { - $emails[$emailId] = '"' . $fromDisplayName . '" <' . $email . '> '; - } - } - $fromEmail = CRM_Utils_Array::crmArrayMerge($emails, CRM_Core_OptionGroup::values('from_email_address')); + $fromEmail = CRM_Core_BAO_Email::getFromEmail(); // from email address if (isset($params['from_email_address'])) { diff --git a/CRM/Contribute/Form/Task/PDF.php b/CRM/Contribute/Form/Task/PDF.php index 2455d38fde..d3572b21ef 100644 --- a/CRM/Contribute/Form/Task/PDF.php +++ b/CRM/Contribute/Form/Task/PDF.php @@ -119,7 +119,7 @@ AND {$this->_componentClause}"; $this->add('checkbox', 'receipt_update', ts('Update receipt dates for these contributions'), FALSE); $this->add('checkbox', 'override_privacy', ts('Override privacy setting? (Do not email / Do not mail)'), FALSE); - $this->add('select', 'fromEmailAddress', ts('From Email'), $this->_fromEmails, FALSE, array('class' => 'crm-select2 huge')); + $this->add('select', 'from_email_address', ts('From Email'), $this->_fromEmails, FALSE); $this->addButtons(array( array( @@ -197,11 +197,9 @@ AND {$this->_componentClause}"; $objects['contribution']->receive_date = CRM_Utils_Date::isoToMysql($objects['contribution']->receive_date); $values = array(); - if (isset($params['fromEmailAddress']) && !$elements['createPdf']) { + if (isset($params['from_email_address']) && !$elements['createPdf']) { // CRM-19129 Allow useres the choice of From Email to send the receipt from. - $fromEmail = $params['fromEmailAddress']; - $from = CRM_Utils_Array::value($fromEmail, $this->_emails); - $fromDetails = explode(' <', $from); + $fromDetails = explode(' <', $params['from_email_address']); $input['receipt_from_email'] = substr(trim($fromDetails[1]), 0, -1); $input['receipt_from_name'] = str_replace('"', '', $fromDetails[0]); } diff --git a/CRM/Contribute/Form/Task/PDFLetterCommon.php b/CRM/Contribute/Form/Task/PDFLetterCommon.php index 370900a74f..ace2053964 100644 --- a/CRM/Contribute/Form/Task/PDFLetterCommon.php +++ b/CRM/Contribute/Form/Task/PDFLetterCommon.php @@ -368,6 +368,9 @@ class CRM_Contribute_Form_Task_PDFLetterCommon extends CRM_Contact_Form_Task_PDF $emails = array_keys($emails); $defaults['from'] = array_pop($emails); } + else { + $defaults['from'] = $params['from']; + } if (!empty($params['subject'])) { $defaults['subject'] = $params['subject']; } diff --git a/CRM/Core/BAO/Domain.php b/CRM/Core/BAO/Domain.php index 5c519baf1f..85235802de 100644 --- a/CRM/Core/BAO/Domain.php +++ b/CRM/Core/BAO/Domain.php @@ -169,9 +169,13 @@ class CRM_Core_BAO_Domain extends CRM_Core_DAO_Domain { * name & email for domain * @throws Exception */ - public static function getNameAndEmail($skipFatal = FALSE) { + public static function getNameAndEmail($skipFatal = FALSE, $returnString = FALSE) { $fromEmailAddress = CRM_Core_OptionGroup::values('from_email_address', NULL, NULL, NULL, ' AND is_default = 1'); if (!empty($fromEmailAddress)) { + if ($returnString) { + // Return a string like: "Demonstrators Anonymous" + return $fromEmailAddress; + } foreach ($fromEmailAddress as $key => $value) { $email = CRM_Utils_Mail::pluckEmailFromHeader($value); $fromArray = explode('"', $value); @@ -180,12 +184,13 @@ class CRM_Core_BAO_Domain extends CRM_Core_DAO_Domain { } return array($fromName, $email); } - elseif ($skipFatal) { - return array('', ''); + + if ($skipFatal) { + return array(NULL, NULL); } - $url = CRM_Utils_System::url('civicrm/admin/domain', - 'action=update&reset=1' + $url = CRM_Utils_System::url('civicrm/admin/options/from_email_address', + 'reset=1' ); $status = ts("There is no valid default from email address configured for the domain. You can configure here Configure From Email Address.", array(1 => $url)); @@ -287,8 +292,8 @@ class CRM_Core_BAO_Domain extends CRM_Core_DAO_Domain { /** * CRM-20308 & CRM-19657 - * Return domain information / user information for the useage in receipts - * Try default from adress then fall back to using logged in user details + * Return domain information / user information for the usage in receipts + * Try default from address then fall back to using logged in user details */ public static function getDefaultReceiptFrom() { $domain = civicrm_api3('domain', 'getsingle', array('id' => CRM_Core_Config::domainID())); diff --git a/CRM/Core/BAO/Email.php b/CRM/Core/BAO/Email.php index 3bfee2724e..2227465cf9 100644 --- a/CRM/Core/BAO/Email.php +++ b/CRM/Core/BAO/Email.php @@ -275,6 +275,20 @@ AND reset_date IS NULL } } + /** + * Generate an array of Domain email addresses. + * @return array $domainEmails; + */ + public static function domainEmails() { + $domainEmails = array(); + $domainFrom = (array) CRM_Core_OptionGroup::values('from_email_address'); + foreach (array_keys($domainFrom) as $k) { + $domainEmail = $domainFrom[$k]; + $domainEmails[$domainEmail] = htmlspecialchars($domainEmail); + } + return $domainEmails; + } + /** * Build From Email as the combination of all the email ids of the logged in user and * the domain email id @@ -283,22 +297,20 @@ AND reset_date IS NULL * an array of email ids */ public static function getFromEmail() { - $contactID = CRM_Core_Session::singleton()->getLoggedInContactID(); - $fromEmailValues = array(); - // add all configured FROM email addresses - $domainFrom = CRM_Core_OptionGroup::values('from_email_address'); - foreach (array_keys($domainFrom) as $k) { - $domainEmail = $domainFrom[$k]; - $fromEmailValues[$domainEmail] = htmlspecialchars($domainEmail); + $fromEmailValues = self::domainEmails(); + + if (!Civi::settings()->get('allow_mail_from_logged_in_contact')) { + return $fromEmailValues; } // add logged in user's active email ids + $contactID = CRM_Core_Session::singleton()->getLoggedInContactID(); if ($contactID) { $contactEmails = self::allEmails($contactID); - $fromDisplayName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactID, 'display_name'); + $fromDisplayName = CRM_Core_Session::singleton()->getLoggedInContactDisplayName(); - foreach ($contactEmails as $emailVal) { + foreach ($contactEmails as $emailId => $emailVal) { $email = trim($emailVal['email']); if (!$email || $emailVal['on_hold']) { continue; @@ -309,7 +321,7 @@ AND reset_date IS NULL if (!empty($emailVal['is_primary'])) { $fromEmailHtml .= ' ' . ts('(preferred)'); } - $fromEmailValues[$fromEmail] = $fromEmailHtml; + $fromEmailValues[$emailId] = $fromEmailHtml; } } return $fromEmailValues; diff --git a/CRM/Event/Cart/Form/Checkout/Payment.php b/CRM/Event/Cart/Form/Checkout/Payment.php index 59f843ad46..51f9126b9d 100644 --- a/CRM/Event/Cart/Form/Checkout/Payment.php +++ b/CRM/Event/Cart/Form/Checkout/Payment.php @@ -328,16 +328,6 @@ class CRM_Event_Cart_Form_Checkout_Payment extends CRM_Event_Cart_Form_Cart { $this->sub_total += $amount; } - /** - * Get default from address. - * - * @return mixed - */ - public function getDefaultFrom() { - $values = CRM_Core_OptionGroup::values('from_email_address'); - return $values[1]; - } - /** * Send email receipt. * @@ -362,7 +352,7 @@ class CRM_Event_Cart_Form_Checkout_Payment extends CRM_Event_Cart_Form_Cart { $send_template_params = array( 'table' => 'civicrm_msg_template', 'contactId' => $this->payer_contact_id, - 'from' => $this->getDefaultFrom(), + 'from' => CRM_Core_BAO_Domain::getNameAndEmail(TRUE, TRUE), 'groupName' => 'msg_tpl_workflow_event', 'isTest' => FALSE, 'toEmail' => $contact_details[1], diff --git a/CRM/Mailing/BAO/Mailing.php b/CRM/Mailing/BAO/Mailing.php index 0bd1fa660e..7b156577b1 100644 --- a/CRM/Mailing/BAO/Mailing.php +++ b/CRM/Mailing/BAO/Mailing.php @@ -1717,7 +1717,7 @@ ORDER BY civicrm_email.is_bulkmail DESC // Get the default from email address, if not provided. if (empty($defaults['from_email'])) { - $defaultAddress = CRM_Core_OptionGroup::values('from_email_address', NULL, NULL, NULL, ' AND is_default = 1'); + $defaultAddress = CRM_Core_BAO_Domain::getNameAndEmail(TRUE, TRUE); foreach ($defaultAddress as $id => $value) { if (preg_match('/"(.*)" <(.*)>/', $value, $match)) { $defaults['from_email'] = $match[2]; diff --git a/CRM/Member/Form/Membership.php b/CRM/Member/Form/Membership.php index acb14746d6..007acbf72b 100644 --- a/CRM/Member/Form/Membership.php +++ b/CRM/Member/Form/Membership.php @@ -936,7 +936,7 @@ class CRM_Member_Form_Membership extends CRM_Member_Form { */ public static function emailReceipt(&$form, &$formValues, &$membership) { // retrieve 'from email id' for acknowledgement - $receiptFrom = $formValues['from_email_address']; + $receiptFrom = CRM_Utils_Array::value('from_email_address', $formValues); if (!empty($formValues['payment_instrument_id'])) { $paymentInstrument = CRM_Contribute_PseudoConstant::paymentInstrument(); diff --git a/api/v3/Mailing.php b/api/v3/Mailing.php index 300ac3b07c..22aba4bfda 100644 --- a/api/v3/Mailing.php +++ b/api/v3/Mailing.php @@ -160,7 +160,7 @@ function _civicrm_api3_mailing_create_spec(&$params) { $params['resubscribe_id']['api.default'] = CRM_Mailing_PseudoConstant::defaultComponent('Resubscribe', ''); $params['unsubscribe_id']['api.default'] = CRM_Mailing_PseudoConstant::defaultComponent('Unsubscribe', ''); $params['mailing_type']['api.default'] = 'standalone'; - $defaultAddress = CRM_Core_OptionGroup::values('from_email_address', NULL, NULL, NULL, ' AND is_default = 1'); + $defaultAddress = CRM_Core_BAO_Domain::getNameAndEmail(TRUE, TRUE); foreach ($defaultAddress as $value) { if (preg_match('/"(.*)" <(.*)>/', $value, $match)) { $params['from_email']['api.default'] = $match[2]; diff --git a/settings/Mailing.setting.php b/settings/Mailing.setting.php index cc2626fa4c..e38584c89f 100644 --- a/settings/Mailing.setting.php +++ b/settings/Mailing.setting.php @@ -346,4 +346,17 @@ return array( 'description' => 'Enable this setting to rebuild recipient list automatically during composing mail. Disable will allow you to rebuild recipient manually.', 'help_text' => 'CiviMail automatically fetches recipient list and count whenever mailing groups are included or excluded while composing bulk mail. This phenomena may degrade performance for large sites, so disable this setting to build and fetch recipients for selected groups, manually.', ), + 'allow_mail_from_logged_in_contact' => array( + 'group_name' => 'Mailing Preferences', + 'group' => 'mailing', + 'name' => 'allow_mail_from_logged_in_contact', + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', + 'default' => 1, + 'title' => 'Allow mail from logged in contact', + 'is_domain' => 1, + 'is_contact' => 0, + 'description' => 'Allow sending email from the logged in contact\'s email address', + 'help_text' => 'CiviCRM allows you to send email from the domain from email addresses and the logged in contact id addresses by default. Disable this if you only want to allow the domain from addresses to be used.', + ), ); diff --git a/templates/CRM/Admin/Form/Setting/Smtp.hlp b/templates/CRM/Admin/Form/Setting/Smtp.hlp new file mode 100644 index 0000000000..ed5f9fd466 --- /dev/null +++ b/templates/CRM/Admin/Form/Setting/Smtp.hlp @@ -0,0 +1,31 @@ +{*--------------------------------------------------------------------+ + | CiviCRM version 4.7 | + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC (c) 2004-2017 | + +--------------------------------------------------------------------+ + | This file is a part of CiviCRM. | + | | + | CiviCRM is free software; you can copy, modify, and distribute it | + | under the terms of the GNU Affero General Public License | + | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | + | | + | CiviCRM is distributed in the hope that it will be useful, but | + | WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | + | See the GNU Affero General Public License for more details. | + | | + | You should have received a copy of the GNU Affero General Public | + | License and the CiviCRM Licensing Exception along | + | with this program; if not, contact CiviCRM LLC | + | at info[AT]civicrm[DOT]org. If you have questions about the | + | GNU Affero General Public License or the licensing of CiviCRM, | + | see the CiviCRM license FAQ at http://civicrm.org/licensing | + +-------------------------------------------------------------------*} + +{htxt id='allow_mail_contact_email'} +{capture assign=adminFromEmailURL}{crmURL p="civicrm/admin/options/from_email_address" q="reset=1"}{/capture} +{ts 1=$adminFromEmailURL}If this is enabled a logged in user can send email from their own email address as well as the configured + FROM Email addresses. This applies to actions such as send Email, Email invoice.. If this setting + is disabled then only the system configured FROM Email addresses will be available for selection.{/ts} +{/htxt} + diff --git a/templates/CRM/Admin/Form/Setting/Smtp.tpl b/templates/CRM/Admin/Form/Setting/Smtp.tpl index aac1790078..8ab910f8ab 100644 --- a/templates/CRM/Admin/Form/Setting/Smtp.tpl +++ b/templates/CRM/Admin/Form/Setting/Smtp.tpl @@ -24,13 +24,24 @@ +--------------------------------------------------------------------+ *}
-
-

{ts}CiviCRM offers several options to send emails. The default option should work fine on linux systems. If you are using windows, you probably need to enter settings for your SMTP/Sendmail server. You can send a test email to check your settings by clicking "Save and Send Test Email". If you're unsure of the correct values, check with your system administrator, ISP or hosting provider.{/ts}

-

{ts}If you do not want users to send outbound mail from CiviCRM, select "Disable Outbound Email". NOTE: If you disable outbound email, and you are using Online Contribution pages or online Event Registration - you will need to disable automated receipts and registration confirmations.{/ts}

-

{ts}If you choose Redirect to Database, all emails will be recorded as archived mailings instead of being sent out. They can be found in the civicrm_mailing_spool table in the CiviCRM database.{/ts}

- -
+
+

{ts}General{/ts}

+ + + + +
{$form.allow_mail_from_logged_in_contact.html}{$form.allow_mail_from_logged_in_contact.label} {help id=allow_mail_contact_email}
+
+ {crmRegion name="smtp-mailer-config"} +
+

{ts}Mailer Configuration{/ts}

+
+

{ts}CiviCRM offers several options to send emails. You can send a test email to check your settings by clicking "Save and Send Test Email". If you're unsure of the correct values, check with your system administrator, ISP or hosting provider.{/ts}

+

{ts}If you do not want users to send outbound mail from CiviCRM, select "Disable Outbound Email". NOTE: If you disable outbound email, and you are using Online Contribution pages or online Event Registration - you will need to disable automated receipts and registration confirmations.{/ts}

+

{ts}If you choose Redirect to Database, all emails will be recorded as archived mailings instead of being sent out. They can be found in the civicrm_mailing_spool table in the CiviCRM database.{/ts}

+
+ @@ -92,7 +103,6 @@
{include file="CRM/common/formButtons.tpl"}
- {literal} {/literal} + + {/crmRegion} + diff --git a/templates/CRM/Contact/Form/Domain.hlp b/templates/CRM/Contact/Form/Domain.hlp index 0723bf1417..0a41cc9232 100644 --- a/templates/CRM/Contact/Form/Domain.hlp +++ b/templates/CRM/Contact/Form/Domain.hlp @@ -30,21 +30,6 @@ {ts 1='{domain.name}'}Enter the name of the organization or entity which owns this CiviCRM domain. Use the %1 token to include this value in mailing content. It is used in the default Opt-out Message.{/ts} {/htxt} - -{htxt id="from-name-title"} -{ts}From Name{/ts} -{/htxt} -{htxt id="from-name"} -{ts}The FROM Name and Email Address are used when automated emails are sent from this domain (e.g. subscribe and unsubscribe confirmations...). This Name and Email Address are also used as the default 'sender' values when you create a new CiviMail Mailing.{/ts} -{/htxt} - -{htxt id="from-email-title"} -{ts}From Address{/ts} -{/htxt} -{htxt id="from-email"} -{ts}The FROM Name and Email Address are used when automated emails are sent from this domain (e.g. subscribe and unsubscribe confirmations...). This Name and Email Address are also used as the default 'sender' values when you create a new CiviMail Mailing.{/ts} -{/htxt} - {htxt id="return-path-title"} {ts}Return Path{/ts} {/htxt} diff --git a/templates/CRM/Contact/Form/Domain.tpl b/templates/CRM/Contact/Form/Domain.tpl index f5619a8145..81affcc9d3 100644 --- a/templates/CRM/Contact/Form/Domain.tpl +++ b/templates/CRM/Contact/Form/Domain.tpl @@ -44,20 +44,6 @@
{$form.outBound_option.label} {$form.outBound_option.html}
-

{ts}System-generated Mail Settings{/ts}

- - - - - -
- {$form.email_name.label} {help id="from-name"}
- {$form.email_name.html} -
- {$form.email_address.label} {help id="from-email"}
- {$form.email_address.html} -
(info@example.org) -

{ts}Default Organization Address{/ts}

{ts 1={domain.address}}CiviMail mailings must include the sending organization's address. This is done by putting the %1 token in either the body or footer of the mailing. This token may also be used in regular 'Email - send now' messages and in other Message Templates. The token is replaced by the address entered below when the message is sent.{/ts}
diff --git a/templates/CRM/Contact/Form/Task/Email.tpl b/templates/CRM/Contact/Form/Task/Email.tpl index 304ee5ea1e..e3ca4f8e61 100644 --- a/templates/CRM/Contact/Form/Task/Email.tpl +++ b/templates/CRM/Contact/Form/Task/Email.tpl @@ -31,10 +31,10 @@
{/if} - - - - + + + + + + + + diff --git a/templates/CRM/Contribute/Form/Task/Invoice.hlp b/templates/CRM/Contribute/Form/Task/Invoice.hlp index 6d34a053d2..4845835cab 100644 --- a/templates/CRM/Contribute/Form/Task/Invoice.hlp +++ b/templates/CRM/Contribute/Form/Task/Invoice.hlp @@ -26,16 +26,6 @@ {htxt id ="id-from_email-title"} {ts}From Address{/ts} {/htxt} -{htxt id ="id-from_email"} -

{ts}Select the "FROM" Email Address for this mailing from the dropdown list. Available email addresses are configurable by users with Administer CiviCRM permission. EXAMPLE: "Client Services" <clientservices@example.org>{/ts}

-{if $params.isAdmin} - {capture assign="fromConfig"}{crmURL p="civicrm/admin/options/from_email_address" q="reset=1"}{/capture} -

{ts 1=$fromConfig}Go to Administer CiviCRM » Communications » FROM Email Addresses to add or edit email addresses. Make sure these email addresses are valid email accounts with your email service provider.{/ts}

-{else} - {ts}Contact your site administrator if you need to use a "FROM" Email Address which is not in the dropdown list.{/ts} -{/if} -{/htxt} - {htxt id="content-intro-title"} {ts}Message Formats{/ts} {/htxt} diff --git a/templates/CRM/Contribute/Form/Task/Invoice.tpl b/templates/CRM/Contribute/Form/Task/Invoice.tpl index 6c6fa9053a..fd2a6cb918 100644 --- a/templates/CRM/Contribute/Form/Task/Invoice.tpl +++ b/templates/CRM/Contribute/Form/Task/Invoice.tpl @@ -36,22 +36,27 @@
{$form.fromEmailAddress.label}{$form.fromEmailAddress.html} {help id="id-from_email" file="CRM/Contact/Form/Task/Email.hlp" isAdmin=$isAdmin}
{if $single eq false}{ts}Recipient(s){/ts}{else}{$form.to.label}{/if} diff --git a/templates/CRM/Contact/Form/Task/PDFLetterCommon.tpl b/templates/CRM/Contact/Form/Task/PDFLetterCommon.tpl index 5391f478c5..6c224af596 100644 --- a/templates/CRM/Contact/Form/Task/PDFLetterCommon.tpl +++ b/templates/CRM/Contact/Form/Task/PDFLetterCommon.tpl @@ -35,6 +35,10 @@ {$form.template.html} {ts}OR{/ts} {$form.document_file.html}
{$form.subject.label} {$form.subject.html}
{if $selectedOutput ne 'email'} + {/if} - - + + + - + + {if $selectedOutput ne 'email'} + {/if} - + +
{$form.output.email_invoice.label} {$form.output.email_invoice.html}
{$form.output.pdf_invoice.label} {$form.output.pdf_invoice.html}
{$form.pdf_format_id.html} {$form.pdf_format_id.label} {$form.pdf_format_id.label}{$form.pdf_format_id.html}
diff --git a/templates/CRM/Contribute/Form/Task/PDF.tpl b/templates/CRM/Contribute/Form/Task/PDF.tpl index 67d9934ef9..a198d00a58 100644 --- a/templates/CRM/Contribute/Form/Task/PDF.tpl +++ b/templates/CRM/Contribute/Form/Task/PDF.tpl @@ -35,8 +35,9 @@ {$form.output.email_receipt.html} - - {$form.fromEmailAddress.label}: {$form.fromEmailAddress.html} + + {$form.from_email_address.label} + {$form.from_email_address.html} {help id="id-from_email" file="CRM/Contact/Form/Task/Email.hlp" isAdmin=$isAdmin} {$form.output.pdf_receipt.html} diff --git a/templates/CRM/Contribute/Form/Task/PDFLetter.tpl b/templates/CRM/Contribute/Form/Task/PDFLetter.tpl index 6e9a49087f..c8cfb68c11 100644 --- a/templates/CRM/Contribute/Form/Task/PDFLetter.tpl +++ b/templates/CRM/Contribute/Form/Task/PDFLetter.tpl @@ -49,6 +49,10 @@ {$form.email_options.label} {help id="id-contribution-email-print"} {$form.email_options.html} + + {$form.from_email_address.label} {help id="id-from_email"} + {$form.from_email_address.html} +
diff --git a/templates/CRM/Member/Form/Membership.hlp b/templates/CRM/Member/Form/Membership.hlp index 5d62203578..e3d5297a2d 100644 --- a/templates/CRM/Member/Form/Membership.hlp +++ b/templates/CRM/Member/Form/Membership.hlp @@ -36,3 +36,12 @@ {/if} {/htxt} +{htxt id ="id-from_email"} +

{ts}Select the "FROM" Email Address for this mailing from the dropdown list. Available email addresses are configurable by users with Administer CiviCRM permission. EXAMPLE: "Client Services" <clientservices@example.org>{/ts}

+{if $params.isAdmin} + {capture assign="fromConfig"}{crmURL p="civicrm/admin/options/from_email_address" q="reset=1"}{/capture} +

{ts 1=$fromConfig}Go to Administer CiviCRM » Communications » FROM Email Addresses to add or edit email addresses. Make sure these email addresses are valid email accounts with your email service provider.{/ts}

+{else} + {ts}Contact your site administrator if you need to use a "FROM" Email Address which is not in the dropdown list.{/ts} +{/if} +{/htxt} diff --git a/templates/CRM/Member/Form/Membership.tpl b/templates/CRM/Member/Form/Membership.tpl index 61b5cdb950..460d3b712d 100644 --- a/templates/CRM/Member/Form/Membership.tpl +++ b/templates/CRM/Member/Form/Membership.tpl @@ -190,9 +190,9 @@ {ts}For auto-renewing memberships the emails are sent when each payment is received{/ts} {/if} - + {$form.from_email_address.label} - {$form.from_email_address.html} + {$form.from_email_address.html} {help id="id-from_email" file="CRM/Contact/Form/Task/Email.hlp" isAdmin=$isAdmin} {$form.receipt_text.label} diff --git a/templates/CRM/Member/Form/MembershipRenewal.tpl b/templates/CRM/Member/Form/MembershipRenewal.tpl index d4e181d432..758c590bef 100644 --- a/templates/CRM/Member/Form/MembershipRenewal.tpl +++ b/templates/CRM/Member/Form/MembershipRenewal.tpl @@ -129,7 +129,7 @@ {$form.from_email_address.label} - {$form.from_email_address.html} + {$form.from_email_address.html} {help id="id-from_email" isAdmin=$isAdmin} {$form.receipt_text_renewal.label} diff --git a/tests/phpunit/CRM/Contact/Form/Task/EmailCommonTest.php b/tests/phpunit/CRM/Contact/Form/Task/EmailCommonTest.php index ad5a510d22..ce684d09fe 100644 --- a/tests/phpunit/CRM/Contact/Form/Task/EmailCommonTest.php +++ b/tests/phpunit/CRM/Contact/Form/Task/EmailCommonTest.php @@ -46,7 +46,7 @@ class CRM_Contact_Form_Task_EmailCommonTest extends CiviUnitTestCase { * Test generating domain emails */ public function testDomainEmailGeneration() { - $emails = CRM_Contact_Form_Task_EmailCommon::domainEmails(); + $emails = CRM_Core_BAO_Email::domainEmails(); $this->assertNotEmpty($emails); $optionValue = $this->callAPISuccess('OptionValue', 'Get', array( 'id' => $this->_optionValue['id'], diff --git a/tests/phpunit/CRM/Contribute/Form/Task/PDFLetterCommonTest.php b/tests/phpunit/CRM/Contribute/Form/Task/PDFLetterCommonTest.php index 93faf4db3b..ba946538a5 100644 --- a/tests/phpunit/CRM/Contribute/Form/Task/PDFLetterCommonTest.php +++ b/tests/phpunit/CRM/Contribute/Form/Task/PDFLetterCommonTest.php @@ -206,6 +206,7 @@ class CRM_Contribute_Form_Task_PDFLetterCommonTest extends CiviUnitTestCase { 'html_message' => $htmlMessage, 'email_options' => 'both', 'subject' => 'Testy test test', + 'from' => 'info@example.com', ); $contributionIDs = array(); -- 2.25.1