From e9841a516b5c0f10f55d95474fbe2b3ba739e820 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Mon, 4 Oct 2021 10:11:21 +1300 Subject: [PATCH] Towards full metadata - fully declare 'bespoke' --- CRM/Activity/Tokens.php | 37 +++++--- CRM/Core/EntityTokens.php | 9 +- CRM/Event/ParticipantTokens.php | 13 ++- CRM/Event/Tokens.php | 88 +++++++++++++------ CRM/Member/Tokens.php | 50 +++++++---- .../CRM/Utils/TokenConsistencyTest.php | 22 ++++- 6 files changed, 157 insertions(+), 62 deletions(-) diff --git a/CRM/Activity/Tokens.php b/CRM/Activity/Tokens.php index 86b9da6b8d..222bf680a2 100644 --- a/CRM/Activity/Tokens.php +++ b/CRM/Activity/Tokens.php @@ -122,20 +122,6 @@ class CRM_Activity_Tokens extends CRM_Core_EntityTokens { } } - /** - * Get all the tokens supported by this processor. - * - * @return array|string[] - * @throws \API_Exception - */ - protected function getAllTokens(): array { - $tokens = parent::getAllTokens(); - if (array_key_exists('CiviCase', CRM_Core_Component::getEnabledComponents())) { - $tokens['case_id'] = ts('Activity Case ID'); - } - return $tokens; - } - /** * Get the basic tokens provided. * @@ -162,6 +148,29 @@ class CRM_Activity_Tokens extends CRM_Core_EntityTokens { return $this->basicTokens; } + /** + * Get tokens that are special or calculated for this enitty. + * + * @return array|array[] + */ + protected function getBespokeTokens(): array { + $tokens = []; + if (array_key_exists('CiviCase', CRM_Core_Component::getEnabledComponents())) { + $tokens['case_id'] = ts('Activity Case ID'); + return [ + 'case_id' => [ + 'title' => ts('Activity Case ID'), + 'name' => 'case_id', + 'type' => 'calculated', + 'options' => NULL, + 'data_type' => 'Integer', + 'audience' => 'user', + ], + ]; + } + return $tokens; + } + /** * @inheritDoc */ diff --git a/CRM/Core/EntityTokens.php b/CRM/Core/EntityTokens.php index e8b5362ca6..56c1428deb 100644 --- a/CRM/Core/EntityTokens.php +++ b/CRM/Core/EntityTokens.php @@ -174,7 +174,10 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber { unset($basicTokens[$fieldName]); } } - return array_merge($basicTokens, $this->getPseudoTokens(), $this->getBespokeTokens(), CRM_Utils_Token::getCustomFieldTokens($this->getApiEntityName())); + foreach ($this->getBespokeTokens() as $token) { + $basicTokens[$token['name']] = $token['title']; + } + return array_merge($basicTokens, $this->getPseudoTokens(), CRM_Utils_Token::getCustomFieldTokens($this->getApiEntityName())); } /** @@ -275,7 +278,7 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber { /** * Get any tokens with custom calculation. */ - public function getBespokeTokens(): array { + protected function getBespokeTokens(): array { return []; } @@ -431,7 +434,7 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber { * @return string[] * */ - public function getExposedFields(): array { + protected function getExposedFields(): array { $return = []; foreach ($this->getFieldMetadata() as $field) { if (!in_array($field['name'], $this->getSkippedFields(), TRUE)) { diff --git a/CRM/Event/ParticipantTokens.php b/CRM/Event/ParticipantTokens.php index e132d8faa1..5733e10af9 100644 --- a/CRM/Event/ParticipantTokens.php +++ b/CRM/Event/ParticipantTokens.php @@ -45,8 +45,17 @@ class CRM_Event_ParticipantTokens extends CRM_Core_EntityTokens { /** * Get any tokens with custom calculation. */ - public function getBespokeTokens(): array { - return ['balance' => ts('Event Balance')]; + protected function getBespokeTokens(): array { + return [ + 'balance' => [ + 'title' => ts('Event Balance'), + 'name' => 'balance', + 'type' => 'calculated', + 'options' => NULL, + 'data_type' => 'Money', + 'audience' => 'user', + ], + ]; } /** diff --git a/CRM/Event/Tokens.php b/CRM/Event/Tokens.php index 061e7197fa..87ad1de375 100644 --- a/CRM/Event/Tokens.php +++ b/CRM/Event/Tokens.php @@ -41,24 +41,44 @@ class CRM_Event_Tokens extends CRM_Core_EntityTokens { * * This function will be removed once the parent class can determine it. */ - public function getAllTokens(): array { - return array_merge( - [ - 'event_type_id:label' => ts('Event Type'), - 'title' => ts('Event Title'), - 'id' => ts('Event ID'), - 'start_date' => ts('Event Start Date'), - 'end_date' => ts('Event End Date'), - 'summary' => ts('Event Summary'), - 'description' => ts('Event Description'), - 'location' => ts('Event Location'), - 'info_url' => ts('Event Info URL'), - 'registration_url' => ts('Event Registration URL'), - 'contact_email' => ts('Event Contact Email'), - 'contact_phone' => ts('Event Contact Phone'), + protected function getBespokeTokens(): array { + return [ + 'location' => [ + 'title' => ts('Event Location'), + 'name' => 'location', + 'type' => 'calculated', + 'options' => NULL, + 'data_type' => 'String', ], - CRM_Utils_Token::getCustomFieldTokens('Event') - ); + 'info_url' => [ + 'title' => ts('Event Info URL'), + 'name' => 'info_url', + 'type' => 'calculated', + 'options' => NULL, + 'data_type' => 'String', + ], + 'registration_url' => [ + 'title' => ts('Event Registration URL'), + 'name' => 'registration_url', + 'type' => 'calculated', + 'options' => NULL, + 'data_type' => 'String', + ], + 'contact_email' => [ + 'title' => ts('Event Contact Email'), + 'name' => 'contact_email', + 'type' => 'calculated', + 'options' => NULL, + 'data_type' => 'String', + ], + 'contact_phone' => [ + 'title' => ts('Event Contact Phone'), + 'name' => 'contact_phone', + 'type' => 'calculated', + 'options' => NULL, + 'data_type' => '', + ], + ]; } /** @@ -94,15 +114,7 @@ class CRM_Event_Tokens extends CRM_Core_EntityTokens { $cacheKey = __CLASS__ . 'event_tokens' . $eventID . '_' . CRM_Core_I18n::getLocale(); if (!Civi::cache('metadata')->has($cacheKey)) { $event = Event::get(FALSE)->addWhere('id', '=', $eventID) - ->setSelect([ - 'event_type_id', - 'title', - 'id', - 'start_date', - 'end_date', - 'summary', - 'description', - 'loc_block_id', + ->setSelect(array_merge([ 'loc_block_id.address_id.street_address', 'loc_block_id.address_id.city', 'loc_block_id.address_id.state_province_id:label', @@ -110,7 +122,7 @@ class CRM_Event_Tokens extends CRM_Core_EntityTokens { 'loc_block_id.email_id.email', 'loc_block_id.phone_id.phone', 'custom.*', - ]) + ], $this->getExposedFields())) ->execute()->first(); $tokens['location']['text/plain'] = \CRM_Utils_Address::format([ 'street_address' => $event['loc_block_id.address_id.street_address'], @@ -124,6 +136,7 @@ class CRM_Event_Tokens extends CRM_Core_EntityTokens { $tokens['start_date']['text/html'] = !empty($event['start_date']) ? new DateTime($event['start_date']) : ''; $tokens['end_date']['text/html'] = !empty($event['end_date']) ? new DateTime($event['end_date']) : ''; $tokens['event_type_id:label']['text/html'] = CRM_Core_PseudoConstant::getLabel('CRM_Event_BAO_Event', 'event_type_id', $event['event_type_id']); + $tokens['event_type_id:name']['text/html'] = CRM_Core_PseudoConstant::getName('CRM_Event_BAO_Event', 'event_type_id', $event['event_type_id']); $tokens['contact_phone']['text/html'] = $event['loc_block_id.phone_id.phone']; $tokens['contact_email']['text/html'] = $event['loc_block_id.email_id.email']; @@ -143,4 +156,25 @@ class CRM_Event_Tokens extends CRM_Core_EntityTokens { return Civi::cache('metadata')->get($cacheKey); } + /** + * Get entity fields that should be exposed as tokens. + * + * Event has traditionally exposed very few fields. This is probably because + * a) there are a tonne of weird fields so an opt out approach doesn't work and + * b) so people just added what they needed at the time... + * + * @return string[] + * + */ + protected function getExposedFields(): array { + return ['event_type_id', + 'title', + 'id', + 'start_date', + 'end_date', + 'summary', + 'description', + ]; + } + } diff --git a/CRM/Member/Tokens.php b/CRM/Member/Tokens.php index 07aa7ef65a..3d369285d0 100644 --- a/CRM/Member/Tokens.php +++ b/CRM/Member/Tokens.php @@ -34,23 +34,23 @@ class CRM_Member_Tokens extends CRM_Core_EntityTokens { } /** - * Get all tokens. + * List out the fields that are exposed. * - * This function will be removed once the parent class can determine it. + * For historical reasons these are the only exposed fields. + * + * It is also possible to list 'skippedFields' + * + * @return string[] */ - public function getAllTokens(): array { - return array_merge( - [ - 'fee' => ts('Membership Fee'), - 'id' => ts('Membership ID'), - 'join_date' => ts('Member Since'), - 'start_date' => ts('Membership Start Date'), - 'end_date' => ts('Membership Expiration Date'), - 'status_id:label' => ts('Status'), - 'membership_type_id:label' => ts('Membership Type'), - ], - CRM_Utils_Token::getCustomFieldTokens('Membership') - ); + protected function getExposedFields(): array { + return [ + 'id', + 'join_date', + 'start_date', + 'end_date', + 'status_id', + 'membership_type_id', + ]; } /** @@ -76,4 +76,24 @@ class CRM_Member_Tokens extends CRM_Core_EntityTokens { return ['fee' => 'membership_type_id']; } + /** + * Get any tokens with custom calculation. + * + * In this case 'fee' should be converted to{membership.membership_type_id.fee} + * but we don't have the formatting support to do that with no + * custom intervention yet. + */ + protected function getBespokeTokens(): array { + return [ + 'fee' => [ + 'title' => ts('Membership Fee'), + 'name' => 'fee', + 'type' => 'calculated', + 'options' => NULL, + 'data_type' => 'integer', + 'audience' => 'user', + ], + ]; + } + } diff --git a/tests/phpunit/CRM/Utils/TokenConsistencyTest.php b/tests/phpunit/CRM/Utils/TokenConsistencyTest.php index 0f79c174c1..92f1048c25 100644 --- a/tests/phpunit/CRM/Utils/TokenConsistencyTest.php +++ b/tests/phpunit/CRM/Utils/TokenConsistencyTest.php @@ -214,6 +214,20 @@ case.custom_1 :' . ' $this->assertEquals($this->getExpectedContributionRecurTokenOutPut(), $tokenProcessor->getRow(0)->render('html')); } + /** + * Get tokens that are not advertised via listTokens. + * + * @return string[] + */ + public function getUnadvertisedTokens(): array { + return [ + '{membership.status_id}' => 'Status ID', + '{membership.membership_type_id}' => 'Membership Type ID', + '{membership.status_id:name}' => 'Machine name: Status', + '{membership.membership_type_id:name}' => 'Machine name: Membership Type', + ]; + } + /** * Get the contribution recur tokens keyed by the token. * @@ -411,6 +425,8 @@ contribution_recur.payment_instrument_id:name :Check $tokens = $tokenProcessor->listTokens(); // Add in custom tokens as token processor supports these. $expectedTokens['{membership.custom_1}'] = 'Enter text here :: Group with field text'; + // Add in unadvertised tokens - for now they are included. + $expectedTokens = array_merge($expectedTokens, $this->getUnadvertisedTokens()); $this->assertEquals(array_merge($expectedTokens, $this->getDomainTokens()), $tokens); $tokenProcessor->addMessage('html', $tokenString, 'text/plain'); $tokenProcessor->addRow(['membershipId' => $this->getMembershipID()]); @@ -665,7 +681,11 @@ December 21st, 2007 $this->setupParticipantScheduledReminder(); $tokens = CRM_Core_SelectValues::eventTokens(); - $this->assertEquals($this->getEventTokens(), $tokens); + $unadvertisedTokens = [ + '{event.event_type_id}' => 'Event Type', + '{event.event_type_id:name}' => 'Machine name: Event Type', + ]; + $this->assertEquals(array_merge($this->getEventTokens(), $unadvertisedTokens), $tokens); $tokenProcessor = new TokenProcessor(\Civi::dispatcher(), [ 'controller' => __CLASS__, 'smarty' => FALSE, -- 2.25.1