[ ['setupSmartyAliases', 1000], ], 'civi.token.render' => 'onRender', ]; } /** * Interpret the variable `$context['smartyTokenAlias']` (e.g. `mySmartyField' => `tkn_entity.tkn_field`). * * We need to ensure that any tokens like `{tkn_entity.tkn_field}` are hydrated, so * we pretend that they are in use. * * @param \Civi\Token\Event\TokenValueEvent $e */ public function setupSmartyAliases(TokenValueEvent $e) { $aliasedTokens = []; foreach ($e->getRows() as $row) { $aliasedTokens = array_unique(array_merge($aliasedTokens, array_values($row->context['smartyTokenAlias'] ?? []))); } $fakeMessage = implode('', array_map(function ($f) { return '{' . $f . '}'; }, $aliasedTokens)); $proc = $e->getTokenProcessor(); $proc->addMessage('TokenCompatSubscriber.aliases', $fakeMessage, 'text/plain'); } /** * Apply the various CRM_Utils_Token helpers. * * @param \Civi\Token\Event\TokenRenderEvent $e */ public function onRender(TokenRenderEvent $e): void { $useSmarty = !empty($e->context['smarty']); $e->string = $e->getTokenProcessor()->visitTokens($e->string, function() { // For historical consistency, we filter out unrecognized tokens. return ''; }); if ($useSmarty) { $smartyVars = []; foreach ($e->context['smartyTokenAlias'] ?? [] as $smartyName => $tokenName) { $smartyVars[$smartyName] = \CRM_Utils_Array::pathGet($e->row->tokens, explode('.', $tokenName)); } \CRM_Core_Smarty::singleton()->pushScope($smartyVars); try { $e->string = \CRM_Utils_String::parseOneOffStringThroughSmarty($e->string); } finally { \CRM_Core_Smarty::singleton()->popScope(); } } } }