eca-1.0.x-dev/modules/config/src/Plugin/ECA/Event/ConfigEvent.php
modules/config/src/Plugin/ECA/Event/ConfigEvent.php
<?php
namespace Drupal\eca_config\Plugin\ECA\Event;
use Drupal\Core\Config\ConfigCollectionEvents;
use Drupal\Core\Config\ConfigCollectionInfo;
use Drupal\Core\Config\ConfigCrudEvent;
use Drupal\Core\Config\ConfigEvents;
use Drupal\Core\Config\ConfigImporterEvent;
use Drupal\Core\Config\ConfigRenameEvent;
use Drupal\Core\Config\Importer\MissingContentEvent;
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\DataType\DataTransferObject;
use Drupal\eca\Plugin\ECA\Event\EventBase;
use Symfony\Contracts\EventDispatcher\Event;
/**
* Plugin implementation of the ECA Events for config.
*/
#[EcaEvent(
id: 'config',
deriver: 'Drupal\eca_config\Plugin\ECA\Event\ConfigEventDeriver',
version_introduced: '1.0.0',
)]
class ConfigEvent extends EventBase {
/**
* {@inheritdoc}
*/
public static function definitions(): array {
return [
'delete' => [
'label' => 'Delete config',
'event_name' => ConfigEvents::DELETE,
'event_class' => ConfigCrudEvent::class,
'tags' => Tag::CONFIG | Tag::WRITE | Tag::PERSISTENT | Tag::AFTER,
],
'collection_info' => [
'label' => 'Collect information on all config collections',
'event_name' => ConfigCollectionEvents::COLLECTION_INFO,
'event_class' => ConfigCollectionInfo::class,
'tags' => Tag::READ | Tag::PERSISTENT | Tag::AFTER,
],
'import' => [
'label' => 'Import config',
'event_name' => ConfigEvents::IMPORT,
'event_class' => ConfigImporterEvent::class,
'tags' => Tag::CONFIG | Tag::WRITE | Tag::PERSISTENT | Tag::AFTER,
],
'import_missing_content' => [
'label' => 'Import config but content missing',
'event_name' => ConfigEvents::IMPORT_MISSING_CONTENT,
'event_class' => MissingContentEvent::class,
'tags' => Tag::CONFIG | Tag::WRITE | Tag::PERSISTENT | Tag::BEFORE,
],
'import_validate' => [
'label' => 'Import config validation',
'event_name' => ConfigEvents::IMPORT_VALIDATE,
'subscriber_priority' => 1024,
'event_class' => ConfigImporterEvent::class,
'tags' => Tag::CONFIG | Tag::WRITE | Tag::PERSISTENT | Tag::BEFORE,
],
'rename' => [
'label' => 'Rename config',
'event_name' => ConfigEvents::RENAME,
'event_class' => ConfigRenameEvent::class,
'tags' => Tag::CONFIG | Tag::WRITE | Tag::PERSISTENT | Tag::BEFORE,
],
'save' => [
'label' => 'Save config',
'event_name' => ConfigEvents::SAVE,
'event_class' => ConfigCrudEvent::class,
'tags' => Tag::CONFIG | Tag::WRITE | Tag::PERSISTENT | Tag::AFTER,
],
];
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration(): array {
$default = parent::defaultConfiguration();
if ($this->eventClass() === ConfigCrudEvent::class) {
$default['config_name'] = '';
$default['sync_mode'] = '';
if ($this->eventName() === ConfigEvents::SAVE) {
$default['write_mode'] = '';
}
}
return $default;
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
if ($this->eventClass() === ConfigCrudEvent::class) {
$form['config_name'] = [
'#type' => 'textfield',
'#title' => $this->t('Config name'),
'#description' => $this->t('Leave empty to apply to all events. To limit this event to just specific events, provide the machine name of the configuration, e.g. "system.site". This can also be limited to a range of configuration, e.g. with "node.type.", this applies to all configurations with a name starting with this pattern.'),
'#default_value' => $this->configuration['config_name'],
];
$form['sync_mode'] = [
'#type' => 'select',
'#title' => $this->t('Sync Mode'),
'#description' => $this->t('During config sync, the Drupal site is in sync mode.'),
'#default_value' => $this->configuration['sync_mode'],
'#options' => [
'' => $this->t('always'),
'yes' => $this->t('Only in sync mode'),
'no' => $this->t('Only when not sync mode'),
],
];
if ($this->eventName() === ConfigEvents::SAVE) {
$form['write_mode'] = [
'#type' => 'select',
'#title' => $this->t('Write Mode'),
'#default_value' => $this->configuration['write_mode'],
'#options' => [
'' => $this->t('always'),
'new' => $this->t('Only when config is new'),
'update' => $this->t('Only when config already exists'),
],
];
}
}
return parent::buildConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
if ($this->eventClass() === ConfigCrudEvent::class) {
$this->configuration['config_name'] = trim($form_state->getValue('config_name', ''));
$this->configuration['sync_mode'] = trim($form_state->getValue('sync_mode', ''));
if ($this->eventName() === ConfigEvents::SAVE) {
$this->configuration['write_mode'] = trim($form_state->getValue('write_mode', ''));
}
}
parent::submitConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function generateWildcard(string $eca_config_id, EcaEventObject $ecaEvent): string {
if ($this->eventClass() === ConfigCrudEvent::class) {
$parts = [];
$configuration = $ecaEvent->getConfiguration();
$parts[] = empty($configuration['config_name']) ? '*' : $configuration['config_name'];
$parts[] = empty($configuration['sync_mode']) ? '*' : $configuration['sync_mode'];
if ($this->eventName() === ConfigEvents::SAVE) {
$parts[] = empty($configuration['write_mode']) ? '*' : $configuration['write_mode'];
}
return implode('::', $parts);
}
return parent::generateWildcard($eca_config_id, $ecaEvent);
}
/**
* {@inheritdoc}
*/
public static function appliesForWildcard(Event $event, string $event_name, string $wildcard): bool {
if ($event::class === ConfigCrudEvent::class) {
$parts = explode('::', $wildcard);
if ($parts[0] !== '*' && !str_starts_with($event->getConfig()->getName(), $parts[0])) {
return FALSE;
}
$applies = TRUE;
if ($parts[1] !== '*') {
$isSyncing = \Drupal::isConfigSyncing();
$applies = ($parts[1] === 'yes' && $isSyncing) || ($parts[1] === 'no' && !$isSyncing);
}
if ($applies && $event_name === ConfigEvents::SAVE && $parts[2] !== '*') {
$isNew = empty($event->getConfig()->getOriginal());
$applies = ($parts[2] === 'new' && $isNew) || ($parts[2] === 'update' && !$isNew);
}
return $applies;
}
return parent::appliesForWildcard($event, $event_name, $wildcard);
}
/**
* {@inheritdoc}
*/
#[Token(
name: 'config',
description: 'The configuration with all current values.',
)]
#[Token(
name: 'config_original',
description: 'The configuration with all original values plus overrides.',
)]
#[Token(
name: 'config_name',
description: 'The name of the configuration.',
)]
public function getData(string $key): mixed {
$event = $this->event;
if ($event instanceof ConfigCrudEvent) {
$config = $event->getConfig();
switch ($key) {
case 'config':
return DataTransferObject::create($config->get());
case 'config_original':
return DataTransferObject::create($config->getOriginal());
case 'config_name':
return $config->getName();
}
}
return parent::getData($key);
}
}
