From b2404da31c235bd9d8e5bb8aebefcc9c68e14411 Mon Sep 17 00:00:00 2001 From: mxh <16778-hauptm@users.noreply.drupalcode.org> Date: Wed, 19 Mar 2025 09:26:00 +0000 Subject: [PATCH 01/10] Issue #3513674 by mxh, jurgenhaas: ECA Extra field does not work with Field Group in forms --- modules/render/eca_render.module | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/render/eca_render.module b/modules/render/eca_render.module index 418e3dc92..9a3b6165d 100644 --- a/modules/render/eca_render.module +++ b/modules/render/eca_render.module @@ -378,6 +378,10 @@ function _eca_render_trigger_extra_field(array &$build, EntityInterface $entity, $render_build = &$event->getRenderArray(); } $build[$name] = $render_build; + if (!empty($build[$name]) && ($display_type === 'form') && !isset($build[$name]['#type'])) { + // Wrap as container so that the extra field can be grouped. + $build[$name]['#type'] = 'container'; + } if (!isset($build['#weight']) && isset($options['weight'])) { $build['#weight'] = $options['weight']; } -- GitLab From 674336ef48cc6ea569b34ed9441d0955eee084ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Haas?= <21467-jurgenhaas@users.noreply.drupalcode.org> Date: Wed, 19 Mar 2025 09:40:46 +0000 Subject: [PATCH 02/10] Issue #3513657 by jurgenhaas, mxh: ECA Views field: Additionally pass along arguments passed to the view --- modules/render/src/Plugin/ECA/Event/RenderEvent.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/render/src/Plugin/ECA/Event/RenderEvent.php b/modules/render/src/Plugin/ECA/Event/RenderEvent.php index 060fb5764..d5214c11c 100644 --- a/modules/render/src/Plugin/ECA/Event/RenderEvent.php +++ b/modules/render/src/Plugin/ECA/Event/RenderEvent.php @@ -575,6 +575,9 @@ class RenderEvent extends EventBase implements PluginUsageInterface { new Token(name: 'view_id', description: 'The view ID.', classes: [ EcaRenderViewsFieldEvent::class, ]), + new Token(name: 'view_args:?', description: 'The list of arguments given to the view.', classes: [ + EcaRenderViewsFieldEvent::class, + ]), ] )] protected function buildEventData(): array { @@ -613,6 +616,7 @@ class RenderEvent extends EventBase implements PluginUsageInterface { $data += [ 'entity' => $event->getEntity(), 'relationships' => $event->getRelationshipEntities(), + 'view_args' => $event->getFieldPlugin()->view->args, 'view_id' => $event->getFieldPlugin()->view->id(), 'view_display' => $event->getFieldPlugin()->view->current_display, ]; -- GitLab From 7f0199cae20070cd028415aadffb067a416cf053 Mon Sep 17 00:00:00 2001 From: Daniel <11906-dsasser@users.noreply.drupalcode.org> Date: Mon, 31 Mar 2025 16:04:17 +0000 Subject: [PATCH 03/10] Issue #3515195 by coderdan, jurgenhaas: Add migration_id token to migrate events --- .../src/Plugin/ECA/Event/MigrateEvent.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/modules/migrate/src/Plugin/ECA/Event/MigrateEvent.php b/modules/migrate/src/Plugin/ECA/Event/MigrateEvent.php index b3636d4ab..debb719ad 100644 --- a/modules/migrate/src/Plugin/ECA/Event/MigrateEvent.php +++ b/modules/migrate/src/Plugin/ECA/Event/MigrateEvent.php @@ -102,6 +102,17 @@ class MigrateEvent extends EventBase { MigrateIdMapMessageEvent::class, ] )] + #[Token( + name: 'migration_id', + description: 'The migration plugin id being run.', + classes: [ + MigrateImportEvent::class, + MigratePreRowSaveEvent::class, + MigrateRollbackEvent::class, + MigrateRowDeleteEvent::class, + MigrateIdMapMessageEvent::class, + ] + )] #[Token( name: 'map', description: 'The map plugin that caused the event to fire.', @@ -176,6 +187,18 @@ class MigrateEvent extends EventBase { } break; + case 'migration_id': + if ($event instanceof MigrateImportEvent + || $event instanceof MigratePreRowSaveEvent + || $event instanceof MigrateRollbackEvent + || $event instanceof MigrateRowDeleteEvent + || $event instanceof MigrateIdMapMessageEvent + ) { + $migration = $event->getMigration(); + return $migration->id(); + } + break; + case 'map': if ($event instanceof MigrateMapSaveEvent || $event instanceof MigrateMapDeleteEvent -- GitLab From 718d02727e4c6b7b67e7a33449318addb46cc05c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Haas?= <21467-jurgenhaas@users.noreply.drupalcode.org> Date: Wed, 2 Apr 2025 15:41:41 +0000 Subject: [PATCH 04/10] Issue #3516245 by jurgenhaas, lammensj: Event data not available --- .../EcaExecutionGeneralSubscriber.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/EventSubscriber/EcaExecutionGeneralSubscriber.php b/src/EventSubscriber/EcaExecutionGeneralSubscriber.php index 2898446d0..0d4534e6c 100644 --- a/src/EventSubscriber/EcaExecutionGeneralSubscriber.php +++ b/src/EventSubscriber/EcaExecutionGeneralSubscriber.php @@ -12,6 +12,7 @@ use Drupal\eca\Event\AfterInitialExecutionEvent; use Drupal\eca\Event\BeforeInitialExecutionEvent; use Drupal\eca\Event\EntityEventInterface; use Drupal\eca\Event\RenderEventInterface; +use Drupal\eca\Plugin\ECA\Event\EventInterface; /** * General ECA event subscriber for EcaEvents::BEFORE_INITIAL_EXECUTION events. @@ -40,6 +41,15 @@ class EcaExecutionGeneralSubscriber extends EcaExecutionSubscriberBase { classes: [EntityEventInterface::class], )] public function onBeforeInitialExecution(BeforeInitialExecutionEvent $before_event): void { + // Find previous token provider of type EventInterface and remove it from + // the list and remember it to be restored afterwards. + foreach ($this->tokenService->getDataProviders() as $dataProvider) { + if ($dataProvider instanceof EventInterface) { + $this->tokenService->removeTokenDataProvider($dataProvider); + $before_event->setPrestate('previous_data_provider', $dataProvider); + } + } + $plugin = $before_event->getEcaEvent()->getPlugin(); $this->tokenService->addTokenDataProvider($plugin); @@ -86,6 +96,10 @@ class EcaExecutionGeneralSubscriber extends EcaExecutionSubscriberBase { public function onAfterInitialExecution(AfterInitialExecutionEvent $after_event): void { $plugin = $after_event->getEcaEvent()->getPlugin(); $this->tokenService->removeTokenDataProvider($plugin); + // Restore the previous EventInterface token data provider if available. + if ($dataProvider = $after_event->getPrestate('previous_data_provider')) { + $this->tokenService->addTokenDataProvider($dataProvider); + } } /** -- GitLab From 1ac9f25ee91867fbdf46a5d814cd9c81b8394413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Haas?= <21467-jurgenhaas@users.noreply.drupalcode.org> Date: Mon, 31 Mar 2025 16:25:35 +0000 Subject: [PATCH 05/10] Issue #3515498 by jurgenhaas, ikam: Form Field: Set as Disable - usage of the "Set as Disabled" yes/no --- .../src/Plugin/Action/FormFieldDisable.php | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/modules/form/src/Plugin/Action/FormFieldDisable.php b/modules/form/src/Plugin/Action/FormFieldDisable.php index 0dba943d5..0fd14b331 100644 --- a/modules/form/src/Plugin/Action/FormFieldDisable.php +++ b/modules/form/src/Plugin/Action/FormFieldDisable.php @@ -29,29 +29,24 @@ class FormFieldDisable extends FormFlagFieldActionBase { */ protected function flagAllChildren(&$element, bool $flag): void { parent::flagAllChildren($element, $flag); - $this->setFormFieldAttributes($element); - } - - /** - * Set form field attributes on the given element. - * - * Sometimes it is too late that the form builder sets proper HTML attributes. - * Therefore, this helper method assures they are set. - * - * @param array &$element - * The form element. - * - * @see \Drupal\Core\Form\FormBuilder::handleInputElement - */ - protected function setFormFieldAttributes(array &$element): void { if (empty($element['#input'])) { return; } if (!empty($element['#allow_focus'])) { - $element['#attributes']['readonly'] = 'readonly'; + if ($flag) { + $element['#attributes']['readonly'] = 'readonly'; + } + else { + unset($element['#attributes']['readonly']); + } } else { - $element['#attributes']['disabled'] = 'disabled'; + if ($flag) { + $element['#attributes']['disabled'] = 'disabled'; + } + else { + unset($element['#attributes']['disabled']); + } } } -- GitLab From 47a80fd00e61cf2cb77890976a74f97e6814b942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Haas?= <21467-jurgenhaas@users.noreply.drupalcode.org> Date: Wed, 9 Apr 2025 09:23:50 +0000 Subject: [PATCH 06/10] Update some routes --- modules/ui/eca_ui.routing.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/ui/eca_ui.routing.yml b/modules/ui/eca_ui.routing.yml index d21d9e27f..0f9e0c4b0 100644 --- a/modules/ui/eca_ui.routing.yml +++ b/modules/ui/eca_ui.routing.yml @@ -17,6 +17,7 @@ eca.save: _controller: '\Drupal\eca_ui\Controller\EcaController::save' requirements: _permission: 'administer eca' + _csrf_request_header_token: 'TRUE' entity.eca.delete_form: path: '/admin/config/workflow/eca/{eca}/delete' defaults: @@ -30,24 +31,28 @@ entity.eca.enable: _controller: '\Drupal\eca_ui\Controller\EcaController::enable' requirements: _permission: 'administer eca' + _csrf_token: 'TRUE' entity.eca.disable: path: '/admin/config/workflow/eca/{eca}/disable' defaults: _controller: '\Drupal\eca_ui\Controller\EcaController::disable' requirements: _permission: 'administer eca' + _csrf_token: 'TRUE' entity.eca.clone: path: '/admin/config/workflow/eca/{eca}/clone' defaults: _controller: '\Drupal\eca_ui\Controller\EcaController::clone' requirements: _permission: 'administer eca' + _csrf_token: 'TRUE' entity.eca.export: path: '/admin/config/workflow/eca/{eca}/export' defaults: _controller: '\Drupal\eca_ui\Controller\EcaController::export' requirements: _permission: 'administer eca' + _csrf_token: 'TRUE' entity.eca.export_recipe: path: '/admin/config/workflow/eca/{eca}/recipe' defaults: -- GitLab From 2046e305ce2ce22527547c4641045ba02ca50c72 Mon Sep 17 00:00:00 2001 From: starlight-sparkle <66705-PixlRainbow@users.noreply.drupalcode.org> Date: Wed, 9 Apr 2025 04:13:14 +0000 Subject: [PATCH 07/10] Issue #3518078: eca_render: Action "Render: Unserialize" does not work for "_eca_token" format --- modules/render/src/Plugin/Action/Unserialize.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/render/src/Plugin/Action/Unserialize.php b/modules/render/src/Plugin/Action/Unserialize.php index 69d874357..9f43c8eec 100644 --- a/modules/render/src/Plugin/Action/Unserialize.php +++ b/modules/render/src/Plugin/Action/Unserialize.php @@ -70,6 +70,10 @@ class Unserialize extends Serialize { $serialized = (string) $this->tokenService->replace($value); $format = $this->configuration['format']; + if ($format === '_eca_token') { + $format = $this->getTokenValue('format', 'json'); + } + $type = $this->configuration['type']; if ($type === '_eca_token') { $type = $this->getTokenValue('type', 'array'); -- GitLab From 8ed78fc6bcfd820eda9597362f2ffb60488b16b0 Mon Sep 17 00:00:00 2001 From: Martin Anderson-Clutz <46883-mandclu@users.noreply.drupalcode.org> Date: Thu, 10 Apr 2025 13:49:17 +0000 Subject: [PATCH 08/10] Issue #3517979 by mandclu, jurgenhaas: Allow ECA to manipulate module-provided menu links --- modules/menu/eca_menu.info.yml | 7 ++ .../menu/src/Plugin/Action/EnableMenuItem.php | 91 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 modules/menu/eca_menu.info.yml create mode 100644 modules/menu/src/Plugin/Action/EnableMenuItem.php diff --git a/modules/menu/eca_menu.info.yml b/modules/menu/eca_menu.info.yml new file mode 100644 index 000000000..7016156c1 --- /dev/null +++ b/modules/menu/eca_menu.info.yml @@ -0,0 +1,7 @@ +name: 'ECA Menu' +type: module +description: 'Additional options for working with menu links.' +core_version_requirement: ^10.3 || ^11 +package: ECA +dependencies: + - eca:eca diff --git a/modules/menu/src/Plugin/Action/EnableMenuItem.php b/modules/menu/src/Plugin/Action/EnableMenuItem.php new file mode 100644 index 000000000..9af138063 --- /dev/null +++ b/modules/menu/src/Plugin/Action/EnableMenuItem.php @@ -0,0 +1,91 @@ +<?php + +namespace Drupal\eca_menu\Plugin\Action; + +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Menu\MenuLinkManagerInterface; +use Drupal\eca\Plugin\Action\ConfigurableActionBase; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Enables a specified menu item. + * + * @Action( + * id = "eca_menu_enable_menu_item", + * label = @Translation("Menu Item: Enable or Disable"), + * description = @Translation("Enable or disable a menu link (can be module provided)."), + * eca_version_introduced = "2.1.x", + * type = "entity" + * ) + */ +class EnableMenuItem extends ConfigurableActionBase { + + /** + * The MenuLinkManager. + * + * @var \Drupal\Core\Menu\MenuLinkManagerInterface + */ + protected MenuLinkManagerInterface $menuLinkManager; + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static { + $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition); + $instance->menuLinkManager = $container->get('plugin.manager.menu.link'); + return $instance; + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration(): array { + return [ + 'menu_item' => '', + 'enabled' => TRUE, + ] + parent::defaultConfiguration(); + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(array $form, FormStateInterface $form_state): array { + $form['menu_item'] = [ + '#type' => 'textfield', + '#title' => $this->t('ID of menu item'), + '#default_value' => $this->configuration['menu_item'], + '#description' => $this->t('The id of a menu item provided by code (e.g. not a menu_link_content created in the menu UI).'), + '#eca_token_replacement' => TRUE, + '#required' => TRUE, + ]; + $form['enabled'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Enable'), + '#description' => $this->t('Select to have the menu item enabled, or leave unchecked to have it disabled.'), + '#default_value' => $this->configuration['enabled'], + ]; + + return parent::buildConfigurationForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void { + $this->configuration['menu_item'] = $form_state->getValue('menu_item'); + $this->configuration['enabled'] = !empty($form_state->getValue('enabled')); + parent::submitConfigurationForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function execute(mixed $entity = NULL): void { + $menuItemId = (string) $this->tokenService->replace($this->configuration['menu_item']); + $definition = $this->menuLinkManager->getDefinition($menuItemId); + // Set the 'enabled' value based on the configuration, and save. + $definition['enabled'] = ($this->configuration['enabled']) ? 1 : 0; + $this->menuLinkManager->updateDefinition($menuItemId, $definition); + } + +} -- GitLab From 7d2f97596a37fac9c11474f46acdedd88288a533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Haas?= <21467-jurgenhaas@users.noreply.drupalcode.org> Date: Fri, 18 Apr 2025 09:45:07 +0000 Subject: [PATCH 09/10] Issue #3519886 by jurgenhaas: ECA Form: set field value in ajax calls --- modules/form/src/Plugin/Action/FormFieldDefaultValue.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/form/src/Plugin/Action/FormFieldDefaultValue.php b/modules/form/src/Plugin/Action/FormFieldDefaultValue.php index cb25dddea..1f2ea7ab0 100644 --- a/modules/form/src/Plugin/Action/FormFieldDefaultValue.php +++ b/modules/form/src/Plugin/Action/FormFieldDefaultValue.php @@ -29,9 +29,12 @@ class FormFieldDefaultValue extends FormFieldActionBase { */ protected function doExecute(): void { if ($element = &$this->getTargetElement()) { + $form_state = $this->getCurrentFormState(); $element = &$this->jumpToFirstFieldChild($element); $value = $this->configuration['value']; - $default_value_key = '#default_value'; + $default_value_key = $form_state->isRebuilding() ? + '#value' : + '#default_value'; switch ($element['#type'] ?? NULL) { -- GitLab From a08b9f735ed01bc0fd6c295ea09ed8f777194135 Mon Sep 17 00:00:00 2001 From: jurgenhaas <juergen.haas@lakedrops.com> Date: Sat, 26 Apr 2025 11:34:58 +0200 Subject: [PATCH 10/10] Issue #3519886 by jurgenhaas, mxh: ECA Form: provide a way to set the form field value when submitted via Ajax --- modules/form/src/Plugin/Action/FormFieldDefaultValue.php | 5 +---- modules/form/src/Plugin/Action/FormFieldSetValue.php | 4 ++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/form/src/Plugin/Action/FormFieldDefaultValue.php b/modules/form/src/Plugin/Action/FormFieldDefaultValue.php index 1f2ea7ab0..cb25dddea 100644 --- a/modules/form/src/Plugin/Action/FormFieldDefaultValue.php +++ b/modules/form/src/Plugin/Action/FormFieldDefaultValue.php @@ -29,12 +29,9 @@ class FormFieldDefaultValue extends FormFieldActionBase { */ protected function doExecute(): void { if ($element = &$this->getTargetElement()) { - $form_state = $this->getCurrentFormState(); $element = &$this->jumpToFirstFieldChild($element); $value = $this->configuration['value']; - $default_value_key = $form_state->isRebuilding() ? - '#value' : - '#default_value'; + $default_value_key = '#default_value'; switch ($element['#type'] ?? NULL) { diff --git a/modules/form/src/Plugin/Action/FormFieldSetValue.php b/modules/form/src/Plugin/Action/FormFieldSetValue.php index 4b0737965..187620de0 100644 --- a/modules/form/src/Plugin/Action/FormFieldSetValue.php +++ b/modules/form/src/Plugin/Action/FormFieldSetValue.php @@ -114,6 +114,10 @@ class FormFieldSetValue extends ConfigurableActionBase { } $this->filterFormFieldValue($value); + if ($element = &$this->getTargetElement()) { + $element['#value'] = $value; + } + $original_field_name = $this->configuration['field_name']; $this->configuration['field_name'] = (string) $this->tokenService->replace($original_field_name); -- GitLab