Skip to content
Snippets Groups Projects
Unverified Commit 490bdff6 authored by totten's avatar totten Committed by GitHub
Browse files

Merge pull request #25548 from eileenmcnaughton/559_token

(#4109) Fix tokens like `{contact.email_primary.email}`
parents 79c1c047 9f8abff4
Branches
Tags
No related merge requests found
......@@ -397,14 +397,17 @@ class CRM_Contact_Tokens extends CRM_Core_EntityTokens {
foreach ($metadata as $field) {
if ($entity === 'website') {
// It's not the primary - it's 'just one of them' - so the name is _first not _primary
$field['name'] = 'website_first.' . $field['name'];
$this->addFieldToTokenMetadata($tokensMetadata, $field, $exposedFields, 'website_first');
}
else {
$field['name'] = $entity . '_primary.' . $field['name'];
$this->addFieldToTokenMetadata($tokensMetadata, $field, $exposedFields, $entity . '_primary');
$field['label'] .= ' (' . ts('Billing') . ')';
// Set audience to sysadmin in case adding them to UI annoys people. If people ask to see this
// in the UI we could set to 'user'.
$field['audience'] = 'sysadmin';
$field['name'] = $entity . '_billing.' . $field['name'];
$this->addFieldToTokenMetadata($tokensMetadata, $field, $exposedFields, $entity . '_billing');
}
}
......@@ -453,13 +456,11 @@ class CRM_Contact_Tokens extends CRM_Core_EntityTokens {
if ($fieldSpec['table_name'] === 'civicrm_website') {
$tableAlias = 'website_first';
$joins[$tableAlias] = $fieldSpec['entity'];
$prefix = $tableAlias . '.';
}
if ($fieldSpec['table_name'] === 'civicrm_openid') {
// We could start to deprecate this one maybe..... I've made it un-advertised.
$tableAlias = 'openid_primary';
$joins[$tableAlias] = $fieldSpec['entity'];
$prefix = $tableAlias . '.';
}
if ($fieldSpec['type'] === 'Custom') {
$customFields['custom_' . $fieldSpec['custom_field_id']] = $fieldSpec['name'];
......
......@@ -611,7 +611,8 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber {
* @param string $prefix
*/
protected function addFieldToTokenMetadata(array &$tokensMetadata, array $field, array $exposedFields, string $prefix = ''): void {
if ($field['type'] !== 'Custom' && !in_array($field['name'], $exposedFields, TRUE)) {
$isExposed = in_array(str_replace($prefix . '.', '', $field['name']), $exposedFields, TRUE);
if ($field['type'] !== 'Custom' && !$isExposed) {
return;
}
$field['audience'] = $field['audience'] ?? 'user';
......@@ -635,8 +636,9 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber {
$tokensMetadata[$tokenName] = $field;
return;
}
$tokenName = $prefix ? ($prefix . '.' . $field['name']) : $field['name'];
if (in_array($field['name'], $exposedFields, TRUE)) {
$tokenName = $field['name'];
// Presumably this line can not be reached unless isExposed = TRUE.
if ($isExposed) {
if (
($field['options'] || !empty($field['suffixes']))
// At the time of writing currency didn't have a label option - this may have changed.
......
......@@ -272,6 +272,24 @@ case.custom_1 :' . '
];
}
/**
* Test the standard new location token format - which matches apiv4 return properties.
*
* @throws \CRM_Core_Exception
*/
public function testLocationTokens(): void {
$contactID = $this->individualCreate(['email' => 'me@example.com']);
Address::create()->setValues([
'contact_id' => $contactID,
'is_primary' => TRUE,
'street_address' => 'Heartbreak Hotel',
'supplemental_address_1' => 'Lonely Street',
])->execute();
$text = '{contact.first_name} {contact.email_primary.email} {contact.address_primary.street_address}';
$text = $this->renderText(['contactId' => $contactID], $text);
$this->assertEquals('Anthony me@example.com Heartbreak Hotel', $text);
}
/**
* Test tokens in 2 ways to ensure consistent handling.
*
......@@ -563,6 +581,8 @@ contribution_recur.payment_instrument_id:name :Check
/**
* Get expected output from token parsing.
*
* @param int|null $participantCreatedID
*
* @return string
*/
protected function getExpectedParticipantTokenOutput(int $participantCreatedID = NULL): string {
......@@ -811,13 +831,8 @@ United States', $tokenProcessor->getRow(0)->render('message'));
$mut = new CiviMailUtils($this);
$this->setupParticipantScheduledReminder();
$tokens = CRM_Core_SelectValues::eventTokens();
$this->assertEquals(array_merge($this->getEventTokens()), $tokens);
$tokenProcessor = new TokenProcessor(\Civi::dispatcher(), [
'controller' => __CLASS__,
'smarty' => FALSE,
'schema' => ['eventId'],
]);
$tokens = array_merge($this->getEventTokens());
$tokenProcessor = $this->getTokenProcessor(['schema' => ['eventId']]);
$this->assertEquals(array_merge($tokens, $this->getDomainTokens()), $tokenProcessor->listTokens());
$expectedEventString = $this->getExpectedEventTokenOutput();
......@@ -1026,4 +1041,36 @@ United States', $tokenProcessor->getRow(0)->render('message'));
$this->assertEquals($expected, $rendered);
}
/**
* @param array $override
*
* @return \Civi\Token\TokenProcessor
*/
protected function getTokenProcessor(array $override): TokenProcessor {
return new TokenProcessor(\Civi::dispatcher(), array_merge([
'controller' => __CLASS__,
], $override));
}
/**
* Render the text via the token processor.
*
* @param array $rowContext
* @param string $text
* @param array $context
*
* @return string
*/
protected function renderText(array $rowContext, string $text, array $context = []): string {
$context['schema'] = $context['schema'] ?? [];
foreach (array_keys($rowContext) as $key) {
$context['schema'][] = $key;
}
$tokenProcessor = $this->getTokenProcessor($context);
$tokenProcessor->addRow($rowContext);
$tokenProcessor->addMessage('text', $text, 'text/html');
$tokenProcessor->evaluate();
return $tokenProcessor->getRow(0)->render('text');
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment