diff --git a/CHANGELOG.md b/CHANGELOG.md index 277c04936e7..2c9ccd920f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -202,6 +202,8 @@ The present file will list all changes made to the project; according to the - `Glpi\Api\API::returnSanitizedContent()` - `Glpi\Dashboard\Widget::getCssGradientPalette()` - `Glpi\Inventory\Conf::importFile()` +- `Glpi\Socket::executeAddMulti()` +- `Glpi\Socket::showNetworkPortForm()` - `Glpi\System\Requirement\DataDirectoriesProtectedPath` class. - `Glpi\System\Requirement\ProtectedWebAccess` class. - `Glpi\System\Requirement\SafeDocumentRoot` class. diff --git a/front/socket.form.php b/front/socket.form.php index 23dd71cb536..23be8b618ee 100644 --- a/front/socket.form.php +++ b/front/socket.form.php @@ -161,7 +161,6 @@ } // Add a socket from item : format data - // see Socket::showNetworkPortForm() if ( isset($_REQUEST['_add_fromitem']) && isset($_REQUEST['_from_itemtype']) diff --git a/src/Dropdown.php b/src/Dropdown.php index 27762c66325..fd5690b6d84 100644 --- a/src/Dropdown.php +++ b/src/Dropdown.php @@ -36,6 +36,7 @@ use Glpi\Application\View\TemplateRenderer; use Glpi\DBAL\QueryExpression; use Glpi\DBAL\QueryFunction; +use Glpi\Features\DCBreadcrumb; use Glpi\Plugin\Hooks; use Glpi\SocketModel; @@ -367,7 +368,8 @@ public static function show($itemtype, $options = []) } if ($params['display_dc_position']) { - if ($rack = $item->isRackPart($itemtype, $params['value'], true)) { + /** @var DCBreadcrumb $item */ + if ($rack = $item->getParentRack()) { $dc_icon = ""; $dc_icon .= " "; $dc_icon .= ""; diff --git a/src/Socket.php b/src/Socket.php index e527253d179..e12d463b4b2 100644 --- a/src/Socket.php +++ b/src/Socket.php @@ -35,17 +35,14 @@ namespace Glpi; -use Ajax; use Cable; use CommonDBChild; use CommonDBTM; use CommonGLPI; -use Computer; use Dropdown; use Glpi\Application\View\TemplateRenderer; use Glpi\DBAL\QuerySubQuery; use Glpi\DBAL\QueryUnion; -use Html; use HTMLTableCell; use HTMLTableRow; use Location; @@ -80,19 +77,16 @@ public function canCreateItem() return Session::haveRight(static::$rightname, CREATE); } - public function canPurgeItem() { return Session::haveRight(static::$rightname, PURGE); } - public function isEntityAssign() { return false; } - public function defineTabs($options = []) { $ong = []; @@ -103,94 +97,11 @@ public function defineTabs($options = []) return $ong; } - - /** - * NetworkPort Form. - * - * @return void - */ - public static function showNetworkPortForm($itemtype, $items_id, $networkports_id = 0, $options = []) - { - - /** @var array $CFG_GLPI */ - global $CFG_GLPI; - - //if form is called from an item, retrieve itemtype and items - if (isset($options['_add_fromitem'])) { - $itemtype = $options['_add_fromitem']["_from_itemtype"]; - $items_id = $options['_add_fromitem']["_from_items_id"]; - } - - $rand_itemtype = rand(); - $rand_items_id = rand(); - - echo ""; - Dropdown::showFromArray('itemtype', self::getSocketLinkTypes(), ['value' => $itemtype, - 'rand' => $rand_itemtype - ]); - echo ""; - - $params = ['itemtype' => '__VALUE__', - 'dom_rand' => $rand_items_id, - 'dom_name' => 'items_id', - 'action' => 'get_items_from_itemtype' - ]; - Ajax::updateItemOnSelectEvent( - "dropdown_itemtype$rand_itemtype", - "show_items_id_field", - $CFG_GLPI["root_doc"] . "/ajax/cable.php", - $params - ); - - echo ""; - if (!empty($itemtype)) { - $rand_items_id = $itemtype::dropdown(['name' => 'items_id', - 'value' => $items_id, - 'display_emptychoice' => true, - 'display_dc_position' => in_array($itemtype, $CFG_GLPI['rackable_types']), - 'rand' => $rand_items_id - ]); - } - echo ""; - - - //Do not display NetworkPort field if several mode - if (!isset($options['several'])) { - echo ""; - NetworkPort::dropdown(['name' => 'networkports_id', - 'value' => $networkports_id, - 'display_emptychoice' => true, - 'condition' => ['items_id' => $items_id, - 'itemtype' => $itemtype - ], - 'comments' => false - ]); - echo ""; - - //Listener to update breacrumb / socket - echo Html::scriptBlock(" - //listener to remove socket selector and breadcrumb - $(document).on('change', '#dropdown_itemtype" . $rand_itemtype . "', function(e) { - $('#show_front_asset_breadcrumb').empty(); - $('#show_front_sockets_field').empty(); - }); - - //listener to refresh socket selector and breadcrumb - $(document).on('change', '#dropdown_items_id" . $rand_items_id . "', function(e) { - var items_id = $('#dropdown_items_id" . $rand_items_id . "').find(':selected').val(); - var itemtype = $('#dropdown_itemtype" . $rand_itemtype . "').find(':selected').val(); - refreshAssetBreadcrumb(itemtype, items_id, 'show_asset_breadcrumb'); - refreshNetworkPortDropdown(itemtype, items_id, 'show_networkport_field'); - }); - "); - } - } - /** * Print the version form * - * @param $ID integer ID of the item - * @param $options array + * @param integer $ID ID of the item + * @param array $options * - target for the Form * - itemtype type of the item for add process * - items_id ID of the item for add process @@ -199,30 +110,33 @@ public static function showNetworkPortForm($itemtype, $items_id, $networkports_i **/ public function showForm($ID, array $options = []) { - $itemtype = null; - if (isset($options['_add_fromitem']) && !empty($options['_add_fromitem'])) { + if (!empty($options['_add_fromitem'])) { $itemtype = $options['_add_fromitem']['_from_itemtype']; } else if (isset($this->fields['itemtype']) && !empty($this->fields['itemtype'])) { $itemtype = $this->fields['itemtype']; - } else { - throw new \RuntimeException('Unable to retrieve itemtype'); } - $item = new $itemtype(); - if ($ID > 0) { - $this->check($ID, READ); - $item->getFromDB($this->fields['items_id']); - } else { - $this->check(-1, CREATE, $options); - if (isset($options['_add_fromitem'])) { - $item->getFromDB($options['_add_fromitem']['_from_items_id']); + $items_id = null; + if ($itemtype !== null) { + if ($ID > 0) { + $this->check($ID, READ); + $items_id = $this->fields['items_id']; + } else { + $this->check(-1, CREATE, $options); + if (isset($options['_add_fromitem'])) { + $items_id = $options['_add_fromitem']['_from_items_id']; + } } } TemplateRenderer::getInstance()->display('pages/assets/socket.html.twig', [ 'item' => $this, 'params' => $options, + 'parent' => [ + 'itemtype' => $itemtype, + 'items_id' => $items_id, + ] ]); return true; } @@ -233,7 +147,6 @@ public function prepareInputForAdd($input) return $input; } - public function prepareInputForUpdate($input) { $input = $this->retrievedataFromNetworkPort($input); @@ -242,14 +155,14 @@ public function prepareInputForUpdate($input) public function retrievedataFromNetworkPort($input) { - //get position from networkport if needed + // get position from networkport if needed if ((isset($input["networkports_id"]) && $input["networkports_id"] > 0 ) && $input["position"] == 'auto') { $networkport = new NetworkPort(); $networkport->getFromDB($input["networkports_id"]); $input['position'] = $networkport->fields['logical_number']; } - //get name from networkport if needed + // get name from networkport if needed if ((isset($input["networkports_id"]) && $input["networkports_id"] > 0 ) && empty($input["name"])) { $networkport = new NetworkPort(); $networkport->getFromDB($input["networkports_id"]); @@ -259,7 +172,6 @@ public function retrievedataFromNetworkPort($input) return $input; } - /** * Get possible itemtype * @return array Array of types @@ -271,7 +183,7 @@ public static function getSocketLinkTypes() $values = []; foreach ($CFG_GLPI["socket_types"] as $itemtype) { if ($item = getItemForItemtype($itemtype)) { - $values[$itemtype] = $item->getTypeName(); + $values[$itemtype] = $item::getTypeName(); } } return $values; @@ -290,7 +202,7 @@ public static function getSocketAlreadyLinked(string $itemtype, int $items_id): $sub_query[] = new QuerySubQuery([ 'SELECT' => ['sockets.id AS socket_id'], - 'FROM' => Socket::getTable() . ' AS sockets', + 'FROM' => self::getTable() . ' AS sockets', 'LEFT JOIN' => [ Cable::getTable() . ' AS cables' => [ 'ON' => [ @@ -310,7 +222,7 @@ public static function getSocketAlreadyLinked(string $itemtype, int $items_id): $sub_query[] = new QuerySubQuery([ 'SELECT' => ['sockets.id AS socket_id'], - 'FROM' => Socket::getTable() . ' AS sockets', + 'FROM' => self::getTable() . ' AS sockets', 'LEFT JOIN' => [ Cable::getTable() . ' AS cables' => [ 'ON' => [ @@ -339,7 +251,6 @@ public static function getSocketAlreadyLinked(string $itemtype, int $items_id): return $already_use; } - /** * Dropdown of Wiring Side * @@ -365,7 +276,6 @@ public static function dropdownWiringSide($name, $options = [], bool $full = fal return Dropdown::showFromArray($name, self::getSides($full), $params); } - /** * Get sides * @return array Array of types @@ -384,14 +294,12 @@ public static function getSides(bool $full = false) return $data; } - public function post_getEmpty() { $this->fields['itemtype'] = 'Computer'; $this->fields['position'] = -1; } - /** * Get wiring side name * @@ -402,17 +310,15 @@ public function post_getEmpty() public static function getWiringSideName($value) { $tab = static::getSides(); - // Return $value if not defined - return (isset($tab[$value]) ? $tab[$value] : $value); + // Return $value if not defined + return ($tab[$value] ?? $value); } - public static function getTypeName($nb = 0) { return _n('Socket', 'Sockets', $nb); } - public function rawSearchOptions() { $tab = parent::rawSearchOptions(); @@ -480,7 +386,6 @@ public function rawSearchOptions() return $tab; } - public static function rawSearchOptionsToAdd() { $tab = []; @@ -542,7 +447,7 @@ public static function rawSearchOptionsToAdd() * @param $field * @param $name (default '') * @param $values (default '') - * @param $options array + * @param array $options array * * @return string **/ @@ -574,7 +479,7 @@ public static function getSpecificValueToSelect($field, $name = '', $values = '' * * @param $field * @param $values - * @param $options array + * @param array $options **/ public static function getSpecificValueToDisplay($field, $values, array $options = []) { @@ -601,11 +506,10 @@ public static function getSpecificValueToDisplay($field, $values, array $options return parent::getSpecificValueToDisplay($field, $values, $options); } - /** * check if a socket already exists (before import) * - * @param $input array of value to import (name, locations_id) + * @param array $input Array of values to import (name, locations_id) * * @return integer the ID of the new (or -1 if not found) **/ @@ -617,7 +521,7 @@ public function findID(array &$input) if (!empty($input["name"])) { $iterator = $DB->request([ 'SELECT' => 'id', - 'FROM' => $this->getTable(), + 'FROM' => self::getTable(), 'WHERE' => [ 'name' => $input['name'], 'locations_id' => $input["locations_id"] ?? 0 @@ -633,7 +537,6 @@ public function findID(array &$input) return -1; } - public function post_addItem() { $parent = $this->fields['locations_id']; @@ -656,24 +559,24 @@ public function cleanIfStealNetworkPort() { /** @var \DBmysql $DB */ global $DB; - //find other socket with same networkport and reset it + // find other socket with same networkport and reset it if ($this->fields['networkports_id'] > 0) { - $iter = $DB->request(['SELECT' => 'id', - 'FROM' => getTableForItemType(Socket::getType()), + $iter = $DB->request([ + 'SELECT' => 'id', + 'FROM' => getTableForItemType(self::getType()), 'WHERE' => [ 'networkports_id' => $this->fields['networkports_id'], ['NOT' => ['id' => $this->fields['id']]] ] ]); - foreach (Socket::getFromIter($iter) as $socket) { + foreach (self::getFromIter($iter) as $socket) { $socket->fields['networkports_id'] = 0; $socket->update($socket->fields); } } } - public function post_deleteFromDB() { $parent = $this->fields['locations_id']; @@ -685,7 +588,6 @@ public function post_deleteFromDB() } } - public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { /** @var array $CFG_GLPI */ @@ -719,7 +621,6 @@ public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) return ''; } - public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { /** @var array $CFG_GLPI */ @@ -732,11 +633,10 @@ public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $ return true; } - /** * Print the HTML array of the Socket associated to a Location * - * @param $item Location + * @param CommonDBTM $item * * @return void **/ @@ -747,7 +647,6 @@ public static function showListForItem($item) global $DB; $canedit = self::canUpdate(); - $rand = mt_rand(); if (!Session::haveRight(self::$rightname, READ)) { return false; @@ -756,123 +655,68 @@ public static function showListForItem($item) if ($item->isNewID($item->getID())) { return false; } + $rand = mt_rand(); // Link to open a new socket if ($item->getID() && self::canCreate()) { - echo "
"; - echo "\n
\n"; - echo "\n"; - echo "\n"; - echo "
\n"; - echo ""; - echo ""; - echo "\n"; - echo "
"; - echo "\n"; - - echo ""; - - echo "\n"; - echo __('Add several sockets'); - echo " 
\n"; - echo "
"; + $twig_params = [ + 'socket_itemtypes' => self::getSocketLinkTypes(), + '_add_fromitem' => [ + '_from_itemtype' => $item::class, + '_from_items_id' => $item->getID() + ] + ]; + TemplateRenderer::getInstance()->display('pages/assets/socket_short_form.html.twig', $twig_params); } $iterator = $DB->request([ - 'FROM' => Socket::getTable(), + 'SELECT' => 'id', + 'FROM' => self::getTable(), 'WHERE' => [ 'itemtype' => $item->getType(), 'items_id' => $item->getID(), ] ]); - $numrows = count($iterator); - - $massive_action_form_id = 'mass' . str_replace('\\', '', static::class) . $rand; - if ($canedit) { - Html::openMassiveActionsForm($massive_action_form_id); - $massiveactionparams - = ['num_displayed' - => min($_SESSION['glpilist_limit'], $numrows), - 'specific_actions' - => ['update' => _x('button', 'Update'), - 'purge' => _x('button', 'Delete permanently') - ] - ]; - - Html::showMassiveActions($massiveactionparams); - } - - echo ""; - $header_begin = ""; - $header_top = ''; - $header_bottom = ''; - $header_end = ''; - - if ($canedit) { - $header_begin .= ""; - } - $header_end .= ""; - $header_end .= ""; - $header_end .= ""; - $header_end .= ""; - $header_end .= ""; - $header_end .= ""; - $header_end .= ""; - $header_end .= ""; - $header_end .= "\n"; - echo $header_begin . $header_top . $header_end; - - Session::initNavigateListItems( - "Socket", - //TRANS: %1$s is the itemtype name, - // %2$s is the name of the item (used for headings of a list) - sprintf( - __('%1$s = %2$s'), - $item->getTypeName(1), - $item->getName() - ) - ); + $entries = []; + $socket = new Socket(); + $networkport = new NetworkPort(); + $cable = new Cable(); foreach ($iterator as $data) { - $socket = new Socket(); $socket->getFromDB($data['id']); - Session::addToNavigateListItems(get_class($socket), $socket->fields["id"]); - echo ""; - - if ($canedit) { - echo ""; - echo ""; - } else { - echo ""; - } - - echo ""; - echo ""; - echo ""; - $networkport = new NetworkPort(); + $socket_name = $canedit + ? sprintf( + '%s', + htmlspecialchars($socket->getLinkURL()), + htmlspecialchars($socket->fields['name']) + ) + : htmlspecialchars($socket->fields['name']); + $netport_name = ''; if ($networkport->getFromDB($socket->fields["networkports_id"])) { - echo ""; - } else { - echo ""; + $netport_name = sprintf( + '%s', + htmlspecialchars($networkport->getLinkURL()), + htmlspecialchars($networkport->fields['name']) + ); } - - $cable = new Cable(); - if ( - $cable->getFromDBByCrit(['OR' => ['sockets_id_endpoint_a' => $socket->fields["id"], + $has_cable = $cable->getFromDBByCrit([ + 'OR' => [ + 'sockets_id_endpoint_a' => $socket->fields["id"], 'sockets_id_endpoint_b' => $socket->fields["id"] ] - ]) - ) { - echo ""; + ]); + + $cable_name = $has_cable + ? sprintf( + '%s', + htmlspecialchars($cable->getLinkURL()), + htmlspecialchars($cable->getName()) + ) + : ''; + $itemtype = ''; + $item_id = ''; + if ($has_cable) { if ( $cable->fields['itemtype_endpoint_a'] === $item->getType() && $cable->fields['items_id_endpoint_a'] === $item->getID() @@ -883,37 +727,71 @@ public static function showListForItem($item) $itemtype = $cable->fields['itemtype_endpoint_a']; $item_id = $cable->fields['items_id_endpoint_a']; } - - $endpoint = getItemForItemtype($itemtype); - if ($endpoint !== false && $item_id !== 0 && $endpoint->getFromDB($item_id)) { - echo ""; - echo ""; - } else { - echo ""; - echo ""; - } + } + $endpoint = getItemForItemtype($itemtype); + if ($endpoint !== false && $item_id !== 0 && $endpoint->getFromDB($item_id)) { + $itemtype_label = $endpoint::getType(); + $item_label = sprintf( + '%s', + htmlspecialchars($endpoint->getLinkURL()), + htmlspecialchars($endpoint->getName()) + ); } else { - // No cable, so empty columns for Cable, Itemtype and Item Name - echo ""; + $itemtype_label = ''; + $item_label = ''; } - - echo "\n"; + $entries[] = [ + 'itemtype' => self::class, + 'id' => $socket->getID(), + 'name' => $socket_name, + 'position' => $socket->fields["position"], + 'socketmodels_id' => Dropdown::getDropdownName(SocketModel::getTable(), $socket->fields["socketmodels_id"]), + 'wiring_side' => self::getWiringSideName($socket->fields["wiring_side"]), + 'networkports_id' => $netport_name, + 'cable' => $cable_name, + 'endpoint_itemtype' => $itemtype_label, + 'endpoint_itemname' => $item_label, + ]; } - echo $header_begin . $header_bottom . $header_end; - echo "
"; - $header_top .= Html::getCheckAllAsCheckbox($massive_action_form_id); - $header_bottom .= Html::getCheckAllAsCheckbox($massive_action_form_id); - $header_end .= "" . __('Name') . "" . __('Position') . "" . SocketModel::getTypeName(0) . "" . __('Wiring side') . "" . _n('Network port', 'Network ports', Session::getPluralNumber()) . "" . Cable::getTypeName(0) . "" . __('Itemtype') . "" . __('Item Name') . "
"; - Html::showMassiveActionCheckBox(__CLASS__, $socket->fields["id"]); - echo "" . $socket->fields["name"] . "" . $socket->fields["name"] . "" . $socket->fields["position"] . "" . Dropdown::getDropdownName(SocketModel::getTable(), $socket->fields["socketmodels_id"]) . "" . self::getWiringSideName($socket->fields["wiring_side"]) . "" . $networkport->fields['name'] . "" . $cable->getName() . "" . $endpoint->getType() . "" . $endpoint->getName() . "
\n"; - if ($canedit) { - $massiveactionparams['ontop'] = false; - Html::showMassiveActions($massiveactionparams); - Html::closeForm(); - } + TemplateRenderer::getInstance()->display('components/datatable.html.twig', [ + 'is_tab' => true, + 'nofilter' => true, + 'columns' => [ + 'name' => __('Name'), + 'position' => __('Position'), + 'socketmodels_id' => SocketModel::getTypeName(1), + 'wiring_side' => __('Wiring side'), + 'networkports_id' => _n('Network port', 'Network ports', 1), + 'cable' => Cable::getTypeName(1), + 'endpoint_itemtype' => __('Itemtype'), + 'endpoint_itemname' => __('Item Name'), + ], + 'formatters' => [ + 'name' => 'raw_html', + 'networkports_id' => 'raw_html', + 'cable' => 'raw_html', + 'endpoint_itemname' => 'raw_html', + ], + 'entries' => $entries, + 'total_number' => count($entries), + 'filtered_number' => count($entries), + 'showmassiveactions' => $canedit, + 'massiveactionparams' => [ + 'num_displayed' => min($_SESSION['glpilist_limit'], count($entries)), + 'container' => 'mass' . str_replace('\\', '', __CLASS__) . $rand, + 'specific_actions' => [ + 'update' => _x('button', 'Update'), + 'purge' => _x('button', 'Delete permanently') + ] + ], + ]); } - /** * Print the HTML array of the Socket associated to a Location * - * @param $item Location + * @param Location $item * * @return void **/ @@ -923,226 +801,113 @@ public static function showForLocation($item) global $DB; $ID = $item->getField('id'); - $socket = new self(); $item->check($ID, READ); $canedit = $item->canEdit($ID); - if (isset($_GET["start"])) { - $start = intval($_GET["start"]); - } else { - $start = 0; + $start = (int)($_GET["start"] ?? 0); + $sort = $_GET["sort"] ?? ''; + $order = strtoupper($_GET["order"] ?? ''); + if ($sort === '') { + $sort = 'name'; + } + if ($order === '') { + $order = 'ASC'; } - $number = countElementsInTable('glpi_sockets', ['locations_id' => $ID ]); + $rand = mt_rand(); + $number = countElementsInTable('glpi_sockets', ['locations_id' => $ID]); + $socket_form_url = self::getFormURL(); if ($canedit) { $socket_itemtypes = array_keys(self::getSocketLinkTypes()); - echo "
"; - // Minimal form for quick input. - echo "
"; - echo "
"; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - - echo ""; - echo "\n"; - echo "
" . _n('Network socket', 'Network sockets', 1) . "" . __('Name') . ""; - echo Html::input( - 'name', - [ - 'value' => '', + $twig_params = [ + 'socket_itemtypes' => $socket_itemtypes, + '_add_fromitem' => [ + '_from_itemtype' => Location::class, + '_from_items_id' => $ID ] - ); - echo "" . SocketModel::getTypeName(1) . ""; - SocketModel::dropdown(); - echo "" . __('Wiring side') . ""; - Socket::dropdownWiringSide("wiring_side", []); - echo "" . __('Itemtype') . ""; - Dropdown::showSelectItemFromItemtypes([ - 'itemtypes' => $socket_itemtypes, - 'default_itemtype' => Computer::getType(), - 'display_emptychoice' => false, - ]); - echo ""; - echo ""; - echo ""; - echo "
\n"; - Html::closeForm(); - - // Minimal form for massive input. - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - - echo ""; - echo "\n"; - echo "
" . _n('Network socket', 'Network sockets', Session::getPluralNumber()) . "" . __('Name') . ""; - echo " "; - Dropdown::showNumber('_from', ['value' => 0, - 'min' => 0, - 'max' => 400 - ]); - echo " --> "; - Dropdown::showNumber('_to', ['value' => 0, - 'min' => 0, - 'max' => 400 - ]); - - echo " 
"; - echo "
" . SocketModel::getTypeName(1) . ""; - SocketModel::dropdown(); - echo "" . __('Wiring side') . ""; - Socket::dropdownWiringSide("wiring_side", []); - echo "" . __('Itemtype') . ""; - Dropdown::showSelectItemFromItemtypes([ - 'itemtypes' => $socket_itemtypes, - 'default_itemtype' => Computer::getType(), - 'display_emptychoice' => false, - ]); - echo ""; - echo ""; - echo ""; - echo "
\n"; - Html::closeForm(); - echo "
"; + ]; + TemplateRenderer::getInstance()->display('pages/assets/socket_short_form.html.twig', $twig_params); } - echo "
"; - - if ($number < 1) { - echo ""; - echo ""; - echo ""; - echo "
" . self::getTypeName(1) . "" . __('No item found') . "
\n"; - } else { - Html::printAjaxPager( - sprintf(__('Network sockets for %s'), $item->getTreeLink()), - $start, - $number - ); + $entries = []; - $rand = mt_rand(); - $massive_action_form_id = 'mass' . str_replace('\\', '', __CLASS__) . $rand; - if ($canedit) { - Html::openMassiveActionsForm($massive_action_form_id); - $massiveactionparams - = ['num_displayed' - => min($_SESSION['glpilist_limit'], $number), - 'container' - => $massive_action_form_id, - 'specific_actions' - => ['purge' => _x('button', 'Delete permanently')] - ]; - Html::showMassiveActions($massiveactionparams); - } - - echo ""; - - if ($canedit) { - echo ""; - } - - echo ""; // Name - echo ""; // socket Model - echo ""; // Asset - echo ""; // NetworkPort - echo ""; // Wiring side - echo ""; // Comment - echo "\n"; - - $crit = ['locations_id' => $ID, - 'ORDER' => 'name', - 'START' => $start, - 'LIMIT' => $_SESSION['glpilist_limit'] - ]; + $it = $DB->request([ + 'FROM' => self::getTable(), + 'WHERE' => [ + 'locations_id' => $ID + ], + 'ORDER' => "$sort $order", + 'START' => $start, + 'LIMIT' => $_SESSION['glpilist_limit'] + ]); + $socket_form_url = htmlspecialchars(self::getFormURL()); - Session::initNavigateListItems( - 'Socket', - //TRANS : %1$s is the itemtype name, %2$s is the name of the item (used for headings of a list) - sprintf( - __('%1$s = %2$s'), - $item->getTypeName(1), - $item->getName() - ) + foreach ($it as $data) { + $name = sprintf( + '%s', + htmlspecialchars(self::getFormURLWithID($data['id'])), + htmlspecialchars($data['name']) ); - foreach ($DB->request('glpi_sockets', $crit) as $data) { - Session::addToNavigateListItems('Socket', $data["id"]); - echo ""; - - if ($canedit) { - echo ""; + $socketmodel = new SocketModel(); + $socketmodel->getFromDB($data['socketmodels_id']); + $link = ''; + if (isset($data['itemtype']) && class_exists($data['itemtype'])) { + $itemtype = $data['itemtype']; + $asset = new $itemtype(); + if ($asset->getFromDB($data['items_id'])) { + $link = $asset->getLink(); } - echo ""; - - $socketmodel = new SocketModel(); - $socketmodel->getFromDB($data['socketmodels_id']); - echo ""; - - $link = ''; - if (isset($data['itemtype']) && class_exists($data['itemtype'])) { - $itemtype = $data['itemtype']; - $asset = new $itemtype(); - if ($asset->getFromDB($data['items_id'])) { - $link = $asset->getLink(); - } - } - echo ""; - - $networkport = new NetworkPort(); - $networkport->getFromDB($data['networkports_id']); - echo ""; - - echo ""; - echo ""; - echo "\n"; } - - echo "
"; - echo Html::getCheckAllAsCheckbox($massive_action_form_id); - echo "" . __('Name') . "" . __('Socket Model') . "" . _n('Asset', 'Assets', Session::getPluralNumber()) . "" . __('NetworkPort') . "" . __('Wiring side') . "" . __('Comments') . "
" . Html::getMassiveActionCheckBox(__CLASS__, $data["id"]) . "" . $data['name'] . "" . $socketmodel->getLink() . "" . $link . "" . $networkport->getLink() . "" . self::getSides()[$data['wiring_side']] . "" . $data['comment'] . "
\n"; - - if ($canedit) { - $massiveactionparams['ontop'] = false; - Html::showMassiveActions($massiveactionparams); - Html::closeForm(); - } - Html::printAjaxPager( - sprintf(__('Network sockets for %s'), $item->getTreeLink()), - $start, - $number - ); + $networkport = new NetworkPort(); + $networkport->getFromDB($data['networkports_id']); + + $entries[] = [ + 'itemtype' => self::class, + 'id' => $data['id'], + 'name' => $name, + 'socketmodels_id' => $socketmodel->getLink(), + 'asset' => $link, + 'networkports_id' => $networkport->getLink(), + 'wiring_side' => self::getWiringSideName($data['wiring_side']), + 'comment' => $data['comment'], + ]; } - echo "
\n"; - } - - /** - * Handled Multi add item - * - * @since 0.83 (before addMulti) - * - * @param $input array of values - **/ - public function executeAddMulti(array $input) - { - $this->check(-1, CREATE, $input); - for ($i = $input["_from"]; $i <= $input["_to"]; $i++) { - $input["name"] = $input["_before"] . $i . $input["_after"]; - $this->add($input); - } + TemplateRenderer::getInstance()->display('components/datatable.html.twig', [ + 'start' => $start, + 'sort' => $sort, + 'order' => $order, + 'is_tab' => true, + 'nofilter' => true, + 'columns' => [ + 'name' => __('Name'), + 'socketmodels_id' => SocketModel::getTypeName(1), + 'asset' => _n('Asset', 'Assets', 1), + 'networkports_id' => NetworkPort::getTypeName(1), + 'wiring_side' => __('Wiring side'), + 'comment' => __('Comments'), + ], + 'formatters' => [ + 'name' => 'raw_html', + 'socketmodels_id' => 'raw_html', + 'asset' => 'raw_html', + 'networkports_id' => 'raw_html', + ], + 'entries' => $entries, + 'total_number' => $number, + 'filtered_number' => $number, + 'showmassiveactions' => $canedit, + 'massiveactionparams' => [ + 'num_displayed' => min($_SESSION['glpilist_limit'], $number), + 'container' => 'mass' . str_replace('\\', '', __CLASS__) . $rand, + 'specific_actions' => [ + 'purge' => _x('button', 'Delete permanently') + ] + ], + ]); } - /** * @since 0.84 * diff --git a/templates/pages/assets/socket.html.twig b/templates/pages/assets/socket.html.twig index 7ecfcd12b99..8525f998b8d 100644 --- a/templates/pages/assets/socket.html.twig +++ b/templates/pages/assets/socket.html.twig @@ -36,88 +36,53 @@ {% set params = params ?? [] %} {% block more_fields %} - - + + - {{ fields.nullField() }} - {% set add_several = params['several'] is defined and params['several'] %} - - {# Do not display position if several mode, value is compute on add #} - {% if not add_several %} - {{ fields.numberField( - 'position', - item.fields['position'], - __('Position'), - field_options - ) }} - {% else %} {{ fields.nullField() }} - {% endif %} + {% set add_several = params['several'] is defined and params['several'] %} - {% set wiring_side %} - {% do call('Glpi\\Socket::dropdownWiringSide', [ - 'wiring_side', - { - 'value': item.fields['wiring_side'], - }, - add_several - ]) %} - {% endset %} - {{ fields.htmlField( - 'wiring_side', - wiring_side, - __('Wiring side'), - ) }} + {# Do not display position if several mode, value is compute on add #} + {% if not add_several %} + {{ fields.numberField('position', item.fields['position'], __('Position'), field_options) }} + {% else %} + {{ fields.nullField() }} + {% endif %} - {% set networkports %} - {% do call('Glpi\\Socket::showNetworkPortForm', [ - item.fields['itemtype'], - item.fields['items_id'], - item.fields['networkports_id'], - params - ]) %} - {% endset %} - {{ fields.htmlField( - 'networkports_id', - networkports, - _n('Network port', 'Network ports', get_plural_number()), - ) }} + {% set wiring_side %} + {% do call('Glpi\\Socket::dropdownWiringSide', [ + 'wiring_side', + { + 'value': item.fields['wiring_side'], + }, + add_several + ]) %} + {% endset %} + {{ fields.htmlField('wiring_side', wiring_side, __('Wiring side')) }} - {% if add_several %} + {% set networkports %} + {% set netport_params = params|merge({ + 'itemtype': parent['itemtype'], + 'items_id': parent['items_id'], + 'networkports_id': item.fields['networkports_id'], + }) %} + {% include 'pages/assets/socket_networkport.html.twig' with netport_params only %} + {% endset %} + {{ fields.htmlField('networkports_id', networkports, _n('Network port', 'Network ports', get_plural_number())) }} - {{ fields.dropdownNumberField( - '_from', - 1, - __('From'), - { + {% if add_several %} + {{ fields.dropdownNumberField('_from', 1, __('From'), { 'min': 1 - } - ) }} + }) }} - {{ fields.dropdownNumberField( - '_to', - 1, - __('To'), - { + {{ fields.dropdownNumberField('_to', 1, __('To'), { 'min': 1 - } - ) }} - - {{ fields.textField( - '_before', - '', - __('Prefix'), - {} - ) }} + }) }} - {{ fields.textField( - '_after', - '', - __('Suffix'), - {} - ) }} + {{ fields.textField('_before', '', __('Prefix')) }} - - {% endif %} + {{ fields.textField('_after', '', __('Suffix')) }} + + {% endif %} {% endblock %} diff --git a/templates/pages/assets/socket_networkport.html.twig b/templates/pages/assets/socket_networkport.html.twig new file mode 100644 index 00000000000..fac18716d16 --- /dev/null +++ b/templates/pages/assets/socket_networkport.html.twig @@ -0,0 +1,99 @@ +{# + # --------------------------------------------------------------------- + # + # GLPI - Gestionnaire Libre de Parc Informatique + # + # http://glpi-project.org + # + # @copyright 2015-2024 Teclib' and contributors. + # @copyright 2003-2014 by the INDEPNET Development Team. + # @licence https://www.gnu.org/licenses/gpl-3.0.html + # + # --------------------------------------------------------------------- + # + # LICENSE + # + # This file is part of GLPI. + # + # This program is free software: you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation, either version 3 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program. If not, see . + # + # --------------------------------------------------------------------- + #} + +{% import 'components/form/fields_macros.html.twig' as fields %} + +{% set rand = random() %} +{% set several = several|default(false) %} + + + {{ fields.dropdownArrayField('itemtype', itemtype, call('Glpi\\Socket::getSocketLinkTypes'), null, { + no_label: true, + rand: rand, + mb: '', + field_class: 'col-12' + }) }} + +{% do call('Ajax::updateItemOnSelectEvent', [ + 'dropdown_itemtype' ~ rand, + 'show_items_id_field', + CFG_GLPI.root_doc ~ '/ajax/cable.php', + { + itemtype: '__VALUE__', + dom_rand: rand, + dom_name: 'items_id', + action: 'get_items_from_itemtype' + } +]) %} + + {% if itemtype is not empty %} + {{ fields.dropdownField(itemtype, 'items_id', items_id, null, { + no_label: true, + display_emptychoice: true, + display_dc_position: itemtype in config('rackable_types'), + rand: rand, + mb: '', + field_class: 'col-12' + }) }} + {% endif %} + +{% if not several %} + + {{ fields.dropdownField('NetworkPort', 'networkports_id', networkports_id, null, { + no_label: true, + condition: { + items_id: items_id, + itemtype: itemtype + }, + display_emptychoice: true, + comments: false, + mb: '', + field_class: 'col-12' + }) }} + + +{% endif %} diff --git a/templates/pages/assets/socket_short_form.html.twig b/templates/pages/assets/socket_short_form.html.twig new file mode 100644 index 00000000000..19bc0ea7c2f --- /dev/null +++ b/templates/pages/assets/socket_short_form.html.twig @@ -0,0 +1,140 @@ +{# + # --------------------------------------------------------------------- + # + # GLPI - Gestionnaire Libre de Parc Informatique + # + # http://glpi-project.org + # + # @copyright 2015-2024 Teclib' and contributors. + # @copyright 2003-2014 by the INDEPNET Development Team. + # @licence https://www.gnu.org/licenses/gpl-3.0.html + # + # --------------------------------------------------------------------- + # + # LICENSE + # + # This file is part of GLPI. + # + # This program is free software: you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation, either version 3 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program. If not, see . + # + # --------------------------------------------------------------------- + #} + +{% import 'components/form/fields_macros.html.twig' as fields %} +{% import 'components/form/basic_inputs_macros.html.twig' as inputs %} + +
+ {% if _add_fromitem['_from_itemtype'] == 'Location' %} + {{ inputs.hidden('locations_id', _add_fromitem['_from_items_id']) }} + {% else %} + {{ inputs.hidden('items_id', _add_fromitem['_from_items_id']) }} + {{ inputs.hidden('itemtype', _add_fromitem['_from_itemtype']) }} + {% endif %} + {{ inputs.hidden('_glpi_csrf_token', csrf_token()) }} +
+ {{ fields.sliderField('_add_multiple', 0, __('Add several sockets')) }} + +
+
+
+ {{ fields.textField('name', '', __('Name'), { + label_class: 'col-xxl-2', + field_class: 'col-xxl-10', + full_width: true + }) }} +
+
+ {% set name_fields %} + {{ fields.textField('_before', '', null, { + no_label: true, + 'mb': '', + field_class: '', + additional_attributes: { + placeholder: __('Prefix') + } + }) }} + {{ fields.dropdownNumberField('_from', 0, null, { + no_label: true, + 'mb': '', + field_class: '', + min: 0, + max: 400 + }) }} + --> + {{ fields.dropdownNumberField('_to', 0, null, { + no_label: true, + 'mb': '', + field_class: '', + min: 0, + max: 400 + }) }} + {{ fields.textField('_after', '', null, { + no_label: true, + 'mb': '', + field_class: '', + additional_attributes: { + placeholder: __('Suffix') + } + }) }} + {% endset %} + {{ fields.htmlField('', name_fields, __('Name'), { + wrapper_class: 'd-flex', + label_class: 'col-xxl-2', + field_class: 'col-xxl-10', + full_width: true + }) }} +
+
+ {{ fields.dropdownField('Glpi\\SocketModel', 'socketmodels_id', 0, 'Glpi\\SocketModel'|itemtype_name, { + label_class: 'col-xxl-4', + }) }} + {% set wiring_side_field %} + {% do call('Glpi\\Socket::dropdownWiringSide', ['wiring_side']) %} + {% endset %} + {{ fields.htmlField('', wiring_side_field, __('Wiring side'), { + label_class: 'col-xxl-3', + }) }} + {% if _add_fromitem['_from_itemtype'] == 'Location' %} + {{ fields.dropdownItemsFromItemtypes('', __('Itemtype'), { + label_class: 'col-xxl-4', + itemtype: socket_itemtypes, + default_itemtype: 'Computer', + display_emptychoice: false + }) }} + {% else %} + {{ fields.dropdownField('Location', 'locations_id', 0, 'Location'|itemtype_name, { + label_class: 'col-xxl-4', + }) }} + {% endif %} +
+
+ {{ inputs.submit('execute_single', _x('button', 'Add'), 1) }} +
+
+
+