Skip to content

Commit

Permalink
Reference token metadata internally
Browse files Browse the repository at this point in the history
This references the token metadata rather than the metadata retrieved from the api
call. Since the former is cached it should save a look up -
albeit not when prefetch is happening, at this stage
  • Loading branch information
eileenmcnaughton committed Oct 7, 2021
1 parent bb6fc75 commit cc17ec9
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 38 deletions.
86 changes: 54 additions & 32 deletions CRM/Core/EntityTokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ public function registerTokens(TokenRegisterEvent $e) {
if (!$this->checkActive($e->getTokenProcessor())) {
return;
}
foreach ($this->getTokenMetadata() as $field) {
foreach ($this->getTokenMetadata() as $tokenName => $field) {
if ($field['audience'] === 'user') {
$e->register([
'entity' => $this->entity,
'field' => $field['name'],
'field' => $tokenName,
'label' => $field['title'],
]);
}
Expand All @@ -83,31 +83,30 @@ protected function getTokenMetadata(): array {
$this->tokensMetadata = Civi::cache('metadata')->get($cacheKey);
}
else {
foreach (array_merge($this->getFieldMetadata(), $this->getBespokeTokens()) as $field) {
if (
$field['type'] === 'Custom'
|| !empty($this->getBespokeTokens()[$field['name']])
|| in_array($field['name'], $this->getExposedFields(), TRUE)
) {
$field['audience'] = 'user';
if ($field['name'] === 'contact_id') {
// Since {contact.id} is almost always present don't confuse users
// by also adding (e.g {participant.contact_id)
$field['audience'] = 'sysadmin';
}
if (!empty($this->getTokenMetadataOverrides()[$field['name']])) {
$field = array_merge($field, $this->getTokenMetadataOverrides()[$field['name']]);
}
if ($field['type'] === 'Custom') {
// Convert to apiv3 style for now. Later we can add v4 with
// portable naming & support for labels/ dates etc so let's leave
// the space open for that.
// Not the existing quickform widget has handling for the custom field
// format based on the title using this syntax.
$field['name'] = 'custom_' . $field['custom_field_id'];
$parts = explode(': ', $field['label']);
$field['title'] = "{$parts[1]} :: {$parts[0]}";
}
$this->tokensMetadata = $this->getBespokeTokens();
foreach ($this->getFieldMetadata() as $field) {
$field['audience'] = 'user';
if ($field['name'] === 'contact_id') {
// Since {contact.id} is almost always present don't confuse users
// by also adding (e.g {participant.contact_id)
$field['audience'] = 'sysadmin';
}
if (!empty($this->getTokenMetadataOverrides()[$field['name']])) {
$field = array_merge($field, $this->getTokenMetadataOverrides()[$field['name']]);
}
if ($field['type'] === 'Custom') {
// Convert to apiv3 style for now. Later we can add v4 with
// portable naming & support for labels/ dates etc so let's leave
// the space open for that.
// Not the existing quickform widget has handling for the custom field
// format based on the title using this syntax.
$parts = explode(': ', $field['label']);
$field['title'] = "{$parts[1]} :: {$parts[0]}";
$tokenName = 'custom_' . $field['custom_field_id'];
$this->tokensMetadata[$tokenName] = $field;
continue;
}
if (in_array($field['name'], $this->getExposedFields(), TRUE)) {
if (
($field['options'] || !empty($field['suffixes']))
// At the time of writing currency didn't have a label option - this may have changed.
Expand Down Expand Up @@ -247,7 +246,7 @@ public function getReturnFields(): array {
* @return bool
*/
public function isBooleanField(string $fieldName): bool {
return $this->getFieldMetadata()[$fieldName]['data_type'] === 'Boolean';
return $this->getMetadataForField($fieldName)['data_type'] === 'Boolean';
}

/**
Expand All @@ -258,7 +257,7 @@ public function isBooleanField(string $fieldName): bool {
* @return bool
*/
public function isDateField(string $fieldName): bool {
return in_array($this->getFieldMetadata()[$fieldName]['data_type'], ['Timestamp', 'Date'], TRUE);
return in_array($this->getMetadataForField($fieldName)['data_type'], ['Timestamp', 'Date'], TRUE);
}

/**
Expand Down Expand Up @@ -291,7 +290,7 @@ public function isCustomField(string $fieldName) : bool {
* @return bool
*/
public function isMoneyField(string $fieldName): bool {
return $this->getFieldMetadata()[$fieldName]['data_type'] === 'Money';
return $this->getMetadataForField($fieldName)['data_type'] === 'Money';
}

/**
Expand Down Expand Up @@ -553,7 +552,7 @@ public function getDependencies(): array {
* @return string
*/
protected function getCustomFieldName(int $id): string {
foreach ($this->getFieldMetadata() as $key => $field) {
foreach ($this->getTokenMetadata() as $key => $field) {
if (($field['custom_field_id'] ?? NULL) === $id) {
return $key;
}
Expand All @@ -570,12 +569,35 @@ protected function getCustomFieldName(int $id): string {
*/
protected function getCustomFieldValue($entityID, string $field) {
$id = str_replace('custom_', '', $field);
$value = $this->prefetch[$entityID][$this->getCustomFieldName($id)] ?? NULL;
$value = $this->prefetch[$entityID][$this->getCustomFieldName($id)] ?? '';
if ($value !== NULL) {
return CRM_Core_BAO_CustomField::displayValue($value, $id);
}
}

/**
* Get the metadata for the field.
*
* @param string $fieldName
*
* @return array
*/
protected function getMetadataForField($fieldName): array {
if (isset($this->getTokenMetadata()[$fieldName])) {
return $this->getTokenMetadata()[$fieldName];
}
return $this->getTokenMetadata()[$this->getDeprecatedTokens()[$fieldName]];
}

/**
* Get array of deprecated tokens and the new token they map to.
*
* @return array
*/
protected function getDeprecatedTokens(): array {
return [];
}

/**
* Get any overrides for token metadata.
*
Expand Down
18 changes: 12 additions & 6 deletions CRM/Event/Tokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,34 +49,39 @@ protected function getBespokeTokens(): array {
'type' => 'calculated',
'options' => NULL,
'data_type' => 'String',
'audience' => 'user',
],
'info_url' => [
'title' => ts('Event Info URL'),
'name' => 'info_url',
'type' => 'calculated',
'options' => NULL,
'data_type' => 'String',
'audience' => 'user',
],
'registration_url' => [
'title' => ts('Event Registration URL'),
'name' => 'registration_url',
'type' => 'calculated',
'options' => NULL,
'data_type' => 'String',
'audience' => 'user',
],
'contact_email' => [
'title' => ts('Event Contact Email'),
'name' => 'contact_email',
'type' => 'calculated',
'options' => NULL,
'data_type' => 'String',
'audience' => 'user',
],
'contact_phone' => [
'title' => ts('Event Contact Phone'),
'name' => 'contact_phone',
'type' => 'calculated',
'options' => NULL,
'data_type' => '',
'audience' => 'user',
],
];
}
Expand All @@ -92,7 +97,7 @@ public function evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL)
}
if (array_key_exists($field, $this->getEventTokenValues($eventID))) {
foreach ($this->getEventTokenValues($eventID)[$field] as $format => $value) {
$row->format($format)->tokens($entity, $field, $value);
$row->format($format)->tokens($entity, $field, $value ?? '');
}
}
}
Expand Down Expand Up @@ -143,14 +148,15 @@ protected function getEventTokenValues(int $eventID = NULL): array {
$tokens['contact_phone']['text/html'] = $event['loc_block_id.phone_id.phone'];
$tokens['contact_email']['text/html'] = $event['loc_block_id.email_id.email'];

foreach (array_keys($this->getTokenMetadata()) as $field) {
if (!isset($tokens[$field])) {
if ($this->isCustomField($field)) {
foreach ($this->getTokenMetadata() as $fieldName => $fieldSpec) {
if (!isset($tokens[$fieldName])) {
if ($fieldSpec['type'] === 'Custom') {
$this->prefetch[$eventID] = $event;
$tokens[$field]['text/html'] = $this->getCustomFieldValue($eventID, $field);
$value = $event[$fieldSpec['name']];
$tokens[$fieldName]['text/html'] = CRM_Core_BAO_CustomField::displayValue($value, $fieldSpec['custom_field_id']);
}
else {
$tokens[$field]['text/html'] = $event[$field];
$tokens[$fieldName]['text/html'] = $event[$fieldName];
}
}
}
Expand Down

0 comments on commit cc17ec9

Please sign in to comment.