From fdc8ecaf9d924eca6b78e561a899698abbb59f3d Mon Sep 17 00:00:00 2001 From: Stanislas Date: Fri, 29 Apr 2022 11:18:29 +0200 Subject: [PATCH] Add many new itemtype dropdown field types --- hook.php | 2 + inc/container.class.php | 51 ++++++++----------- inc/field.class.php | 91 +++++++++++++++++++++++++++++++--- inc/labeltranslation.class.php | 2 - inc/migration.class.php | 37 ++++++++------ templates/fields.html.twig | 18 ++----- 6 files changed, 134 insertions(+), 67 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 90cda1e1..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 === '' - || (in_array($field['type'], ['dropdown', 'dropdownuser', 'dropdownoperatingsystems']) && $value == 0) + || (($field['type'] === 'dropdown' || preg_match('/^dropdown-.+/i', $field['type'])) && $value == 0) || (in_array($field['type'], ['date', 'datetime']) && $value == 'NULL') ) ) { @@ -1610,56 +1610,47 @@ static function getAddSearchOptions($itemtype, $containers_id = false) { $opt[$i]['joinparams']['beforejoin']['joinparams']['jointype'] = "itemtype_item"; } - if ($data['type'] === "dropdownuser") { - $opt[$i]['table'] = 'glpi_users'; + $is_itemtype_dropdown = false; + $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']; - $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"; - } - if ($data['type'] === "dropdownoperatingsystems") { - $opt[$i]['table'] = 'glpi_operatingsystems'; - $opt[$i]['field'] = 'name'; - $opt[$i]['linkfield'] = $data['name']; - $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 ($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 $data['type'] === 'dropdown': + case $is_itemtype_dropdown: + $opt[$i]['datatype'] = "dropdown"; + break; default: $opt[$i]['datatype'] = "string"; } diff --git a/inc/field.class.php b/inc/field.class.php index bc04f7c0..f4052cf4 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,29 @@ static function install(Migration $migration, $version) { if (!$DB->fieldExists($table, 'mandatory')) { $migration->addField($table, 'mandatory', 'bool', ['value' => 0]); } - $migration->executeMigration(); + + //increase the size of column 'type' (25 to 255) + $migration->changeField($table, 'type', 'type', 'string'); $toolbox = new PluginFieldsToolbox(); $toolbox->fixFieldsNames($migration, ['NOT' => ['type' => 'dropdown']]); + //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; } @@ -459,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")." : "; @@ -728,6 +746,26 @@ 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_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; + $field['dropdown_condition'] = []; + + $object = new $dropdown_class(); + if ($object->maybeDeleted()){ + $field['dropdown_condition']['is_deleted'] = false; + } + if ($object->maybeActive()){ + $field['dropdown_condition']['is_active'] = true; + } + } + //get value $value = null; if (is_array($found_v)) { @@ -826,8 +864,10 @@ function post_getEmpty() { $this->fields['type'] = 'text'; } - static function getTypes() { - return [ + static function getTypes(bool $flat_list = true) { + global $CFG_GLPI; + + $common_types = [ 'header' => __("Header", "fields"), 'text' => __("Text (single line)", "fields"), 'textarea' => __("Text (multiples lines)", "fields"), @@ -837,10 +877,47 @@ static function getTypes() { 'yesno' => __("Yes/No", "fields"), 'date' => __("Date", "fields"), 'datetime' => __("Date & time", "fields"), - 'dropdownuser' => _n("User", "Users", 2), - 'dropdownoperatingsystems' => _n("Operating system", "Operating systems", 2), + ]; + $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) { + $model_types['dropdown-'.$model_class::getType()] = $model_class::getTypeName(Session::getPluralNumber()); + } + } + //complete Model / Type list + foreach ($CFG_GLPI['dictionnary_types'] as $class) { + if (strpos(strtolower($class), "model") !== false) { + $model_types['dropdown-'.$class::getType()] = $class::getTypeName(Session::getPluralNumber()); + } else if (strpos(strtolower($class), "type") !== false) { + $type_types['dropdown-'.$class::getType()] = $class::getTypeName(Session::getPluralNumber()); + } + } + $all_types = [ + __('Common') => $common_types, + __('Asset') => $asset_types, + __('Model') => $model_types, + __('Type') => $type_types, + __('Administration') => $administration_types, + __('Other') => $other_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 becef9b3..1a148c1d 100644 --- a/inc/migration.class.php +++ b/inc/migration.class.php @@ -78,21 +78,30 @@ function migrateCustomfieldTypes($old_type) { } static function getSQLType($field_type) { - $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', - 'dropdownuser' => "INT {$default_key_sign} NOT NULL DEFAULT 0", - 'dropdownoperatingsystems' => "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; + } - return $types[$field_type]; + return $sql_type; } } diff --git a/templates/fields.html.twig b/templates/fields.html.twig index e65496c4..bf19eda9 100644 --- a/templates/fields.html.twig +++ b/templates/fields.html.twig @@ -96,23 +96,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' %} + {% elseif type matches '/^dropdown-.+/i' %} {% if not massiveaction %} - {{ macros.dropdownField('OperatingSystem', name, value, label, field_options|merge({ - 'entity': -1, + {{ macros.dropdownField(field['dropdown_class'], name, value, label, field_options|merge({ + 'entity': field['model_class'] == 'User' ? -1 : item.getEntityID(), 'right': 'all', + 'condition': field['dropdown_condition'] })) }} {% endif %} {% endif %}