Merge pull request #23742 from eileenmcnaughton/import_remove
[civicrm-core.git] / CRM / Core / EntityTokens.php
index 7f7b669959e161ca7e14f372fb9ec93e09d9306d..8f7866971b5a5230c43acc062d5b08bea1896aa5 100644 (file)
@@ -75,23 +75,18 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber {
    * @return array
    */
   protected function getTokenMetadata(): array {
-    if (empty($this->tokensMetadata)) {
-      $cacheKey = $this->getCacheKey();
-      if (Civi::cache('metadata')->has($cacheKey)) {
-        $this->tokensMetadata = Civi::cache('metadata')->get($cacheKey);
+    $cacheKey = $this->getCacheKey();
+    if (!Civi::cache('metadata')->has($cacheKey)) {
+      $tokensMetadata = $this->getBespokeTokens();
+      foreach ($this->getFieldMetadata() as $field) {
+        $this->addFieldToTokenMetadata($tokensMetadata, $field, $this->getExposedFields());
       }
-      else {
-        $this->tokensMetadata = $this->getBespokeTokens();
-        foreach ($this->getFieldMetadata() as $field) {
-          $this->addFieldToTokenMetadata($field, $this->getExposedFields());
-        }
-        foreach ($this->getHiddenTokens() as $name) {
-          $this->tokensMetadata[$name]['audience'] = 'hidden';
-        }
-        Civi::cache('metadata')->set($cacheKey, $this->tokensMetadata);
+      foreach ($this->getHiddenTokens() as $name) {
+        $tokensMetadata[$name]['audience'] = 'hidden';
       }
+      Civi::cache('metadata')->set($cacheKey, $tokensMetadata);
     }
-    return $this->tokensMetadata;
+    return Civi::cache('metadata')->get($cacheKey);
   }
 
   /**
@@ -125,6 +120,9 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber {
     }
     if ($this->isMoneyField($field)) {
       $currency = $this->getCurrency($row);
+      if (empty($fieldValue) && !is_numeric($fieldValue)) {
+        $fieldValue = 0;
+      }
       if (!$currency) {
         // too hard basket for now - just do what we always did.
         return $row->format('text/plain')->tokens($entity, $field,
@@ -501,6 +499,8 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber {
    * @param int $id
    *
    * @return string
+   *
+   * @throws \CRM_Core_Exception
    */
   protected function getCustomFieldName(int $id): string {
     foreach ($this->getTokenMetadata() as $key => $field) {
@@ -508,6 +508,9 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber {
         return $key;
       }
     }
+    throw new CRM_Core_Exception(
+      "A custom field with the ID {$id} does not exist"
+    );
   }
 
   /**
@@ -520,9 +523,14 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber {
    */
   protected function getCustomFieldValue($entityID, string $field) {
     $id = str_replace('custom_', '', $field);
-    $value = $this->prefetch[$entityID][$this->getCustomFieldName($id)] ?? '';
-    if ($value !== NULL) {
-      return CRM_Core_BAO_CustomField::displayValue($value, $id);
+    try {
+      $value = $this->prefetch[$entityID][$this->getCustomFieldName($id)] ?? '';
+      if ($value !== NULL) {
+        return CRM_Core_BAO_CustomField::displayValue($value, $id);
+      }
+    }
+    catch (CRM_Core_Exception $exception) {
+      return NULL;
     }
   }
 
@@ -597,11 +605,12 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber {
   /**
    * Add the token to the metadata based on the field spec.
    *
+   * @param array $tokensMetadata
    * @param array $field
    * @param array $exposedFields
    * @param string $prefix
    */
-  protected function addFieldToTokenMetadata(array $field, array $exposedFields, string $prefix = ''): void {
+  protected function addFieldToTokenMetadata(array &$tokensMetadata, array $field, array $exposedFields, string $prefix = ''): void {
     if ($field['type'] !== 'Custom' && !in_array($field['name'], $exposedFields, TRUE)) {
       return;
     }
@@ -623,7 +632,7 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber {
       $parts = explode(': ', $field['label']);
       $field['title'] = "{$parts[1]} :: {$parts[0]}";
       $tokenName = 'custom_' . $field['custom_field_id'];
-      $this->tokensMetadata[$tokenName] = $field;
+      $tokensMetadata[$tokenName] = $field;
       return;
     }
     $tokenName = $prefix ? ($prefix . '.' . $field['name']) : $field['name'];
@@ -633,21 +642,21 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber {
         // At the time of writing currency didn't have a label option - this may have changed.
         && !in_array($field['name'], $this->getCurrencyFieldName(), TRUE)
       ) {
-        $this->tokensMetadata[$tokenName . ':label'] = $this->tokensMetadata[$tokenName . ':name'] = $field;
+        $tokensMetadata[$tokenName . ':label'] = $tokensMetadata[$tokenName . ':name'] = $field;
         $fieldLabel = $field['input_attrs']['label'] ?? $field['label'];
-        $this->tokensMetadata[$tokenName . ':label']['name'] = $field['name'] . ':label';
-        $this->tokensMetadata[$tokenName . ':name']['name'] = $field['name'] . ':name';
-        $this->tokensMetadata[$tokenName . ':name']['audience'] = 'sysadmin';
-        $this->tokensMetadata[$tokenName . ':label']['title'] = $fieldLabel;
-        $this->tokensMetadata[$tokenName . ':name']['title'] = ts('Machine name') . ': ' . $fieldLabel;
+        $tokensMetadata[$tokenName . ':label']['name'] = $field['name'] . ':label';
+        $tokensMetadata[$tokenName . ':name']['name'] = $field['name'] . ':name';
+        $tokensMetadata[$tokenName . ':name']['audience'] = 'sysadmin';
+        $tokensMetadata[$tokenName . ':label']['title'] = $fieldLabel;
+        $tokensMetadata[$tokenName . ':name']['title'] = ts('Machine name') . ': ' . $fieldLabel;
         $field['audience'] = 'sysadmin';
       }
       if ($field['data_type'] === 'Boolean') {
-        $this->tokensMetadata[$tokenName . ':label'] = $field;
-        $this->tokensMetadata[$tokenName . ':label']['name'] = $field['name'] . ':label';
+        $tokensMetadata[$tokenName . ':label'] = $field;
+        $tokensMetadata[$tokenName . ':label']['name'] = $field['name'] . ':label';
         $field['audience'] = 'sysadmin';
       }
-      $this->tokensMetadata[$tokenName] = $field;
+      $tokensMetadata[$tokenName] = $field;
     }
   }