From a00d5128170de5ebbaa05a1d088903545221b203 Mon Sep 17 00:00:00 2001 From: stonebuzz Date: Wed, 31 Jan 2024 09:59:10 +0100 Subject: [PATCH] fix(SearchOption): Fix search on multiple dropdown --- hook.php | 42 +++++++++++++++++++++++++ inc/abstractcontainerinstance.class.php | 37 ++++++++++++++++++++++ inc/container.class.php | 2 ++ 3 files changed, 81 insertions(+) diff --git a/hook.php b/hook.php index 62ffa5d9..cbf44bcc 100644 --- a/hook.php +++ b/hook.php @@ -335,3 +335,45 @@ function plugin_datainjection_populate_fields() } } } + +function plugin_fields_addWhere($link, $nott, $itemtype, $ID, $val, $searchtype) +{ + /** @var \DBmysql $DB */ + global $DB; + + $searchopt = &Search::getOptions($itemtype); + $table = $searchopt[$ID]["table"]; + $field = $searchopt[$ID]["field"]; + + $field_field = new PluginFieldsField(); + + // if 'multiple' field with name is found -> 'Dropdown-XXXX' case + // update WHERE clause with LIKE statement + if ( + $field_field->getFromDBByCrit( + [ + 'name' => $field, + 'multiple' => true + ] + ) + ) { + return $link . $DB->quoteName("$table" . "_" . "$field") . "." . $DB->quoteName($field) . "LIKE " . $DB->quoteValue("%\"$val\"%") ; + } else { + // if 'multiple' field with cleaned name is found -> 'dropdown' case + // update WHERE clause with LIKE statement + $cleanfield = str_replace("plugin_fields_", "", $field); + $cleanfield = str_replace("dropdowns_id", "", $cleanfield); + if ( + $field_field->getFromDBByCrit( + [ + 'name' => $cleanfield, + 'multiple' => true + ] + ) + ) { + return $link . $DB->quoteName("$table" . "_" . "$cleanfield") . "." . $DB->quoteName($field) . "LIKE " . $DB->quoteValue("%\"$val\"%") ; + } else { + return false; + } + } +} diff --git a/inc/abstractcontainerinstance.class.php b/inc/abstractcontainerinstance.class.php index 8ad555ec..0b595d12 100644 --- a/inc/abstractcontainerinstance.class.php +++ b/inc/abstractcontainerinstance.class.php @@ -30,6 +30,43 @@ abstract class PluginFieldsAbstractContainerInstance extends CommonDBTM { + public static function getSpecificValueToSelect($field, $name = '', $values = '', array $options = []) + { + + if (!is_array($values)) { + $values = [$field => $values]; + } + + $field_id = $options['searchopt']['pfields_fields_id'] ?? null; + + $field_specs = new PluginFieldsField(); + if ($field_id !== null && $field_specs->getFromDB($field_id)) { + $dropdown_matches = []; + if ( + preg_match('/^dropdown-(?.+)$/i', $field_specs->fields['type'], $dropdown_matches) === 1 + && $field_specs->fields['multiple'] + ) { + $itemtype = $dropdown_matches['class']; + if (!is_a($itemtype, CommonDBTM::class, true)) { + return ''; // Itemtype not exists (maybe a deactivated plugin) + } + $display_with = []; + if ($itemtype == User::class) { + $display_with = ['realname', 'firstname']; + } + return Dropdown::show($itemtype, ['displaywith' => $display_with, 'name' => $name, 'display' => false]); + } else if ( + $field_specs->fields['type'] === 'dropdown' + && $field_specs->fields['multiple'] + ) { + $itemtype = PluginFieldsDropdown::getClassname($field_specs->fields['name']); + return Dropdown::show($itemtype, ['name' => $name, 'display' => false]); + } + } + return parent::getSpecificValueToSelect($field, $name, $values, $options); + } + + public static function getSpecificValueToDisplay($field, $values, array $options = []) { if (!is_array($values)) { diff --git a/inc/container.class.php b/inc/container.class.php index 00d67cf7..a6444efb 100644 --- a/inc/container.class.php +++ b/inc/container.class.php @@ -1910,6 +1910,7 @@ public static function getAddSearchOptions($itemtype, $containers_id = false) if ($data['multiple']) { $opt[$i]['table'] = $tablename; $opt[$i]['field'] = $field_name; + $opt[$i]['searchtype'] = ['equals', 'notequals']; $opt[$i]['datatype'] = 'specific'; } else { $opt[$i]['table'] = 'glpi_plugin_fields_' . $data['field_name'] . 'dropdowns'; @@ -1929,6 +1930,7 @@ public static function getAddSearchOptions($itemtype, $containers_id = false) ) { if ($data['multiple']) { $opt[$i]['datatype'] = 'specific'; + $opt[$i]['searchtype'] = ['equals', 'notequals']; } else { $opt[$i]['table'] = CommonDBTM::getTable($dropdown_matches['class']); $opt[$i]['field'] = 'name';