From 60f3aa7d498c38efffdc27bee1ea5da5ce38990e Mon Sep 17 00:00:00 2001 From: Gabriel Carneiro Date: Tue, 25 Jun 2024 16:41:01 -0300 Subject: [PATCH 1/5] =?UTF-8?q?feat(groups-users):=20espelho=20dos=20campo?= =?UTF-8?q?s=20de=20atribui=C3=A7=C3=A3o=20[actors].?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inc/field.class.php | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/inc/field.class.php b/inc/field.class.php index 4707d053..fd5e4ee2 100644 --- a/inc/field.class.php +++ b/inc/field.class.php @@ -806,6 +806,8 @@ public static function showForTabContainer($c_id, $item) echo Html::hidden('itemtype', ['value' => $item->getType()]); echo ""; echo self::prepareHtmlFields($fields, $item, $canedit); + + var_dump('810'); if ($canedit) { echo "
"; @@ -850,6 +852,7 @@ public static function showDomContainer($id, $item, $type = "dom", $subtype = "" echo Html::hidden('_plugin_fields_type', ['value' => $type]); echo Html::hidden('_plugin_fields_subtype', ['value' => $subtype]); echo self::prepareHtmlFields($fields, $item, true, true, false, $field_options); + var_dump('855'); } /** @@ -970,7 +973,7 @@ function(obj, item) { if (!(name in obj)) { obj[name] = []; } - obj[name].push(item.value); + obj[name].push(item.value); } else { obj[item.name] = item.value; } @@ -1056,6 +1059,8 @@ public static function prepareHtmlFields( $massiveaction = false, $field_options = [] ) { + /** @var DBmysql $DB */ + global $DB; if (empty($fields)) { return false; @@ -1156,6 +1161,30 @@ public static function prepareHtmlFields( ]; } else { $value = $found_v[$field['name']] ?? ""; + //Check if field is Group or User and alter actors + if($found_v['itemtype'] == 'Ticket'){ + $ticket_id = $found_v['items_id']; + if(str_starts_with($field['name'], 'groups_id')){ + $DB->update( + 'glpi_groups_tickets', [ + 'groups_id' => $value, + ], [ + 'tickets_id' => $ticket_id, + 'type' => CommonITILActor::ASSIGN + ] + ); + } elseif(str_starts_with($field['name'], 'users_id')) { + $DB->update( + 'glpi_tickets_users', [ + 'users_id' => $value, + ], [ + 'tickets_id' => $ticket_id, + 'type' => CommonITILActor::ASSIGN + ] + ); + } + } + } } @@ -1298,7 +1327,9 @@ public static function showSingle($itemtype, $searchOption, $massiveaction = fal $item = new $itemtype(); $item->getEmpty(); - echo self::prepareHtmlFields($fields, $item, true, false, $massiveaction); + echo self::prepareHtmlFields($fields, $item, true, false, $massiveaction); + var_dump('1311'); + return true; } From ff333b36298ea96b419f7ce8b8c85dab4740e90d Mon Sep 17 00:00:00 2001 From: Gabriel Carneiro Date: Tue, 25 Jun 2024 16:45:57 -0300 Subject: [PATCH 2/5] fix(dumps): remove debug dumps. --- inc/field.class.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/inc/field.class.php b/inc/field.class.php index fd5e4ee2..aed86ca1 100644 --- a/inc/field.class.php +++ b/inc/field.class.php @@ -807,8 +807,6 @@ public static function showForTabContainer($c_id, $item) echo ""; echo self::prepareHtmlFields($fields, $item, $canedit); - var_dump('810'); - if ($canedit) { echo "
"; echo " $type]); echo Html::hidden('_plugin_fields_subtype', ['value' => $subtype]); echo self::prepareHtmlFields($fields, $item, true, true, false, $field_options); - var_dump('855'); } /** @@ -1328,8 +1325,6 @@ public static function showSingle($itemtype, $searchOption, $massiveaction = fal $item->getEmpty(); echo self::prepareHtmlFields($fields, $item, true, false, $massiveaction); - var_dump('1311'); - return true; } From df3e789c9d47226aa8805696ffb6cca176701644 Mon Sep 17 00:00:00 2001 From: Gabriel Carneiro Date: Tue, 25 Jun 2024 17:16:04 -0300 Subject: [PATCH 3/5] =?UTF-8?q?chore(version):=20altera=C3=A7=C3=A3o=20da?= =?UTF-8?q?=20vers=C3=A3o=20e=20dos=20creditos.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.php b/setup.php index 74833020..92eb02ee 100644 --- a/setup.php +++ b/setup.php @@ -28,7 +28,7 @@ * ------------------------------------------------------------------------- */ -define('PLUGIN_FIELDS_VERSION', '1.21.10'); +define('PLUGIN_FIELDS_VERSION', '1.22.0'); // Minimal GLPI version, inclusive define("PLUGIN_FIELDS_MIN_GLPI", "10.0.0"); @@ -200,8 +200,8 @@ function plugin_version_fields() return [ 'name' => __("Additional fields", "fields"), 'version' => PLUGIN_FIELDS_VERSION, - 'author' => 'Teclib\', Olivier Moron', - 'homepage' => 'https://github.com/pluginsGLPI/fields', + 'author' => 'Teclib\', Olivier Moron, Gabriel Carneiro', + 'homepage' => 'https://github.com/bielcode/fields', 'license' => 'GPLv2+', 'requirements' => [ 'glpi' => [ From 43ad13850acf688eae7c244779150f4e2322e8a4 Mon Sep 17 00:00:00 2001 From: Gabriel Carneiro Date: Tue, 25 Jun 2024 20:05:43 -0300 Subject: [PATCH 4/5] =?UTF-8?q?feat(field-value):=20pegar=20valor=20do=20c?= =?UTF-8?q?ampo=20de=20atribui=C3=A7=C3=A3o=20nativo=20+=20identa=C3=A7?= =?UTF-8?q?=C3=A3o.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inc/field.class.php | 832 ++++++++++++++++++++------------------------ 1 file changed, 375 insertions(+), 457 deletions(-) diff --git a/inc/field.class.php b/inc/field.class.php index aed86ca1..c31cf9f5 100644 --- a/inc/field.class.php +++ b/inc/field.class.php @@ -44,15 +44,13 @@ class PluginFieldsField extends CommonDBChild public static $itemtype = PluginFieldsContainer::class; public static $items_id = 'plugin_fields_containers_id'; - public function getForbiddenStandardMassiveAction() { - $forbidden = parent::getForbiddenStandardMassiveAction(); + $forbidden = parent::getForbiddenStandardMassiveAction(); $forbidden[] = 'clone'; return $forbidden; } - /** * Install or update plugin base data. * @@ -73,7 +71,7 @@ public static function installBaseData(Migration $migration, $version) $table = self::getTable(); if (!$DB->tableExists($table)) { - $migration->displayMessage(sprintf(__("Installing %s"), $table)); + $migration->displayMessage(sprintf(__('Installing %s'), $table)); $query = "CREATE TABLE IF NOT EXISTS `$table` ( `id` INT {$default_key_sign} NOT NULL auto_increment, @@ -127,21 +125,9 @@ public static function installBaseData(Migration $migration, $version) $toolbox->fixFieldsNames($migration, ['NOT' => ['type' => 'dropdown']]); //move old types to new format - $migration->addPostQuery( - $DB->buildUpdate( - PluginFieldsField::getTable(), - ['type' => 'dropdown-User'], - ['type' => 'dropdownuser'] - ) - ); + $migration->addPostQuery($DB->buildUpdate(PluginFieldsField::getTable(), ['type' => 'dropdown-User'], ['type' => 'dropdownuser'])); - $migration->addPostQuery( - $DB->buildUpdate( - PluginFieldsField::getTable(), - ['type' => 'dropdown-OperatingSystem'], - ['type' => 'dropdownoperatingsystems'] - ) - ); + $migration->addPostQuery($DB->buildUpdate(PluginFieldsField::getTable(), ['type' => 'dropdown-OperatingSystem'], ['type' => 'dropdownoperatingsystems'])); // 1.18.3 Make search options ID stable over time ad constant across profiles if (Config::getConfigurationValue('plugin:fields', 'stable_search_options') !== 'yes') { @@ -186,43 +172,33 @@ private static function migrateToStableSO(Migration $migration): void // > leaving a single backslash to be matched against. $search_string = str_replace('\\', '\\\\', $search_string); - $fields = $DB->request( - [ - 'SELECT' => [ - 'glpi_plugin_fields_fields.id', - ], - 'FROM' => 'glpi_plugin_fields_fields', - 'INNER JOIN' => [ - 'glpi_plugin_fields_containers' => [ - 'FKEY' => [ - 'glpi_plugin_fields_containers' => 'id', - 'glpi_plugin_fields_fields' => 'plugin_fields_containers_id', - [ - 'AND' => [ - 'glpi_plugin_fields_containers.is_active' => 1, - ] - ] - ] + $fields = $DB->request([ + 'SELECT' => ['glpi_plugin_fields_fields.id'], + 'FROM' => 'glpi_plugin_fields_fields', + 'INNER JOIN' => [ + 'glpi_plugin_fields_containers' => [ + 'FKEY' => [ + 'glpi_plugin_fields_containers' => 'id', + 'glpi_plugin_fields_fields' => 'plugin_fields_containers_id', + [ + 'AND' => [ + 'glpi_plugin_fields_containers.is_active' => 1, + ], + ], ], ], - 'WHERE' => [ - 'glpi_plugin_fields_containers.itemtypes' => ['LIKE', '%' . $DB->escape($search_string) . '%'], - ['NOT' => ['glpi_plugin_fields_fields.type' => 'header']], - ], - 'ORDERBY' => [ - 'glpi_plugin_fields_fields.id', - ], - ] - ); + ], + 'WHERE' => [ + 'glpi_plugin_fields_containers.itemtypes' => ['LIKE', '%' . $DB->escape($search_string) . '%'], + ['NOT' => ['glpi_plugin_fields_fields.type' => 'header']], + ], + 'ORDERBY' => ['glpi_plugin_fields_fields.id'], + ]); $i = PluginFieldsField::SEARCH_OPTION_STARTING_INDEX; foreach ($fields as $field_data) { - $migration->changeSearchOption( - $itemtype, - $i, - PluginFieldsField::SEARCH_OPTION_STARTING_INDEX + $field_data['id'] - ); + $migration->changeSearchOption($itemtype, $i, PluginFieldsField::SEARCH_OPTION_STARTING_INDEX + $field_data['id']); $i++; } @@ -234,17 +210,16 @@ public static function uninstall() /** @var DBmysql $DB */ global $DB; - $DB->query("DROP TABLE IF EXISTS `" . self::getTable() . "`"); + $DB->query('DROP TABLE IF EXISTS `' . self::getTable() . '`'); return true; } public static function getTypeName($nb = 0) { - return __("Field", "fields"); + return __('Field', 'fields'); } - public function prepareInputForAdd($input) { //parse name @@ -256,22 +231,16 @@ public function prepareInputForAdd($input) //reject adding when field name is too long for mysql if (strlen($input['name']) > 64) { - Session::AddMessageAfterRedirect( - __("Field name is too long for database (digits in name are replaced by characters, try to remove them)", 'fields'), - false, - ERROR - ); + Session::AddMessageAfterRedirect(__('Field name is too long for database (digits in name are replaced by characters, try to remove them)', 'fields'), false, ERROR); return false; } - if ($input['type'] === "dropdown") { + if ($input['type'] === 'dropdown') { //search if dropdown already exist in this container - $found = $this->find( - [ - 'name' => $input['name'], - 'plugin_fields_containers_id' => $input['plugin_fields_containers_id'], - ] - ); + $found = $this->find([ + 'name' => $input['name'], + 'plugin_fields_containers_id' => $input['plugin_fields_containers_id'], + ]); //reject adding for same dropdown on same bloc if (!empty($found)) { @@ -281,33 +250,25 @@ public function prepareInputForAdd($input) //reject adding when dropdown name is too long for mysql table name if (strlen(getTableForItemType(PluginFieldsDropdown::getClassname($input['name']))) > 64) { - Session::AddMessageAfterRedirect( - __("Field name is too long for database (digits in name are replaced by characters, try to remove them)", 'fields'), - false, - ERROR - ); + Session::AddMessageAfterRedirect(__('Field name is too long for database (digits in name are replaced by characters, try to remove them)', 'fields'), false, ERROR); return false; } } // Before adding, add the ranking of the new field - if (empty($input["ranking"])) { - $input["ranking"] = $this->getNextRanking(); + if (empty($input['ranking'])) { + $input['ranking'] = $this->getNextRanking(); } //add field to container table - if ($input['type'] !== "header") { + 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) { $classname = PluginFieldsContainer::getClassname($itemtype, $container_obj->fields['name']); - $classname::addField( - $input['name'], - $input['type'], - [ - 'multiple' => (bool)($input['multiple'] ?? false) - ] - ); + $classname::addField($input['name'], $input['type'], [ + 'multiple' => (bool) ($input['multiple'] ?? false), + ]); } } @@ -318,26 +279,21 @@ public function prepareInputForAdd($input) return $input; } - public function prepareInputForUpdate($input) { - if ( - array_key_exists('default_value', $input) - && $this->fields['multiple'] - ) { + if (array_key_exists('default_value', $input) && $this->fields['multiple']) { $input['default_value'] = json_encode($input['default_value'] ?: []); } return $input; } - private function cleanDisplayPreferences($itemtype, $so_id) { $displayPref = new DisplayPreference(); $displayPref->deleteByCriteria([ - "itemtype" => $itemtype, - "num" => $so_id + 'itemtype' => $itemtype, + 'num' => $so_id, ]); } @@ -352,14 +308,11 @@ public function pre_deleteItem() $so = PluginFieldsContainer::getAddSearchOptions($itemtype, $this->fields['plugin_fields_containers_id']); foreach ($so as $so_id => $so_value) { if ($this->fields['type'] == 'glpi_item') { - if ( - $so_value['field'] == "items_id_" . $this->fields['name'] - || $so_value['field'] == "itemtype_" . $this->fields['name'] - ) { + if ($so_value['field'] == 'items_id_' . $this->fields['name'] || $so_value['field'] == 'itemtype_' . $this->fields['name']) { $this->cleanDisplayPreferences($itemtype, $so_id); } } elseif ($this->fields['type'] == 'dropdown') { - if ($so_value['linkfield'] == "plugin_fields_" . $this->fields['name'] . "dropdowns_id") { + if ($so_value['linkfield'] == 'plugin_fields_' . $this->fields['name'] . 'dropdowns_id') { $this->cleanDisplayPreferences($itemtype, $so_id); } } else { @@ -371,11 +324,7 @@ public function pre_deleteItem() } //remove field in container table - if ( - $this->fields['type'] !== "header" - && !isset($_SESSION['uninstall_fields']) - && !isset($_SESSION['delete_container']) - ) { + if ($this->fields['type'] !== 'header' && !isset($_SESSION['uninstall_fields']) && !isset($_SESSION['delete_container'])) { foreach (json_decode($container_obj->fields['itemtypes']) as $itemtype) { $classname = PluginFieldsContainer::getClassname($itemtype, $container_obj->fields['name']); $classname::removeField($this->fields['name'], $this->fields['type']); @@ -386,10 +335,10 @@ public function pre_deleteItem() $translation_obj = new PluginFieldsLabelTranslation(); $translation_obj->deleteByCriteria([ 'itemtype' => self::getType(), - 'items_id' => $this->fields['id'] + 'items_id' => $this->fields['id'], ]); - if ($this->fields['type'] === "dropdown") { + if ($this->fields['type'] === 'dropdown') { return PluginFieldsDropdown::destroy($this->fields['name']); } return true; @@ -401,25 +350,24 @@ public function post_purgeItem() /** @var DBmysql $DB */ global $DB; - $table = getTableForItemType(__CLASS__); + $table = getTableForItemType(__CLASS__); $old_container = $this->fields['plugin_fields_containers_id']; - $old_ranking = $this->fields['ranking']; + $old_ranking = $this->fields['ranking']; $DB->update( $table, [ - 'ranking' => new QueryExpression($DB->quoteName('ranking') . ' - 1') + 'ranking' => new QueryExpression($DB->quoteName('ranking') . ' - 1'), ], [ 'plugin_fields_containers_id' => $old_container, - 'ranking' => ['>', $old_ranking] - ] + 'ranking' => ['>', $old_ranking], + ], ); return true; } - /** * parse name for avoid non alphanumeric char in it and conflict with other fields * @param array $input the field form input @@ -435,7 +383,7 @@ public function prepareName($input, bool $prevent_duplicated = true) } //for dropdown, if already exists, link to it - if (isset($input['type']) && $input['type'] === "dropdown") { + if (isset($input['type']) && $input['type'] === 'dropdown') { $found = $this->find(['name' => $input['name']]); if (!empty($found)) { return $input['name']; @@ -452,7 +400,7 @@ public function prepareName($input, bool $prevent_duplicated = true) $container = new PluginFieldsContainer(); $container->getFromDB($input['plugin_fields_containers_id']); - $field = new self(); + $field = new self(); $field_name = $input['name']; if ($prevent_duplicated) { @@ -490,18 +438,16 @@ public function getNextRanking() global $DB; $iterator = $DB->request([ - 'SELECT' => new \QueryExpression( - 'max(' . $DB->quoteName('ranking') . ') AS ' . $DB->quoteName('rank') - ), - 'FROM' => self::getTable(), - 'WHERE' => [ - 'plugin_fields_containers_id' => $this->fields['plugin_fields_containers_id'] - ] + 'SELECT' => new \QueryExpression('max(' . $DB->quoteName('ranking') . ') AS ' . $DB->quoteName('rank')), + 'FROM' => self::getTable(), + 'WHERE' => [ + 'plugin_fields_containers_id' => $this->fields['plugin_fields_containers_id'], + ], ]); if (count($iterator) > 0) { $data = $iterator->current(); - return $data["rank"] + 1; + return $data['rank'] + 1; } return 0; } @@ -516,13 +462,7 @@ public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) } } - return self::createTabEntry( - __("Fields", "fields"), - countElementsInTable( - self::getTable(), - ['plugin_fields_containers_id' => $item->getID()] - ) - ); + return self::createTabEntry(__('Fields', 'fields'), countElementsInTable(self::getTable(), ['plugin_fields_containers_id' => $item->getID()])); } public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) @@ -556,49 +496,58 @@ public function showSummary($container) 'SELECT' => ['id', 'label'], 'FROM' => self::getTable(), 'WHERE' => ['plugin_fields_containers_id' => $cID], - 'ORDER' => 'ranking ASC' + 'ORDER' => 'ranking ASC', ]); - $rand = mt_rand(); + $rand = mt_rand(); echo "
"; $ajax_params = [ - 'type' => __CLASS__, - 'parenttype' => PluginFieldsContainer::class, + 'type' => __CLASS__, + 'parenttype' => PluginFieldsContainer::class, 'plugin_fields_containers_id' => $cID, - 'id' => -1 + 'id' => -1, ]; - echo Html::scriptBlock(' - viewAddField' . $cID . $rand . ' = function() { - $("#viewField' . $cID . $rand . '").load( - "' . $CFG_GLPI['root_doc'] . '/ajax/viewsubitem.php", - ' . json_encode($ajax_params) . ' + echo Html::scriptBlock( + ' + viewAddField' . + $cID . + $rand . + ' = function() { + $("#viewField' . + $cID . + $rand . + '").load( + "' . + $CFG_GLPI['root_doc'] . + '/ajax/viewsubitem.php", + ' . + json_encode($ajax_params) . + ' ); }; - '); + ', + ); - echo "
"; + echo "
'; if (count($iterator) == 0) { echo ""; - echo "
" . __("No field for this block", "fields") . "
"; + echo "
" . __('No field for this block', 'fields') . '
'; } else { echo '
'; - echo Html::hidden("_plugin_fields_containers_id", ['value' => $cID, - 'id' => 'plugin_fields_containers_id' - ]); + echo Html::hidden('_plugin_fields_containers_id', ['value' => $cID, 'id' => 'plugin_fields_containers_id']); echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ""; - echo ""; + echo ''; $fields_type = self::getTypes(); @@ -608,17 +557,14 @@ public function showSummary($container) if ($this->getFromDB($data['id'])) { echo ""; - echo ""; - echo ""; - echo "'; + echo ''; + echo '"; - echo ""; + echo ''; + echo "'; echo ""; + echo $this->isActive() ? __('Yes') : '' . __('No') . ''; + echo ''; - echo ""; + echo ''; echo ''; - echo ""; + echo ''; } } } @@ -681,7 +622,6 @@ public function showSummary($container) });'); } - public function showForm($ID, $options = []) { $rand = mt_rand(); @@ -689,10 +629,7 @@ public function showForm($ID, $options = []) $container = new PluginFieldsContainer(); if (isset($options['parent_id']) && !empty($options['parent_id'])) { $container->getFromDB($options['parent_id']); - } else if ( - isset($options['parent']) - && $options['parent'] instanceof CommonDBTM - ) { + } elseif (isset($options['parent']) && $options['parent'] instanceof CommonDBTM) { $container = $options['parent']; } @@ -709,79 +646,66 @@ public function showForm($ID, $options = []) $this->initForm($ID, $options); $this->showFormHeader($options); - echo ""; - echo ""; + echo ''; + echo ''; echo ""; + echo ''; - echo ""; - echo ""; - echo ""; + echo ''; + echo ''; + echo ''; echo ""; - echo ""; + echo ''; + echo ''; echo ''; echo ''; echo ''; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - - echo ""; - echo ""; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + echo ''; + echo ''; echo ""; - echo ""; + Dropdown::showYesNo('is_readonly', $this->fields['is_readonly']); + echo ''; + echo ''; $this->showFormButtons($options); @@ -799,22 +723,21 @@ public static function showForTabContainer($c_id, $item) //get fields for this container $field_obj = new self(); - $fields = $field_obj->find(['plugin_fields_containers_id' => $c_id, 'is_active' => 1], "ranking"); + $fields = $field_obj->find(['plugin_fields_containers_id' => $c_id, 'is_active' => 1], 'ranking'); echo ""; echo Html::hidden('plugin_fields_containers_id', ['value' => $c_id]); echo Html::hidden('items_id', ['value' => $item->getID()]); echo Html::hidden('itemtype', ['value' => $item->getType()]); echo "
" . __("Label") . "" . __("Type") . "" . __("Default values") . "" . __("Mandatory field") . "" . __("Active") . "" . __("Read only", "fields") . "
' . __('Label') . '' . __('Type') . '' . __('Default values') . '' . __('Mandatory field') . '' . __('Active') . '' . __('Read only', 'fields') . ' 
"; + echo ''; $label = !empty($this->fields['label']) ? $this->fields['label'] : NOT_AVAILABLE; echo "getID()}'>{$label}"; - echo "" . $fields_type[$this->fields['type']] . "" ; + echo '' . $fields_type[$this->fields['type']] . ''; $dropdown_matches = []; - if ( - preg_match('/^dropdown-(?.+)$/', $this->fields['type'], $dropdown_matches) === 1 - && !empty($this->fields['default_value']) - ) { + if (preg_match('/^dropdown-(?.+)$/', $this->fields['type'], $dropdown_matches) === 1 && !empty($this->fields['default_value'])) { $itemtype = $dropdown_matches['class']; // Itemtype may not exists (for instance for a deactivated plugin) if (is_a($itemtype, CommonDBTM::class, true)) { @@ -643,34 +589,29 @@ public function showSummary($container) } elseif ($this->fields['type'] === 'dropdown' && !empty($this->fields['default_value'])) { $table = getTableForItemType(PluginFieldsDropdown::getClassname($this->fields['name'])); if ($this->fields['multiple']) { - echo implode( - ', ', - Dropdown::getDropdownArrayNames($table, json_decode($this->fields['default_value'])) - ); + echo implode(', ', Dropdown::getDropdownArrayNames($table, json_decode($this->fields['default_value']))); } else { echo Dropdown::getDropdownName($table, $this->fields['default_value']); } } else { echo $this->fields['default_value']; } - echo "" . Dropdown::getYesNo($this->fields["mandatory"]) . "" . Dropdown::getYesNo($this->fields['mandatory']) . '"; - echo ($this->isActive()) - ? __('Yes') - : '' . __('No') . ''; - echo ""; - echo Dropdown::getYesNo($this->fields["is_readonly"]); - echo "'; + echo Dropdown::getYesNo($this->fields['is_readonly']); + echo ''; echo '
'; echo ''; echo '
'; echo '
" . __("Label") . " :
' . __('Label') . ' : "; echo Html::hidden('plugin_fields_containers_id', ['value' => $container->getField('id')]); echo Html::input( 'label', [ 'value' => $this->fields['label'], - ] + $attrs + ] + $attrs, ); - echo "
" . __("Type") . " :
' . __('Type') . ' : "; if ($edit) { echo self::getTypes(true)[$this->fields['type']]; } else { - Dropdown::showFromArray( - 'type', - self::getTypes(false), - [ - 'value' => $this->fields['type'], - 'rand' => $rand, - ] - ); + Dropdown::showFromArray('type', self::getTypes(false), [ + 'value' => $this->fields['type'], + 'rand' => $rand, + ]); } - echo "
'; - Ajax::updateItemOnSelectEvent( - "dropdown_type$rand", - "plugin_fields_specific_fields_$rand", - "../ajax/field_specific_fields.php", - [ - 'id' => $ID, - 'type' => '__VALUE__', - 'rand' => $rand, - ] - ); - Ajax::updateItem( - "plugin_fields_specific_fields_$rand", - "../ajax/field_specific_fields.php", - [ - 'id' => $ID, - 'type' => $this->fields['type'] ?? '', - 'rand' => $rand, - ] - ); + Ajax::updateItemOnSelectEvent("dropdown_type$rand", "plugin_fields_specific_fields_$rand", '../ajax/field_specific_fields.php', [ + 'id' => $ID, + 'type' => '__VALUE__', + 'rand' => $rand, + ]); + Ajax::updateItem("plugin_fields_specific_fields_$rand", '../ajax/field_specific_fields.php', [ + 'id' => $ID, + 'type' => $this->fields['type'] ?? '', + 'rand' => $rand, + ]); echo '
" . __('Active') . " :"; - Dropdown::showYesNo('is_active', $this->fields["is_active"]); - echo "" . __("Mandatory field") . " : "; - Dropdown::showYesNo("mandatory", $this->fields["mandatory"]); - echo "
" . __("Read only", "fields") . " :
' . __('Active') . ' :'; + Dropdown::showYesNo('is_active', $this->fields['is_active']); + echo '' . __('Mandatory field') . ' : '; + Dropdown::showYesNo('mandatory', $this->fields['mandatory']); + echo '
' . __('Read only', 'fields') . ' :"; - Dropdown::showYesNo("is_readonly", $this->fields["is_readonly"]); - echo "
"; echo self::prepareHtmlFields($fields, $item, $canedit); - + if ($canedit) { echo ""; + echo ""; + echo ''; } - echo "
"; - echo ""; - echo "
"; + echo '
'; Html::closeForm(); return true; @@ -830,9 +753,8 @@ public static function showForTabContainer($c_id, $item) * * @return void */ - public static function showDomContainer($id, $item, $type = "dom", $subtype = "", $field_options = []) + public static function showDomContainer($id, $item, $type = 'dom', $subtype = '', $field_options = []) { - if ($id !== false) { //get fields for this container $field_obj = new self(); @@ -841,7 +763,7 @@ public static function showDomContainer($id, $item, $type = "dom", $subtype = "" 'plugin_fields_containers_id' => $id, 'is_active' => 1, ], - "ranking" + 'ranking', ); } else { $fields = []; @@ -864,26 +786,20 @@ public static function showForTab($params) $item = $params['item']; $functions = array_column(debug_backtrace(), 'function'); - $subtype = isset($_SESSION['glpi_tabs'][strtolower($item::getType())]) ? $_SESSION['glpi_tabs'][strtolower($item::getType())] : ""; - $type = substr($subtype, -strlen('$main')) === '$main' - || in_array('showForm', $functions) - || in_array('showPrimaryForm', $functions) - || in_array('showFormHelpdesk', $functions) - || $item::getType() == ITILSolution::class - ? 'dom' - : 'domtab'; + $subtype = isset($_SESSION['glpi_tabs'][strtolower($item::getType())]) ? $_SESSION['glpi_tabs'][strtolower($item::getType())] : ''; + $type = substr($subtype, -strlen('$main')) === '$main' || in_array('showForm', $functions) || in_array('showPrimaryForm', $functions) || in_array('showFormHelpdesk', $functions) || $item::getType() == ITILSolution::class ? 'dom' : 'domtab'; if ($subtype == -1) { $type = 'dom'; } // if we are in 'dom' or 'tab' type, no need for subtype ('domtab' specific) if ($type != 'domtab') { - $subtype = ""; + $subtype = ''; } //find container (if not exist, do nothing) if (isset($_REQUEST['c_id'])) { $c_id = $_REQUEST['c_id']; - } else if (!$c_id = PluginFieldsContainer::findContainer(get_Class($item), $type, $subtype)) { + } elseif (!($c_id = PluginFieldsContainer::findContainer(get_Class($item), $type, $subtype))) { return false; } @@ -915,10 +831,10 @@ public static function showForTab($params) } $current_url = $_SERVER['REQUEST_URI']; if ( - strpos($current_url, ".form.php") === false - && strpos($current_url, ".injector.php") === false - && strpos($current_url, ".public.php") === false - && strpos($current_url, "ajax/timeline.php") === false // ITILSolution load from timeline + strpos($current_url, '.form.php') === false && + strpos($current_url, '.injector.php') === false && + strpos($current_url, '.public.php') === false && + strpos($current_url, 'ajax/timeline.php') === false // ITILSolution load from timeline ) { return false; } @@ -932,130 +848,119 @@ public static function showForTab($params) } $html_id = 'plugin_fields_container_' . mt_rand(); - if (strpos($current_url, "helpdesk.public.php") !== false) { + if (strpos($current_url, 'helpdesk.public.php') !== false) { echo "
"; echo "
"; $field_options = [ 'label_class' => 'col-lg-3', - 'input_class' => 'col-lg-9' + 'input_class' => 'col-lg-9', ]; } else { echo "
"; } $display_condition = new PluginFieldsContainerDisplayCondition(); if ($display_condition->computeDisplayContainer($item, $c_id)) { - self::showDomContainer( - $c_id, - $item, - $type, - $subtype, - $field_options ?? [] - ); + self::showDomContainer($c_id, $item, $type, $subtype, $field_options ?? []); } - if (strpos($current_url, "helpdesk.public.php") !== false) { - echo "
"; + if (strpos($current_url, 'helpdesk.public.php') !== false) { + echo '
'; } - echo "
"; + echo ''; //JS to trigger any change and check if container need to be display or not - $ajax_url = Plugin::getWebDir('fields') . '/ajax/container.php'; + $ajax_url = Plugin::getWebDir('fields') . '/ajax/container.php'; $items_id = !$item->isNewItem() ? $item->getID() : 0; - echo Html::scriptBlock(<< 0) { - return; // Do nothing if element is inside fields container - } - refreshContainer(); + $.ajax( + { + url: '{$ajax_url}', + type: 'GET', + data: { + action: 'get_fields_html', + id: {$c_id}, + itemtype: '{$item::getType()}', + items_id: {$items_id}, + type: '{$type}', + subtype: '{$subtype}', + input: data + }, + success: function(data) { + // Close open select2 dropdown that will be replaced + $('#{$html_id}').find('.select2-hidden-accessible').select2('close'); + // Refresh fields HTML + $('#{$html_id}').html(data); + } + } + ); } - ); - - var refresh_timeout = null; - form.find('textarea').each( - function () { - const editor = tinymce.get(this.id); - if (editor !== null) { - editor.on( + $( + function () { + const form = $('#{$html_id}').closest('form'); + form.on( 'change', + 'input, select, textarea', function(evt) { - if ($(evt.target.targetElm).closest('#{$html_id}').length > 0) { + if (evt.target.name == "itilcategories_id") { + // Do not refresh tab container when form is reloaded + // to prevent issues diues to duplicated calls + return; + } + if ($(evt.target).closest('#{$html_id}').length > 0) { return; // Do nothing if element is inside fields container } + refreshContainer(); + } + ); - if (refresh_timeout !== null) { - window.clearTimeout(refresh_timeout); + var refresh_timeout = null; + form.find('textarea').each( + function () { + const editor = tinymce.get(this.id); + if (editor !== null) { + editor.on( + 'change', + function(evt) { + if ($(evt.target.targetElm).closest('#{$html_id}').length > 0) { + return; // Do nothing if element is inside fields container + } + + if (refresh_timeout !== null) { + window.clearTimeout(refresh_timeout); + } + refresh_timeout = window.setTimeout(refreshContainer, 1000); + } + ); } - refresh_timeout = window.setTimeout(refreshContainer, 1000); } ); } - } - ); - } - ); -JAVASCRIPT + ); + JAVASCRIPT + , ); } - - public static function prepareHtmlFields( - $fields, - $item, - $canedit = true, - $show_table = true, - $massiveaction = false, - $field_options = [] - ) { + public static function prepareHtmlFields($fields, $item, $canedit = true, $show_table = true, $massiveaction = false, $field_options = []) + { /** @var DBmysql $DB */ global $DB; @@ -1093,12 +998,10 @@ public static function prepareHtmlFields( //find row for this object with the items_id $classname = PluginFieldsContainer::getClassname($item->getType(), $container_obj->fields['name']); $obj = new $classname(); - $found_values = $obj->find( - [ - 'plugin_fields_containers_id' => $first_field['plugin_fields_containers_id'], - 'items_id' => $item->getID(), - ] - ); + $found_values = $obj->find([ + 'plugin_fields_containers_id' => $first_field['plugin_fields_containers_id'], + 'items_id' => $item->getID(), + ]); $found_v = array_shift($found_values); } @@ -1114,7 +1017,7 @@ public static function prepareHtmlFields( $field['allowed_values'] = !empty($field['allowed_values']) ? json_decode($field['allowed_values']) : []; if ($field['type'] === 'glpi_item') { - // Convert allowed values to [$itemtype_class => $itemtype_name] format + // Convert allowed values to [$itemtype_class => $itemtype_name] format $allowed_itemtypes = []; foreach ($field['allowed_values'] as $allowed_itemtype) { if (is_a($allowed_itemtype, CommonDBTM::class, true)) { @@ -1126,10 +1029,7 @@ public static function prepareHtmlFields( //compute classname for 'dropdown-XXXXXX' field $dropdown_matches = []; - if ( - preg_match('/^dropdown-(?.+)$/i', $field['type'], $dropdown_matches) - && class_exists($dropdown_matches['class']) - ) { + if (preg_match('/^dropdown-(?.+)$/i', $field['type'], $dropdown_matches) && class_exists($dropdown_matches['class'])) { $dropdown_class = $dropdown_matches['class']; $field['dropdown_class'] = $dropdown_class; @@ -1147,9 +1047,9 @@ public static function prepareHtmlFields( //get value $value = null; if (is_array($found_v)) { - if ($field['type'] == "dropdown") { - $value = $found_v["plugin_fields_" . $field['name'] . "dropdowns_id"]; - } else if ($field['type'] == "glpi_item") { + if ($field['type'] == 'dropdown') { + $value = $found_v['plugin_fields_' . $field['name'] . 'dropdowns_id']; + } elseif ($field['type'] == 'glpi_item') { $itemtype_key = sprintf('itemtype_%s', $field['name']); $items_id_key = sprintf('items_id_%s', $field['name']); $value = [ @@ -1157,36 +1057,68 @@ public static function prepareHtmlFields( 'items_id' => $found_v[$items_id_key], ]; } else { - $value = $found_v[$field['name']] ?? ""; + $value = $found_v[$field['name']] ?? ''; //Check if field is Group or User and alter actors - if($found_v['itemtype'] == 'Ticket'){ - $ticket_id = $found_v['items_id']; - if(str_starts_with($field['name'], 'groups_id')){ - $DB->update( - 'glpi_groups_tickets', [ - 'groups_id' => $value, - ], [ - 'tickets_id' => $ticket_id, - 'type' => CommonITILActor::ASSIGN - ] - ); - } elseif(str_starts_with($field['name'], 'users_id')) { - $DB->update( - 'glpi_tickets_users', [ - 'users_id' => $value, - ], [ - 'tickets_id' => $ticket_id, - 'type' => CommonITILActor::ASSIGN - ] - ); - } + if ($found_v['itemtype'] == 'Ticket') { + $ticket_id = $found_v['items_id']; + + if (str_starts_with($field['name'], 'groups_id')) { + if ($value == 0) { + $groups_id_req = $DB->request([ + 'SELECT' => 'groups_id', + 'FROM' => 'glpi_groups_tickets', + 'WHERE' => [ + 'tickets_id' => $ticket_id, + 'type' => CommonITILActor::ASSIGN, + ], + ]); + if ($groups_id_row = $groups_id_req->current()) { + $value = $groups_id_row['groups_id']; + } + } else { + $DB->update( + 'glpi_groups_tickets', + [ + 'groups_id' => $value, + ], + [ + 'tickets_id' => $ticket_id, + 'type' => CommonITILActor::ASSIGN, + ], + ); + } + } elseif (str_starts_with($field['name'], 'users_id')) { + if ($value == 0) { + $users_id_req = $DB->request([ + 'SELECT' => 'users_id', + 'FROM' => 'glpi_tickets_users', + 'WHERE' => [ + 'tickets_id' => $ticket_id, + 'type' => CommonITILActor::ASSIGN, + ], + ]); + if ($users_id_row = $users_id_req->current()) { + $value = $users_id_row['users_id']; + } + } else { + $DB->update( + 'glpi_tickets_users', + [ + 'users_id' => $value, + ], + [ + 'tickets_id' => $ticket_id, + 'type' => CommonITILActor::ASSIGN, + ], + ); + } + } } - } } if (!$field['is_readonly']) { - if ($field['type'] == "dropdown") { + if ($field['type'] == 'dropdown') { $field_name = sprintf('plugin_fields_%sdropdowns_id', $field['name']); if (isset($_SESSION['plugin']['fields']['values_sent'][$field_name])) { $value = $_SESSION['plugin']['fields']['values_sent'][$field_name]; @@ -1195,15 +1127,15 @@ public static function prepareHtmlFields( $value = $item->input[$field_name]; } } elseif ($field['type'] === 'glpi_item') { - if (isset($_SESSION['plugin']['fields']['values_sent']["itemtype_" . $field['name']])) { - $value['itemtype'] = $_SESSION['plugin']['fields']['values_sent']["itemtype_" . $field['name']]; - } elseif (isset($item->input["itemtype_" . $field['name']])) { - $value['itemtype'] = $item->input["itemtype_" . $field['name']] ?? ''; + if (isset($_SESSION['plugin']['fields']['values_sent']['itemtype_' . $field['name']])) { + $value['itemtype'] = $_SESSION['plugin']['fields']['values_sent']['itemtype_' . $field['name']]; + } elseif (isset($item->input['itemtype_' . $field['name']])) { + $value['itemtype'] = $item->input['itemtype_' . $field['name']] ?? ''; } - if (isset($_SESSION['plugin']['fields']['values_sent']["items_id_" . $field['name']])) { - $value['items_id'] = $_SESSION['plugin']['fields']['values_sent']["items_id_" . $field['name']]; - } elseif (isset($item->input["items_id_" . $field['name']])) { - $value['items_id'] = $item->input["items_id_" . $field['name']] ?? ''; + if (isset($_SESSION['plugin']['fields']['values_sent']['items_id_' . $field['name']])) { + $value['items_id'] = $_SESSION['plugin']['fields']['values_sent']['items_id_' . $field['name']]; + } elseif (isset($item->input['items_id_' . $field['name']])) { + $value['items_id'] = $item->input['items_id_' . $field['name']] ?? ''; } } else { if (isset($_SESSION['plugin']['fields']['values_sent'][$field['name']])) { @@ -1219,15 +1151,12 @@ public static function prepareHtmlFields( if ($value === null) { if (in_array($field['type'], ['dropdown', 'yesno']) && $field['default_value'] === '') { $value = 0; - } else if ($field['default_value'] !== "") { + } elseif ($field['default_value'] !== '') { $value = $field['default_value']; // shortcut for date/datetime - if ( - in_array($field['type'], ['date', 'datetime']) - && $value == 'now' - ) { - $value = $_SESSION["glpi_currenttime"]; + if (in_array($field['type'], ['date', 'datetime']) && $value == 'now') { + $value = $_SESSION['glpi_currenttime']; } } } @@ -1247,12 +1176,12 @@ public static function prepareHtmlFields( } $html = TemplateRenderer::getInstance()->render('@fields/fields.html.twig', [ - 'item' => $item, - 'fields' => $fields, - 'canedit' => $canedit, - 'massiveaction' => $massiveaction, - 'container' => $container_obj, - 'field_options' => $field_options, + 'item' => $item, + 'fields' => $fields, + 'canedit' => $canedit, + 'massiveaction' => $massiveaction, + 'container' => $container_obj, + 'field_options' => $field_options, ]); unset($_SESSION['plugin']['fields']['values_sent']); @@ -1266,20 +1195,11 @@ public static function showSingle($itemtype, $searchOption, $massiveaction = fal global $DB; //clean dropdown [pre/su]fix if exists - $cleaned_linkfield = preg_replace( - "/plugin_fields_(.*)dropdowns_id/", - "$1", - $searchOption['linkfield'] - ); + $cleaned_linkfield = preg_replace('/plugin_fields_(.*)dropdowns_id/', "$1", $searchOption['linkfield']); //find field $iterator = $DB->request([ - 'SELECT' => [ - 'fields.plugin_fields_containers_id', - 'fields.is_readonly', - 'fields.multiple', - 'fields.default_value' - ], + 'SELECT' => ['fields.plugin_fields_containers_id', 'fields.is_readonly', 'fields.multiple', 'fields.default_value'], 'FROM' => self::getTable() . ' AS fields', 'LEFT JOIN' => [ 'glpi_plugin_fields_containers AS containers' => [ @@ -1288,14 +1208,14 @@ public static function showSingle($itemtype, $searchOption, $massiveaction = fal 'fields' => 'plugin_fields_containers_id', [ 'AND' => [ - 'containers.itemtypes' => ['LIKE' => "%$itemtype%"] - ] - ] - ] - ] + 'containers.itemtypes' => ['LIKE' => "%$itemtype%"], + ], + ], + ], + ], ], 'WHERE' => [ - 'fields.name' => $cleaned_linkfield + 'fields.name' => $cleaned_linkfield, ], ]); @@ -1309,22 +1229,23 @@ public static function showSingle($itemtype, $searchOption, $massiveaction = fal echo Html::hidden('c_id', ['value' => $data['plugin_fields_containers_id']]); //prepare array for function prepareHtmlFields - $fields = [[ - 'id' => 0, - 'type' => $searchOption['pfields_type'], - 'plugin_fields_containers_id' => $data['plugin_fields_containers_id'], - 'name' => $cleaned_linkfield, - 'is_readonly' => $data['is_readonly'], - 'default_value' => $data['default_value'], - 'multiple' => $data['multiple'] - ] + $fields = [ + [ + 'id' => 0, + 'type' => $searchOption['pfields_type'], + 'plugin_fields_containers_id' => $data['plugin_fields_containers_id'], + 'name' => $cleaned_linkfield, + 'is_readonly' => $data['is_readonly'], + 'default_value' => $data['default_value'], + 'multiple' => $data['multiple'], + ], ]; //show field $item = new $itemtype(); $item->getEmpty(); - echo self::prepareHtmlFields($fields, $item, true, false, $massiveaction); + echo self::prepareHtmlFields($fields, $item, true, false, $massiveaction); return true; } @@ -1333,23 +1254,23 @@ public static function showSingle($itemtype, $searchOption, $massiveaction = fal public function post_getEmpty() { $this->fields['is_active'] = 1; - $this->fields['type'] = 'text'; + $this->fields['type'] = 'text'; } public static function getTypes(bool $flat_list = true) { $common_types = [ - 'header' => __("Header", "fields"), - 'text' => __("Text (single line)", "fields"), - 'textarea' => __("Text (multiples lines)", "fields"), - 'richtext' => __("Rich Text", "fields"), - 'number' => __("Number", "fields"), - 'url' => __("URL", "fields"), - 'dropdown' => __("Dropdown", "fields"), - 'yesno' => __("Yes/No", "fields"), - 'date' => __("Date", "fields"), - 'datetime' => __("Date & time", "fields"), - 'glpi_item' => __("GLPI item", "fields"), + 'header' => __('Header', 'fields'), + 'text' => __('Text (single line)', 'fields'), + 'textarea' => __('Text (multiples lines)', 'fields'), + 'richtext' => __('Rich Text', 'fields'), + 'number' => __('Number', 'fields'), + 'url' => __('URL', 'fields'), + 'dropdown' => __('Dropdown', 'fields'), + 'yesno' => __('Yes/No', 'fields'), + 'date' => __('Date', 'fields'), + 'datetime' => __('Date & time', 'fields'), + 'glpi_item' => __('GLPI item', 'fields'), ]; $all_types = [ @@ -1372,7 +1293,7 @@ public function post_addItem() $input = $this->fields; //dropdowns : create files - if ($input['type'] === "dropdown") { + if ($input['type'] === 'dropdown') { //search if dropdown already exist in other container $found = $this->find(['id' => ['!=', $input['id']], 'name' => $input['name']]); //for dropdown, if already exist, don't create files @@ -1392,21 +1313,21 @@ public function rawSearchOptions() $tab = []; $tab[] = [ - 'id' => 2, - 'table' => self::getTable(), - 'field' => 'label', - 'name' => __('Label'), + 'id' => 2, + 'table' => self::getTable(), + 'field' => 'label', + 'name' => __('Label'), 'massiveaction' => false, - 'autocomplete' => true, + 'autocomplete' => true, ]; $tab[] = [ - 'id' => 3, - 'table' => self::getTable(), - 'field' => 'default_value', - 'name' => __('Default values'), + 'id' => 3, + 'table' => self::getTable(), + 'field' => 'default_value', + 'name' => __('Default values'), 'massiveaction' => false, - 'autocomplete' => true, + 'autocomplete' => true, ]; return $tab; @@ -1427,9 +1348,6 @@ public function prepareInputForClone($input) public function getCloneRelations(): array { - return [ - PluginFieldsStatusOverride::class, - PluginFieldsLabelTranslation::class, - ]; + return [PluginFieldsStatusOverride::class, PluginFieldsLabelTranslation::class]; } } From f40c56cc9f5003c3d13e6a4584f3413c329612cf Mon Sep 17 00:00:00 2001 From: Gabriel Carneiro Date: Tue, 25 Jun 2024 20:06:48 -0300 Subject: [PATCH 5/5] =?UTF-8?q?chore(versionamento):=20atualizacao=20vers?= =?UTF-8?q?=C3=A3o.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.php b/setup.php index 92eb02ee..eba3c035 100644 --- a/setup.php +++ b/setup.php @@ -28,7 +28,7 @@ * ------------------------------------------------------------------------- */ -define('PLUGIN_FIELDS_VERSION', '1.22.0'); +define('PLUGIN_FIELDS_VERSION', '1.23.0'); // Minimal GLPI version, inclusive define("PLUGIN_FIELDS_MIN_GLPI", "10.0.0");