eca-1.0.x-dev/src/EventSubscriber/EcaExecutionTokenSubscriber.php
src/EventSubscriber/EcaExecutionTokenSubscriber.php
<?php
namespace Drupal\eca\EventSubscriber;
use Drupal\eca\Attribute\Token;
use Drupal\eca\EcaEvents;
use Drupal\eca\Event\AfterInitialExecutionEvent;
use Drupal\eca\Event\BeforeInitialExecutionEvent;
use Drupal\eca\Event\TokenReceiverInterface;
/**
* Prepares and cleans up the Token service when executing ECA logic.
*/
class EcaExecutionTokenSubscriber extends EcaExecutionSubscriberBase {
/**
* Subscriber method before initial execution.
*
* @param \Drupal\eca\Event\BeforeInitialExecutionEvent $event
* The according event.
*/
#[Token(
name: 'VARIOUS',
description: 'All tokens forwarded by the dispatcher.',
classes: [TokenReceiverInterface::class],
)]
public function onBeforeInitialExecution(BeforeInitialExecutionEvent $event): void {
// Determine explicitly defined tokens to be forwarded.
$forwardTokens = [];
$triggeredEvent = $event->getEvent();
if ($triggeredEvent instanceof TokenReceiverInterface) {
foreach ($triggeredEvent->getTokenNamesToReceive() as $key) {
if ($this->tokenService->hasTokenData($key)) {
$forwardTokens[$key] = $this->tokenService->getTokenData($key);
}
}
}
// The following block resets the data state of the Token services, with an
// exception for explicitly defined Tokens to be forwarded. This reset step
// is necessary, so that variables are only available within their scope.
$token_data = $this->tokenService->getTokenData();
$event->setPrestate('token_data', $token_data);
$this->tokenService->clearTokenData();
foreach ($forwardTokens as $key => $value) {
$this->tokenService->addTokenData($key, $value);
}
}
/**
* Subscriber method after initial execution.
*
* @param \Drupal\eca\Event\AfterInitialExecutionEvent $event
* The according event.
*/
public function onAfterInitialExecution(AfterInitialExecutionEvent $event): void {
// Determine explicitly defined tokens to be received back.
$receiveTokens = [];
$triggeredEvent = $event->getEvent();
if ($triggeredEvent instanceof TokenReceiverInterface) {
foreach ($triggeredEvent->getTokenNamesToReceive() as $key) {
if ($this->tokenService->hasTokenData($key)) {
$receiveTokens[$key] = $this->tokenService->getTokenData($key);
}
}
}
// Clear the Token data once more, and restore the state of Token data
// for the wrapping logic (if any). Doing so prevents locally scoped Tokens
// from unintentionally breaking out.
$this->tokenService->clearTokenData();
$token_data = $event->getPrestate('token_data') ?? [];
foreach ($token_data as $key => $data) {
$this->tokenService->addTokenData($key, $data);
}
foreach ($receiveTokens as $key => $value) {
$this->tokenService->addTokenData($key, $value);
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array {
$events[EcaEvents::BEFORE_INITIAL_EXECUTION][] = [
'onBeforeInitialExecution',
1000,
];
$events[EcaEvents::AFTER_INITIAL_EXECUTION][] = [
'onAfterInitialExecution',
-1000,
];
return $events;
}
}
