Commit | Line | Data |
---|---|---|
43ceab3f TO |
1 | <?php |
2 | namespace Civi\Token; | |
3 | ||
4 | use Civi\Token\Event\TokenRenderEvent; | |
5 | use Civi\Token\Event\TokenValueEvent; | |
f70a513f | 6 | use Money\Money; |
43ceab3f TO |
7 | use 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 | */ |
15 | class 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 | } |