eca-1.0.x-dev/modules/workflow/src/Plugin/ECA/Event/WorkflowEvent.php
modules/workflow/src/Plugin/ECA/Event/WorkflowEvent.php
<?php
namespace Drupal\eca_workflow\Plugin\ECA\Event;
use Drupal\Core\Form\FormStateInterface;
use Drupal\eca\Attribute\EcaEvent;
use Drupal\eca\Attribute\Token;
use Drupal\eca\Entity\Objects\EcaEvent as EcaEventObject;
use Drupal\eca\Event\Tag;
use Drupal\eca\Plugin\ECA\Event\EventBase;
use Drupal\eca\Service\ContentEntityTypes;
use Drupal\eca_workflow\Event\TransitionEventContent;
use Drupal\eca_workflow\WorkflowEvents;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Contracts\EventDispatcher\Event;
/**
* Plugin implementation of the ECA workflow events.
*/
#[EcaEvent(
id: 'workflow',
deriver: 'Drupal\eca_workflow\Plugin\ECA\Event\WorkflowEventDeriver',
version_introduced: '1.0.0',
)]
class WorkflowEvent extends EventBase {
/**
* The content entity types service.
*
* @var \Drupal\eca\Service\ContentEntityTypes
*/
protected ContentEntityTypes $entityTypes;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance->setEntityTypes($container->get('eca.service.content_entity_types'));
return $instance;
}
/**
* {@inheritdoc}
*/
public static function definitions(): array {
$definitions = [];
$definitions['transition'] = [
'label' => 'Workflow: state transition',
'event_name' => WorkflowEvents::TRANSITION,
'event_class' => TransitionEventContent::class,
'tags' => Tag::CONTENT | Tag::PERSISTENT | Tag::BEFORE,
];
return $definitions;
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration(): array {
if ($this->eventClass() === TransitionEventContent::class) {
$values = [
'type' => ContentEntityTypes::ALL,
'from_state' => '',
'to_state' => '',
];
}
else {
$values = [];
}
return $values + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
if ($this->eventClass() === TransitionEventContent::class) {
$form['type'] = [
'#type' => 'select',
'#title' => $this->t('Type (and bundle)'),
'#options' => $this->entityTypes->getTypesAndBundles(TRUE),
'#default_value' => $this->configuration['type'],
'#weight' => 10,
];
$form['from_state'] = [
'#type' => 'textfield',
'#title' => $this->t('From state'),
'#description' => $this->t('Optionally restrict to the machine name of the previous state.'),
'#default_value' => $this->configuration['from_state'],
'#weight' => 20,
];
$form['to_state'] = [
'#type' => 'textfield',
'#title' => $this->t('To state'),
'#description' => $this->t('Optionally restrict to the machine name of the new state.'),
'#default_value' => $this->configuration['to_state'],
'#weight' => 30,
];
}
return parent::buildConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
parent::submitConfigurationForm($form, $form_state);
if ($this->eventClass() === TransitionEventContent::class) {
$this->configuration['type'] = $form_state->getValue('type');
$this->configuration['from_state'] = trim($form_state->getValue('from_state', ''));
$this->configuration['to_state'] = trim($form_state->getValue('to_state', ''));
}
}
/**
* {@inheritdoc}
*/
public function generateWildcard(string $eca_config_id, EcaEventObject $ecaEvent): string {
switch ($this->getDerivativeId()) {
case 'transition':
$config = $ecaEvent->getConfiguration();
$type = $config['type'] ?? ContentEntityTypes::ALL;
if ($type === ContentEntityTypes::ALL) {
$wildcard = '*::*';
}
else {
[$entityType, $bundle] = array_merge(explode(' ', $type), [ContentEntityTypes::ALL]);
if ($bundle === ContentEntityTypes::ALL) {
$wildcard = $entityType . '::*';
}
else {
$wildcard = $entityType . '::' . $bundle;
}
}
$wildcard .= in_array(($config['from_state'] ?? ''), ['', '*']) ? '::*' : '::' . $config['from_state'];
$wildcard .= in_array(($config['to_state'] ?? ''), ['', '*']) ? '::*' : '::' . $config['to_state'];
return $wildcard;
default:
return parent::generateWildcard($eca_config_id, $ecaEvent);
}
}
/**
* {@inheritdoc}
*/
public static function appliesForWildcard(Event $event, string $event_name, string $wildcard): bool {
/** @var \Drupal\eca_workflow\Event\TransitionEventContent $event */
[$w_entity_type_id, $w_entity_bundle, $w_from_state, $w_to_state] = explode('::', $wildcard);
$entity = $event->getEntity();
if (($w_entity_type_id !== '*') && ($w_entity_type_id !== $entity->getEntityTypeId())) {
return FALSE;
}
if (($w_entity_bundle !== '*') && ($w_entity_bundle !== $entity->bundle())) {
return FALSE;
}
if (($w_from_state !== '*') && ($w_from_state !== $event->getFromState())) {
return FALSE;
}
if (($w_to_state !== '*') && ($w_to_state !== $event->getToState())) {
return FALSE;
}
return TRUE;
}
/**
* Set the content entity types service.
*
* @param \Drupal\eca\Service\ContentEntityTypes $entity_types
* The content entity types service.
*/
public function setEntityTypes(ContentEntityTypes $entity_types): void {
$this->entityTypes = $entity_types;
}
/**
* {@inheritdoc}
*/
#[Token(name: 'from_state', description: 'The source workflow state of the entity.', classes: [TransitionEventContent::class])]
#[Token(name: 'to_state', description: 'The destination workflow state of the entity.', classes: [TransitionEventContent::class])]
public function getData(string $key): mixed {
$event = $this->event;
if ($event instanceof TransitionEventContent) {
if ($key === 'from_state' && $fromState = $event->getFromState()) {
return $fromState;
}
if ($key === 'to_state') {
return $event->getToState();
}
}
return parent::getData($key);
}
}
