Skip to content

Commit

Permalink
Simplify greeting handling, add test
Browse files Browse the repository at this point in the history
  • Loading branch information
eileenmcnaughton committed May 31, 2022
1 parent 2a63803 commit 96cd3f3
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 162 deletions.
11 changes: 0 additions & 11 deletions CRM/Contact/BAO/Contact.php
Original file line number Diff line number Diff line change
Expand Up @@ -782,17 +782,6 @@ protected static function contactTrash($contact): bool {
*/
public static function resolveDefaults(&$defaults, $reverse = FALSE) {

//lookup value of email/postal greeting, addressee, CRM-4575
foreach (self::$_greetingTypes as $greeting) {
$filterCondition = [
'contact_type' => $defaults['contact_type'] ?? NULL,
'greeting_type' => $greeting,
];
CRM_Utils_Array::lookupValue($defaults, $greeting,
CRM_Core_PseudoConstant::greeting($filterCondition), $reverse
);
}

$blocks = ['address'];
foreach ($blocks as $name) {
if (!array_key_exists($name, $defaults) || !is_array($defaults[$name])) {
Expand Down
118 changes: 12 additions & 106 deletions CRM/Contact/Import/Parser/Contact.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ class CRM_Contact_Import_Parser_Contact extends CRM_Import_Parser {
'email',
'website',
'url',
'email_greeting',
'email_greeting_id',
'postal_greeting',
'postal_greeting_id',
'addressee',
'addressee_id',
];

/**
Expand Down Expand Up @@ -288,10 +294,10 @@ public function import($onDuplicate, &$values) {
}

$params = $this->getMappedRow($values);
$formatted = array_intersect_key($params, array_fill_keys($this->metadataHandledFields, 1));
foreach ($formatted as $key => $value) {
if (!is_array($value) && !strlen($value)) {
unset($formatted[$key]);
$formatted = [];
foreach ($params as $key => $value) {
if ($value !== '') {
$formatted[$key] = $value;
}
}

Expand Down Expand Up @@ -972,66 +978,6 @@ public function isErrorInCoreData($params, &$errorMessage) {
}
break;

//check for any error in email/postal greeting, addressee,
//custom email/postal greeting, custom addressee, CRM-4575

case 'email_greeting':
$emailGreetingFilter = [
'contact_type' => $this->_contactType,
'greeting_type' => 'email_greeting',
];
if (!self::in_value($value, CRM_Core_PseudoConstant::greeting($emailGreetingFilter))) {
$errors[] = ts('Email Greeting must be one of the configured format options. Check Administer >> System Settings >> Option Groups >> Email Greetings for valid values');
}
break;

case 'postal_greeting':
$postalGreetingFilter = [
'contact_type' => $this->_contactType,
'greeting_type' => 'postal_greeting',
];
if (!self::in_value($value, CRM_Core_PseudoConstant::greeting($postalGreetingFilter))) {
$errors[] = ts('Postal Greeting must be one of the configured format options. Check Administer >> System Settings >> Option Groups >> Postal Greetings for valid values');
}
break;

case 'addressee':
$addresseeFilter = [
'contact_type' => $this->_contactType,
'greeting_type' => 'addressee',
];
if (!self::in_value($value, CRM_Core_PseudoConstant::greeting($addresseeFilter))) {
$errors[] = ts('Addressee must be one of the configured format options. Check Administer >> System Settings >> Option Groups >> Addressee for valid values');
}
break;

case 'email_greeting_custom':
if (array_key_exists('email_greeting', $params)) {
$emailGreetingLabel = key(CRM_Core_OptionGroup::values('email_greeting', TRUE, NULL, NULL, 'AND v.name = "Customized"'));
if (CRM_Utils_Array::value('email_greeting', $params) != $emailGreetingLabel) {
$errors[] = ts('Email Greeting - Custom');
}
}
break;

case 'postal_greeting_custom':
if (array_key_exists('postal_greeting', $params)) {
$postalGreetingLabel = key(CRM_Core_OptionGroup::values('postal_greeting', TRUE, NULL, NULL, 'AND v.name = "Customized"'));
if (CRM_Utils_Array::value('postal_greeting', $params) != $postalGreetingLabel) {
$errors[] = ts('Postal Greeting - Custom');
}
}
break;

case 'addressee_custom':
if (array_key_exists('addressee', $params)) {
$addresseeLabel = key(CRM_Core_OptionGroup::values('addressee', TRUE, NULL, NULL, 'AND v.name = "Customized"'));
if (CRM_Utils_Array::value('addressee', $params) != $addresseeLabel) {
$errors[] = ts('Addressee - Custom');
}
}
break;

case 'do_not_email':
case 'do_not_phone':
case 'do_not_mail':
Expand Down Expand Up @@ -1373,11 +1319,7 @@ private function formatProfileContactParams(
}
}
else {
if (in_array($key, CRM_Contact_BAO_Contact::$_greetingTypes, TRUE)) {
//save email/postal greeting and addressee values if any, CRM-4575
$data[$key . '_id'] = $value;
}
elseif (($customFieldId = CRM_Core_BAO_CustomField::getKeyID($key))) {
if (($customFieldId = CRM_Core_BAO_CustomField::getKeyID($key))) {
// for autocomplete transfer hidden value instead of label
if ($params[$key] && isset($params[$key . '_id'])) {
$value = $params[$key . '_id'];
Expand Down Expand Up @@ -2048,43 +1990,6 @@ protected function formatContactParameters(&$values, &$params) {
// @todo - remove this after confirming this is just a compilation of other-wise-cached fields.
static $fields = [];

// CRM-4575
if (isset($values['email_greeting'])) {
if (!empty($params['email_greeting_id'])) {
$emailGreetingFilter = [
'contact_type' => $params['contact_type'] ?? NULL,
'greeting_type' => 'email_greeting',
];
$emailGreetings = CRM_Core_PseudoConstant::greeting($emailGreetingFilter);
$params['email_greeting'] = $emailGreetings[$params['email_greeting_id']];
}
else {
$params['email_greeting'] = $values['email_greeting'];
}

return TRUE;
}

if (isset($values['postal_greeting'])) {
if (!empty($params['postal_greeting_id'])) {
$postalGreetingFilter = [
'contact_type' => $params['contact_type'] ?? NULL,
'greeting_type' => 'postal_greeting',
];
$postalGreetings = CRM_Core_PseudoConstant::greeting($postalGreetingFilter);
$params['postal_greeting'] = $postalGreetings[$params['postal_greeting_id']];
}
else {
$params['postal_greeting'] = $values['postal_greeting'];
}
return TRUE;
}

if (isset($values['addressee'])) {
$params['addressee'] = $values['addressee'];
return TRUE;
}

if (isset($values['note'])) {
// add a note field
if (!isset($params['note'])) {
Expand Down Expand Up @@ -2620,6 +2525,7 @@ private function addFieldToParams(array &$contactArray, array $locationValues, s
}
}
else {
$fieldName = array_search($fieldName, $this->getOddlyMappedMetadataFields(), TRUE) ?: $fieldName;
$contactArray[$fieldName] = $this->getTransformedFieldValue($fieldName, $importedValue);
}
}
Expand Down
91 changes: 46 additions & 45 deletions CRM/Import/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
+--------------------------------------------------------------------+
*/

use Civi\Api4\CustomField;
use Civi\Api4\UserJob;

/**
Expand Down Expand Up @@ -818,43 +819,6 @@ private function _civicrm_api3_deprecated_add_formatted_param(&$values, &$params
return TRUE;
}

// CRM-4575
if (isset($values['email_greeting'])) {
if (!empty($params['email_greeting_id'])) {
$emailGreetingFilter = [
'contact_type' => $params['contact_type'] ?? NULL,
'greeting_type' => 'email_greeting',
];
$emailGreetings = CRM_Core_PseudoConstant::greeting($emailGreetingFilter);
$params['email_greeting'] = $emailGreetings[$params['email_greeting_id']];
}
else {
$params['email_greeting'] = $values['email_greeting'];
}

return TRUE;
}

if (isset($values['postal_greeting'])) {
if (!empty($params['postal_greeting_id'])) {
$postalGreetingFilter = [
'contact_type' => $params['contact_type'] ?? NULL,
'greeting_type' => 'postal_greeting',
];
$postalGreetings = CRM_Core_PseudoConstant::greeting($postalGreetingFilter);
$params['postal_greeting'] = $postalGreetings[$params['postal_greeting_id']];
}
else {
$params['postal_greeting'] = $values['postal_greeting'];
}
return TRUE;
}

if (isset($values['addressee'])) {
$params['addressee'] = $values['addressee'];
return TRUE;
}

if (isset($values['gender'])) {
if (!empty($params['gender_id'])) {
$genders = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'gender_id');
Expand Down Expand Up @@ -1268,25 +1232,43 @@ protected function getFieldOptions(string $fieldName) {
*/
protected function getFieldMetadata(string $fieldName, bool $loadOptions = FALSE, $limitToContactType = FALSE): array {

$fieldMap = ['country_id' => 'country'];
$fieldMap = $this->getOddlyMappedMetadataFields();
$fieldMapName = empty($fieldMap[$fieldName]) ? $fieldName : $fieldMap[$fieldName];

$fieldMetadata = $this->getImportableFieldsMetadata()[$fieldMapName] ?? ($limitToContactType ? NULL : CRM_Contact_BAO_Contact::importableFields('All')[$fieldMapName]);
if ($loadOptions && !isset($fieldMetadata['options'])) {
// This whole business of only loading metadata for one type when we actually need it for all is ... dubious.
if (empty($this->getImportableFieldsMetadata()[$fieldMapName])) {
if ($loadOptions || !$limitToContactType) {
$this->importableFieldsMetadata[$fieldMapName] = CRM_Contact_BAO_Contact::importableFields('All')[$fieldMapName];
}
}

$fieldMetadata = $this->getImportableFieldsMetadata()[$fieldMapName];
if ($loadOptions && !isset($fieldMetadata['options'])) {
$optionFieldName = empty($fieldMap[$fieldName]) ? $fieldMetadata['name'] : $fieldName;
if (!empty($fieldMetadata['custom_group_id'])) {
$customField = CustomField::get(FALSE)->addWhere('id', '=', $fieldMetadata['custom_field_id'])
->addSelect('name', 'custom_group_id.name')->execute()->first();
$optionFieldName = $customField['custom_group_id.name'] . '.' . $customField['name'];
}
$options = civicrm_api4($this->getFieldEntity($fieldName), 'getFields', [
'loadOptions' => ['id', 'name', 'label'],
'where' => [['name', '=', empty($fieldMap[$fieldName]) ? $fieldMetadata['name'] : $fieldName]],
'loadOptions' => ['id', 'name', 'label', 'abbr'],
'where' => [['name', '=', $optionFieldName]],
'select' => ['options'],
])->first()['options'];
if (is_array($options)) {
// We create an array of the possible variants - notably including
// name AND label as either might be used. We also lower case before checking
$values = [];
foreach ($options as $option) {
$values[$option['id']] = $option['id'];
$values[mb_strtolower($option['name'])] = $option['id'];
$values[mb_strtolower($option['label'])] = $option['id'];
$idKey = is_numeric($option['id']) ? $option['id'] : mb_strtolower($option['id']);
$values[$idKey] = $option['id'];
foreach (['name', 'label', 'abbr'] as $key) {
$optionValue = mb_strtolower($option[$key] ?? '');
if ($optionValue !== '') {
$values[$optionValue] = $option['id'];
}
}

}
$this->importableFieldsMetadata[$fieldMapName]['options'] = $values;
}
Expand Down Expand Up @@ -1385,6 +1367,9 @@ protected function getFieldEntity(string $fieldName) {
if ($fieldName === 'do_not_import') {
return NULL;
}
if (in_array($fieldName, ['email_greeting_id', 'postal_greeting_id', 'addressee_id'], TRUE)) {
return 'Contact';
}
$metadata = $this->getFieldMetadata($fieldName);
if (!isset($metadata['entity'])) {
return in_array($metadata['extends'], ['Individual', 'Organization', 'Household'], TRUE) ? 'Contact' : $metadata['extends'];
Expand Down Expand Up @@ -1443,4 +1428,20 @@ protected function getAvailableCountries() {
return $this->availableCountries;
}

/**
* Get the metadata field for which importable fields does not key the actual field name.
*
* @return string[]
*/
protected function getOddlyMappedMetadataFields(): array {
return [
'country_id' => 'country',
'state_province_id' => 'state_province',
'county_id' => 'county',
'email_greeting_id' => 'email_greeting',
'postal_greeting_id' => 'postal_greeting',
'addressee_id' => 'addressee',
];
}

}
43 changes: 43 additions & 0 deletions tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,49 @@ public function testGenderLabel() {
$this->callAPISuccessGetSingle('Contact', $contactValues);
}

/**
* Test greeting imports.
*
* @throws \API_Exception
* @throws \CRM_Core_Exception
* @throws \CiviCRM_API3_Exception
*/
public function testGreetings(): void {
$contactValues = [
'first_name' => 'Bill',
'last_name' => 'Gates',
// id = 2
'email_greeting' => 'Dear {contact.prefix_id:label} {contact.first_name} {contact.last_name}',
// id = 3
'postal_greeting' => 'Dear {contact.prefix_id:label} {contact.last_name}',
// id = 1
'addressee' => '{contact.prefix_id:label}{ }{contact.first_name}{ }{contact.middle_name}{ }{contact.last_name}{ }{contact.suffix_id:label}',
5 => 1,
];
$userJobID = $this->getUserJobID(['mapper' => [['first_name'], ['last_name'], ['email_greeting'], ['postal_greeting'], ['addressee']]]);
$parser = new CRM_Contact_Import_Parser_Contact(array_keys($contactValues));
$parser->setUserJobID($userJobID);
$values = array_values($contactValues);
$parser->import(CRM_Import_Parser::DUPLICATE_UPDATE, $values);
$contact = Contact::get(FALSE)->addWhere('last_name', '=', 'Gates')->addSelect('email_greeting_id', 'postal_greeting_id', 'addressee_id')->execute()->first();
$this->assertEquals(2, $contact['email_greeting_id']);
$this->assertEquals(3, $contact['postal_greeting_id']);
$this->assertEquals(1, $contact['addressee_id']);

Contact::delete()->addWhere('id', '=', $contact['id'])->setUseTrash(TRUE)->execute();

// Now try again with numbers.
$values[2] = 2;
$values[3] = 3;
$values[4] = 1;
$parser->import(CRM_Import_Parser::DUPLICATE_UPDATE, $values);
$contact = Contact::get(FALSE)->addWhere('last_name', '=', 'Gates')->addSelect('email_greeting_id', 'postal_greeting_id', 'addressee_id')->execute()->first();
$this->assertEquals(2, $contact['email_greeting_id']);
$this->assertEquals(3, $contact['postal_greeting_id']);
$this->assertEquals(1, $contact['addressee_id']);

}

/**
* Test prefix & suffix work when you specify the label.
*
Expand Down

0 comments on commit 96cd3f3

Please sign in to comment.