diff --git a/inc/container.class.php b/inc/container.class.php index eca06ca1..abcdc780 100644 --- a/inc/container.class.php +++ b/inc/container.class.php @@ -1282,7 +1282,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') ) ) { @@ -1598,21 +1598,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'; @@ -1624,30 +1617,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 815816f1..41f48f34 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 ""; @@ -710,6 +720,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)) { @@ -808,8 +836,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"), @@ -818,11 +856,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 %}