Merge pull request #21879 from mariav0/patch-17
[civicrm-core.git] / Civi / Token / TokenCompatSubscriber.php
CommitLineData
43ceab3f
TO
1<?php
2namespace Civi\Token;
3
4use Civi\Token\Event\TokenRenderEvent;
5use Civi\Token\Event\TokenValueEvent;
f70a513f 6use Money\Money;
43ceab3f
TO
7use Symfony\Component\EventDispatcher\EventSubscriberInterface;
8
9/**
10 * Class TokenCompatSubscriber
11 * @package Civi\Token
12 *
a7f29bf4 13 * This class handles the smarty processing of tokens.
43ceab3f
TO
14 */
15class TokenCompatSubscriber implements EventSubscriberInterface {
16
17 /**
18 * @inheritDoc
19 */
fb9c59fe 20 public static function getSubscribedEvents(): array {
c64f69d9 21 return [
8996a8b6
TO
22 'civi.token.eval' => [
23 ['setupSmartyAliases', 1000],
8996a8b6 24 ],
4c367668 25 'civi.token.render' => 'onRender',
c64f69d9 26 ];
43ceab3f
TO
27 }
28
8996a8b6
TO
29 /**
30 * Interpret the variable `$context['smartyTokenAlias']` (e.g. `mySmartyField' => `tkn_entity.tkn_field`).
31 *
32 * We need to ensure that any tokens like `{tkn_entity.tkn_field}` are hydrated, so
33 * we pretend that they are in use.
34 *
35 * @param \Civi\Token\Event\TokenValueEvent $e
36 */
37 public function setupSmartyAliases(TokenValueEvent $e) {
38 $aliasedTokens = [];
39 foreach ($e->getRows() as $row) {
40 $aliasedTokens = array_unique(array_merge($aliasedTokens,
41 array_values($row->context['smartyTokenAlias'] ?? [])));
42 }
43
44 $fakeMessage = implode('', array_map(function ($f) {
45 return '{' . $f . '}';
46 }, $aliasedTokens));
47
48 $proc = $e->getTokenProcessor();
49 $proc->addMessage('TokenCompatSubscriber.aliases', $fakeMessage, 'text/plain');
50 }
51
43ceab3f
TO
52 /**
53 * Apply the various CRM_Utils_Token helpers.
54 *
34f3bbd9 55 * @param \Civi\Token\Event\TokenRenderEvent $e
43ceab3f 56 */
0432df8d 57 public function onRender(TokenRenderEvent $e): void {
43ceab3f 58 $useSmarty = !empty($e->context['smarty']);
03946c16
TO
59 $e->string = $e->getTokenProcessor()->visitTokens($e->string, function() {
60 // For historical consistency, we filter out unrecognized tokens.
61 return '';
62 });
43ceab3f 63
d49e8eec
EM
64 // This removes the pattern used in greetings of having bits of text that
65 // depend on the tokens around them - ie '{first_name}{ }{last_name}
66 // has an extra construct '{ }' which will resolve as a space if the
67 // tokens on either side are resolved to 'something'
68 $e->string = preg_replace('/\\\\|\{(\s*)?\}/', ' ', $e->string);
69
43ceab3f 70 if ($useSmarty) {
8996a8b6
TO
71 $smartyVars = [];
72 foreach ($e->context['smartyTokenAlias'] ?? [] as $smartyName => $tokenName) {
f70a513f
EM
73 $smartyVars[$smartyName] = \CRM_Utils_Array::pathGet($e->row->tokens, explode('.', $tokenName), $e->context['locale'] ?? NULL);
74 if ($smartyVars[$smartyName] instanceof \Brick\Money\Money) {
75 $smartyVars[$smartyName] = \Civi::format()->money($smartyVars[$smartyName]->getAmount(), $smartyVars[$smartyName]->getCurrency());
76 }
8996a8b6
TO
77 }
78 \CRM_Core_Smarty::singleton()->pushScope($smartyVars);
79 try {
80 $e->string = \CRM_Utils_String::parseOneOffStringThroughSmarty($e->string);
81 }
82 finally {
83 \CRM_Core_Smarty::singleton()->popScope();
84 }
43ceab3f
TO
85 }
86 }
87
88}