diff --git a/CRM/Utils/Token.php b/CRM/Utils/Token.php index 46990bed095f..c3aa61b9294c 100644 --- a/CRM/Utils/Token.php +++ b/CRM/Utils/Token.php @@ -1534,21 +1534,6 @@ protected static function _buildContributionTokens() { self::$_tokens[$key] = Civi::$statics[__CLASS__][__FUNCTION__][$key]; } - /** - * Store membership tokens on the static _tokens array. - */ - protected static function _buildMembershipTokens() { - $key = 'membership'; - if (!isset(self::$_tokens[$key]) || self::$_tokens[$key] == NULL) { - $membershipTokens = []; - $tokens = CRM_Core_SelectValues::membershipTokens(); - foreach ($tokens as $token => $dontCare) { - $membershipTokens[] = substr($token, (strpos($token, '.') + 1), -1); - } - self::$_tokens[$key] = $membershipTokens; - } - } - /** * Replace tokens for an entity. * @param string $entity @@ -1705,6 +1690,14 @@ public static function replaceMultipleContributionTokens(string $separator, stri /** * Get replacement strings for any membership tokens (only a small number of tokens are implemnted in the first instance * - this is used by the pdfLetter task from membership search + * + * This is called via replaceEntityTokens. + * + * In the near term it will not be called at all from core as + * the pdf letter task is updated to use the processor. + * + * @deprecated + * * @param string $entity * should always be "membership" * @param string $token @@ -1714,13 +1707,29 @@ public static function replaceMultipleContributionTokens(string $separator, stri * @return string token replacement */ public static function getMembershipTokenReplacement($entity, $token, $membership) { - self::_buildMembershipTokens(); + $supportedTokens = [ + 'id', + 'status', + 'status_id', + 'type', + 'membership_type_id', + 'start_date', + 'join_date', + 'end_date', + 'fee', + ]; switch ($token) { case 'type': + // membership_type_id would only be requested if the calling + // class is mapping it to '{membership:membership_type_id:label'} + case 'membership_type_id': $value = $membership['membership_name']; break; case 'status': + // status_id would only be requested if the calling + // class is mapping it to '{membership:status_id:label'} + case 'status_id': $statuses = CRM_Member_BAO_Membership::buildOptions('status_id'); $value = $statuses[$membership['status_id']]; break; @@ -1741,7 +1750,7 @@ public static function getMembershipTokenReplacement($entity, $token, $membershi break; default: - if (in_array($token, self::$_tokens[$entity])) { + if (in_array($token, $supportedTokens)) { $value = $membership[$token]; if (CRM_Utils_String::endsWith($token, '_date')) { $value = CRM_Utils_Date::customFormat($value); diff --git a/tests/phpunit/CRM/Utils/TokenConsistencyTest.php b/tests/phpunit/CRM/Utils/TokenConsistencyTest.php index d6d9e3274d76..ee3bf2d2998f 100644 --- a/tests/phpunit/CRM/Utils/TokenConsistencyTest.php +++ b/tests/phpunit/CRM/Utils/TokenConsistencyTest.php @@ -357,4 +357,72 @@ protected function getExpectedContributionRecurTokenOutPut(): string { Check'; } + /** + * Test that membership tokens are consistently rendered. + * + * @throws \API_Exception + */ + public function testMembershipTokenConsistency(): void { + $this->createLoggedInUser(); + $this->restoreMembershipTypes(); + $this->createCustomGroupWithFieldOfType(['extends' => 'Membership']); + $tokens = CRM_Core_SelectValues::membershipTokens(); + $this->assertEquals($this->getMembershipTokens(), $tokens); + $newStyleTokens = "\n{membership.status_id:label}\n{membership.membership_type_id:label}\n"; + $tokenString = $newStyleTokens . implode("\n", array_keys($this->getMembershipTokens())); + $memberships = CRM_Utils_Token::getMembershipTokenDetails([$this->getMembershipID()]); + $messageToken = CRM_Utils_Token::getTokens($tokenString); + $tokenHtml = CRM_Utils_Token::replaceEntityTokens('membership', $memberships[$this->getMembershipID()], $tokenString, $messageToken); + $this->assertEquals($this->getExpectedMembershipTokenOutput(), $tokenHtml); + } + + /** + * Get declared membership tokens. + * + * @return string[] + */ + public function getMembershipTokens(): array { + return [ + '{membership.id}' => 'Membership ID', + '{membership.status}' => 'Membership Status', + '{membership.type}' => 'Membership Type', + '{membership.start_date}' => 'Membership Start Date', + '{membership.join_date}' => 'Membership Join Date', + '{membership.end_date}' => 'Membership End Date', + '{membership.fee}' => 'Membership Fee', + ]; + } + + /** + * Get case ID. + * + * @return int + */ + protected function getMembershipID(): int { + if (!isset($this->ids['Membership'][0])) { + $this->ids['Membership'][0] = $this->contactMembershipCreate( + ['contact_id' => $this->getContactID()] + ); + } + return $this->ids['Membership'][0]; + } + + /** + * Get expected output from token parsing. + * + * @return string + */ + protected function getExpectedMembershipTokenOutput(): string { + return ' +Expired +General +1 +Expired +General +January 21st, 2007 +January 21st, 2007 +December 21st, 2007 +100.00'; + } + }