From c8c18c55a62817b65427bb2063705315a4821d01 Mon Sep 17 00:00:00 2001 From: Stanislas KITA Date: Wed, 27 Apr 2022 16:29:04 +0200 Subject: [PATCH 01/21] feat(block): add options to hide block --- ajax/display_container.php | 55 ++++ front/displaycontainer.form.php | 50 ++++ hook.php | 6 +- inc/container.class.php | 13 +- inc/displaycontainer.class.php | 376 ++++++++++++++++++++++++ setup.php | 2 +- templates/forms/display_block.html.twig | 207 +++++++++++++ 7 files changed, 705 insertions(+), 4 deletions(-) create mode 100644 ajax/display_container.php create mode 100644 front/displaycontainer.form.php create mode 100644 inc/displaycontainer.class.php create mode 100644 templates/forms/display_block.html.twig diff --git a/ajax/display_container.php b/ajax/display_container.php new file mode 100644 index 00000000..fbeeafce --- /dev/null +++ b/ajax/display_container.php @@ -0,0 +1,55 @@ +. + * ------------------------------------------------------------------------- + * @copyright Copyright (C) 2013-2022 by Fields plugin team. + * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html + * @link https://github.com/pluginsGLPI/fields + * ------------------------------------------------------------------------- + */ + +include ("../../../inc/includes.php"); + +if (isset($_GET['action'])) { + if ($_GET['action'] === 'get_edit_form') { + $container = new PluginFieldsContainer(); + $container->getFromDB($_GET['plugin_fields_containers_id']); + echo PluginFieldsDisplayContainer::showForTabContainer($container, $_GET); + } else if ($_GET['action'] === 'get_add_form') { + $container = new PluginFieldsContainer(); + $container->getFromDB($_GET['plugin_fields_containers_id']); + echo PluginFieldsDisplayContainer::showForTabContainer($container, $_GET); + } + +} else if (isset($_POST['action'])) { + if($_POST['action'] === 'get_itemtype_so') { + if(isset($_POST['itemtype']) && class_exists($_POST['itemtype'])) { + echo PluginFieldsDisplayContainer::showItemtypeFieldForm($_POST['itemtype']) ; + } else { + echo ""; + } + } +} else { + http_response_code(400); + die(); +} diff --git a/front/displaycontainer.form.php b/front/displaycontainer.form.php new file mode 100644 index 00000000..c29f7870 --- /dev/null +++ b/front/displaycontainer.form.php @@ -0,0 +1,50 @@ + +. + * ------------------------------------------------------------------------- + * @copyright Copyright (C) 2013-2022 by Fields plugin team. + * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html + * @link https://github.com/pluginsGLPI/fields + * ------------------------------------------------------------------------- + */ + +include ("../../../inc/includes.php"); + +$status_override = new PluginFieldsDisplayContainer(); +if (isset($_POST["add"])) { + $status_override->check(-1, CREATE, $_POST); + $newID = $status_override->add($_POST); + Html::back(); +} else if (isset($_POST["update"])) { + $status_override->check(-1, UPDATE, $_POST); + $newID = $status_override->update($_POST); + Html::back(); +} else if (isset($_POST["delete"])) { + $status_override->check($_POST['id'], PURGE); + $status_override->delete([ + 'id' => $_POST['id'] + ]); + Html::back(); +} +Html::back(); diff --git a/hook.php b/hook.php index 7146aeb4..4c5fd4a8 100644 --- a/hook.php +++ b/hook.php @@ -58,7 +58,8 @@ function plugin_fields_install() { 'PluginFieldsValue', 'PluginFieldsProfile', 'PluginFieldsMigration', - 'PluginFieldsStatusOverride' + 'PluginFieldsStatusOverride', + 'PluginFieldsDisplayContainer', ]; $migration = new Migration($version); @@ -131,7 +132,8 @@ function plugin_fields_uninstall() { 'PluginFieldsField', 'PluginFieldsValue', 'PluginFieldsProfile', - 'PluginFieldsMigration' + 'PluginFieldsMigration', + 'PluginFieldsDisplayContainer' ]; foreach ($classesToUninstall as $class) { diff --git a/inc/container.class.php b/inc/container.class.php index 95424b60..f544dcd4 100644 --- a/inc/container.class.php +++ b/inc/container.class.php @@ -403,6 +403,7 @@ function defineTabs($options = []) { $this->addStandardTab('PluginFieldsField', $ong, $options); $this->addStandardTab('PluginFieldsStatusOverride', $ong, $options); $this->addStandardTab('PluginFieldsProfile', $ong, $options); + $this->addStandardTab('PluginFieldsDisplayContainer', $ong, $options); $this->addStandardTab('PluginFieldsLabelTranslation', $ong, $options); return $ong; @@ -564,6 +565,12 @@ function pre_deleteItem() { 'plugin_fields_containers_id' => $this->fields['id'] ]); + //delete display condition + $field_obj = new PluginFieldsDisplayContainer(); + $field_obj->deleteByCriteria([ + 'plugin_fields_containers_id' => $this->fields['id'] + ]); + //delete profiles $profile_obj = new PluginFieldsProfile; $profile_obj->deleteByCriteria([ @@ -1033,7 +1040,11 @@ function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { } if (!$item->isEntityAssign() || in_array($item->fields['entities_id'], $entities)) { - $tabs_entries[$tab_name] = $tab_label; + + $display_condition = new PluginFieldsDisplayContainer(); + if($display_condition->computeDisplayContainer($item, $data['id'])) { + $tabs_entries[$tab_name] = $tab_label; + } } } } diff --git a/inc/displaycontainer.class.php b/inc/displaycontainer.class.php new file mode 100644 index 00000000..5a3f254d --- /dev/null +++ b/inc/displaycontainer.class.php @@ -0,0 +1,376 @@ +. + * ------------------------------------------------------------------------- + * @copyright Copyright (C) 2013-2022 by Fields plugin team. + * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html + * @link https://github.com/pluginsGLPI/fields + * ------------------------------------------------------------------------- + */ + +class PluginFieldsDisplayContainer extends CommonDBTM { + static $rightname = 'config'; + + const SHOW_CONDITION_EQ = 1; + const SHOW_CONDITION_NE = 2; + const SHOW_CONDITION_LT = 3; + const SHOW_CONDITION_GT = 4; + const SHOW_CONDITION_REGEX = 5; + + static function canCreate() { + return self::canUpdate(); + } + + static function canPurge() { + return self::canUpdate(); + } + + static function install(Migration $migration, $version) { + global $DB; + + $default_charset = DBConnection::getDefaultCharset(); + $default_collation = DBConnection::getDefaultCollation(); + $default_key_sign = method_exists('DBConnection', 'getDefaultPrimaryKeySignOption') ? DBConnection::getDefaultPrimaryKeySignOption() : ''; + + $table = self::getTable(); + + if (!$DB->tableExists($table)) { + $migration->displayMessage(sprintf(__("Installing %s"), $table)); + $query = "CREATE TABLE IF NOT EXISTS `$table` ( + `id` INT {$default_key_sign} NOT NULL auto_increment, + `plugin_fields_containers_id` INT {$default_key_sign} NOT NULL DEFAULT '0', + `itemtype` VARCHAR(100) DEFAULT NULL, + `fields` VARCHAR(255) DEFAULT NULL, + `condition` VARCHAR(255) DEFAULT NULL, + `value` VARCHAR(255) DEFAULT NULL, + `is_visible` TINYINT NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + KEY `plugin_fields_containers_id_itemtype` (`plugin_fields_containers_id`, `itemtype`) + ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; + $DB->query($query) or die ($DB->error()); + } + + return true; + } + + + public static function getEnumCondition() : array { + return [ + self::SHOW_CONDITION_EQ => '=', + self::SHOW_CONDITION_NE => '≠', + self::SHOW_CONDITION_LT => '<', + self::SHOW_CONDITION_GT => '>', + self::SHOW_CONDITION_REGEX => __('regular expression matches', 'fields'), + ]; + } + + public static function getConditionName($condition) { + switch ($condition) { + case self::SHOW_CONDITION_EQ: + echo '='; + break; + case self::SHOW_CONDITION_NE: + echo '≠'; + break; + case self::SHOW_CONDITION_LT: + echo '<'; + break; + case self::SHOW_CONDITION_GT: + echo '>'; + case self::SHOW_CONDITION_REGEX: + echo __('regular expression matches', 'fields'); + break; + } + } + + static function uninstall() { + global $DB; + + $DB->query("DROP TABLE IF EXISTS `".self::getTable()."`"); + + return true; + } + + static function getTypeName($nb = 0) { + return __('Condition to hide block', 'fields'); + } + + function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { + return self::createTabEntry(self::getTypeName(), countElementsInTable(self::getTable(), + ['plugin_fields_containers_id' => $item->getID()])); + } + + static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { + if ($item instanceof PluginFieldsContainer) { + self::showForTabContainer($item); + return true; + } + return false; + } + + public function prepareInputForAdd($input) { + return Toolbox::addslashes_deep($input); + } + + public function prepareInputForUpdate($input) { + return Toolbox::addslashes_deep($input); + } + + public static function getDisplayConditionForContainer(int $container_id): array { + global $DB; + $iterator = $DB->request([ + 'SELECT' => [ + self::getTable().'.*', + ], + 'FROM' => self::getTable(), + 'WHERE' => [ + 'plugin_fields_containers_id' => $container_id, + ] + ]); + + $conditions = []; + foreach ($iterator as $data) { + $conditions[] = $data; + } + return $conditions; + } + + private static function getItemtypesForContainer(int $container_id): array { + global $DB; + + $iterator = $DB->request([ + 'SELECT' => ['itemtypes'], + 'FROM' => PluginFieldsContainer::getTable(), + 'WHERE' => [ + 'id' => $container_id, + ] + ]); + + if (count($iterator)) { + $itemtypes = $iterator->current()['itemtypes']; + $itemtypes = importArrayFromDB($itemtypes); + foreach ($itemtypes as $itemtype) { + $results[$itemtype] = $itemtype::getTypeName(); + } + return $results; + } + return []; + } + + public static function getFieldName($so_id, $itemtype) { + echo Search::getOptions($itemtype)[$so_id]['name']; + } + + public static function showItemtypeFieldForm($itemtype) { + return Dropdown::showFromArray("fields",self::removeBlackListedOption(Search::getOptions($itemtype), $itemtype),["display" => false]); + } + + public static function removeBlackListedOption($array, $itemtype_class){ + + $itemtype_object = new $itemtype_class(); + $allowed_so = []; + + //remove "Common" + unset($array['common']); + //remove ID + unset($array[2]); + + $allowed_table = [getTableForItemType($itemtype_class), getTableForItemType(User::getType()), getTableForItemType(Group::getType())]; + + //use relation.constant.php to allow some tables (exclude Location which is managed later) + foreach (getDbRelations() as $tablename => $relation) { + foreach ($relation as $main_table => $foreignKey) { + if($main_table == getTableForItemType($itemtype_class) + && !is_array($foreignKey) + && getTableNameForForeignKeyField($foreignKey) != getTableForItemType(Location::getType())) { + $allowed_table[] = getTableNameForForeignKeyField($foreignKey); + } + } + } + + if($itemtype_object->isEntityAssign()){ + $allowed_table[] = getTableForItemType(Entity::getType()); + } + + //allew specific datatype + $allowed_datatype = ["email", "weblink", "specific", "itemlink", "string", "text","number", "dropdown", "decimal", "integer", "bool"]; + + foreach($array as $subKey => $subArray){ + if(isset($subArray["table"]) && in_array($subArray["table"], $allowed_table) + && in_array($subArray["datatype"], $allowed_datatype) + && !isset($subArray["nosearch"]) //Exclude SO with no search + && !isset($subArray["usehaving"]) //Exclude count SO ex: Ticket -> Number of sons tickets + && !isset($subArray["forcegroupby"]) //Exclude 1-n relation ex: Ticket_User + && !isset($subArray["computation"])){ //Exclude SO with computation Ex : Ticket -> Time to own exceeded + $allowed_so[$subKey] = $subArray["name"]; + }else{ + Toolbox::logError($subArray); + } + } + + if($itemtype_object->maybeLocated()){ + $allowed_so[80] = Location::getTypeName(0); + } + + return $allowed_so; + } + + + public function computeDisplayContainer($item, $container_id){ + //load all condition for itemtype and container + $displayCondition = new self(); + $found_dc = $displayCondition->find(['itemtype' => get_class($item), 'plugin_fields_containers_id' => $container_id]); + + if (count($found_dc)){ + $display = true; + foreach ($found_dc as $data) { + + $displayCondition->getFromDB($data['id']); + $result = $displayCondition->checkCondition($item); + if(!$result){ + return $result; + } + } + + return $display; + }else { + //no condition found -> display container + return true; + } + } + + + public function checkCondition($item){ + $valueToCheck = $this->fields['value']; + $condition = $this->fields['condition']; + $searchOption = Search::getOptions(get_class($item))[$this->fields['fields']]; + + $value = null; + switch ($searchOption['datatype']) { + case 'dropdown': + $dropdown_class = getItemTypeForTable($searchOption['table']); + $dropdown_item = new $dropdown_class(); + if (!$value = $dropdown_item->getFromDBByCrit(['name' => $valueToCheck])){ + $value = null; + } + break; + + case 'email': + case 'weblink': + case 'itemlink': + case 'string': + case 'text': + case 'number': + case 'decimal': + case 'integer': + $value = $valueToCheck; + break; + } + + if($value !== null){ + switch ($condition) { + case self::SHOW_CONDITION_EQ: + // '=' + if ($value == $item->fields[$searchOption['linkfield']]){ + return false; + } + break; + case self::SHOW_CONDITION_NE: + // '≠' + if ($value != $item->fields[$searchOption['linkfield']]){ + return false; + } + break; + case self::SHOW_CONDITION_LT: + // '<'; + if ($item->fields[$searchOption['linkfield']] > $value){ + return false; + } + break; + case self::SHOW_CONDITION_GT: + //'>'; + if ($item->fields[$searchOption['linkfield']] > $value){ + return false; + } + break; + case self::SHOW_CONDITION_REGEX: + //'regex'; + if(self::checkRegex($value)) { + $value = Sanitizer::unsanitize($value); + if (preg_match_all($value . "i", $item->fields[$searchOption['linkfield']], $results) > 0) { + return false; + } + } + break; + } + } + return true; + } + + public static function checkRegex($regex) { + // Avoid php notice when validating the regular expression + set_error_handler(function ($errno, $errstr, $errfile, $errline, $errcontext) { + }); + $isValid = !(preg_match($regex, null) === false); + restore_error_handler(); + return $isValid; + } + + + public static function showForTabContainer(CommonGLPI $item, $options = []) { + + $displayCondition_id = $options['displaycondition_id'] ?? 0; + $display_condition = null; + $fields = null; + + if ($displayCondition_id) { + $display_condition = new self(); + $display_condition->getFromDB($displayCondition_id); + $fields = self::removeBlackListedOption(Search::getOptions($display_condition->fields['itemtype']),$display_condition->fields['itemtype']); + } + + $container_id = $item->getID(); + $twig_params = [ + 'container_id' => $container_id, + 'display_condition' => $display_condition, + 'list_conditions' => SELF::getEnumCondition(), + 'list_fields' => $fields, + 'list_display_conditions' => self::getDisplayConditionForContainer($container_id), + 'container_itemtypes' => self::getItemtypesForContainer($container_id), + 'target' => self::getFormURL(), + 'url_for_on_change' => Plugin::getWebDir('fields') . '/ajax/display_container.php', + 'form_only' => $display_condition !== null || (($options['action'] ?? '') === 'get_add_form'), + ]; + + if ($display_condition === null) { + TemplateRenderer::getInstance()->display('@fields/forms/display_block.html.twig', $twig_params); + } else { + return TemplateRenderer::getInstance()->render('@fields/forms/display_block.html.twig', $twig_params); + } + return ''; + } +} diff --git a/setup.php b/setup.php index d4259b29..2fc5ee72 100644 --- a/setup.php +++ b/setup.php @@ -28,7 +28,7 @@ * ------------------------------------------------------------------------- */ -define ('PLUGIN_FIELDS_VERSION', '1.14.0'); +define ('PLUGIN_FIELDS_VERSION', '1.14.1'); // Minimal GLPI version, inclusive define("PLUGIN_FIELDS_MIN_GLPI", "10.0.0"); diff --git a/templates/forms/display_block.html.twig b/templates/forms/display_block.html.twig new file mode 100644 index 00000000..99de9138 --- /dev/null +++ b/templates/forms/display_block.html.twig @@ -0,0 +1,207 @@ +{# +# ------------------------------------------------------------------------- +# Fields plugin for GLPI +# ------------------------------------------------------------------------- +# +# LICENSE +# +# This file is part of Fields. +# +# Fields is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# Fields is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Fields. If not, see . +# ------------------------------------------------------------------------- +# @copyright Copyright (C) 2013-2022 by Fields plugin team. +# @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html +# @link https://github.com/pluginsGLPI/fields +# ------------------------------------------------------------------------- +#} + +{% import 'components/form/fields_macros.html.twig' as fields %} +{% set rand = random() %} + +{% if form_only is not defined or form_only == false %} +
+{% endif %} + +
+
+ {{ __('The engine is used for hide block when main object meets condition')}} +
+
+
+ + {% if display_condition is null %} + {{ fields.largeTitle(__('Add condition to hide block', 'fields'), '', true) }} + {% else %} +
+ +
+ {{ fields.largeTitle(__('Edit condition to hide block', 'fields'), '', true) }} + {% endif %} +
+
+
+
+
+ + {{ fields.dropdownArrayField('itemtype', display_condition.fields['itemtype']|default(null), container_itemtypes, __('Item type'), {'rand': rand, 'display_emptychoice': true}) }} + {% do call('Ajax::updateItemOnSelectEvent', + [ + 'dropdown_itemtype'~ rand, + 'results_fields', + url_for_on_change, + { + 'itemtype' : '__VALUE__', + 'action': 'get_itemtype_so', + } + ]) + %} + + {% if display_condition is not null %} + {{ fields.dropdownArrayField('fields', display_condition.fields['fields']|default(null), list_fields, '', {'no_label': true, 'rand': rand, 'display_emptychoice': false}) }} + {% endif %} + + + {{ fields.dropdownArrayField('condition', display_condition.fields['condition']|default(null), list_conditions, __('Condition'), {'rand': rand, 'display_emptychoice': false}) }} + {{ fields.textField('value', display_condition.fields['value']|default(null), __('Value'), {}) }} + +
{# .row #} +
+ {% if display_condition is not null %} + + + {% else %} + + {% endif %} + +
+
{# .row #} +
{# .flex-row #} +
+
{# .card-body #} +
+ + {% if form_only is not defined or form_only == false %} + {{ fields.largeTitle(__('Conditions to hide block', 'fields'), '', false) }} +
+
+
+
+
+ + + + + + + + + + + + {% if list_display_conditions|length > 0 %} + {% for data_display_condition in list_display_conditions %} + + {% set condition %} + {% do call('PluginFieldsDisplayContainer::getConditionName', [data_display_condition.condition]) %} + {% endset %} + + {% set field_name %} + {% do call('PluginFieldsDisplayContainer::getFieldName', [data_display_condition.fields, data_display_condition.itemtype]) %} + {% endset %} + + + + + + + + + {% endfor %} + {% else %} + + + + {% endif %} + +
{{ __('Item type') }}{{ __('Field') }}{{ __('Condition') }}{{ __('Value') }}
{{ data_display_condition.itemtype }}{{ field_name }}{{ condition }}{{ data_display_condition.value}} + + +
+ + + +
+
{{ __('No item found') }}
+
{# .row #} +
{# .row #} +
{# .flex-row #} +
+
{# .card-body #} + {% endif %} + {% if form_only is not defined or form_only == false %} + +
+{% endif %} From b5ae2f5b515e11172de4e79bba58bd50239893e7 Mon Sep 17 00:00:00 2001 From: Stanislas KITA Date: Wed, 27 Apr 2022 16:33:37 +0200 Subject: [PATCH 02/21] revert change --- setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.php b/setup.php index 2fc5ee72..d4259b29 100644 --- a/setup.php +++ b/setup.php @@ -28,7 +28,7 @@ * ------------------------------------------------------------------------- */ -define ('PLUGIN_FIELDS_VERSION', '1.14.1'); +define ('PLUGIN_FIELDS_VERSION', '1.14.0'); // Minimal GLPI version, inclusive define("PLUGIN_FIELDS_MIN_GLPI", "10.0.0"); From 4af4acee9a369b8fba16a04492b6a4e0cc356a56 Mon Sep 17 00:00:00 2001 From: Stanislas KITA Date: Wed, 27 Apr 2022 16:34:31 +0200 Subject: [PATCH 03/21] maange 'boolean' type --- inc/displaycontainer.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/inc/displaycontainer.class.php b/inc/displaycontainer.class.php index 5a3f254d..5da90a30 100644 --- a/inc/displaycontainer.class.php +++ b/inc/displaycontainer.class.php @@ -287,6 +287,7 @@ public function checkCondition($item){ case 'number': case 'decimal': case 'integer': + case 'bool': $value = $valueToCheck; break; } From b95ef88996d31e128b544fb4d3ee8894fa630ed3 Mon Sep 17 00:00:00 2001 From: Stanislas KITA Date: Wed, 27 Apr 2022 17:04:17 +0200 Subject: [PATCH 04/21] remove useless debug code --- inc/displaycontainer.class.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/inc/displaycontainer.class.php b/inc/displaycontainer.class.php index 5da90a30..5b588898 100644 --- a/inc/displaycontainer.class.php +++ b/inc/displaycontainer.class.php @@ -1,8 +1,6 @@ Time to own exceeded $allowed_so[$subKey] = $subArray["name"]; - }else{ - Toolbox::logError($subArray); } } From e57ffcfe6686863b47fd268a2616ca8ccd0682c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Thu, 28 Apr 2022 09:13:04 +0200 Subject: [PATCH 05/21] Remove extra whitespace that break form submit --- front/displaycontainer.form.php | 1 - 1 file changed, 1 deletion(-) diff --git a/front/displaycontainer.form.php b/front/displaycontainer.form.php index c29f7870..35fe45fc 100644 --- a/front/displaycontainer.form.php +++ b/front/displaycontainer.form.php @@ -1,4 +1,3 @@ - Date: Thu, 28 Apr 2022 09:17:59 +0200 Subject: [PATCH 06/21] Prevent messages duplication --- templates/forms/display_block.html.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/forms/display_block.html.twig b/templates/forms/display_block.html.twig index 99de9138..eed44942 100644 --- a/templates/forms/display_block.html.twig +++ b/templates/forms/display_block.html.twig @@ -31,13 +31,13 @@ {% if form_only is not defined or form_only == false %}
-{% endif %} -
{{ __('The engine is used for hide block when main object meets condition')}}
+{% endif %} +
{% if display_condition is null %} From a9817bb8ebadcb5ab257fd667d534f1e73dc4c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Thu, 28 Apr 2022 09:18:54 +0200 Subject: [PATCH 07/21] Remove invalid function call --- templates/forms/display_block.html.twig | 2 -- 1 file changed, 2 deletions(-) diff --git a/templates/forms/display_block.html.twig b/templates/forms/display_block.html.twig index eed44942..0ec63b9c 100644 --- a/templates/forms/display_block.html.twig +++ b/templates/forms/display_block.html.twig @@ -183,7 +183,6 @@ } }).then((result) => { $('form[name="asset_form"]').replaceWith(result); - refresh_status_dropdown(true); }); }); $('#container{{ rand }}').on('click', 'button[name="switch_add"]', (e) => { @@ -198,7 +197,6 @@ } }).then((result) => { $('form[name="asset_form"]').replaceWith(result); - refresh_status_dropdown(true); }); }); }); From 66ae335cba4c737876fbdc334c73a05a8a9bc31b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Thu, 28 Apr 2022 09:41:28 +0200 Subject: [PATCH 08/21] datatype may be not set --- inc/displaycontainer.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/displaycontainer.class.php b/inc/displaycontainer.class.php index 5b588898..79aafcf0 100644 --- a/inc/displaycontainer.class.php +++ b/inc/displaycontainer.class.php @@ -219,7 +219,7 @@ public static function removeBlackListedOption($array, $itemtype_class){ foreach($array as $subKey => $subArray){ if(isset($subArray["table"]) && in_array($subArray["table"], $allowed_table) - && in_array($subArray["datatype"], $allowed_datatype) + && isset($subArray["datatype"]) && in_array($subArray["datatype"], $allowed_datatype) && !isset($subArray["nosearch"]) //Exclude SO with no search && !isset($subArray["usehaving"]) //Exclude count SO ex: Ticket -> Number of sons tickets && !isset($subArray["forcegroupby"]) //Exclude 1-n relation ex: Ticket_User From 408cd58482663fbdb49c900e98f436902deda7d2 Mon Sep 17 00:00:00 2001 From: Stanislas KITA Date: Thu, 28 Apr 2022 14:21:32 +0200 Subject: [PATCH 09/21] check if block need to be display --- inc/field.class.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/inc/field.class.php b/inc/field.class.php index cfd89f8d..f69ebc3e 100644 --- a/inc/field.class.php +++ b/inc/field.class.php @@ -641,13 +641,18 @@ static function showForTab($params) { return false; } - self::showDomContainer( - $c_id, - $item::getType(), - $item->getID(), - $type, - $subtype - ); + $display_condition = new PluginFieldsDisplayContainer(); + if($display_condition->computeDisplayContainer($item, $c_id)) { + self::showDomContainer( + $c_id, + $item::getType(), + $item->getID(), + $type, + $subtype + ); + } + + } static function prepareHtmlFields($fields, $items_id, $itemtype, $canedit = true, From 2d846a5d116201a6d4970d5703d366996263c5fa Mon Sep 17 00:00:00 2001 From: Stanislas KITA Date: Thu, 28 Apr 2022 14:22:02 +0200 Subject: [PATCH 10/21] use dropdown for value if needed --- ajax/display_container.php | 7 + inc/displaycontainer.class.php | 223 ++++++++++++++---- templates/forms/display_block.html.twig | 35 +-- .../forms/display_condition_block.html.twig | 71 ++++++ 4 files changed, 279 insertions(+), 57 deletions(-) create mode 100644 templates/forms/display_condition_block.html.twig diff --git a/ajax/display_container.php b/ajax/display_container.php index fbeeafce..c12e9640 100644 --- a/ajax/display_container.php +++ b/ajax/display_container.php @@ -48,6 +48,13 @@ } else { echo ""; } + } else if($_POST['action'] === 'get_condition_switch_so') { + if(isset($_POST['search_option_id']) && (isset($_POST['itemtype']) && class_exists($_POST['itemtype']))) { + echo PluginFieldsDisplayContainer::showSearchOptionCondition($_POST['search_option_id'], $_POST['itemtype']) ; + } else { + echo ""; + } + } } else { http_response_code(400); diff --git a/inc/displaycontainer.class.php b/inc/displaycontainer.class.php index 79aafcf0..1c038e8f 100644 --- a/inc/displaycontainer.class.php +++ b/inc/displaycontainer.class.php @@ -33,11 +33,11 @@ class PluginFieldsDisplayContainer extends CommonDBTM { static $rightname = 'config'; - const SHOW_CONDITION_EQ = 1; - const SHOW_CONDITION_NE = 2; - const SHOW_CONDITION_LT = 3; - const SHOW_CONDITION_GT = 4; - const SHOW_CONDITION_REGEX = 5; + const SHOW_CONDITION_EQ = 1; + const SHOW_CONDITION_NE = 2; + const SHOW_CONDITION_LT = 3; + const SHOW_CONDITION_GT = 4; + const SHOW_CONDITION_REGEX = 5; static function canCreate() { return self::canUpdate(); @@ -49,11 +49,9 @@ static function canPurge() { static function install(Migration $migration, $version) { global $DB; - $default_charset = DBConnection::getDefaultCharset(); $default_collation = DBConnection::getDefaultCollation(); $default_key_sign = method_exists('DBConnection', 'getDefaultPrimaryKeySignOption') ? DBConnection::getDefaultPrimaryKeySignOption() : ''; - $table = self::getTable(); if (!$DB->tableExists($table)) { @@ -62,7 +60,7 @@ static function install(Migration $migration, $version) { `id` INT {$default_key_sign} NOT NULL auto_increment, `plugin_fields_containers_id` INT {$default_key_sign} NOT NULL DEFAULT '0', `itemtype` VARCHAR(100) DEFAULT NULL, - `fields` VARCHAR(255) DEFAULT NULL, + `search_option` VARCHAR(255) DEFAULT NULL, `condition` VARCHAR(255) DEFAULT NULL, `value` VARCHAR(255) DEFAULT NULL, `is_visible` TINYINT NOT NULL DEFAULT '0', @@ -75,15 +73,23 @@ static function install(Migration $migration, $version) { return true; } + public static function getEnumCondition($is_dropdown = false) : array { + + if ($is_dropdown){ + return [ + self::SHOW_CONDITION_EQ => '=', + self::SHOW_CONDITION_NE => '≠' + ]; + } else { + return [ + self::SHOW_CONDITION_EQ => '=', + self::SHOW_CONDITION_NE => '≠', + self::SHOW_CONDITION_LT => '<', + self::SHOW_CONDITION_GT => '>', + self::SHOW_CONDITION_REGEX => __('regular expression matches', 'fields'), + ]; + } - public static function getEnumCondition() : array { - return [ - self::SHOW_CONDITION_EQ => '=', - self::SHOW_CONDITION_NE => '≠', - self::SHOW_CONDITION_LT => '<', - self::SHOW_CONDITION_GT => '>', - self::SHOW_CONDITION_REGEX => __('regular expression matches', 'fields'), - ]; } public static function getConditionName($condition) { @@ -105,23 +111,25 @@ public static function getConditionName($condition) { } } + static function uninstall() { global $DB; - $DB->query("DROP TABLE IF EXISTS `".self::getTable()."`"); - return true; } + static function getTypeName($nb = 0) { return __('Condition to hide block', 'fields'); } + function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { return self::createTabEntry(self::getTypeName(), countElementsInTable(self::getTable(), ['plugin_fields_containers_id' => $item->getID()])); } + static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { if ($item instanceof PluginFieldsContainer) { self::showForTabContainer($item); @@ -130,14 +138,17 @@ static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtem return false; } + public function prepareInputForAdd($input) { return Toolbox::addslashes_deep($input); } + public function prepareInputForUpdate($input) { return Toolbox::addslashes_deep($input); } + public static function getDisplayConditionForContainer(int $container_id): array { global $DB; $iterator = $DB->request([ @@ -157,6 +168,7 @@ public static function getDisplayConditionForContainer(int $container_id): array return $conditions; } + private static function getItemtypesForContainer(int $container_id): array { global $DB; @@ -179,14 +191,112 @@ private static function getItemtypesForContainer(int $container_id): array { return []; } + public static function getFieldName($so_id, $itemtype) { echo Search::getOptions($itemtype)[$so_id]['name']; } + public static function showItemtypeFieldForm($itemtype) { - return Dropdown::showFromArray("fields",self::removeBlackListedOption(Search::getOptions($itemtype), $itemtype),["display" => false]); + + $rand = mt_rand(); + $out = ""; + $out .= Dropdown::showFromArray("search_option",self::removeBlackListedOption(Search::getOptions($itemtype), $itemtype),["display_emptychoice" => true, "display" => false, 'rand' => $rand]); + + $out .= Ajax::updateItemOnSelectEvent( + "dropdown_search_option" . $rand, + "results_condition", + Plugin::getWebDir('fields') . '/ajax/display_container.php', + [ + 'search_option_id' => '__VALUE__', + 'itemtype' => $itemtype, + 'action' => 'get_condition_switch_so' + ] + ); + + echo $out; + + } + + + public static function showSearchOptionCondition($searchoption_id, $itemtype) { + $so = Search::getOptions($itemtype)[$searchoption_id]; + $twig_params = []; + $twig_params['rand'] = rand(); + + $twig_params['is_dropdown'] = false; + $twig_params['is_specific'] = false; + $twig_params['is_list_values'] = false; + + if ($so['datatype'] == 'dropdown'){ + $twig_params['is_dropdown'] = true; + $twig_params['dropdown_itemtype'] = getItemTypeForTable($so['table']); + $twig_params['list_conditions'] = self::getEnumCondition(true); + + } else if ($so['datatype'] == 'specific' && get_parent_class($itemtype) == CommonITILObject::getType()) { + $twig_params['list_conditions'] = self::getEnumCondition(true); + $twig_params['is_specific'] = true; + switch ($so['field']) { + case 'status': + $twig_params['is_list_values'] = true; + $twig_params['list_values'] = $itemtype::getAllStatusArray(false); + break; + case 'impact': + case 'urgency': + case 'priority': + $twig_params['item'] = new $itemtype(); + $twig_params['itemtype_field'] = $so['field']; + break; + case 'global_validation': + $twig_params['is_list_values'] = true; + $twig_params['list_values'] = CommonITILValidation::getAllStatusArray(false, true); + break; + + } + }else{ + $twig_params['list_conditions'] = self::getEnumCondition(false); + } + + TemplateRenderer::getInstance()->display('@fields/forms/display_condition_block.html.twig', $twig_params); + } + + + public static function getRawValue($searchoption_id, $itemtype, $value) { + + $so = Search::getOptions($itemtype)[$searchoption_id]; + $raw_value = ''; + + if ($so['datatype'] == 'dropdown'){ + $dropdown_itemtype = getItemTypeForTable($so['table']); + $dropdown = new $dropdown_itemtype(); + $dropdown->getFromDB($value); + $raw_value = $dropdown->fields['name']; + } else if ($so['datatype'] == 'specific' && get_parent_class($itemtype) == CommonITILObject::getType()) { + switch ($so['field']) { + case 'status': + $raw_value = $itemtype::getStatus($value); + break; + case 'impact': + $raw_value = $itemtype::getImpactName($value); + break; + case 'urgency': + $raw_value = $itemtype::getUrgencyName($value); + break; + case 'priority': + $raw_value = $itemtype::getPriorityName($value); + break; + case 'global_validation': + $raw_value = CommonITILValidation::getStatus($value); + break; + } + }else{ + $raw_value = $value; + } + + echo $raw_value; } + public static function removeBlackListedOption($array, $itemtype_class){ $itemtype_object = new $itemtype_class(); @@ -195,7 +305,7 @@ public static function removeBlackListedOption($array, $itemtype_class){ //remove "Common" unset($array['common']); //remove ID - unset($array[2]); + //unset($array[2]); $allowed_table = [getTableForItemType($itemtype_class), getTableForItemType(User::getType()), getTableForItemType(Group::getType())]; @@ -219,7 +329,7 @@ public static function removeBlackListedOption($array, $itemtype_class){ foreach($array as $subKey => $subArray){ if(isset($subArray["table"]) && in_array($subArray["table"], $allowed_table) - && isset($subArray["datatype"]) && in_array($subArray["datatype"], $allowed_datatype) + && (isset($subArray["datatype"]) && in_array($subArray["datatype"], $allowed_datatype)) && !isset($subArray["nosearch"]) //Exclude SO with no search && !isset($subArray["usehaving"]) //Exclude count SO ex: Ticket -> Number of sons tickets && !isset($subArray["forcegroupby"]) //Exclude 1-n relation ex: Ticket_User @@ -263,18 +373,11 @@ public function computeDisplayContainer($item, $container_id){ public function checkCondition($item){ $valueToCheck = $this->fields['value']; $condition = $this->fields['condition']; - $searchOption = Search::getOptions(get_class($item))[$this->fields['fields']]; + $searchOption = Search::getOptions(get_class($item))[$this->fields['search_option']]; $value = null; switch ($searchOption['datatype']) { case 'dropdown': - $dropdown_class = getItemTypeForTable($searchOption['table']); - $dropdown_item = new $dropdown_class(); - if (!$value = $dropdown_item->getFromDBByCrit(['name' => $valueToCheck])){ - $value = null; - } - break; - case 'email': case 'weblink': case 'itemlink': @@ -328,6 +431,7 @@ public function checkCondition($item){ return true; } + public static function checkRegex($regex) { // Avoid php notice when validating the regular expression set_error_handler(function ($errno, $errstr, $errfile, $errline, $errcontext) { @@ -335,39 +439,72 @@ public static function checkRegex($regex) { $isValid = !(preg_match($regex, null) === false); restore_error_handler(); return $isValid; - } + } public static function showForTabContainer(CommonGLPI $item, $options = []) { $displayCondition_id = $options['displaycondition_id'] ?? 0; $display_condition = null; - $fields = null; + $search_option = null; + $twig_params = []; if ($displayCondition_id) { $display_condition = new self(); $display_condition->getFromDB($displayCondition_id); - $fields = self::removeBlackListedOption(Search::getOptions($display_condition->fields['itemtype']),$display_condition->fields['itemtype']); + $search_option = self::removeBlackListedOption(Search::getOptions($display_condition->fields['itemtype']),$display_condition->fields['itemtype']); + + $so = Search::getOptions($display_condition->fields['itemtype'])[$display_condition->fields['search_option']]; + + $twig_params['is_dropdown'] = false; + $twig_params['is_specific'] = false; + $twig_params['is_list_values'] = false; + + if ($so['datatype'] == 'dropdown'){ + $twig_params['is_dropdown'] = true; + $twig_params['dropdown_itemtype'] = getItemTypeForTable($so['table']); + $twig_params['list_conditions'] = self::getEnumCondition(true); + + } else if ($so['datatype'] == 'specific' && get_parent_class($display_condition->fields['itemtype']) == CommonITILObject::getType()) { + $twig_params['list_conditions'] = self::getEnumCondition(true); + $twig_params['is_specific'] = true; + switch ($so['field']) { + case 'status': + $twig_params['is_list_values'] = true; + $twig_params['list_values'] =$display_condition->fields['itemtype']::getAllStatusArray(false); + break; + case 'impact': + case 'urgency': + case 'priority': + $twig_params['item'] = new $display_condition->fields['itemtype'](); + $twig_params['itemtype_field'] = $so['field']; + break; + case 'global_validation': + $twig_params['is_list_values'] = true; + $twig_params['list_values'] = CommonITILValidation::getAllStatusArray(false, true); + break; + } + }else{ + $twig_params['list_conditions'] = self::getEnumCondition(false); + } } $container_id = $item->getID(); - $twig_params = [ - 'container_id' => $container_id, - 'display_condition' => $display_condition, - 'list_conditions' => SELF::getEnumCondition(), - 'list_fields' => $fields, - 'list_display_conditions' => self::getDisplayConditionForContainer($container_id), - 'container_itemtypes' => self::getItemtypesForContainer($container_id), - 'target' => self::getFormURL(), - 'url_for_on_change' => Plugin::getWebDir('fields') . '/ajax/display_container.php', - 'form_only' => $display_condition !== null || (($options['action'] ?? '') === 'get_add_form'), - ]; + $twig_params['container_id'] = $container_id; + $twig_params['display_condition'] = $display_condition; + $twig_params['list_search_option'] = $search_option; + $twig_params['list_display_conditions'] = self::getDisplayConditionForContainer($container_id); + $twig_params['container_itemtypes'] = self::getItemtypesForContainer($container_id); + $twig_params['target'] = self::getFormURL(); + $twig_params['url_for_on_change'] = Plugin::getWebDir('fields') . '/ajax/display_container.php'; + $twig_params['form_only'] = $display_condition !== null || (($options['action'] ?? '') === 'get_add_form'); if ($display_condition === null) { TemplateRenderer::getInstance()->display('@fields/forms/display_block.html.twig', $twig_params); } else { return TemplateRenderer::getInstance()->render('@fields/forms/display_block.html.twig', $twig_params); } + return ''; } } diff --git a/templates/forms/display_block.html.twig b/templates/forms/display_block.html.twig index 0ec63b9c..9436eb9f 100644 --- a/templates/forms/display_block.html.twig +++ b/templates/forms/display_block.html.twig @@ -31,15 +31,15 @@ {% if form_only is not defined or form_only == false %}
-
-
- {{ __('The engine is used for hide block when main object meets condition')}} -
-
{% endif %} +
+
+ {{ __('The engine is used for hide block when main object meets condition')}} +
+
{% if display_condition is null %} {{ fields.largeTitle(__('Add condition to hide block', 'fields'), '', true) }} {% else %} @@ -69,14 +69,17 @@ } ]) %} - - {% if display_condition is not null %} - {{ fields.dropdownArrayField('fields', display_condition.fields['fields']|default(null), list_fields, '', {'no_label': true, 'rand': rand, 'display_emptychoice': false}) }} - {% endif %} - +
+ {% if display_condition is not null %} + {{ fields.dropdownArrayField('search_option', display_condition.fields['search_option']|default(null), list_search_option, '', {'no_label': true, 'rand': rand, 'display_emptychoice': false}) }} + {% endif %} +
- {{ fields.dropdownArrayField('condition', display_condition.fields['condition']|default(null), list_conditions, __('Condition'), {'rand': rand, 'display_emptychoice': false}) }} - {{ fields.textField('value', display_condition.fields['value']|default(null), __('Value'), {}) }} +
+ {% if display_condition is not null %} + {{ include('@fields/forms/display_condition_block.html.twig') }} + {% endif %} +
{# .row #}
@@ -126,14 +129,18 @@ {% endset %} {% set field_name %} - {% do call('PluginFieldsDisplayContainer::getFieldName', [data_display_condition.fields, data_display_condition.itemtype]) %} + {% do call('PluginFieldsDisplayContainer::getFieldName', [data_display_condition.search_option, data_display_condition.itemtype]) %} + {% endset %} + + {% set raw_value %} + {% do call('PluginFieldsDisplayContainer::getRawValue', [data_display_condition.search_option, data_display_condition.itemtype, data_display_condition.value]) %} {% endset %} {{ data_display_condition.itemtype }} {{ field_name }} {{ condition }} - {{ data_display_condition.value}} + {{ raw_value}} +
+ + {{ fields.largeTitle(__('Conditions to hide block', 'fields'), '', false) }} +
+
+
+
+
+ + + + + + + + + + + + {% if container_display_conditions|length > 0 %} + {% for container_display_condition in container_display_conditions %} + + + + + + + + {% endfor %} + {% else %} + + + + {% endif %} + +
{{ __('Item type') }}{{ __('Field') }}{{ __('Condition') }}{{ __('Value') }}
{{ container_display_condition.itemtype|itemtype_name }}{{ call('PluginFieldsContainerDisplayCondition::getFieldName', [container_display_condition.search_option, container_display_condition.itemtype]) }}{{ call('PluginFieldsContainerDisplayCondition::getConditionName', [container_display_condition.condition]) }}{{ call('PluginFieldsContainerDisplayCondition::getRawValue', [container_display_condition.search_option, container_display_condition.itemtype, container_display_condition.value]) }} + + + + + + + +
{{ __('No item found') }}
+
{# .row #} +
{# .row #} +
{# .flex-row #} +
+
{# .card-body #} + +
diff --git a/templates/forms/container_display_condition.html.twig b/templates/forms/container_display_condition.html.twig new file mode 100644 index 00000000..8d70ecf2 --- /dev/null +++ b/templates/forms/container_display_condition.html.twig @@ -0,0 +1,103 @@ +{# + # ------------------------------------------------------------------------- + # Fields plugin for GLPI + # ------------------------------------------------------------------------- + # + # LICENSE + # + # This file is part of Fields. + # + # Fields is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 2 of the License, or + # (at your option) any later version. + # + # Fields is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with Fields. If not, see . + # ------------------------------------------------------------------------- + # @copyright Copyright (C) 2013-2022 by Fields plugin team. + # @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html + # @link https://github.com/pluginsGLPI/fields + # ------------------------------------------------------------------------- + #} + +{% import 'components/form/fields_macros.html.twig' as fields %} +{% set rand = random() %} + +
+ +
+
+
+
+
+ {{ fields.dropdownArrayField('itemtype', container_display_condition.fields['itemtype']|default(null), container_itemtypes, __('Item type'), {'rand': rand, 'display_emptychoice': true}) }} + {% do call('Ajax::updateItemOnSelectEvent', + [ + 'dropdown_itemtype'~ rand, + 'results_fields', + get_plugin_web_dir('fields') ~ '/ajax/container_display_condition.php', + { + 'itemtype': '__VALUE__', + 'action' : 'get_itemtype_so', + } + ]) + %} +
+ {% if not container_display_condition.isNewItem() %} + {{ fields.dropdownArrayField('search_option', container_display_condition.fields['search_option']|default(null), search_options, '', {'no_label': true, 'rand': rand, 'display_emptychoice': false}) }} + {% do call('Ajax::updateItemOnSelectEvent', + [ + 'dropdown_search_option'~ rand, + 'results_condition', + get_plugin_web_dir('fields') ~ '/ajax/container_display_condition.php', + { + 'search_option_id' : '__VALUE__', + 'itemtype' : container_display_condition.fields['itemtype'], + 'action' : 'get_condition_switch_so' + } + ]) + %} + {% endif %} +
+ +
+ {% if not container_display_condition.isNewItem() %} + {{ call( + 'PluginFieldsContainerDisplayCondition::showSearchOptionCondition', + [ + container_display_condition.fields['search_option'], + container_display_condition.fields['itemtype'], + container_display_condition.fields['condition'], + container_display_condition.fields['value'] + ] + )|raw }} + {% endif %} +
+ +
{# .row #} +
+ {% if not container_display_condition.isNewItem() %} + + + {% else %} + + {% endif %} + +
+
{# .row #} +
{# .flex-row #} +
+
{# .card-body #} +
diff --git a/templates/forms/display_block.html.twig b/templates/forms/display_block.html.twig deleted file mode 100644 index 1e3910d6..00000000 --- a/templates/forms/display_block.html.twig +++ /dev/null @@ -1,232 +0,0 @@ -{# - # ------------------------------------------------------------------------- - # Fields plugin for GLPI - # ------------------------------------------------------------------------- - # - # LICENSE - # - # This file is part of Fields. - # - # Fields is free software; you can redistribute it and/or modify - # it under the terms of the GNU General Public License as published by - # the Free Software Foundation; either version 2 of the License, or - # (at your option) any later version. - # - # Fields is distributed in the hope that it will be useful, - # but WITHOUT ANY WARRANTY; without even the implied warranty of - # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - # GNU General Public License for more details. - # - # You should have received a copy of the GNU General Public License - # along with Fields. If not, see . - # ------------------------------------------------------------------------- - # @copyright Copyright (C) 2013-2022 by Fields plugin team. - # @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html - # @link https://github.com/pluginsGLPI/fields - # ------------------------------------------------------------------------- - #} - -{% import 'components/form/fields_macros.html.twig' as fields %} -{% set rand = random() %} - -{% if form_only is not defined or form_only == false %} -
-{% endif %} - -
- -
-
- {{ __('The engine is used for hide block when main object meets condition')}} -
-
- {% if display_condition is null %} - {{ fields.largeTitle(__('Add condition to hide block', 'fields'), '', true) }} - {% else %} -
- -
- {{ fields.largeTitle(__('Edit condition to hide block', 'fields'), '', true) }} - {% endif %} -
-
-
-
-
- - {{ fields.dropdownArrayField('itemtype', display_condition.fields['itemtype']|default(null), container_itemtypes, __('Item type'), {'rand': rand, 'display_emptychoice': true}) }} - {% do call('Ajax::updateItemOnSelectEvent', - [ - 'dropdown_itemtype'~ rand, - 'results_fields', - url_for_on_change, - { - 'itemtype' : '__VALUE__', - 'action': 'get_itemtype_so', - } - ]) - %} -
- {% if display_condition is not null %} - {{ fields.dropdownArrayField('search_option', display_condition.fields['search_option']|default(null), list_search_option, '', {'no_label': true, 'rand': rand, 'display_emptychoice': false}) }} - {% do call('Ajax::updateItemOnSelectEvent', - [ - 'dropdown_search_option'~ rand, - 'results_condition', - url_for_on_change, - { - 'search_option_id' : '__VALUE__', - 'itemtype' : display_condition.fields['itemtype'], - 'action' : 'get_condition_switch_so' - } - ]) - %} - {% endif %} -
- -
- {% if display_condition is not null %} - {{ call( - 'PluginFieldsContainerDisplayCondition::showSearchOptionCondition', - [ - display_condition.fields['search_option'], - display_condition.fields['itemtype'], - display_condition.fields['condition'], - display_condition.fields['value'] - ] - )|raw }} - {% endif %} -
- -
{# .row #} -
- {% if display_condition is not null %} - - - {% else %} - - {% endif %} - -
-
{# .row #} -
{# .flex-row #} -
-
{# .card-body #} -
- - {% if form_only is not defined or form_only == false %} - {{ fields.largeTitle(__('Conditions to hide block', 'fields'), '', false) }} -
-
-
-
-
- - - - - - - - - - - - {% if list_display_conditions|length > 0 %} - {% for data_display_condition in list_display_conditions %} - - {% set condition %} - {% do call('PluginFieldsContainerDisplayCondition::getConditionName', [data_display_condition.condition]) %} - {% endset %} - - {% set field_name %} - {% do call('PluginFieldsContainerDisplayCondition::getFieldName', [data_display_condition.search_option, data_display_condition.itemtype]) %} - {% endset %} - - {% set raw_value %} - {% do call('PluginFieldsContainerDisplayCondition::getRawValue', [data_display_condition.search_option, data_display_condition.itemtype, data_display_condition.value]) %} - {% endset %} - - - - - - - - - {% endfor %} - {% else %} - - - - {% endif %} - -
{{ __('Item type') }}{{ __('Field') }}{{ __('Condition') }}{{ __('Value') }}
{{ data_display_condition.itemtype }}{{ field_name }}{{ condition }}{{ raw_value}} - - -
- - - -
-
{{ __('No item found') }}
-
{# .row #} -
{# .row #} -
{# .flex-row #} -
-
{# .card-body #} - {% endif %} - {% if form_only is not defined or form_only == false %} - -
-{% endif %} From ee2babd77bc6de4d6d45f10457d236e89dff5b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Thu, 28 Apr 2022 16:17:40 +0200 Subject: [PATCH 20/21] Should not be necessary --- inc/containerdisplaycondition.class.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/inc/containerdisplaycondition.class.php b/inc/containerdisplaycondition.class.php index 87cd32ad..fa0e1a52 100644 --- a/inc/containerdisplaycondition.class.php +++ b/inc/containerdisplaycondition.class.php @@ -140,16 +140,6 @@ static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtem } - public function prepareInputForAdd($input) { - return Toolbox::addslashes_deep($input); - } - - - public function prepareInputForUpdate($input) { - return Toolbox::addslashes_deep($input); - } - - public static function getDisplayConditionForContainer(int $container_id): array { global $DB; $iterator = $DB->request([ From 5d47b1bb0f764cf3c25c48cee4d9a8ed51784550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Thu, 28 Apr 2022 16:20:30 +0200 Subject: [PATCH 21/21] Remove useless code --- inc/containerdisplaycondition.class.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/inc/containerdisplaycondition.class.php b/inc/containerdisplaycondition.class.php index fa0e1a52..d8342949 100644 --- a/inc/containerdisplaycondition.class.php +++ b/inc/containerdisplaycondition.class.php @@ -307,8 +307,6 @@ public static function removeBlackListedOption($array, $itemtype_class){ //remove "Common" unset($array['common']); - //remove ID - //unset($array[2]); $allowed_table = [getTableForItemType($itemtype_class), getTableForItemType(User::getType()), getTableForItemType(Group::getType())]; @@ -424,7 +422,7 @@ public function checkCondition($item){ //'regex'; if(self::checkRegex($value)) { $value = Sanitizer::unsanitize($value); - if (preg_match_all($value . "i", $item->fields[$searchOption['linkfield']], $results) > 0) { + if (preg_match_all($value . "i", $item->fields[$searchOption['linkfield']]) > 0) { return false; } }