Skip to content
Snippets Groups Projects
Commit 0261f17f authored by eileen's avatar eileen
Browse files

Tidy up opt out handling in contact import

parent 1d903d19
Branches
Tags
No related merge requests found
......@@ -128,6 +128,7 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser {
try {
$params = $this->getMappedRow($values);
$params['id'] = $this->processContact($params, TRUE);
$formatted = [];
foreach ($params as $key => $value) {
if ($value !== '') {
......@@ -135,8 +136,6 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser {
}
}
$formatted['id'] = $params['id'] = $this->processContact($params, TRUE);
//format common data, CRM-4062
$this->formatCommonData($params, $formatted);
......@@ -450,11 +449,23 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser {
*
* @return \CRM_Contact_BAO_Contact
* If a duplicate is found an array is returned, otherwise CRM_Contact_BAO_Contact
* @throws \CRM_Core_Exception
*/
public function createContact(&$formatted, $contactId = NULL) {
if ($contactId) {
$this->formatParams($formatted, (int) $contactId);
// manage is_opt_out
$existingOptOut = $this->getExistingContactValue($contactId, 'is_opt_out');
if (array_key_exists('is_opt_out', $formatted) && $existingOptOut !== (bool) $formatted['is_opt_out']
) {
// on change, create new civicrm_subscription_history entry
CRM_Contact_BAO_SubscriptionHistory::writeRecord([
'contact_id' => $contactId,
'status' => $formatted['is_opt_out'] ? 'Removed' : 'Added',
'method' => 'Import',
]);
}
}
// Resetting and rebuilding cache could be expensive.
......@@ -472,23 +483,7 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser {
}
$contactFields = CRM_Contact_DAO_Contact::import();
[$data, $contactDetails] = $this->formatProfileContactParams($formatted, $contactFields, $contactId, $formatted['contact_type']);
// manage is_opt_out
if (array_key_exists('is_opt_out', $contactFields) && array_key_exists('is_opt_out', $formatted)) {
$wasOptOut = $contactDetails['is_opt_out'] ?? FALSE;
$isOptOut = $formatted['is_opt_out'];
$data['is_opt_out'] = $isOptOut;
// on change, create new civicrm_subscription_history entry
if (($wasOptOut != $isOptOut) && !empty($contactDetails['contact_id'])) {
$shParams = [
'contact_id' => $contactDetails['contact_id'],
'status' => $isOptOut ? 'Removed' : 'Added',
'method' => 'Web',
];
CRM_Contact_BAO_SubscriptionHistory::create($shParams);
}
}
$data = $this->formatProfileContactParams($formatted, $contactFields, $contactId, $formatted['contact_type']);
$contact = civicrm_api3('Contact', 'create', $data);
$cid = $contact['id'];
......@@ -693,7 +688,7 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser {
}
}
return [$data, $contactDetails];
return $data;
}
/**
......@@ -1313,11 +1308,7 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser {
protected function processContact(array $params, bool $isMainContact): ?int {
$contactID = $this->lookupContactID($params, $isMainContact);
if ($contactID && !empty($params['contact_sub_type'])) {
$contactSubType = Contact::get(FALSE)
->addWhere('id', '=', $contactID)
->addSelect('contact_sub_type')
->execute()
->first()['contact_sub_type'];
$contactSubType = $this->getExistingContactValue($contactID, 'contact_sub_type');
if (!empty($contactSubType) && $contactSubType[0] !== $params['contact_sub_type'] && !CRM_Contact_BAO_ContactType::isAllowEdit($contactID, $contactSubType[0])) {
throw new CRM_Core_Exception('Mismatched contact SubTypes :', CRM_Import_Parser::NO_MATCH);
}
......
......@@ -30,6 +30,7 @@ use Civi\UserJob\UserJobInterface;
* supported.
*/
abstract class CRM_Import_Parser implements UserJobInterface {
use \Civi\API\EntityLookupTrait;
/**
* Return codes
......@@ -186,6 +187,29 @@ abstract class CRM_Import_Parser implements UserJobInterface {
return $this->getDataSourceObject()->isCompleted();
}
/**
* @param int $contactID
* @param string $value
*
* @return int|string|bool|null|array
* @throws \CRM_Core_Exception
*/
public function getExistingContactValue(int $contactID, string $value): mixed {
$identifier = 'Contact' . $contactID;
if (!$this->isDefined($identifier)) {
$existingContact = Contact::get(FALSE)
->addWhere('id', '=', $contactID)
// Don't auto-filter deleted - people use import to undelete.
->addWhere('is_deleted', 'IN', [0, 1])
->execute()->first();
if (empty($existingContact['id'])) {
throw new CRM_Core_Exception('No contact found for this contact ID:' . $contactID, CRM_Import_Parser::NO_MATCH);
}
$this->define('Contact', $identifier, $existingContact);
}
return $this->lookup($identifier, $value);
}
/**
* Get configured contact type.
*
......@@ -587,15 +611,7 @@ abstract class CRM_Import_Parser implements UserJobInterface {
* @throws \CRM_Core_Exception
*/
protected function validateContactID(int $contactID, ?string $contactType): void {
$existingContact = Contact::get(FALSE)
->addWhere('id', '=', $contactID)
// Don't auto-filter deleted - people use import to undelete.
->addWhere('is_deleted', 'IN', [0, 1])
->addSelect('contact_type')->execute()->first();
if (empty($existingContact['id'])) {
throw new CRM_Core_Exception('No contact found for this contact ID:' . $contactID, CRM_Import_Parser::NO_MATCH);
}
if ($contactType && $existingContact['contact_type'] !== $contactType) {
if ($contactType && $this->getExistingContactValue($contactID, 'contact_type') !== $contactType) {
throw new CRM_Core_Exception('Mismatched contact Types', CRM_Import_Parser::NO_MATCH);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment