From fd6a43fbb3f149425aef1c6aaf340c591ab42bf8 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Fri, 19 Aug 2022 18:40:32 +1200 Subject: [PATCH] Fix returnProperties on contact retrieval --- CRM/Contact/Tokens.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/CRM/Contact/Tokens.php b/CRM/Contact/Tokens.php index 731b2f330ceb..e4ca82057e4d 100644 --- a/CRM/Contact/Tokens.php +++ b/CRM/Contact/Tokens.php @@ -330,10 +330,13 @@ public function onEvaluate(TokenValueEvent $e) { * * @param \Civi\Token\TokenRow $row * @param string $field + * * @return string|int + * @throws \CRM_Core_Exception */ protected function getFieldValue(TokenRow $row, string $field) { $entityName = 'contact'; + $contact = $row->context['contact']; if (isset($this->getDeprecatedTokens()[$field])) { // Check the non-deprecated location first, fall back to deprecated // this is important for the greetings because - they are weird in the query object. @@ -347,13 +350,23 @@ protected function getFieldValue(TokenRow $row, string $field) { } foreach ($possibilities as $possibility) { - if (isset($row->context[$entityName][$possibility])) { - return $row->context[$entityName][$possibility]; + if (isset($contact[$possibility])) { + return $contact[$possibility]; + } + if ($this->isPseudoField($possibility)) { + // If we have a name or label field & already have the id loaded then we can + // evaluate from that rather than query again. + $split = explode(':', $possibility); + if (array_key_exists($split[0], $contact)) { + return $row->context['contact'][$possibility] = $this->getPseudoValue($split[0], $split[1], $contact[$split[0]]); + } } } + $contactID = $this->getFieldValue($row, 'id'); if ($contactID) { - $row->context['contact'] = array_merge($this->getContact($contactID, $this->activeTokens), $row->context['contact']); + $missingFields = array_diff_key(array_fill_keys($this->activeTokens, TRUE), $contact); + $row->context['contact'] = array_merge($this->getContact($contactID, array_keys($missingFields)), $contact); if (isset($row->context[$entityName][$field])) { return $row->context[$entityName][$field]; }