From 1972897e1305a853a7bfb043620ef888486d05f1 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Mon, 5 Jul 2021 23:31:01 -0700 Subject: [PATCH] WorkflowMessage - Add assertValid(), renderTemplate(), sendTemplate() helpers to standard impl (FinalHelperTrait) --- .../GenericWorkflowMessage.php | 4 + .../Traits/FinalHelperTrait.php | 85 +++++++++++++++++++ .../WorkflowMessageInterface.php | 55 ++++++++++++ .../ExampleWorkflowMessageTest.php | 45 ++++++++++ 4 files changed, 189 insertions(+) create mode 100644 Civi/WorkflowMessage/Traits/FinalHelperTrait.php diff --git a/Civi/WorkflowMessage/GenericWorkflowMessage.php b/Civi/WorkflowMessage/GenericWorkflowMessage.php index 5c9aaa6f0f..10a8b4373f 100644 --- a/Civi/WorkflowMessage/GenericWorkflowMessage.php +++ b/Civi/WorkflowMessage/GenericWorkflowMessage.php @@ -13,6 +13,7 @@ namespace Civi\WorkflowMessage; use Civi\Schema\Traits\MagicGetterSetterTrait; +use Civi\WorkflowMessage\Traits\FinalHelperTrait; use Civi\WorkflowMessage\Traits\ReflectiveWorkflowTrait; /** @@ -30,6 +31,9 @@ class GenericWorkflowMessage implements WorkflowMessageInterface { // Implement __call() - Public and protected properties are automatically given a default getter/setter. These may be overridden/customized. use MagicGetterSetterTrait; + // Implement assertValid(), renderTemplate(), sendTemplate() - Sugary stub methods that delegate to real APIs. + use FinalHelperTrait; + /** * WorkflowMessage constructor. * diff --git a/Civi/WorkflowMessage/Traits/FinalHelperTrait.php b/Civi/WorkflowMessage/Traits/FinalHelperTrait.php new file mode 100644 index 0000000000..09ab889048 --- /dev/null +++ b/Civi/WorkflowMessage/Traits/FinalHelperTrait.php @@ -0,0 +1,85 @@ +validate(); + if (!$strict) { + $validations = array_filter($validations, function ($validation) { + return $validation['severity'] === 'error'; + }); + } + if (!empty($validations)) { + throw new \CRM_Core_Exception(sprintf("Found %d validation error(s) in %s.", count($validations), get_class($this))); + } + return $this; + } + + /** + * @see \Civi\WorkflowMessage\WorkflowMessageInterface::renderTemplate() + */ + final public function renderTemplate(array $params = []): array { + $params['model'] = $this; + return \CRM_Core_BAO_MessageTemplate::renderTemplate($params); + } + + /** + * @see \Civi\WorkflowMessage\WorkflowMessageInterface::sendTemplate() + */ + final public function sendTemplate(array $params = []): array { + return \CRM_Core_BAO_MessageTemplate::sendTemplate($params + ['model' => $this]); + } + + ///** + // * Get the list of available tokens. + // * + // * @return array + // * Ex: ['contact.first_name' => ['entity' => 'contact', 'field' => 'first_name', 'label' => ts('Last Name')]] + // * Array(string $dottedName => array('entity'=>string, 'field'=>string, 'label'=>string)). + // */ + //final public function getTokens(): array { + // $tp = new TokenProcessor(\Civi::dispatcher(), [ + // 'controller' => static::CLASS, + // ]); + // $tp->addRow($this->export('tokenContext')); + // return $tp->getTokens(); + //} + +} diff --git a/Civi/WorkflowMessage/WorkflowMessageInterface.php b/Civi/WorkflowMessage/WorkflowMessageInterface.php index 25641ed015..c3d4438ce8 100644 --- a/Civi/WorkflowMessage/WorkflowMessageInterface.php +++ b/Civi/WorkflowMessage/WorkflowMessageInterface.php @@ -56,4 +56,59 @@ interface WorkflowMessageInterface { */ public function validate(): array; + // These additional methods are sugar-coating - they're part of the interface to + // make it easier to work with, but implementers should not differentiate themselves + // using this methods. Instead, use FinalHelperTrait as a thin implementation. + + /** + * Assert that the current message data is valid/sufficient. + * + * TIP: Do not implement directly. Use FinalHelperTrait. + * + * @param bool $strict + * If TRUE, then warnings will raise exceptions. + * If FALSE, then only errors will raise exceptions. + * @return $this + * @throws \CRM_Core_Exception + */ + public function assertValid($strict = FALSE); + + /** + * Render a message template. + * + * TIP: Do not implement directly. Use FinalHelperTrait. + * + * @param array $params + * Options for loading the message template. + * If none given, the default for this workflow will be loaded. + * Ex: ['messageTemplate' => ['msg_subject' => 'Hello {contact.first_name}']] + * Ex: ['messageTemplateID' => 123] + * @return array + * Rendered message, consistent of 'subject', 'text', 'html' + * Ex: ['subject' => 'Hello Bob', 'text' => 'It\'s been so long since we sent you an automated notification!'] + * @see \CRM_Core_BAO_MessageTemplate::renderTemplate() + */ + public function renderTemplate(array $params = []): array; + + /** + * Send an email using a message template. + * + * TIP: Do not implement directly. Use FinalHelperTrait. + * + * @param array $params + * List of extra parameters to pass to `sendTemplate()`. Ex: + * - from + * - toName + * - toEmail + * - cc + * - bcc + * - replyTo + * - isTest + * + * @return array + * Array of four parameters: a boolean whether the email was sent, and the subject, text and HTML templates + * @see \CRM_Core_BAO_MessageTemplate::sendTemplate() + */ + public function sendTemplate(array $params = []): array; + } diff --git a/tests/phpunit/Civi/WorkflowMessage/ExampleWorkflowMessageTest.php b/tests/phpunit/Civi/WorkflowMessage/ExampleWorkflowMessageTest.php index 0d3c96e62c..04b1e75ff3 100644 --- a/tests/phpunit/Civi/WorkflowMessage/ExampleWorkflowMessageTest.php +++ b/tests/phpunit/Civi/WorkflowMessage/ExampleWorkflowMessageTest.php @@ -259,4 +259,49 @@ class ExampleWorkflowMessageTest extends \CiviUnitTestCase { $this->assertTrue(!isset($envelope['myProtectedInt'])); } + public function testImpromptuRender() { + $rand = rand(0, 1000); + $cid = $this->individualCreate(['first_name' => 'Foo', 'last_name' => 'Bar' . $rand, 'prefix_id' => NULL, 'suffix_id' => NULL]); + /** @var \Civi\WorkflowMessage\GenericWorkflowMessage $ex */ + $ex = WorkflowMessage::create('some_impromptu_wf', [ + 'tokenContext' => ['contactId' => $cid], + ]); + $rendered = $ex->renderTemplate([ + 'messageTemplate' => [ + 'msg_subject' => 'Hello {contact.display_name}', + ], + ]); + $this->assertEquals('Hello Foo Bar' . $rand, $rendered['subject']); + } + + public function testRenderStoredTemplate() { + $rand = rand(0, 1000); + $cid = $this->individualCreate(['first_name' => 'Foo', 'last_name' => 'Bar' . $rand, 'prefix_id' => NULL, 'suffix_id' => NULL]); + /** @var \Civi\WorkflowMessage\GenericWorkflowMessage $ex */ + $ex = WorkflowMessage::create('petition_sign', [ + 'tokenContext' => ['contactId' => $cid], + 'tplParams' => [ + 'greeting' => 'Greetings yo', + 'petition' => ['title' => 'The Fake Petition'], + 'petitionTitle' => 'The Fake Petition', + 'survey_id' => NULL, + ], + ]); + $rendered = $ex->renderTemplate(); + $this->assertStringContainsString('Foo Bar' . $rand, $rendered['subject']); + $this->assertStringContainsString('Thank you for signing The Fake Petition', $rendered['html']); + $this->assertStringContainsString('Thank you for signing The Fake Petition', $rendered['text']); + } + + //public function testImpromptuTokens() { + // /** @var \Civi\WorkflowMessage\GenericWorkflowMessage $ex */ + // $ex = WorkflowMessage::create('some_impromptu_wf', [ + // 'envelope' => [ + // 'contactId' => 123, + // ], + // ]); + // $tokens = $ex->getTokens(); + // $this->assertEquals('First ZZName', $tokens['contact.first_name']['label']); + //} + } -- 2.25.1