From 4d1a47bb84a6b38c97b6834b6f6a77a4009d36ad Mon Sep 17 00:00:00 2001 From: Lainow Date: Thu, 21 Aug 2025 10:20:37 +0200 Subject: [PATCH 1/7] Add 'replace' or 'add' option in massive action for the multiple dropdown fields --- hook.php | 10 ++++++++++ inc/container.class.php | 42 +++++++++++++++++++++++++++++------------ 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/hook.php b/hook.php index f6fadaa9..6b47ddb8 100644 --- a/hook.php +++ b/hook.php @@ -206,6 +206,16 @@ function plugin_fields_MassiveActionsFieldsDisplay($options = []) $itemtypes = PluginFieldsContainer::getEntries('all'); if (in_array($options['itemtype'], $itemtypes)) { + if ($options['options']['is_multiple']) { + Dropdown::showFromArray( + 'multiple_dropdown_action', + [ + 'replace' => __('Replace'), + 'add' => __('Add'), + ] + ); + } + PluginFieldsField::showSingle($options['itemtype'], $options['options'], true); return true; diff --git a/inc/container.class.php b/inc/container.class.php index 8d5c3fe4..538f8f7a 100644 --- a/inc/container.class.php +++ b/inc/container.class.php @@ -29,6 +29,7 @@ */ use Glpi\Toolbox\Sanitizer; +use GlpiPlugin\Scim\Controller\Common; class PluginFieldsContainer extends CommonDBTM { @@ -1211,6 +1212,17 @@ public function updateFieldsValues($data, $itemtype, $massiveaction = false) return false; } + //Get object classname + $container_obj = new PluginFieldsContainer(); + $container_obj->getFromDB($data['plugin_fields_containers_id']); + + $items_id = $data['items_id']; + $classname = self::getClassname($itemtype, $container_obj->fields['name']); + + $obj = new $classname(); + + $exist = $obj->getFromDBByCrit(['items_id' => $items_id]); + // Convert "multiple" values into a JSON string $multiple_fields_iterator = $DB->request([ 'FROM' => PluginFieldsField::getTable(), @@ -1226,20 +1238,20 @@ public function updateFieldsValues($data, $itemtype, $massiveaction = false) $field_name = 'plugin_fields_' . $field_data['name'] . 'dropdowns_id'; } if (array_key_exists($field_name, $data)) { - $data[$field_name] = json_encode($data[$field_name]); + if ($data['multiple_dropdown_action'] === 'add') { + // Add new values to existing ones + $existing_values = json_decode($obj->fields[$field_name] ?? '[]', true); + $new_values = is_array($data[$field_name]) ? $data[$field_name] : [$data[$field_name]]; + $data[$field_name] = json_encode(array_unique(array_merge($existing_values, $new_values))); + } else { + $data[$field_name] = json_encode($data[$field_name]); + } } elseif (array_key_exists('_' . $field_name . '_defined', $data)) { $data[$field_name] = json_encode([]); } } - $container_obj = new PluginFieldsContainer(); - $container_obj->getFromDB($data['plugin_fields_containers_id']); - - $items_id = $data['items_id']; - $classname = self::getClassname($itemtype, $container_obj->fields['name']); - - $obj = new $classname(); - if ($obj->getFromDBByCrit(['items_id' => $items_id]) === false) { + if ($exist === false) { // add fields data $obj->add($data); } else { @@ -1723,12 +1735,13 @@ public static function preItem(CommonDBTM $item) return false; } - if (false !== ($data = self::populateData($c_id, $item))) { + if (false !== ($data = self::populateData($c_id, $item, $loc_c))) { if (self::validateValues($data, $item::getType(), isset($_REQUEST['massiveaction'])) === false) { $item->input = []; return false; } + $item->input['_plugin_fields_data'] = $data; return true; @@ -1745,7 +1758,7 @@ public static function preItem(CommonDBTM $item) * * @return array|false */ - private static function populateData($c_id, CommonDBTM $item) + private static function populateData($c_id, CommonDBTM $item, CommonDBTM $fielditem) { //find fields associated to found container $field_obj = new PluginFieldsField(); @@ -1819,6 +1832,7 @@ private static function populateData($c_id, CommonDBTM $item) // ex my_dom[] //in these conditions, the input is never sent by the browser if ($field['multiple']) { + $data['multiple_dropdown_action'] = $_POST['multiple_dropdown_action']; //handle multi dropdown field if ($field['type'] == 'dropdown') { $multiple_key = sprintf('plugin_fields_%sdropdowns_id', $field['name']); @@ -1834,7 +1848,7 @@ private static function populateData($c_id, CommonDBTM $item) $data[$multiple_key] = []; $has_fields = true; } elseif (isset($_REQUEST['massiveaction'])) { // called from massiveaction - if (isset($_POST[$multiple_key])) { + if (is_array($_POST[$multiple_key])) { $data[$multiple_key] = $_POST[$multiple_key]; $has_fields = true; } @@ -1960,6 +1974,10 @@ public static function getAddSearchOptions($itemtype, $containers_id = false) $opt[$i]['pfields_type'] = $data['type']; $opt[$i]['pfields_fields_id'] = $data['field_id']; + if ($data['type'] === 'dropdown') { + $opt[$i]['is_multiple'] = $data['multiple']; + } + if ($data['is_readonly']) { $opt[$i]['massiveaction'] = false; } From 3731dd45d7240a8ba157ced45a95c5d145b7e1f9 Mon Sep 17 00:00:00 2001 From: Lainow Date: Thu, 21 Aug 2025 10:28:23 +0200 Subject: [PATCH 2/7] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65a67347..0c18dd1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fix incompatibility of `multiple` dropdowns with `massiveaction` +### Added +- Add `replace` and `add` options in massive action for the multiple dropdowns fields + ## [1.21.22] - 2025-05-28 ### Fixed From 6c421f139e361da9cf90583808a7efd81f138208 Mon Sep 17 00:00:00 2001 From: Lainow Date: Thu, 21 Aug 2025 10:30:51 +0200 Subject: [PATCH 3/7] Remove useless part --- inc/container.class.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/inc/container.class.php b/inc/container.class.php index 538f8f7a..69cf01fe 100644 --- a/inc/container.class.php +++ b/inc/container.class.php @@ -29,7 +29,6 @@ */ use Glpi\Toolbox\Sanitizer; -use GlpiPlugin\Scim\Controller\Common; class PluginFieldsContainer extends CommonDBTM { @@ -1735,7 +1734,7 @@ public static function preItem(CommonDBTM $item) return false; } - if (false !== ($data = self::populateData($c_id, $item, $loc_c))) { + if (false !== ($data = self::populateData($c_id, $item))) { if (self::validateValues($data, $item::getType(), isset($_REQUEST['massiveaction'])) === false) { $item->input = []; @@ -1758,7 +1757,7 @@ public static function preItem(CommonDBTM $item) * * @return array|false */ - private static function populateData($c_id, CommonDBTM $item, CommonDBTM $fielditem) + private static function populateData($c_id, CommonDBTM $item) { //find fields associated to found container $field_obj = new PluginFieldsField(); @@ -1848,7 +1847,7 @@ private static function populateData($c_id, CommonDBTM $item, CommonDBTM $fieldi $data[$multiple_key] = []; $has_fields = true; } elseif (isset($_REQUEST['massiveaction'])) { // called from massiveaction - if (is_array($_POST[$multiple_key])) { + if (isset($_POST[$multiple_key])) { $data[$multiple_key] = $_POST[$multiple_key]; $has_fields = true; } From 50d0f30d1328ce5f54b4d675b625169910a854f2 Mon Sep 17 00:00:00 2001 From: Lainow Date: Thu, 21 Aug 2025 10:32:14 +0200 Subject: [PATCH 4/7] Check if obj exist before update --- inc/container.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/container.class.php b/inc/container.class.php index 69cf01fe..5301f671 100644 --- a/inc/container.class.php +++ b/inc/container.class.php @@ -1237,7 +1237,7 @@ public function updateFieldsValues($data, $itemtype, $massiveaction = false) $field_name = 'plugin_fields_' . $field_data['name'] . 'dropdowns_id'; } if (array_key_exists($field_name, $data)) { - if ($data['multiple_dropdown_action'] === 'add') { + if ($data['multiple_dropdown_action'] === 'add' && $exist) { // Add new values to existing ones $existing_values = json_decode($obj->fields[$field_name] ?? '[]', true); $new_values = is_array($data[$field_name]) ? $data[$field_name] : [$data[$field_name]]; From d23d4b450821e3390ae34ceacca66ad171df4114 Mon Sep 17 00:00:00 2001 From: Lainow Date: Thu, 21 Aug 2025 11:34:42 +0200 Subject: [PATCH 5/7] Fix phpcs --- hook.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hook.php b/hook.php index 6b47ddb8..2737142d 100644 --- a/hook.php +++ b/hook.php @@ -212,7 +212,7 @@ function plugin_fields_MassiveActionsFieldsDisplay($options = []) [ 'replace' => __('Replace'), 'add' => __('Add'), - ] + ], ); } From 7c2157ea7f9b0579da58b5e23e066c2a4237e4bb Mon Sep 17 00:00:00 2001 From: Samuel Launay <107540223+Lainow@users.noreply.github.com> Date: Thu, 21 Aug 2025 13:42:16 +0200 Subject: [PATCH 6/7] Update hook.php Co-authored-by: Romain B. <8530352+Rom1-B@users.noreply.github.com> --- hook.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hook.php b/hook.php index 2737142d..9f762dcb 100644 --- a/hook.php +++ b/hook.php @@ -210,8 +210,8 @@ function plugin_fields_MassiveActionsFieldsDisplay($options = []) Dropdown::showFromArray( 'multiple_dropdown_action', [ - 'replace' => __('Replace'), - 'add' => __('Add'), + 'assign' => __('Assign'), + 'append' => __('Add'), ], ); } From 6cbfbf84d7a109c42e5ff31be7d3ed8fa914c3ba Mon Sep 17 00:00:00 2001 From: Lainow Date: Thu, 21 Aug 2025 13:47:21 +0200 Subject: [PATCH 7/7] Replace add by append --- inc/container.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/container.class.php b/inc/container.class.php index 5301f671..132f5a2d 100644 --- a/inc/container.class.php +++ b/inc/container.class.php @@ -1237,7 +1237,7 @@ public function updateFieldsValues($data, $itemtype, $massiveaction = false) $field_name = 'plugin_fields_' . $field_data['name'] . 'dropdowns_id'; } if (array_key_exists($field_name, $data)) { - if ($data['multiple_dropdown_action'] === 'add' && $exist) { + if ($data['multiple_dropdown_action'] === 'append' && $exist) { // Add new values to existing ones $existing_values = json_decode($obj->fields[$field_name] ?? '[]', true); $new_values = is_array($data[$field_name]) ? $data[$field_name] : [$data[$field_name]];