From 06c0c8eabb515875a840f3876145f2f533b9f374 Mon Sep 17 00:00:00 2001 From: "Andrew Crook (Somersoft)" <andrew.crook@somersoft.co.uk> Date: Tue, 6 May 2025 17:13:43 +0100 Subject: [PATCH] For Issue #3198011 Add the patch found at https://www.drupal.org/files/issues/2023-01-03/rules-field_item_list_management-3198011-7.patch Found that the Add functionality removed list items as it checked to see if the item was present. Updated the code to not remove them --- src/Plugin/RulesAction/FieldItemListAdd.php | 95 +++++++++++++++++++ .../RulesAction/FieldItemListRemove.php | 55 +++++++++++ 2 files changed, 150 insertions(+) create mode 100644 src/Plugin/RulesAction/FieldItemListAdd.php create mode 100644 src/Plugin/RulesAction/FieldItemListRemove.php diff --git a/src/Plugin/RulesAction/FieldItemListAdd.php b/src/Plugin/RulesAction/FieldItemListAdd.php new file mode 100644 index 00000000..05226703 --- /dev/null +++ b/src/Plugin/RulesAction/FieldItemListAdd.php @@ -0,0 +1,95 @@ +<?php + +namespace Drupal\rules\Plugin\RulesAction; + +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Field\FieldItemListInterface; +use Drupal\rules\Core\RulesActionBase; + +/** + * Provides an 'Add to field item list' action. + * + * @RulesAction( + * id = "rules_field_list_item_add", + * label = @Translation("Add to field item list"), + * category = @Translation("Data"), + * context_definitions = { + * "list" = @ContextDefinition("list", + * label = @Translation("List"), + * description = @Translation("The field item list, to which an item is to be added."), + * assignment_restriction = "selector" + * ), + * "item" = @ContextDefinition("any", + * label = @Translation("Item"), + * description = @Translation("Item to add.") + * ), + * "unique" = @ContextDefinition("boolean", + * label = @Translation("Enforce uniqueness"), + * description = @Translation("Only add the item to the list if it is not yet contained."), + * default_value = FALSE, + * required = FALSE + * ), + * "position" = @ContextDefinition("string", + * label = @Translation("Insert position"), + * description = @Translation("Position to insert the item."), + * default_value = "end", + * required = FALSE + * ), + * } + * ) + * + * @todo Add access callback information from Drupal 7? + */ +class FieldItemListAdd extends RulesActionBase { + + /** + * Add an item to a list. + * + * @param \Drupal\Core\Field\FieldItemListInterface $list + * A list to which an item is added. + * @param \Drupal\Core\Entity\EntityInterface $item + * An item being added to the list. + * @param bool $unique + * (optional) Whether or not we can add duplicate items. + * @param string $position + * (optional) Determines if item will be added at beginning or end. + * Allowed values: + * - "start": Add to beginning of the list. + * - "end": Add to end of the list. + */ + protected function doExecute(FieldItemListInterface $list, EntityInterface $item, $unique = FALSE, $position = 'end') { + if ($list->isEmpty()) { + $list->appendItem($item); + } + else { + if ($unique) { + // Optionally, only add the list item if it is not yet contained. + $id = $item->id(); + $filtered_list = clone $list; + $filtered_list->filter(function ($list_item) use ($id) { + return $list_item->get($list_item->mainPropertyName()) + ->getValue() == $id; + }); + if ($filtered_list->isEmpty()) { + if ($position === 'start') { + array_unshift($list, $item); + } + else { + $list->appendItem($item); + } + } + } + else { + if ($position === 'start') { + array_unshift($list, $item); + } + else { + $list->appendItem($item); + } + } + } + + $this->setContextValue('list', $list); + } + +} diff --git a/src/Plugin/RulesAction/FieldItemListRemove.php b/src/Plugin/RulesAction/FieldItemListRemove.php new file mode 100644 index 00000000..623c1024 --- /dev/null +++ b/src/Plugin/RulesAction/FieldItemListRemove.php @@ -0,0 +1,55 @@ +<?php + +namespace Drupal\rules\Plugin\RulesAction; + +use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\Entity\EntityInterface; +use Drupal\rules\Core\RulesActionBase; + +/** + * Provides a 'Remove item from list' action. + * + * @RulesAction( + * id = "rules_field_list_item_remove", + * label = @Translation("Remove item from field item list"), + * category = @Translation("Data"), + * context_definitions = { + * "list" = @ContextDefinition("list", + * label = @Translation("List"), + * description = @Translation("The field list from which an item is to be removed."), + * assignment_restriction = "selector" + * ), + * "item" = @ContextDefinition("any", + * label = @Translation("Item"), + * description = @Translation("Item to remove.") + * ), + * } + * ) + * + * @todo Add access callback information from Drupal 7. + */ +class FieldItemListRemove extends RulesActionBase { + + /** + * Removes an item from a list. + * + * @param \Drupal\Core\Field\FieldItemListInterface $list + * An array to remove an item from. + * @param \Drupal\Core\Entity\EntityInterface $item + * An item to remove from the array. + */ + protected function doExecute(FieldItemListInterface $list, EntityInterface $item) { + if (!$list->isEmpty()) { + $id = $item->id(); + foreach ($list->getIterator() as $key => $value) { + if ($value->get($value->mainPropertyName())->getValue() == $id) { + $list->removeItem($key); + break; + } + } + } + + $this->setContextValue('list', $list); + } + +} -- GitLab