From 993a642cb9f193cf4d551987865dde314df83198 Mon Sep 17 00:00:00 2001 From: Ivan Date: Mon, 17 Aug 2020 13:13:33 +0100 Subject: [PATCH] CATL-1614: Add new field to the mail account form - Do not create new contacts when filing emails --- CRM/Admin/Form/MailSettings.php | 4 + CRM/Upgrade/Incremental/php/FiveThirtyOne.php | 11 +++ CRM/Utils/Mail/EmailProcessor.php | 6 +- CRM/Utils/Mail/Incoming.php | 20 +++-- templates/CRM/Admin/Form/MailSettings.tpl | 77 +++++++++++-------- .../CRM/Utils/Mail/EmailProcessorTest.php | 33 ++++++++ xml/schema/Core/MailSettings.xml | 11 +++ 7 files changed, 118 insertions(+), 44 deletions(-) diff --git a/CRM/Admin/Form/MailSettings.php b/CRM/Admin/Form/MailSettings.php index 4de49fe413..3ec4e11d0a 100644 --- a/CRM/Admin/Form/MailSettings.php +++ b/CRM/Admin/Form/MailSettings.php @@ -70,6 +70,8 @@ class CRM_Admin_Form_MailSettings extends CRM_Admin_Form { ]; $this->add('select', 'is_default', ts('Used For?'), $usedfor); $this->addField('activity_status', ['placeholder' => FALSE]); + + $this->add('checkbox', 'is_contact_creation_disabled_if_no_match', ts('Do not create new contacts when filing emails')); } /** @@ -146,6 +148,7 @@ class CRM_Admin_Form_MailSettings extends CRM_Admin_Form { 'is_ssl', 'is_default', 'activity_status', + 'is_contact_creation_disabled_if_no_match', ]; $params = []; @@ -153,6 +156,7 @@ class CRM_Admin_Form_MailSettings extends CRM_Admin_Form { if (in_array($f, [ 'is_default', 'is_ssl', + 'is_contact_creation_disabled_if_no_match', ])) { $params[$f] = CRM_Utils_Array::value($f, $formValues, FALSE); } diff --git a/CRM/Upgrade/Incremental/php/FiveThirtyOne.php b/CRM/Upgrade/Incremental/php/FiveThirtyOne.php index 8cbbaf1aae..52e7374b4c 100644 --- a/CRM/Upgrade/Incremental/php/FiveThirtyOne.php +++ b/CRM/Upgrade/Incremental/php/FiveThirtyOne.php @@ -67,6 +67,17 @@ class CRM_Upgrade_Incremental_php_FiveThirtyOne extends CRM_Upgrade_Incremental_ $this->addTask('Activate core extension "Greenwich"', 'installGreenwich'); } + /** + * Upgrade function. + * + * @param string $rev + */ + public function upgrade_5_31_0($rev) { + $this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev); + $this->addTask('Add is_contact_creation_disabled_if_no_match column to civicrm_mail_settings', 'addColumn', + 'civicrm_mail_settings', 'is_contact_creation_disabled_if_no_match', "TINYINT DEFAULT 0 NOT NULL COMMENT 'If this option is enabled, CiviCRM will not create new contacts when filing emails'"); + } + public static function enableEwaySingleExtension(CRM_Queue_TaskContext $ctx) { $eWAYPaymentProcessorType = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_payment_processor_type WHERE class_name = 'Payment_eWAY'"); if ($eWAYPaymentProcessorType) { diff --git a/CRM/Utils/Mail/EmailProcessor.php b/CRM/Utils/Mail/EmailProcessor.php index a8be02ce0a..b1dcd2a6ff 100644 --- a/CRM/Utils/Mail/EmailProcessor.php +++ b/CRM/Utils/Mail/EmailProcessor.php @@ -157,7 +157,7 @@ class CRM_Utils_Mail_EmailProcessor { try { $store = CRM_Mailing_MailStore::getStore($dao->name); } - catch (Exception$e) { + catch (Exception $e) { $message = ts('Could not connect to MailStore for ') . $dao->username . '@' . $dao->server . '

'; $message .= ts('Error message: '); $message .= '

' . $e->getMessage() . '

'; @@ -226,7 +226,8 @@ class CRM_Utils_Mail_EmailProcessor { if ($usedfor == 0 || $is_create_activities) { // if its the activities that needs to be processed .. try { - $mailParams = CRM_Utils_Mail_Incoming::parseMailingObject($mail); + $createContact = !($dao->is_contact_creation_disabled_if_no_match ?? FALSE); + $mailParams = CRM_Utils_Mail_Incoming::parseMailingObject($mail, $createContact, FALSE); } catch (Exception $e) { echo $e->getMessage(); @@ -241,6 +242,7 @@ class CRM_Utils_Mail_EmailProcessor { if (!empty($dao->activity_status)) { $params['status_id'] = $dao->activity_status; } + $result = civicrm_api('activity', 'create', $params); if ($result['is_error']) { diff --git a/CRM/Utils/Mail/Incoming.php b/CRM/Utils/Mail/Incoming.php index 1e2da04223..a119610812 100644 --- a/CRM/Utils/Mail/Incoming.php +++ b/CRM/Utils/Mail/Incoming.php @@ -322,10 +322,12 @@ class CRM_Utils_Mail_Incoming { /** * @param $mail + * @param $createContact + * @param $requireContact * * @return array */ - public static function parseMailingObject(&$mail) { + public static function parseMailingObject(&$mail, $createContact = TRUE, $requireContact = TRUE) { $config = CRM_Core_Config::singleton(); @@ -342,18 +344,18 @@ class CRM_Utils_Mail_Incoming { } $params['from'] = []; - self::parseAddress($mail->from, $field, $params['from'], $mail); + self::parseAddress($mail->from, $field, $params['from'], $mail, $createContact); // we definitely need a contact id for the from address // if we dont have one, skip this email - if (empty($params['from']['id'])) { + if ($requireContact && empty($params['from']['id'])) { return NULL; } $emailFields = ['to', 'cc', 'bcc']; foreach ($emailFields as $field) { $value = $mail->$field; - self::parseAddresses($value, $field, $params, $mail); + self::parseAddresses($value, $field, $params, $mail, $createContact); } // define other parameters @@ -396,8 +398,9 @@ class CRM_Utils_Mail_Incoming { * @param array $params * @param $subParam * @param $mail + * @param $createContact */ - public static function parseAddress(&$address, &$params, &$subParam, &$mail) { + public static function parseAddress(&$address, &$params, &$subParam, &$mail, $createContact = TRUE) { // CRM-9484 if (empty($address->email)) { return; @@ -408,7 +411,7 @@ class CRM_Utils_Mail_Incoming { $contactID = self::getContactID($subParam['email'], $subParam['name'], - TRUE, + $createContact, $mail ); $subParam['id'] = $contactID ? $contactID : NULL; @@ -419,13 +422,14 @@ class CRM_Utils_Mail_Incoming { * @param $token * @param array $params * @param $mail + * @param $createContact */ - public static function parseAddresses(&$addresses, $token, &$params, &$mail) { + public static function parseAddresses(&$addresses, $token, &$params, &$mail, $createContact = TRUE) { $params[$token] = []; foreach ($addresses as $address) { $subParam = []; - self::parseAddress($address, $params, $subParam, $mail); + self::parseAddress($address, $params, $subParam, $mail, $createContact); $params[$token][] = $subParam; } } diff --git a/templates/CRM/Admin/Form/MailSettings.tpl b/templates/CRM/Admin/Form/MailSettings.tpl index 361ffe09e1..9185c54a18 100644 --- a/templates/CRM/Admin/Form/MailSettings.tpl +++ b/templates/CRM/Admin/Form/MailSettings.tpl @@ -9,62 +9,71 @@ *} {* this template is used for adding/editing email settings. *}

-
{include file="CRM/common/formButtons.tpl" location="top"}
-{if $action eq 8} -
+
{include file="CRM/common/formButtons.tpl" location="top"}
+ {if $action eq 8} +
{icon icon="fa-info-circle"}{/icon} - {ts}WARNING: Deleting this option will result in the loss of mail settings data.{/ts} {ts}Do you want to continue?{/ts} -
+ {ts}WARNING: Deleting this option will result in the loss of mail settings data.{/ts} {ts}Do you want to continue?{/ts} +
{include file="CRM/common/formButtons.tpl" location="top"}
-{else} + {else} - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + + +
{$form.name.label}{$form.name.html}
 {ts}Name of this group of settings.{/ts}
{$form.name.label}{$form.name.html}
 {ts}Name of this group of settings.{/ts}
{$form.server.label}{$form.server.html}
 {ts}Name or IP address of mail server machine.{/ts}
{$form.server.label}{$form.server.html}
 {ts}Name or IP address of mail server machine.{/ts}
{$form.username.label}{$form.username.html}
 {ts}Username to use when polling (for IMAP and POP3).{/ts}
{$form.username.label}{$form.username.html}
 {ts}Username to use when polling (for IMAP and POP3).{/ts}
{$form.password.label}{$form.password.html}
 {ts}Password to use when polling (for IMAP and POP3).{/ts}
{$form.password.label}{$form.password.html}
 {ts}Password to use when polling (for IMAP and POP3).{/ts}
{$form.localpart.label}{$form.localpart.html}
 {ts}Optional local part (e.g., 'civimail+' for addresses like civimail+s.1.2@example.com).{/ts}
{$form.localpart.label}{$form.localpart.html}
 {ts}Optional local part (e.g., 'civimail+' for addresses like civimail+s.1.2@example.com).{/ts}
{$form.domain.label}{$form.domain.html}
 {ts}Email address domain (the part after @).{/ts}
{$form.domain.label}{$form.domain.html}
 {ts}Email address domain (the part after @).{/ts}
{$form.return_path.label}{$form.return_path.html}
 {ts}Contents of the Return-Path header.{/ts}
{$form.return_path.label}{$form.return_path.html}
 {ts}Contents of the Return-Path header.{/ts}
{$form.protocol.label}{$form.protocol.html}
 {ts}Name of the protocol to use for polling.{/ts}
{$form.protocol.label}{$form.protocol.html}
 {ts}Name of the protocol to use for polling.{/ts}
{$form.source.label}{$form.source.html}
 {ts}Folder to poll from when using IMAP (will default to INBOX when empty), path to poll from when using Maildir, etc..{/ts}
{$form.source.label}{$form.source.html}
 {ts}Folder to poll from when using IMAP (will default to INBOX when empty), path to poll from when using Maildir, etc..{/ts}
{$form.is_ssl.label}{$form.is_ssl.html}
 {ts}Whether to use SSL for IMAP and POP3 or not.{/ts}
{$form.is_ssl.label}{$form.is_ssl.html}
 {ts}Whether to use SSL for IMAP and POP3 or not.{/ts}
{$form.is_default.label}{$form.is_default.html}
 {ts}How this mail account will be used. Only one box may be used for bounce processing. It will also be used as the envelope email when sending mass mailings.{/ts}
{$form.is_default.label}{$form.is_default.html}
 {ts}How this mail account will be used. Only one box may be used for bounce processing. It will also be used as the envelope email when sending mass mailings.{/ts}
{$form.activity_status.label}{$form.activity_status.html}
 {$form.is_contact_creation_disabled_if_no_match.html}{$form.is_contact_creation_disabled_if_no_match.label}
 {$form.activity_status.label}
{$form.activity_status.html}
-
{include file="CRM/common/formButtons.tpl" location="bottom"}
-{/if} + +
{include file="CRM/common/formButtons.tpl" location="bottom"}
+ {/if}
+ {literal} {/literal} diff --git a/tests/phpunit/CRM/Utils/Mail/EmailProcessorTest.php b/tests/phpunit/CRM/Utils/Mail/EmailProcessorTest.php index 13a25d78cc..37efac4169 100644 --- a/tests/phpunit/CRM/Utils/Mail/EmailProcessorTest.php +++ b/tests/phpunit/CRM/Utils/Mail/EmailProcessorTest.php @@ -169,4 +169,37 @@ class CRM_Utils_Mail_EmailProcessorTest extends CiviUnitTestCase { $this->eventQueue = $this->callAPISuccess('MailingEventQueue', 'get', ['api.MailingEventQueue.create' => ['hash' => 'aaaaaaaaaaaaaaaa']]); } + /** + * Set up mail account with 'Do not create new contacts when filing emails' + * option enabled. + */ + public function setUpDoNotCreateContact() { + $this->callAPISuccess('MailSettings', 'get', [ + 'api.MailSettings.create' => [ + 'name' => 'mailbox', + 'protocol' => 'Localdir', + 'source' => __DIR__ . '/data/mail', + 'domain' => 'example.com', + 'is_default' => '0', + 'is_contact_creation_disabled_if_no_match' => TRUE, + ], + ]); + } + + /** + * Test case email processing when is_non_case_email_skipped is enabled. + */ + public function testInboundProcessingDoNotCreateContact() { + $this->setUpDoNotCreateContact(); + $mail = 'test_non_cases_email.eml'; + + copy(__DIR__ . '/data/inbound/' . $mail, __DIR__ . '/data/mail/' . $mail); + $this->callAPISuccess('job', 'fetch_activities', []); + $result = civicrm_api3('Contact', 'get', [ + 'sequential' => 1, + 'email' => "from@test.test", + ]); + $this->assertEmpty($result['values']); + } + } diff --git a/xml/schema/Core/MailSettings.xml b/xml/schema/Core/MailSettings.xml index 0dea26c13b..e5f6db3107 100644 --- a/xml/schema/Core/MailSettings.xml +++ b/xml/schema/Core/MailSettings.xml @@ -150,4 +150,15 @@ Select + + is_contact_creation_disabled_if_no_match + boolean + Do not create new contacts when filing emails + 0 + + CheckBox + + If this option is enabled, CiviCRM will not create new contacts when filing emails. + 5.31 + -- 2.25.1