From: eileen Date: Sat, 6 Feb 2021 03:36:45 +0000 (+1300) Subject: Convert Smarty & domain token processing to use token processor X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=82e5b7adb8855392d31268d21b6fefc61223a4cc;p=civicrm-core.git Convert Smarty & domain token processing to use token processor This is a subset of the changes in https://github.com/civicrm/civicrm-core/pull/19550 that we should be able to resolve & merge while addressing that takes longer. It still gets us the benefit of adopting a preferred pattern Note that some test changes exist around handling of subject - the code now converts a new line to a space consistently. In addition tests that rely on leakage have been altered as smarty does not leak with this approach --- diff --git a/CRM/Core/BAO/MessageTemplate.php b/CRM/Core/BAO/MessageTemplate.php index 2b217a834b..e64e2639a9 100644 --- a/CRM/Core/BAO/MessageTemplate.php +++ b/CRM/Core/BAO/MessageTemplate.php @@ -9,6 +9,8 @@ +--------------------------------------------------------------------+ */ +use Civi\Token\TokenProcessor; + /** * * @package CRM @@ -425,7 +427,7 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate { $mailContent['subject'] = $params['subject']; } - $mailContent = self::renderMessageTemplate($mailContent, $params['disableSmarty'], $params['contactId'] ?? NULL, $params['tplParams']); + $mailContent = self::renderMessageTemplate($mailContent, (bool) $params['disableSmarty'], $params['contactId'] ?? NULL, $params['tplParams']); // send the template, honouring the target user’s preferences (if any) $sent = FALSE; @@ -692,35 +694,33 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate { * * @param array $mailContent * @param bool $disableSmarty - * @param int $contactID + * @param int|NULL $contactID * @param array $smartyAssigns * * @return array - * @throws \CRM_Core_Exception */ - public static function renderMessageTemplate(array $mailContent, $disableSmarty, $contactID, $smartyAssigns): array { - $tokens = self::getTokensToResolve($mailContent); - - // When using Smarty we need to pass the $escapeSmarty parameter. - $escapeSmarty = !$disableSmarty; - - $mailContent = self::resolveDomainTokens($mailContent, $tokens, $escapeSmarty); - + public static function renderMessageTemplate(array $mailContent, bool $disableSmarty, $contactID, array $smartyAssigns): array { if ($contactID) { - $mailContent = self::resolveContactTokens($contactID, $tokens, $mailContent, $escapeSmarty); + // @todo resolve contact ID below - see https://github.com/civicrm/civicrm-core/pull/19550 + // for things to resolve first. + $tokens = self::getTokensToResolve($mailContent); + $mailContent = self::resolveContactTokens($contactID, $tokens, $mailContent, !$disableSmarty); } - - // Normally Smarty is run, but it can be disabled using the disableSmarty - // parameter, which may be useful for non-core uses of MessageTemplate.send - // In particular it helps with the mosaicomsgtpl extension. - if (!$disableSmarty) { - $mailContent = self::parseThroughSmarty($mailContent, $smartyAssigns); - } - else { - // Since we're not relying on Smarty for this function, we DIY. - // strip whitespace from ends and turn into a single line - $mailContent['subject'] = trim(preg_replace('/[\r\n]+/', ' ', $mailContent['subject'])); + CRM_Core_Smarty::singleton()->pushScope($smartyAssigns); + $tokenProcessor = new TokenProcessor(\Civi::dispatcher(), ['smarty' => !$disableSmarty]); + $tokenProcessor->addMessage('html', $mailContent['html'], 'text/html'); + $tokenProcessor->addMessage('text', $mailContent['text'], 'text/plain'); + $tokenProcessor->addMessage('subject', $mailContent['subject'], 'text/plain'); + $tokenProcessor->addRow([]); + $tokenProcessor->evaluate(); + foreach ($tokenProcessor->getRows() as $row) { + $mailContent['html'] = $row->render('html'); + $mailContent['text'] = $row->render('text'); + $mailContent['subject'] = $row->render('subject'); } + CRM_Core_Smarty::singleton()->popScope(); + + $mailContent['subject'] = trim(preg_replace('/[\r\n]+/', ' ', $mailContent['subject'])); return $mailContent; } diff --git a/tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php b/tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php index 4ab571b5c5..5ca3f5ed2d 100644 --- a/tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php +++ b/tests/phpunit/CRM/Core/BAO/MessageTemplateTest.php @@ -92,7 +92,7 @@ class CRM_Core_BAO_MessageTemplateTest extends CiviUnitTestCase { Up the road London, 90210 ~ crown@example.com ~ 1 ~ rather nice', $messageContent['text']); - $this->assertEquals('Default Domain Name ~ ~ Buckingham palaceUp the roadLondon, 90210~ crown@example.com ~ 1 ~ rather nice', $messageContent['subject']); + $this->assertEquals('Default Domain Name ~ ~ Buckingham palace Up the road London, 90210 ~ crown@example.com ~ 1 ~ rather nice', $messageContent['subject']); } /** @@ -246,7 +246,7 @@ contact_id:' . $tokenData['contact_id'] . ' '; $this->assertEquals($expected, $messageContent['html']); $this->assertEquals($expected, $messageContent['text']); - $this->assertEquals(str_replace("\n", '', $expected), $messageContent['subject']); + $this->assertEquals(rtrim(str_replace("\n", ' ', $expected)), $messageContent['subject']); } /** diff --git a/tests/phpunit/CRM/Event/Form/Registration/ConfirmTest.php b/tests/phpunit/CRM/Event/Form/Registration/ConfirmTest.php index 7278eacafc..0411a6da6b 100644 --- a/tests/phpunit/CRM/Event/Form/Registration/ConfirmTest.php +++ b/tests/phpunit/CRM/Event/Form/Registration/ConfirmTest.php @@ -20,7 +20,7 @@ class CRM_Event_Form_Registration_ConfirmTest extends CiviUnitTestCase { * * @throws \Exception */ - public function testSubmit() { + public function testSubmit(): void { $event = $this->eventCreate(); $mut = new CiviMailUtils($this, TRUE); CRM_Event_Form_Registration_Confirm::testSubmit([ @@ -77,15 +77,11 @@ class CRM_Event_Form_Registration_ConfirmTest extends CiviUnitTestCase { ], ]); - $participant = $this->callAPISuccessGetSingle('Participant', []); $mut->checkMailLog([ 'Dear Logged In, Thank you for your registration. This is a confirmation that your registration has been received and your status has been updated to Registered.', ]); $mut->stop(); $mut->clearMessages(); - $tplVars = CRM_Core_Smarty::singleton()->get_template_vars(); - $this->assertEquals($participant['id'], $tplVars['participantID']); - } /** @@ -486,8 +482,6 @@ class CRM_Event_Form_Registration_ConfirmTest extends CiviUnitTestCase { $mut->checkMailLog(['Comment: ' . $event['note'] . chr(0x0A)]); $mut->stop(); $mut->clearMessages(); - $tplVars = CRM_Core_Smarty::singleton()->get_template_vars(); - $this->assertEquals($participant['id'], $tplVars['participantID']); //return ['contact_id' => $contact_id, 'participant_id' => $participant['id']]; return [$contact_id, $participant['id']]; } @@ -557,13 +551,17 @@ class CRM_Event_Form_Registration_ConfirmTest extends CiviUnitTestCase { * /dev/event#10 * Test submission with a note in the profile, ensuring the confirmation * email reflects the submitted value + * + * @throws \CRM_Core_Exception + * @throws \CiviCRM_API3_Exception + * @throws \Exception */ - public function testNoteSubmission() { + public function testNoteSubmission(): void { //create an event with an attached profile containing a note $event = $this->creatEventWithProfile(NULL); - $event['custom_pre_id'] = $this->ids["UFGroup"]["our profile"]; + $event['custom_pre_id'] = $this->ids['UFGroup']['our profile']; $event['note'] = 'This is note 1'; - list($contact_id, $participant_id) = $this->submitWithNote($event, NULL); + [$contact_id, $participant_id] = $this->submitWithNote($event, NULL); civicrm_api3('Participant', 'delete', ['id' => $participant_id]); //now that the contact has one note, register this contact again with a different note @@ -571,7 +569,7 @@ class CRM_Event_Form_Registration_ConfirmTest extends CiviUnitTestCase { $event = $this->creatEventWithProfile($event); $event['custom_pre_id'] = $this->ids["UFGroup"]["our profile"]; $event['note'] = 'This is note 2'; - list($contact_id, $participant_id) = $this->submitWithNote($event, $contact_id); + [$contact_id, $participant_id] = $this->submitWithNote($event, $contact_id); civicrm_api3('Participant', 'delete', ['id' => $participant_id]); //finally, submit a blank note and confirm that the note shown in the email is blank diff --git a/tests/phpunit/api/v3/ContributionTest.php b/tests/phpunit/api/v3/ContributionTest.php index 3696a1c2a4..c3f95ad348 100644 --- a/tests/phpunit/api/v3/ContributionTest.php +++ b/tests/phpunit/api/v3/ContributionTest.php @@ -3666,9 +3666,8 @@ class api_v3_ContributionTest extends CiviUnitTestCase { * Test sending a mail via the API. * * @throws \CRM_Core_Exception - * @throws \CiviCRM_API3_Exception */ - public function testSendMail() { + public function testSendMail(): void { $mut = new CiviMailUtils($this, TRUE); $orderParams = $this->_params; $orderParams['contribution_status_id'] = 'Pending'; @@ -3698,7 +3697,6 @@ class api_v3_ContributionTest extends CiviUnitTestCase { $mut->stop(); $tplVars = CRM_Core_Smarty::singleton()->get_template_vars(); $this->assertEquals('bob', $tplVars['billingName']); - $this->assertEquals("bob\nblah\n", $tplVars['address']); } /**