Includes unit test.
Toward CRM-21180: Better static var handling.
Toward CRM-21180: removed static vars; removed unused method parameters.
CRM-21180 add unit test for custom field being set in address
CRM-21180 Inline changes to custom fields aren't reflected in custom greetings
This incorporates Allan's work to cause custom fields to be updated
when a custom value is updated. These have been reconciled with the changes to allow
greeting fields to be set to null per CRM-21474
m
}
}
- $config = CRM_Core_Config::singleton();
+ self::ensureGreetingParamsAreSet($params);
// CRM-6942: set preferred language to the current language if it’s unset (and we’re creating a contact).
if (empty($params['contact_id'])) {
$params['preferred_language'] = $language;
}
- // CRM-9739: set greeting & addressee if unset and we’re creating a contact.
- foreach (self::$_greetingTypes as $greeting) {
- if (empty($params[$greeting . '_id'])) {
- if ($defaultGreetingTypeId
- = CRM_Contact_BAO_Contact_Utils::defaultGreeting($params['contact_type'], $greeting)
- ) {
- $params[$greeting . '_id'] = $defaultGreetingTypeId;
- }
- }
- }
-
// CRM-21041: set default 'Communication Style' if unset when creating a contact.
if (empty($params['communication_style_id'])) {
$defaultCommunicationStyleId = CRM_Core_OptionGroup::values('communication_style', TRUE, NULL, NULL, 'AND is_default = 1');
}
}
- // process greetings CRM-4575, cache greetings
self::processGreetings($contact);
return $contact;
}
+ /**
+ * Ensure greeting parameters are set.
+ *
+ * By always populating greetings here we can be sure they are set if required & avoid a call later.
+ * (ie. knowing we have definitely tried disambiguates between NULL & not loaded.)
+ *
+ * @param array $params
+ */
+ public static function ensureGreetingParamsAreSet(&$params) {
+ $allGreetingParams = array('addressee' => 'addressee_id', 'postal_greeting' => 'postal_greeting_id', 'email_greeting' => 'email_greeting_id');
+ $missingGreetingParams = array();
+
+ foreach ($allGreetingParams as $greetingIndex => $greetingParam) {
+ if (empty($params[$greetingParam])) {
+ $missingGreetingParams[$greetingIndex] = $greetingParam;
+ }
+ }
+
+ if (!empty($params['contact_id']) && !empty($missingGreetingParams)) {
+ $savedGreetings = civicrm_api3('Contact', 'getsingle', array(
+ 'id' => $params['contact_id'],
+ 'return' => array_keys($missingGreetingParams))
+ );
+
+ foreach (array_keys($missingGreetingParams) as $missingGreetingParam) {
+ if (!empty($savedGreetings[$missingGreetingParam . '_custom'])) {
+ $missingGreetingParams[$missingGreetingParam . '_custom'] = $missingGreetingParam . '_custom';
+ }
+ }
+ // Filter out other fields.
+ $savedGreetings = array_intersect_key($savedGreetings, array_flip($missingGreetingParams));
+ $params = array_merge($params, $savedGreetings);
+ }
+ else {
+ foreach ($missingGreetingParams as $greetingName => $greeting) {
+ $params[$greeting] = CRM_Contact_BAO_Contact_Utils::defaultGreeting($params['contact_type'], $greetingName);
+ }
+ }
+
+ foreach ($allGreetingParams as $greetingIndex => $greetingParam) {
+ if ($params[$greetingParam] === 'null') {
+ // If we are setting it to null then null out the display field.
+ $params[$greetingIndex . '_display'] = 'null';
+ }
+ }
+ }
+
/**
* Get the display name and image of a contact.
*
}
}
+ /**
+ * Update contact greetings if an update has resulted in a custom field change.
+ *
+ * @param array $updatedFields
+ * Array of fields that have been updated e.g array('first_name', 'prefix_id', 'custom_2');
+ * @param array $contactParams
+ * Parameters known about the contact. At minimum array('contact_id' => x).
+ * Fields in this array will take precedence over DB fields (so far only
+ * in the case of greeting id fields).
+ */
+ public static function updateGreetingsOnTokenFieldChange($updatedFields, $contactParams) {
+ $contactID = $contactParams['contact_id'];
+ CRM_Contact_BAO_Contact::ensureGreetingParamsAreSet($contactParams);
+ $tokens = CRM_Contact_BAO_Contact_Utils::getTokensRequiredForContactGreetings($contactParams);
+ if (!empty($tokens['all']['contact'])) {
+ $affectedTokens = array_intersect_key($updatedFields[$contactID], array_flip($tokens['all']['contact']));
+ if (!empty($affectedTokens)) {
+ // @todo this is still reloading the whole contact -fix to be more selective & use pre-loaded.
+ $contact = new CRM_Contact_BAO_Contact();
+ $contact->id = $contactID;
+ CRM_Contact_BAO_Contact::processGreetings($contact);
+ }
+ }
+ }
+
/**
* Process greetings and cache.
*
*/
public static function processGreetings(&$contact) {
+ //@todo this function does a lot of unnecessary loading.
+ // ensureGreetingParamsAreSet now makes sure that the contact is
+ // loaded and using updateGreetingsOnTokenFieldChange
+ // allows us the possibility of only doing an update if required.
+
// The contact object has not always required the
// fields that are required to calculate greetings
// so we need to retrieve it again.
}
}
+ /**
+ * Get the tokens that will need to be resolved to populate the contact's greetings.
+ *
+ * @param array $contactParams
+ *
+ * @return array
+ * Array of tokens. The ALL ke
+ */
+ public static function getTokensRequiredForContactGreetings($contactParams) {
+ $tokens = array();
+ foreach (array('addressee', 'email_greeting', 'postal_greeting') as $greeting) {
+ $string = '';
+ if (!empty($contactParams[$greeting . '_id'])) {
+ $string = CRM_Core_PseudoConstant::getLabel('CRM_Contact_BAO_Contact', $greeting . '_id', $contactParams[$greeting . '_id']);
+ }
+ $string = isset($contactParams[$greeting . '_custom']) ? $contactParams[$greeting . '_custom'] : $string;
+ if (empty($string)) {
+ $tokens[$greeting] = array();
+ }
+ else {
+ $tokens[$greeting] = CRM_Utils_Token::getTokens($string);
+ }
+ }
+ $allTokens = array_merge_recursive($tokens['addressee'], $tokens['email_greeting'], $tokens['postal_greeting']);
+ $tokens['all'] = $allTokens;
+ return $tokens;
+ }
+
/**
* Process a greeting template string to produce the individualised greeting text.
*
while ($dao->fetch()) {
// get the group dao to figure which class this custom field extends
$extends = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $dao->custom_group_id, 'extends');
+ $extendsTable = '';
if (array_key_exists($extends, self::$extendsMap)) {
$extendsTable = self::$extendsMap[$extends];
}
return;
}
+ $paramFieldsExtendContactForEntities = array();
+
foreach ($customParams as $tableName => $tables) {
foreach ($tables as $index => $fields) {
$sqlOP = NULL;
$params[$count] = array($value, $type);
$count++;
}
+
+ $fieldExtends = CRM_Utils_Array::value('extends', $field);
+ if (
+ CRM_Utils_Array::value('entity_table', $field) == 'civicrm_contact'
+ || $fieldExtends == 'Contact'
+ || $fieldExtends == 'Individual'
+ || $fieldExtends == 'Organization'
+ || $fieldExtends == 'Household'
+ ) {
+ $paramFieldsExtendContactForEntities[$entityID]['custom_' . CRM_Utils_Array::value('custom_field_id', $field)] = CRM_Utils_Array::value('custom_field_id', $field);
+ }
}
if (!empty($set)) {
}
}
}
+
+ if (!empty($paramFieldsExtendContactForEntities)) {
+ CRM_Contact_BAO_Contact::updateGreetingsOnTokenFieldChange($paramFieldsExtendContactForEntities, array('contact_id' => $entityID));
+ }
}
/**
SELECT cg.table_name as table_name ,
cg.id as cg_id ,
cg.is_multiple as is_multiple,
+ cg.extends as extends,
cf.column_name as column_name,
cf.id as cf_id ,
cf.data_type as data_type
'table_name' => $dao->table_name,
'column_name' => $dao->column_name,
'is_multiple' => $dao->is_multiple,
+ 'extends' => $dao->extends,
);
if ($cvParam['type'] == 'File') {
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*}
-<div id="custom-set-content-{$customGroupId}" {if $permission EQ 'edit'} class="crm-inline-edit" data-edit-params='{ldelim}"cid": "{$contactId}", "class_name": "CRM_Contact_Form_Inline_CustomData", "groupID": "{$customGroupId}", "customRecId": "{$customRecId}", "cgcount" : "{$cgcount}"{rdelim}'{/if}>
+<div id="custom-set-content-{$customGroupId}" {if $permission EQ 'edit'} class="crm-inline-edit" data-edit-params='{ldelim}"cid": "{$contactId}", "class_name": "CRM_Contact_Form_Inline_CustomData", "groupID": "{$customGroupId}", "customRecId": "{$customRecId}", "cgcount" : "{$cgcount}"{rdelim}' data-dependent-fields='["#crm-communication-pref-content"]'{/if}>
<div class="crm-clear crm-inline-block-content" {if $permission EQ 'edit'}title="{ts}Edit{/ts}"{/if}>
{if $permission EQ 'edit'}
<div class="crm-edit-help">
$this->assertEquals('custom_value.id', $fields['custom_value.id']['name']);
}
+ /**
+ * Test that custom fields in greeting strings are updated.
+ */
+ public function testUpdateCustomGreetings() {
+ // Create a custom group with one field.
+ $customGroupResult = $this->callAPISuccess('CustomGroup', 'create', array(
+ 'sequential' => 1,
+ 'title' => "test custom group",
+ 'extends' => "Individual",
+ ));
+ $customFieldResult = $this->callAPISuccess('CustomField', 'create', array(
+ 'custom_group_id' => $customGroupResult['id'],
+ 'label' => "greeting test",
+ 'data_type' => "String",
+ 'html_type' => "Text",
+ ));
+ $customFieldId = $customFieldResult['id'];
+
+ // Create a contact with an email greeting format that includes the new custom field.
+ $contactResult = $this->callAPISuccess('Contact', 'create', array(
+ 'contact_type' => 'Individual',
+ 'email' => substr(sha1(rand()), 0, 7) . '@yahoo.com',
+ 'email_greeting_id' => "Customized",
+ 'email_greeting_custom' => "Dear {contact.custom_{$customFieldId}}",
+ ));
+ $cid = $contactResult['id'];
+
+ // Define testing values.
+ $uniq = uniqid();
+ $testGreetingValue = "Dear $uniq";
+
+ // Update contact's custom field with CustomValue.create
+ $customValueResult = $this->callAPISuccess('CustomValue', 'create', array(
+ 'entity_id' => $cid,
+ "custom_{$customFieldId}" => $uniq,
+ 'entity_table' => "civicrm_contact",
+ ));
+
+ $contact = $this->callAPISuccessGetSingle('Contact', array('id' => $cid, 'return' => 'email_greeting'));
+ $this->assertEquals($testGreetingValue, $contact['email_greeting_display']);
+
+ }
+
}