From 595cc868bf0deb902254529a1afa6d4d7cee5dc4 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Wed, 15 Sep 2021 02:46:46 -0700 Subject: [PATCH] EntityTokens - Allow using mocked data Before: EntityTokens reads `$tokenContext['contributionId']` and fetches the corresponding `civicrm_contribution`. The data must exist in that record. After: EntityTokens reads both `$tokenContext['contributionId']` and `$tokenContext['contribution']`. Data in `$tokenContext['contribution']` takes precedence, rendering the content of `civicrm_contribution` mute. --- CRM/Core/EntityTokens.php | 5 ++ .../phpunit/Civi/Token/TokenProcessorTest.php | 80 +++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/CRM/Core/EntityTokens.php b/CRM/Core/EntityTokens.php index dd5d63e390..5226f5e9fe 100644 --- a/CRM/Core/EntityTokens.php +++ b/CRM/Core/EntityTokens.php @@ -293,6 +293,11 @@ class CRM_Core_EntityTokens extends AbstractTokenSubscriber { * @return string|int */ protected function getFieldValue(TokenRow $row, string $field) { + $entityName = $this->getEntityName(); + if (isset($row->context[$entityName][$field])) { + return $row->context[$entityName][$field]; + } + $actionSearchResult = $row->context['actionSearchResult']; $aliasedField = $this->getEntityAlias() . $field; if (isset($actionSearchResult->{$aliasedField})) { diff --git a/tests/phpunit/Civi/Token/TokenProcessorTest.php b/tests/phpunit/Civi/Token/TokenProcessorTest.php index 44f90c13c2..9b726e2752 100644 --- a/tests/phpunit/Civi/Token/TokenProcessorTest.php +++ b/tests/phpunit/Civi/Token/TokenProcessorTest.php @@ -444,6 +444,86 @@ class TokenProcessorTest extends \CiviUnitTestCase { $this->assertEquals(2, $loops); } + /** + * Process a message using mocked data. + */ + public function testMockData_Contribution() { + $this->dispatcher->addSubscriber(new \CRM_Contribute_Tokens()); + + $p = new TokenProcessor($this->dispatcher, [ + 'controller' => __CLASS__, + 'schema' => ['contributionId'], + ]); + $p->addMessage('example', 'Invoice #{contribution.invoice_id}!', 'text/plain'); + $p->addRow([ + 'contributionId' => 111, + 'contribution' => [ + 'id' => 111, + 'receive_date' => '2012-01-02', + 'invoice_id' => 11111, + ], + ]); + $p->addRow([ + 'contributionId' => 222, + 'contribution' => [ + 'id' => 111, + 'receive_date' => '2012-01-02', + 'invoice_id' => 22222, + ], + ]); + $p->evaluate(); + + $outputs = []; + foreach ($p->getRows() as $row) { + $outputs[] = $row->render('example'); + } + $this->assertEquals('Invoice #11111!', $outputs[0]); + $this->assertEquals('Invoice #22222!', $outputs[1]); + } + + /** + * Process a message using mocked data, accessed through a Smarty alias. + */ + public function testMockData_SmartyAlias_Contribution() { + $this->dispatcher->addSubscriber(new TokenCompatSubscriber()); + $this->dispatcher->addSubscriber(new \CRM_Contribute_Tokens()); + + $p = new TokenProcessor($this->dispatcher, [ + 'controller' => __CLASS__, + 'schema' => ['contributionId'], + 'smarty' => TRUE, + 'smartyTokenAlias' => [ + 'theInvoiceId' => 'contribution.invoice_id', + ], + ]); + $p->addMessage('example', 'Invoice #{$theInvoiceId}!', 'text/plain'); + $p->addRow([ + 'contributionId' => 333, + 'contribution' => [ + 'id' => 333, + 'receive_date' => '2012-01-02', + 'invoice_id' => 33333, + ], + ]); + $p->addRow([ + 'contributionId' => 444, + 'contribution' => [ + 'id' => 444, + 'receive_date' => '2012-01-02', + 'invoice_id' => 44444, + ], + ]); + $p->evaluate(); + + $outputs = []; + foreach ($p->getRows() as $row) { + $outputs[] = $row->render('example'); + } + $this->assertEquals('Invoice #33333!', $outputs[0]); + $this->assertEquals('Invoice #44444!', $outputs[1]); + + } + /** * This defines a compatibility mechanism wherein an old Smarty expression can * be evaluated based on a newer token expression. -- 2.25.1