From 69863342f37479bef57c4ec820420f25716da21f Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Mon, 13 Sep 2021 11:04:29 +1200 Subject: [PATCH] dev/core#2817 Use token processor to resolve caseTokens for pdfs --- CRM/Contact/Form/Task/PDFLetterCommon.php | 20 +++---- CRM/Core/EntityTokens.php | 9 +-- .../Contact/Form/Task/PDFLetterCommonTest.php | 55 +++++++++++++++++++ 3 files changed, 68 insertions(+), 16 deletions(-) diff --git a/CRM/Contact/Form/Task/PDFLetterCommon.php b/CRM/Contact/Form/Task/PDFLetterCommon.php index 79baef807a..6ca9dd00ad 100644 --- a/CRM/Contact/Form/Task/PDFLetterCommon.php +++ b/CRM/Contact/Form/Task/PDFLetterCommon.php @@ -109,12 +109,14 @@ class CRM_Contact_Form_Task_PDFLetterCommon extends CRM_Core_Form_Task_PDFLetter * Process the form after the input has been submitted and validated. * * @param CRM_Core_Form $form + * * @throws \CRM_Core_Exception * @throws \CiviCRM_API3_Exception + * @throws \API_Exception */ - public static function postProcess(&$form) { + public static function postProcess(&$form): void { $formValues = $form->controller->exportValues($form->getName()); - list($formValues, $categories, $html_message, $messageToken, $returnProperties) = self::processMessageTemplate($formValues); + [$formValues, $categories, $html_message, $messageToken, $returnProperties] = self::processMessageTemplate($formValues); $skipOnHold = $form->skipOnHold ?? FALSE; $skipDeceased = $form->skipDeceased ?? TRUE; $html = $activityIds = []; @@ -125,7 +127,7 @@ class CRM_Contact_Form_Task_PDFLetterCommon extends CRM_Core_Form_Task_PDFLetter } if (!empty($formValues['document_file_path'])) { - list($html_message, $zip) = CRM_Utils_PDF_Document::unzipDoc($formValues['document_file_path'], $formValues['document_type']); + [$html_message, $zip] = CRM_Utils_PDF_Document::unzipDoc($formValues['document_file_path'], $formValues['document_type']); } foreach ($form->_contactIds as $item => $contactId) { @@ -136,11 +138,8 @@ class CRM_Contact_Form_Task_PDFLetterCommon extends CRM_Core_Form_Task_PDFLetter if (empty($caseId) && !empty($form->_caseIds[$item])) { $caseId = $form->_caseIds[$item]; } - if ($caseId) { - $params['case_id'] = $caseId; - } - list($contact) = CRM_Utils_Token::getTokenDetails($params, + [$contact] = CRM_Utils_Token::getTokenDetails($params, $returnProperties, $skipOnHold, $skipDeceased, @@ -154,14 +153,11 @@ class CRM_Contact_Form_Task_PDFLetterCommon extends CRM_Core_Form_Task_PDFLetter continue; } - $tokenHtml = $html_message; - if ($caseId) { - $tokenHtml = CRM_Utils_Token::replaceCaseTokens($caseId, $tokenHtml, $messageToken); - } $tokenHtml = CRM_Core_BAO_MessageTemplate::renderTemplate([ 'contactId' => $contactId, - 'messageTemplate' => ['msg_html' => $tokenHtml], + 'messageTemplate' => ['msg_html' => $html_message], 'tplParams' => ['contact' => $contact], + 'tokenContext' => $caseId ? ['caseId' => $caseId] : [], 'disableSmarty' => (!defined('CIVICRM_MAIL_SMARTY') || !CIVICRM_MAIL_SMARTY), ])['html']; diff --git a/CRM/Core/EntityTokens.php b/CRM/Core/EntityTokens.php index ad86cd6d5b..db8bd723c6 100644 --- a/CRM/Core/EntityTokens.php +++ b/CRM/Core/EntityTokens.php @@ -11,6 +11,7 @@ */ use Civi\Token\AbstractTokenSubscriber; +use Civi\Token\Event\TokenValueEvent; use Civi\Token\TokenRow; use Civi\ActionSchedule\Event\MailingQueryEvent; use Civi\Token\TokenProcessor; @@ -400,11 +401,11 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber { return CRM_Core_DAO_AllCoreTables::convertEntityNameToLower($this->getApiEntityName()); } - public function getEntityIDField() { + public function getEntityIDField(): string { return $this->getEntityName() . 'Id'; } - public function prefetch(\Civi\Token\Event\TokenValueEvent $e): ?array { + public function prefetch(TokenValueEvent $e): ?array { $entityIDs = $e->getTokenProcessor()->getContextValues($this->getEntityIDField()); if (empty($entityIDs)) { return []; @@ -437,8 +438,8 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber { return CRM_Core_Config::singleton()->defaultCurrency; } - public function getPrefetchFields(\Civi\Token\Event\TokenValueEvent $e): array { - return array_intersect(array_merge($this->getActiveTokens($e), $this->getCurrencyFieldName()), array_keys($this->getAllTokens())); + public function getPrefetchFields(TokenValueEvent $e): array { + return array_intersect(array_merge($this->getActiveTokens($e), $this->getCurrencyFieldName(), ['id']), array_keys($this->getAllTokens())); } } diff --git a/tests/phpunit/CRM/Contact/Form/Task/PDFLetterCommonTest.php b/tests/phpunit/CRM/Contact/Form/Task/PDFLetterCommonTest.php index f8a0d44a94..c66a08d033 100644 --- a/tests/phpunit/CRM/Contact/Form/Task/PDFLetterCommonTest.php +++ b/tests/phpunit/CRM/Contact/Form/Task/PDFLetterCommonTest.php @@ -17,6 +17,8 @@ */ class CRM_Contact_Form_Task_PDFLetterCommonTest extends CiviUnitTestCase { + use CRMTraits_Custom_CustomDataTrait; + /** * Contact ID. * @@ -153,4 +155,57 @@ class CRM_Contact_Form_Task_PDFLetterCommonTest extends CiviUnitTestCase { $this->assertStringContainsString('Logged In, Dear Logged In', $processedMessage); } + /** + * Test case tokens are resolved in pdf letter. + */ + public function testCaseTokensAreResolved() : void { + // @todo - find a better way to set case id.... + $_REQUEST['caseid'] = $this->getCaseID(); + $form = $this->getPDFForm([ + 'html_message' => '{contact.first_name}, {case.case_type_id:label} {case.' . $this->getCustomFieldName('text') . '}', + ], [$this->contactId]); + $processedMessage = $this->submitForm($form)['html']; + $this->assertStringContainsString('Logged In, Housing Support bb', $processedMessage); + } + + /** + * Get case ID. + * + * @return int + */ + protected function getCaseID(): int { + if (!isset($this->ids['Case'][0])) { + CRM_Core_BAO_ConfigSetting::enableComponent('CiviCase'); + $this->createCustomGroupWithFieldOfType(['extends' => 'Case']); + $this->ids['Case'][0] = $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', + // Note end_date is inconsistent with status Ongoing but for the + // purposes of testing tokens is ok. Creating it with status Resolved + // then ignores our known fixed end date. + 'end_date' => '2021-07-26 18:07:20', + 'medium_id' => 2, + 'details' => 'case details', + 'activity_details' => 'blah blah', + 'sequential' => 1, + $this->getCustomFieldName('text') => 'bb', + ])['id']; + } + return $this->ids['Case'][0]; + } + + /** + * @return int + */ + protected function getContactID(): int { + if (!isset($this->ids['Contact'][0])) { + $this->ids['Contact'][0] = $this->individualCreate(); + } + return $this->ids['Contact'][0]; + } + } -- 2.25.1