From 9415e0def9855f2ddb2d2c23291aac7d9c40c7d1 Mon Sep 17 00:00:00 2001 From: Stanislas KITA Date: Tue, 22 Mar 2022 09:52:44 +0100 Subject: [PATCH 1/3] Add model fields --- inc/container.class.php | 45 ++++++++------------- inc/field.class.php | 82 ++++++++++++++++++++++++++++++++++---- inc/migration.class.php | 36 +++++++++++++++-- inc/toolbox.class.php | 26 ++++++++++++ templates/fields.html.twig | 20 +++------- 5 files changed, 156 insertions(+), 53 deletions(-) diff --git a/inc/container.class.php b/inc/container.class.php index 90cda1e1..211c8312 100644 --- a/inc/container.class.php +++ b/inc/container.class.php @@ -1294,7 +1294,7 @@ static function validateValues($data, $itemtype, $massiveaction) { && ( $value === null || $value === '' - || (in_array($field['type'], ['dropdown', 'dropdownuser', 'dropdownoperatingsystems']) && $value == 0) + || (strpos($field['type'], 'dropdown') && $value == 0) || (in_array($field['type'], ['date', 'datetime']) && $value == 'NULL') ) ) { @@ -1610,21 +1610,14 @@ static function getAddSearchOptions($itemtype, $containers_id = false) { $opt[$i]['joinparams']['beforejoin']['joinparams']['jointype'] = "itemtype_item"; } - if ($data['type'] === "dropdownuser") { - $opt[$i]['table'] = 'glpi_users'; - $opt[$i]['field'] = 'name'; - $opt[$i]['linkfield'] = $data['name']; - $opt[$i]['right'] = 'all'; + if(strpos($data['type'], 'dropdown-') !== false && $data['type'] !== "dropdown"){ - $opt[$i]['forcegroupby'] = true; + //remove 'dropdown-' + $class = str_replace('dropdown-', '' , $data['type']); + //remove slashes added by GLPI (useful for namespaced GLPI Object ie: GLPI\SocketModel) + $class = Toolbox::stripslashes_deep($class); - $opt[$i]['joinparams']['jointype'] = ""; - $opt[$i]['joinparams']['beforejoin']['table'] = $tablename; - $opt[$i]['joinparams']['beforejoin']['joinparams']['jointype'] = "itemtype_item"; - } - - if ($data['type'] === "dropdownoperatingsystems") { - $opt[$i]['table'] = 'glpi_operatingsystems'; + $opt[$i]['table'] = CommonDBTM::getTable($class); $opt[$i]['field'] = 'name'; $opt[$i]['linkfield'] = $data['name']; $opt[$i]['right'] = 'all'; @@ -1636,30 +1629,26 @@ static function getAddSearchOptions($itemtype, $containers_id = false) { $opt[$i]['joinparams']['beforejoin']['joinparams']['jointype'] = "itemtype_item"; } - switch ($data['type']) { - case 'dropdown': - case 'dropdownuser': - $opt[$i]['datatype'] = "dropdown"; - break; - case 'dropdownoperatingsystems': - $opt[$i]['datatype'] = "dropdown"; - break; - case 'yesno': + switch (true) { + case $data['type'] === 'yesno': $opt[$i]['datatype'] = "bool"; break; - case 'textarea': + case $data['type'] === 'textarea': $opt[$i]['datatype'] = "text"; break; - case 'number': + case $data['type'] === 'number': $opt[$i]['datatype'] = "decimal"; break; - case 'date': - case 'datetime': + case $data['type'] === 'date': + case $data['type'] === 'datetime': $opt[$i]['datatype'] = $data['type']; break; - case 'url': + case $data['type'] === 'url': $opt[$i]['datatype'] = 'weblink'; break; + case strpos($data['type'], 'dropdown') !== false: + $opt[$i]['datatype'] = "dropdown"; + break; default: $opt[$i]['datatype'] = "string"; } diff --git a/inc/field.class.php b/inc/field.class.php index bc04f7c0..752687ba 100644 --- a/inc/field.class.php +++ b/inc/field.class.php @@ -65,7 +65,7 @@ static function install(Migration $migration, $version) { `id` INT {$default_key_sign} NOT NULL auto_increment, `name` VARCHAR(255) DEFAULT NULL, `label` VARCHAR(255) DEFAULT NULL, - `type` VARCHAR(25) DEFAULT NULL, + `type` VARCHAR(255) DEFAULT NULL, `plugin_fields_containers_id` INT {$default_key_sign} NOT NULL DEFAULT '0', `ranking` INT NOT NULL DEFAULT '0', `default_value` VARCHAR(255) DEFAULT NULL, @@ -93,11 +93,18 @@ static function install(Migration $migration, $version) { if (!$DB->fieldExists($table, 'mandatory')) { $migration->addField($table, 'mandatory', 'bool', ['value' => 0]); } + + //increase the size of column 'type' (25 to 255) + $migration->changeField($table, 'type', 'type', 'string'); $migration->executeMigration(); $toolbox = new PluginFieldsToolbox(); $toolbox->fixFieldsNames($migration, ['NOT' => ['type' => 'dropdown']]); + //move old type to new format + $toolbox->migrateFieldtype('dropdownusers', 'dropdown-User'); + $toolbox->migrateFieldtype('dropdownoperatingsystems', 'dropdown-OperatingSystem'); + return true; } @@ -177,6 +184,9 @@ function prepareInputForAdd($input) { $input['name'] = $oldname; } + //useful for namespaced GLPI Object (ie: glpi\SocketModel) + $input['type'] = Toolbox::addslashes_deep($input['type']); + return $input; } @@ -377,7 +387,7 @@ function showSummary($container) { echo " "; echo ""; - $fields_type = self::getTypes(); + $fields_type = self::getFieldsTypesName(); Session::initNavigateListItems('PluginFieldsField', __('Fields list')); @@ -388,7 +398,7 @@ function showSummary($container) { echo ""; echo "getID()}'>{$this->fields['label']}"; echo ""; - echo "".$fields_type[$this->fields['type']].""; + echo "".$fields_type[Toolbox::stripslashes_deep($this->fields['type'])].""; echo "".$this->fields['default_value'].""; echo "".Dropdown::getYesNo($this->fields["mandatory"]).""; echo ""; @@ -728,6 +738,24 @@ static function prepareHtmlFields($fields, $items_id, $itemtype, $canedit = true $field['itemtype'] = self::getType(); $field['label'] = PluginFieldsLabelTranslation::getLabelFor($field); + //compute classname for 'dropdown-XXXXXX' field + $dropdown_class = ''; + if (strpos($field['type'], 'dropdown-') !== false && $field['type'] != "dropdown"){ + //remove 'dropdown-' + $dropdown_class = str_replace('dropdown-', '' , $field['type']); + //remove slashes added by GLPI (useful for namespaced GLPI Object ie: GLPI\SocketModel) + $dropdown_class = Toolbox::stripslashes_deep($dropdown_class); + + $object = new $dropdown_class(); + if ($object->maybeDeleted()){ + $field['dropdown_field_options']['is_delete'] = false; + } + if ($object->maybeActive()){ + $field['dropdown_field_options']['is_active'] = true; + } + } + $field['model_class'] = $dropdown_class; + //get value $value = null; if (is_array($found_v)) { @@ -826,8 +854,18 @@ function post_getEmpty() { $this->fields['type'] = 'text'; } + static function getFieldsTypesName() { + $cleaned_array = []; + foreach (self::getTypes() as $value) { + $cleaned_array = array_merge($cleaned_array, $value); + } + return $cleaned_array; + } + static function getTypes() { - return [ + global $CFG_GLPI; + + $types = [ __('Common') => [ 'header' => __("Header", "fields"), 'text' => __("Text (single line)", "fields"), 'textarea' => __("Text (multiples lines)", "fields"), @@ -836,11 +874,39 @@ static function getTypes() { 'dropdown' => __("Dropdown", "fields"), 'yesno' => __("Yes/No", "fields"), 'date' => __("Date", "fields"), - 'datetime' => __("Date & time", "fields"), - 'dropdownuser' => _n("User", "Users", 2), - 'dropdownoperatingsystems' => _n("Operating system", "Operating systems", 2), + 'datetime' => __("Date & time", "fields") + ]]; - ]; + //get All available Model class and assets + foreach ($CFG_GLPI['state_types'] as $class) { + $itemtype = new $class(); + $model_class = $itemtype->getModelClass(); + if ($model_class != null) { + $types[__('Model')]['dropdown-'.$model_class::getType()] = $model_class::getTypeName(2); + } + $types[__('Asset')]['dropdown-'.$class::getType()] = $class::getTypeName(2); + } + + //complete Model / Type list + foreach ($CFG_GLPI['dictionnary_types'] as $class) { + if (strpos(strtolower($class), "model") !== false) { + $types[__('Model')]['dropdown-'.$class::getType()] = $class::getTypeName(2); + } else if (strpos(strtolower($class), "type") !== false) { + $types[__('Type')]['dropdown-'.$class::getType()] = $class::getTypeName(2); + } + } + + //complete Asset list + foreach ($CFG_GLPI['state_types'] as $class) { + $types[__('Asset')]['dropdown-'.$class::getType()] = $class::getTypeName(2); + } + + //other + $types[__('Administration')]['dropdown-'.User::getType()] = _n("User", "Users", 2); + $types[__('Administration')]['dropdown-'.Group::getType()] = _n("Group", "Groups", 2); + $types[__('Other')]['dropdown-'.OperatingSystem::getType()] = _n("Operating system", "Operating systems", 2); + + return $types; } function post_addItem() { diff --git a/inc/migration.class.php b/inc/migration.class.php index becef9b3..b47db167 100644 --- a/inc/migration.class.php +++ b/inc/migration.class.php @@ -78,6 +78,8 @@ function migrateCustomfieldTypes($old_type) { } static function getSQLType($field_type) { + + global $CFG_GLPI; $default_key_sign = DBConnection::getDefaultPrimaryKeySignOption(); $types = [ @@ -89,10 +91,38 @@ static function getSQLType($field_type) { 'yesno' => 'INT NOT NULL DEFAULT 0', 'date' => 'VARCHAR(255) DEFAULT NULL', 'datetime' => 'VARCHAR(255) DEFAULT NULL', - 'dropdownuser' => "INT {$default_key_sign} NOT NULL DEFAULT 0", - 'dropdownoperatingsystems' => "INT {$default_key_sign} NOT NULL DEFAULT 0", ]; - return $types[$field_type]; + + //get All available Model class and assets + foreach ($CFG_GLPI['state_types'] as $class) { + $itemtype = new $class(); + $model_class = $itemtype->getModelClass(); + if ($model_class != null) { + $types['dropdown-'.$model_class::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0";; + } + $types['dropdown-'.$class::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; + } + + //complete Model / Type list + foreach ($CFG_GLPI['dictionnary_types'] as $class) { + if (strpos(strtolower($class), "model") !== false) { + $types['dropdown-'.$class::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; + } else if (strpos(strtolower($class), "type") !== false) { + $types['dropdown-'.$class::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; + } + } + + //complete Asset list + foreach ($CFG_GLPI['state_types'] as $class) { + $types['dropdown-'.$class::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; + } + + $types['dropdown-'.User::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; + $types['dropdown-'.Group::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; + $types['dropdown-'.OperatingSystem::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; + + //remove slashes added by GLPI (useful for namespaced GLPI Object ie: GLPI\SocketModel) + return $types[Toolbox::stripslashes_deep($field_type)]; } } diff --git a/inc/toolbox.class.php b/inc/toolbox.class.php index 55f5cf57..200ce3a5 100644 --- a/inc/toolbox.class.php +++ b/inc/toolbox.class.php @@ -30,6 +30,32 @@ class PluginFieldsToolbox { + + /** + * Migration field type. + * + * @param string $old_type + * @param string $new_type + * + * @return string + */ + function migrateFieldtype($old_type, $new_type){ + global $DB; + $migration = new Migration(0); + $migration->addPostQuery( + $DB->buildUpdate( + PluginFieldsField::getTable() , + [ + 'type' => $new_type + ], + [ + 'type' => $old_type, + ] + ) + ); + $migration->executeMigration(); + } + /** * Get a clean system name from a label. * diff --git a/templates/fields.html.twig b/templates/fields.html.twig index e65496c4..5269c85b 100644 --- a/templates/fields.html.twig +++ b/templates/fields.html.twig @@ -45,6 +45,8 @@ {% set label = field['label'] %} {% set value = field['value'] %} {% set readonly = field['is_readonly'] %} + {% set model_class = field['model_class'] %} + {% set dropdown_field_options = field['dropdown_field_options'] %} {% set field_options = { 'readonly': readonly or not canedit, @@ -96,23 +98,13 @@ {{ macros.dropdownField(dropdown_itemtype, name_fk, value, label, field_options|merge({ 'entity': item.getEntityID(), })) }} - {% elseif type == 'dropdownuser' %} - {% if not massiveaction %} - {{ macros.dropdownField('User', name, value, label, field_options|merge({ - 'entity': -1, - 'right': 'all', - 'condition': { - 'is_active': 1, - 'is_deleted': 0 - } - })) }} - {% endif %} - {% elseif type == 'dropdownoperatingsystems' %} + {% else %} {% if not massiveaction %} - {{ macros.dropdownField('OperatingSystem', name, value, label, field_options|merge({ - 'entity': -1, + {{ macros.dropdownField(model_class, name, value, label, field_options|merge({ + 'entity': entities_id, 'right': 'all', + 'condition': dropdown_field_options })) }} {% endif %} {% endif %} From ffeedde758030f95d87b94e65612048509cbb908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Fri, 29 Apr 2022 10:58:36 +0200 Subject: [PATCH 2/3] Simplify and fix issues --- hook.php | 2 + inc/container.class.php | 21 ++++--- inc/field.class.php | 100 ++++++++++++++++++--------------- inc/labeltranslation.class.php | 2 - inc/migration.class.php | 65 ++++++++------------- inc/toolbox.class.php | 26 --------- templates/fields.html.twig | 10 ++-- 7 files changed, 92 insertions(+), 134 deletions(-) diff --git a/hook.php b/hook.php index ce35ddf9..e7f9e7e2 100644 --- a/hook.php +++ b/hook.php @@ -94,6 +94,8 @@ function plugin_fields_install() { } } + $migration->executeMigration(); + echo ""; echo ""; echo ""; diff --git a/inc/container.class.php b/inc/container.class.php index 211c8312..9e9d983a 100644 --- a/inc/container.class.php +++ b/inc/container.class.php @@ -1294,7 +1294,7 @@ static function validateValues($data, $itemtype, $massiveaction) { && ( $value === null || $value === '' - || (strpos($field['type'], 'dropdown') && $value == 0) + || (($field['type'] === 'dropdown' || preg_match('/^dropdown-[a-z]+/i', $field['type'])) && $value == 0) || (in_array($field['type'], ['date', 'datetime']) && $value == 'NULL') ) ) { @@ -1610,23 +1610,21 @@ static function getAddSearchOptions($itemtype, $containers_id = false) { $opt[$i]['joinparams']['beforejoin']['joinparams']['jointype'] = "itemtype_item"; } - if(strpos($data['type'], 'dropdown-') !== false && $data['type'] !== "dropdown"){ - - //remove 'dropdown-' - $class = str_replace('dropdown-', '' , $data['type']); - //remove slashes added by GLPI (useful for namespaced GLPI Object ie: GLPI\SocketModel) - $class = Toolbox::stripslashes_deep($class); - - $opt[$i]['table'] = CommonDBTM::getTable($class); + $is_itemtype_dropdown = false; + $dropdown_matches = []; + if (preg_match('/^dropdown-(?[a-z]+)/i', $data['type'], $dropdown_matches)) { + $opt[$i]['table'] = CommonDBTM::getTable($dropdown_matches['class']); $opt[$i]['field'] = 'name'; $opt[$i]['linkfield'] = $data['name']; - $opt[$i]['right'] = 'all'; + $opt[$i]['right'] = 'all'; $opt[$i]['forcegroupby'] = true; $opt[$i]['joinparams']['jointype'] = ""; $opt[$i]['joinparams']['beforejoin']['table'] = $tablename; $opt[$i]['joinparams']['beforejoin']['joinparams']['jointype'] = "itemtype_item"; + + $is_itemtype_dropdown = true; } switch (true) { @@ -1646,7 +1644,8 @@ static function getAddSearchOptions($itemtype, $containers_id = false) { case $data['type'] === 'url': $opt[$i]['datatype'] = 'weblink'; break; - case strpos($data['type'], 'dropdown') !== false: + case $data['type'] === 'dropdown': + case $is_itemtype_dropdown: $opt[$i]['datatype'] = "dropdown"; break; default: diff --git a/inc/field.class.php b/inc/field.class.php index 752687ba..0d5d88c5 100644 --- a/inc/field.class.php +++ b/inc/field.class.php @@ -96,14 +96,25 @@ static function install(Migration $migration, $version) { //increase the size of column 'type' (25 to 255) $migration->changeField($table, 'type', 'type', 'string'); - $migration->executeMigration(); $toolbox = new PluginFieldsToolbox(); $toolbox->fixFieldsNames($migration, ['NOT' => ['type' => 'dropdown']]); - //move old type to new format - $toolbox->migrateFieldtype('dropdownusers', 'dropdown-User'); - $toolbox->migrateFieldtype('dropdownoperatingsystems', 'dropdown-OperatingSystem'); + //move old types to new format + $migration->addPostQuery( + $DB->buildUpdate( + PluginFieldsField::getTable() , + ['type' => 'dropdown-User'], + ['type' => 'dropdownusers'] + ) + ); + $migration->addPostQuery( + $DB->buildUpdate( + PluginFieldsField::getTable() , + ['type' => 'dropdown-User'], + ['type' => 'dropdownusers'] + ) + ); return true; } @@ -184,9 +195,6 @@ function prepareInputForAdd($input) { $input['name'] = $oldname; } - //useful for namespaced GLPI Object (ie: glpi\SocketModel) - $input['type'] = Toolbox::addslashes_deep($input['type']); - return $input; } @@ -387,7 +395,7 @@ function showSummary($container) { echo " "; echo ""; - $fields_type = self::getFieldsTypesName(); + $fields_type = self::getTypes(); Session::initNavigateListItems('PluginFieldsField', __('Fields list')); @@ -398,7 +406,7 @@ function showSummary($container) { echo ""; echo "getID()}'>{$this->fields['label']}"; echo ""; - echo "".$fields_type[Toolbox::stripslashes_deep($this->fields['type'])].""; + echo "".$fields_type[$this->fields['type']].""; echo "".$this->fields['default_value'].""; echo "".Dropdown::getYesNo($this->fields["mandatory"]).""; echo ""; @@ -469,7 +477,7 @@ function showForm($ID, $options = []) { echo ""; echo "".__("Type")." : "; echo ""; - Dropdown::showFromArray('type', self::getTypes(), ['value' => $this->fields["type"]]); + Dropdown::showFromArray('type', self::getTypes(false), ['value' => $this->fields["type"]]); echo ""; } echo "".__("Default values")." : "; @@ -739,22 +747,21 @@ static function prepareHtmlFields($fields, $items_id, $itemtype, $canedit = true $field['label'] = PluginFieldsLabelTranslation::getLabelFor($field); //compute classname for 'dropdown-XXXXXX' field - $dropdown_class = ''; - if (strpos($field['type'], 'dropdown-') !== false && $field['type'] != "dropdown"){ - //remove 'dropdown-' - $dropdown_class = str_replace('dropdown-', '' , $field['type']); - //remove slashes added by GLPI (useful for namespaced GLPI Object ie: GLPI\SocketModel) - $dropdown_class = Toolbox::stripslashes_deep($dropdown_class); + $dropdown_matches = []; + if (preg_match('/^dropdown-(?[a-z]+)/i', $field['type'], $dropdown_matches)) { + $dropdown_class = $dropdown_matches['class']; + + $field['dropdown_class'] = $dropdown_class; + $field['dropdown_condition'] = []; $object = new $dropdown_class(); if ($object->maybeDeleted()){ - $field['dropdown_field_options']['is_delete'] = false; + $field['dropdown_condition']['is_deleted'] = false; } if ($object->maybeActive()){ - $field['dropdown_field_options']['is_active'] = true; + $field['dropdown_condition']['is_active'] = true; } } - $field['model_class'] = $dropdown_class; //get value $value = null; @@ -854,18 +861,10 @@ function post_getEmpty() { $this->fields['type'] = 'text'; } - static function getFieldsTypesName() { - $cleaned_array = []; - foreach (self::getTypes() as $value) { - $cleaned_array = array_merge($cleaned_array, $value); - } - return $cleaned_array; - } - - static function getTypes() { + static function getTypes(bool $flat_list = true) { global $CFG_GLPI; - $types = [ __('Common') => [ + $common_types = [ 'header' => __("Header", "fields"), 'text' => __("Text (single line)", "fields"), 'textarea' => __("Text (multiples lines)", "fields"), @@ -874,39 +873,48 @@ static function getTypes() { 'dropdown' => __("Dropdown", "fields"), 'yesno' => __("Yes/No", "fields"), 'date' => __("Date", "fields"), - 'datetime' => __("Date & time", "fields") - ]]; + 'datetime' => __("Date & time", "fields"), + ]; + $administration_types = [ + 'dropdown-User' => User::getTypeName(Session::getPluralNumber()), + 'dropdown-Group' => Group::getTypeName(Session::getPluralNumber()), + ]; + $other_types = [ + 'dropdown-OperatingSystem' => OperatingSystem::getTypeName(Session::getPluralNumber()), + ]; //get All available Model class and assets + $asset_types = []; + $model_types = []; + $type_types = []; foreach ($CFG_GLPI['state_types'] as $class) { + $asset_types['dropdown-'.$class::getType()] = $class::getTypeName(Session::getPluralNumber()); + $itemtype = new $class(); $model_class = $itemtype->getModelClass(); if ($model_class != null) { - $types[__('Model')]['dropdown-'.$model_class::getType()] = $model_class::getTypeName(2); + $model_types['dropdown-'.$model_class::getType()] = $model_class::getTypeName(Session::getPluralNumber()); } - $types[__('Asset')]['dropdown-'.$class::getType()] = $class::getTypeName(2); } - //complete Model / Type list foreach ($CFG_GLPI['dictionnary_types'] as $class) { if (strpos(strtolower($class), "model") !== false) { - $types[__('Model')]['dropdown-'.$class::getType()] = $class::getTypeName(2); + $model_types['dropdown-'.$class::getType()] = $class::getTypeName(Session::getPluralNumber()); } else if (strpos(strtolower($class), "type") !== false) { - $types[__('Type')]['dropdown-'.$class::getType()] = $class::getTypeName(2); + $type_types['dropdown-'.$class::getType()] = $class::getTypeName(Session::getPluralNumber()); } } - //complete Asset list - foreach ($CFG_GLPI['state_types'] as $class) { - $types[__('Asset')]['dropdown-'.$class::getType()] = $class::getTypeName(2); - } - - //other - $types[__('Administration')]['dropdown-'.User::getType()] = _n("User", "Users", 2); - $types[__('Administration')]['dropdown-'.Group::getType()] = _n("Group", "Groups", 2); - $types[__('Other')]['dropdown-'.OperatingSystem::getType()] = _n("Operating system", "Operating systems", 2); + $all_types = [ + __('Common') => $common_types, + __('Asset') => $asset_types, + __('Model') => $model_types, + __('Type') => $type_types, + __('Administration') => $administration_types, + __('Other') => $other_types, + ]; - return $types; + return $flat_list ? array_merge([], ...array_values($all_types)) : $all_types; } function post_addItem() { diff --git a/inc/labeltranslation.class.php b/inc/labeltranslation.class.php index 6949e82f..c64d4348 100644 --- a/inc/labeltranslation.class.php +++ b/inc/labeltranslation.class.php @@ -74,8 +74,6 @@ static function install(Migration $migration, $version) { $DB->query($query) or die ($DB->error()); } - $migration->displayMessage("Updating $table"); - $migration->executeMigration(); return true; } diff --git a/inc/migration.class.php b/inc/migration.class.php index b47db167..1a148c1d 100644 --- a/inc/migration.class.php +++ b/inc/migration.class.php @@ -79,50 +79,29 @@ function migrateCustomfieldTypes($old_type) { static function getSQLType($field_type) { - global $CFG_GLPI; - $default_key_sign = DBConnection::getDefaultPrimaryKeySignOption(); - - $types = [ - 'text' => 'VARCHAR(255) DEFAULT NULL', - 'url' => 'TEXT DEFAULT NULL', - 'textarea' => 'TEXT DEFAULT NULL', - 'number' => 'VARCHAR(255) DEFAULT NULL', - 'dropdown' => "INT {$default_key_sign} NOT NULL DEFAULT 0", - 'yesno' => 'INT NOT NULL DEFAULT 0', - 'date' => 'VARCHAR(255) DEFAULT NULL', - 'datetime' => 'VARCHAR(255) DEFAULT NULL', - ]; - - - //get All available Model class and assets - foreach ($CFG_GLPI['state_types'] as $class) { - $itemtype = new $class(); - $model_class = $itemtype->getModelClass(); - if ($model_class != null) { - $types['dropdown-'.$model_class::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0";; - } - $types['dropdown-'.$class::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; + $sql_type = ''; + switch (true) { + case $field_type === 'dropdown': + case preg_match('/^dropdown-[a-z]+/i', $field_type): + $default_key_sign = DBConnection::getDefaultPrimaryKeySignOption(); + $sql_type = "INT {$default_key_sign} NOT NULL DEFAULT 0"; + break; + case $field_type === 'textarea': + case $field_type === 'url': + $sql_type = 'TEXT DEFAULT NULL'; + break; + case $field_type === 'yesno': + $sql_type = 'INT NOT NULL DEFAULT 0'; + break; + case $field_type === 'date': + case $field_type === 'datetime': + case $field_type === 'number': + case $field_type === 'text': + default: + $sql_type = 'VARCHAR(255) DEFAULT NULL'; + break; } - //complete Model / Type list - foreach ($CFG_GLPI['dictionnary_types'] as $class) { - if (strpos(strtolower($class), "model") !== false) { - $types['dropdown-'.$class::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; - } else if (strpos(strtolower($class), "type") !== false) { - $types['dropdown-'.$class::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; - } - } - - //complete Asset list - foreach ($CFG_GLPI['state_types'] as $class) { - $types['dropdown-'.$class::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; - } - - $types['dropdown-'.User::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; - $types['dropdown-'.Group::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; - $types['dropdown-'.OperatingSystem::getType()] = "INT {$default_key_sign} NOT NULL DEFAULT 0"; - - //remove slashes added by GLPI (useful for namespaced GLPI Object ie: GLPI\SocketModel) - return $types[Toolbox::stripslashes_deep($field_type)]; + return $sql_type; } } diff --git a/inc/toolbox.class.php b/inc/toolbox.class.php index 200ce3a5..55f5cf57 100644 --- a/inc/toolbox.class.php +++ b/inc/toolbox.class.php @@ -30,32 +30,6 @@ class PluginFieldsToolbox { - - /** - * Migration field type. - * - * @param string $old_type - * @param string $new_type - * - * @return string - */ - function migrateFieldtype($old_type, $new_type){ - global $DB; - $migration = new Migration(0); - $migration->addPostQuery( - $DB->buildUpdate( - PluginFieldsField::getTable() , - [ - 'type' => $new_type - ], - [ - 'type' => $old_type, - ] - ) - ); - $migration->executeMigration(); - } - /** * Get a clean system name from a label. * diff --git a/templates/fields.html.twig b/templates/fields.html.twig index 5269c85b..ac3cdcb8 100644 --- a/templates/fields.html.twig +++ b/templates/fields.html.twig @@ -45,8 +45,6 @@ {% set label = field['label'] %} {% set value = field['value'] %} {% set readonly = field['is_readonly'] %} - {% set model_class = field['model_class'] %} - {% set dropdown_field_options = field['dropdown_field_options'] %} {% set field_options = { 'readonly': readonly or not canedit, @@ -99,12 +97,12 @@ 'entity': item.getEntityID(), })) }} - {% else %} + {% elseif type matches '/^dropdown-[a-z]+/i' %} {% if not massiveaction %} - {{ macros.dropdownField(model_class, name, value, label, field_options|merge({ - 'entity': entities_id, + {{ macros.dropdownField(field['dropdown_class'], name, value, label, field_options|merge({ + 'entity': field['model_class'] == 'User' ? -1 : item.getEntityID(), 'right': 'all', - 'condition': dropdown_field_options + 'condition': field['dropdown_condition'] })) }} {% endif %} {% endif %} From e23c8604fd681f652bbe594a8d2b13acd4ab33bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Fri, 29 Apr 2022 11:10:29 +0200 Subject: [PATCH 3/3] fix handling of namespaced itemtypes --- inc/container.class.php | 7 +++++-- inc/field.class.php | 5 ++++- templates/fields.html.twig | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/inc/container.class.php b/inc/container.class.php index 9e9d983a..38011a76 100644 --- a/inc/container.class.php +++ b/inc/container.class.php @@ -1294,7 +1294,7 @@ static function validateValues($data, $itemtype, $massiveaction) { && ( $value === null || $value === '' - || (($field['type'] === 'dropdown' || preg_match('/^dropdown-[a-z]+/i', $field['type'])) && $value == 0) + || (($field['type'] === 'dropdown' || preg_match('/^dropdown-.+/i', $field['type'])) && $value == 0) || (in_array($field['type'], ['date', 'datetime']) && $value == 'NULL') ) ) { @@ -1612,7 +1612,10 @@ static function getAddSearchOptions($itemtype, $containers_id = false) { $is_itemtype_dropdown = false; $dropdown_matches = []; - if (preg_match('/^dropdown-(?[a-z]+)/i', $data['type'], $dropdown_matches)) { + if ( + preg_match('/^dropdown-(?.+)$/i', $data['type'], $dropdown_matches) + && class_exists($dropdown_matches['class']) + ) { $opt[$i]['table'] = CommonDBTM::getTable($dropdown_matches['class']); $opt[$i]['field'] = 'name'; $opt[$i]['linkfield'] = $data['name']; diff --git a/inc/field.class.php b/inc/field.class.php index 0d5d88c5..f4052cf4 100644 --- a/inc/field.class.php +++ b/inc/field.class.php @@ -748,7 +748,10 @@ static function prepareHtmlFields($fields, $items_id, $itemtype, $canedit = true //compute classname for 'dropdown-XXXXXX' field $dropdown_matches = []; - if (preg_match('/^dropdown-(?[a-z]+)/i', $field['type'], $dropdown_matches)) { + if ( + preg_match('/^dropdown-(?.+)$/i', $field['type'], $dropdown_matches) + && class_exists($dropdown_matches['class']) + ) { $dropdown_class = $dropdown_matches['class']; $field['dropdown_class'] = $dropdown_class; diff --git a/templates/fields.html.twig b/templates/fields.html.twig index ac3cdcb8..bf19eda9 100644 --- a/templates/fields.html.twig +++ b/templates/fields.html.twig @@ -97,7 +97,7 @@ 'entity': item.getEntityID(), })) }} - {% elseif type matches '/^dropdown-[a-z]+/i' %} + {% elseif type matches '/^dropdown-.+/i' %} {% if not massiveaction %} {{ macros.dropdownField(field['dropdown_class'], name, value, label, field_options|merge({ 'entity': field['model_class'] == 'User' ? -1 : item.getEntityID(),