diff --git a/CRM/Utils/Token.php b/CRM/Utils/Token.php index 96e4598a4678..f2aec1d44e89 100644 --- a/CRM/Utils/Token.php +++ b/CRM/Utils/Token.php @@ -1633,10 +1633,13 @@ public static function replaceEntityTokens($entity, $entityArray, $str, $knownTo * @return string * @throws \CiviCRM_API3_Exception */ - public static function replaceCaseTokens($caseId, $str, $knownTokens = [], $escapeSmarty = FALSE) { - if (!$knownTokens || empty($knownTokens['case'])) { + public static function replaceCaseTokens($caseId, $str, $knownTokens = NULL, $escapeSmarty = FALSE): string { + if (strpos($str, '{case.') === FALSE) { return $str; } + if (!$knownTokens) { + $knownTokens = self::getTokens($str); + } $case = civicrm_api3('case', 'getsingle', ['id' => $caseId]); return self::replaceEntityTokens('case', $case, $str, $knownTokens, $escapeSmarty); } diff --git a/tests/phpunit/CRM/Utils/TokenConsistencyTest.php b/tests/phpunit/CRM/Utils/TokenConsistencyTest.php new file mode 100644 index 000000000000..bae1d43e1ef6 --- /dev/null +++ b/tests/phpunit/CRM/Utils/TokenConsistencyTest.php @@ -0,0 +1,150 @@ +quickCleanup(['civicrm_case', 'civicrm_case_type']); + parent::tearDown(); + } + + /** + * Test that case tokens are consistently rendered. + * + * @throws \API_Exception + * @throws \CiviCRM_API3_Exception + */ + public function testCaseTokenConsistency(): void { + $this->createLoggedInUser(); + CRM_Core_BAO_ConfigSetting::enableComponent('CiviCase'); + $this->createCustomGroupWithFieldOfType(['extends' => 'Case']); + $tokens = CRM_Core_SelectValues::caseTokens(); + $this->assertEquals($this->getCaseTokens(), $tokens); + $caseID = $this->getCaseID(); + $tokenHtml = CRM_Utils_Token::replaceCaseTokens($caseID, implode("\n", array_keys($this->getCaseTokens())), ['case' => $this->getCaseTokenKeys()]); + $this->assertEquals($this->getExpectedCaseTokenOutput(), $tokenHtml); + // Now do the same without passing in 'knownTokens' + $tokenHtml = CRM_Utils_Token::replaceCaseTokens($caseID, implode("\n", array_keys($this->getCaseTokens()))); + $this->assertEquals($this->getExpectedCaseTokenOutput(), $tokenHtml); + } + + /** + * Get expected output from token parsing. + * + * @return string + */ + protected function getExpectedCaseTokenOutput(): string { + return '1 +Housing Support +Case Subject +July 23rd, 2021 +July 26th, 2021 +case details +Ongoing +No +' . $this->case['modified_date'] . ' +' . $this->case['created_date'] . ' +'; + } + + /** + * @return int + */ + protected function getContactID(): int { + if (!isset($this->ids['Contact'][0])) { + $this->ids['Contact'][0] = $this->individualCreate(); + } + return $this->ids['Contact'][0]; + } + + /** + * Get the keys for the case tokens. + * + * @return array + */ + public function getCaseTokenKeys(): array { + $return = []; + foreach (array_keys($this->getCaseTokens()) as $key) { + $return[] = substr($key, 6, -1); + } + return $return; + } + + /** + * Get declared tokens. + * + * @return string[] + */ + public function getCaseTokens(): array { + return [ + '{case.id}' => 'Case ID', + '{case.case_type_id}' => 'Case Type ID', + '{case.subject}' => 'Case Subject', + '{case.start_date}' => 'Case Start Date', + '{case.end_date}' => 'Case End Date', + '{case.details}' => 'Details', + '{case.status_id}' => 'Case Status', + '{case.is_deleted}' => 'Case is in the Trash', + '{case.created_date}' => 'Created Date', + '{case.modified_date}' => 'Modified Date', + '{case.custom_1}' => 'Enter text here :: Group with field text', + ]; + } + + /** + * Get case ID. + * + * @return int + */ + protected function getCaseID(): int { + if (!isset($this->case)) { + $this->case = $this->callAPISuccess('Case', 'create', [ + 'case_type_id' => 'housing_support', + 'activity_subject' => 'Case Subject', + 'client_id' => $this->getContactID(), + 'status_id' => 1, + 'subject' => 'Case Subject', + 'start_date' => '2021-07-23 15:39:20', + 'end_date' => '2021-07-26 18:07:20', + 'medium_id' => 2, + 'details' => 'case details', + 'activity_details' => 'blah blah', + 'sequential' => 1, + ])['values'][0]; + } + return $this->case['id']; + } + +}