From e9c300c3be2ebe19e0fd24021e16a4a37db5a3cc Mon Sep 17 00:00:00 2001 From: Stanislas Kita Date: Fri, 24 Oct 2025 09:43:13 +0200 Subject: [PATCH 1/2] Fix(Core): Fix json_decode for 'itemtypes' field --- hook.php | 2 +- inc/container.class.php | 30 +++++++++++++++--------------- inc/field.class.php | 8 ++++---- setup.php | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/hook.php b/hook.php index c38b7619..86f11568 100644 --- a/hook.php +++ b/hook.php @@ -338,7 +338,7 @@ function plugin_datainjection_populate_fields() $container = new PluginFieldsContainer(); $found = $container->find(['is_active' => 1]); foreach ($found as $values) { - $types = json_decode($values['itemtypes']); + $types = PluginFieldsToolbox::decodeJSONItemtypes($values['itemtypes']); foreach ($types as $type) { $classname = PluginFieldsContainer::getClassname($type, $values['name'], 'Injection'); diff --git a/inc/container.class.php b/inc/container.class.php index e6ccd70c..5baa4c80 100644 --- a/inc/container.class.php +++ b/inc/container.class.php @@ -172,7 +172,7 @@ public static function installBaseData(Migration $migration, $version) foreach ($result as $type) { $migration_genericobject_itemtype[$type['itemtype']] = [ 'genericobject_itemtype' => $type['itemtype'], - 'itemtype' => 'Glpi\CustomAsset\\' . $type['name'] . 'Asset', + 'itemtype' => 'Glpi\\\\CustomAsset\\\\' . $type['name'] . 'Asset', 'genericobject_name' => $type['name'], 'name' => $type['name'] . 'Asset', ]; @@ -191,7 +191,7 @@ public static function installBaseData(Migration $migration, $version) $container_class = new self(); foreach ($result as $container) { self::generateTemplate($container); - foreach (json_decode($container['itemtypes']) as $itemtype) { + foreach (PluginFieldsToolbox::decodeJSONItemtypes($container['itemtypes']) as $itemtype) { $classname = self::getClassname($itemtype, $container["name"]); $old_table = $classname::getTable(); // Rename genericobject container table @@ -239,7 +239,7 @@ public static function installUserData(Migration $migration, $version) foreach ($containers as $container) { $itemtypes = []; if (!empty($container['itemtypes'])) { - $decoded = json_decode($container['itemtypes'], true); + $decoded = PluginFieldsToolbox::decodeJSONItemtypes($container['itemtypes'], true); if (is_array($decoded)) { $itemtypes = $decoded; } @@ -290,7 +290,7 @@ public static function installUserData(Migration $migration, $version) // Update container name $new_name = $toolbox->getSystemNameFromLabel($container['label']); - foreach (json_decode($container['itemtypes']) as $itemtype) { + foreach (PluginFieldsToolbox::decodeJSONItemtypes($container['itemtypes']) as $itemtype) { while (strlen(getTableForItemType(self::getClassname($itemtype, $new_name))) > 64) { // limit tables names to 64 chars (MySQL limit) $new_name = substr($new_name, 0, -1); @@ -304,7 +304,7 @@ public static function installUserData(Migration $migration, $version) ); // Rename container tables and itemtype if needed - foreach (json_decode($container['itemtypes']) as $itemtype) { + foreach (PluginFieldsToolbox::decodeJSONItemtypes($container['itemtypes']) as $itemtype) { $migration->renameItemtype( self::getClassname($itemtype, $old_name), self::getClassname($itemtype, $new_name), @@ -640,7 +640,7 @@ public function prepareInputForAdd($input) $found = $this->find(['type' => 'dom']); if (count($found) > 0) { foreach (array_column($found, 'itemtypes') as $founditemtypes) { - foreach (json_decode($founditemtypes) as $founditemtype) { + foreach (PluginFieldsToolbox::decodeJSONItemtypes($founditemtypes) as $founditemtype) { if (in_array($founditemtype, $input['itemtypes'])) { Session::AddMessageAfterRedirect(__("You cannot add several blocks with type 'Insertion in the form' on same object", 'fields'), false, ERROR); @@ -656,7 +656,7 @@ public function prepareInputForAdd($input) $found = $this->find(['type' => 'domtab', 'subtype' => $input['subtype']]); if (count($found) > 0) { foreach (array_column($found, 'itemtypes') as $founditemtypes) { - foreach (json_decode($founditemtypes) as $founditemtype) { + foreach (PluginFieldsToolbox::decodeJSONItemtypes($founditemtypes) as $founditemtype) { if (in_array($founditemtype, $input['itemtypes'])) { Session::AddMessageAfterRedirect(__("You cannot add several blocks with type 'Insertion in the form of a specific tab' on same object tab", 'fields'), false, ERROR); @@ -688,7 +688,7 @@ public function prepareInputForAdd($input) $found = $this->find(['name' => $input['name']]); if (count($found) > 0) { foreach (array_column($found, 'itemtypes') as $founditemtypes) { - foreach (json_decode($founditemtypes) as $founditemtype) { + foreach (PluginFieldsToolbox::decodeJSONItemtypes($founditemtypes) as $founditemtype) { if (in_array($founditemtype, $input['itemtypes'])) { Session::AddMessageAfterRedirect(__('You cannot add several blocs with identical name on same object', 'fields'), false, ERROR); @@ -781,7 +781,7 @@ public function pre_deleteItem() $_SESSION['delete_container'] = true; - foreach (json_decode($this->fields['itemtypes']) as $itemtype) { + foreach (PluginFieldsToolbox::decodeJSONItemtypes($this->fields['itemtypes']) as $itemtype) { $classname = self::getClassname($itemtype, $this->fields['name']); $sysname = self::getSystemName($itemtype, $this->fields['name']); $class_filename = $sysname . '.class.php'; @@ -843,7 +843,7 @@ public static function preItemPurge($item) $containers = new self(); $founded_containers = $containers->find(); foreach ($founded_containers as $container) { - $itemtypes = json_decode($container['itemtypes']); + $itemtypes = PluginFieldsToolbox::decodeJSONItemtypes($container['itemtypes']); if (in_array($itemtype, $itemtypes)) { $classname = 'PluginFields' . $itemtype . getSingular($container['name']); $classname = preg_replace('/s{2}$/i', 's', $classname); // in case name ends with 'ss' remove last 's' @@ -928,7 +928,7 @@ public function showForm($ID, $options = []) echo '' . __('Associated item type') . ' : '; echo ''; if ($ID > 0) { - $types = json_decode($this->fields['itemtypes']); + $types = PluginFieldsToolbox::decodeJSONItemtypes($this->fields['itemtypes']); $obj = ''; $count = count($types); $i = 1; @@ -969,7 +969,7 @@ public function showForm($ID, $options = []) echo ''; echo " "; if ($ID > 0 && !empty($this->fields['subtype'])) { - $itemtypes = json_decode($this->fields['itemtypes'], true); + $itemtypes = PluginFieldsToolbox::decodeJSONItemtypes($this->fields['itemtypes'], true); $itemtype = array_shift($itemtypes); $dbu = new DbUtils(); $item = $dbu->getItemForItemtype($itemtype); @@ -1234,7 +1234,7 @@ public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) foreach ($itemtypes[$item->getType()] as $tab_name => $tab_label) { // needs to check if entity of item is in hierachy of $tab_name foreach ($container->find(['is_active' => 1, 'name' => $tab_name]) as $data) { - $dataitemtypes = json_decode($data['itemtypes']); + $dataitemtypes = PluginFieldsToolbox::decodeJSONItemtypes($data['itemtypes']); if (in_array(get_class($item), $dataitemtypes) != false) { $entities = [$data['entities_id']]; if ($data['is_recursive']) { @@ -1266,7 +1266,7 @@ public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $ //retrieve container for current tab $container = new self(); if ($container->getFromDB($tabnum)) { - $dataitemtypes = json_decode($container->fields['itemtypes']); + $dataitemtypes = PluginFieldsToolbox::decodeJSONItemtypes($container->fields['itemtypes']); if (in_array(get_class($item), $dataitemtypes) != false) { return PluginFieldsField::showForTabContainer($container->fields['id'], $item); } @@ -2243,7 +2243,7 @@ public function prepareInputForClone($input) if (array_key_exists('itemtypes', $input) && !empty($input['itemtypes'])) { // $input has been transformed with `Toolbox::addslashes_deep()`, and `self::prepareInputForAdd()` // is expecting an array, so it have to be unslashed then json decoded. - $input['itemtypes'] = json_decode($input['itemtypes']); + $input['itemtypes'] = PluginFieldsToolbox::decodeJSONItemtypes($input['itemtypes']); } else { unset($input['itemtypes']); } diff --git a/inc/field.class.php b/inc/field.class.php index 95f249c2..659f2743 100644 --- a/inc/field.class.php +++ b/inc/field.class.php @@ -302,7 +302,7 @@ public function prepareInputForAdd($input) if ($input['type'] !== 'header') { $container_obj = new PluginFieldsContainer(); $container_obj->getFromDB($input['plugin_fields_containers_id']); - foreach (json_decode($container_obj->fields['itemtypes']) as $itemtype) { + foreach (PluginFieldsToolbox::decodeJSONItemtypes($container_obj->fields['itemtypes']) as $itemtype) { $classname = PluginFieldsContainer::getClassname($itemtype, $container_obj->fields['name']); $classname::addField( $input['name'], @@ -354,7 +354,7 @@ public function pre_deleteItem() $container_obj = new PluginFieldsContainer(); $container_obj->getFromDB($this->fields['plugin_fields_containers_id']); - foreach (json_decode($container_obj->fields['itemtypes']) as $itemtype) { + foreach (PluginFieldsToolbox::decodeJSONItemtypes($container_obj->fields['itemtypes']) as $itemtype) { $so = PluginFieldsContainer::getAddSearchOptions($itemtype, $this->fields['plugin_fields_containers_id']); foreach ($so as $so_id => $so_value) { if ($this->fields['type'] == 'glpi_item') { @@ -380,7 +380,7 @@ public function pre_deleteItem() && !isset($_SESSION['uninstall_fields']) && !isset($_SESSION['delete_container']) ) { - foreach (json_decode($container_obj->fields['itemtypes']) as $itemtype) { + foreach (PluginFieldsToolbox::decodeJSONItemtypes($container_obj->fields['itemtypes']) as $itemtype) { $classname = PluginFieldsContainer::getClassname($itemtype, $container_obj->fields['name']); $classname::removeField($this->fields['name'], $this->fields['type']); } @@ -400,7 +400,7 @@ public function pre_deleteItem() $use_by_another = false; foreach ($all_container as $container_fields) { - foreach (json_decode($container_fields['itemtypes']) as $itemtype) { + foreach (PluginFieldsToolbox::decodeJSONItemtypes($container_fields['itemtypes']) as $itemtype) { $dropdown_classname = PluginFieldsDropdown::getClassname($this->fields['name']); $classname = PluginFieldsContainer::getClassname($itemtype, $container_fields['name']); $dropdown_fk = getForeignKeyFieldForItemType($dropdown_classname); diff --git a/setup.php b/setup.php index 51dc8a11..6336098f 100644 --- a/setup.php +++ b/setup.php @@ -305,7 +305,7 @@ function plugin_fields_exportBlockAsYaml($container_id = null) $containers = $container_obj->find($where); foreach ($containers as $container) { $itemtypes = (strlen($container['itemtypes']) > 0) - ? json_decode($container['itemtypes'], true) + ? PluginFieldsToolbox::decodeJSONItemtypes($container['itemtypes'], true) : []; foreach ($itemtypes as $itemtype) { From 28e77f198406afb5e87c7379603ba6d074b48cd4 Mon Sep 17 00:00:00 2001 From: Stanislas Kita Date: Fri, 24 Oct 2025 10:02:08 +0200 Subject: [PATCH 2/2] adapt CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71e904df..9d208f02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +- Fix `json_decode` using class with namespace - Fix drag and drop - Increased the maximum length of the language column to support longer locale codes