. * --------------------------------------------------------------------- */ if (!defined('GLPI_ROOT')) { die("Sorry. You can't access this file directly"); } /** * NetworkPort Class * * There is two parts for a given NetworkPort. * The first one, generic, only contains the link to the item, the name and the type of network port. * All specific characteristics are owned by the instanciation of the network port : NetworkPortInstantiation. * Whenever a port is display (through its form or though item port listing), the NetworkPort class * load its instantiation from the instantiation database to display the elements. * Moreover, in NetworkPort form, if there is no more than one NetworkName attached to the current * port, then, the fields of NetworkName are display. Thus, NetworkPort UI remain similar to 0.83 **/ class NetworkPort extends CommonDBChild { // From CommonDBChild static public $itemtype = 'itemtype'; static public $items_id = 'items_id'; public $dohistory = true; static public $checkParentRights = CommonDBConnexity::HAVE_SAME_RIGHT_ON_ITEM; static protected $forward_entity_to = ['NetworkName']; static $rightname = 'networking'; function getForbiddenStandardMassiveAction() { $forbidden = parent::getForbiddenStandardMassiveAction(); $forbidden[] = 'update'; return $forbidden; } /** * @since 0.84 * * @see CommonDBTM::getPreAdditionalInfosForName **/ function getPreAdditionalInfosForName() { if ($item = $this->getItem()) { return $item->getName(); } return ''; } /** * \brief get the list of available network port type. * * @since 0.84 * * @return array of available type of network ports **/ static function getNetworkPortInstantiations() { global $CFG_GLPI; return $CFG_GLPI['networkport_instantiations']; } static function getNetworkPortInstantiationsWithNames() { $types = self::getNetworkPortInstantiations(); $tab = []; foreach ($types as $itemtype) { $tab[$itemtype] = call_user_func([$itemtype, 'getTypeName']); } return $tab; } static function getTypeName($nb = 0) { return _n('Network port', 'Network ports', $nb); } /** * \brief get the instantiation of the current NetworkPort * The instantiation rely on the instantiation_type field and the id of the NetworkPort. If the * network port exists, but not its instantiation, then, the instantiation will be empty. * * @since 0.84 * * @return NetworkPortInstantiation|false the instantiation object or false if the type of instantiation is not known **/ function getInstantiation() { if (isset($this->fields['instantiation_type']) && in_array($this->fields['instantiation_type'], self::getNetworkPortInstantiations())) { if ($instantiation = getItemForItemtype($this->fields['instantiation_type'])) { if (!$instantiation->getFromDB($this->getID())) { if (!$instantiation->getEmpty()) { unset($instantiation); return false; } } return $instantiation; } } return false; } /** * Change the instantion type of a NetworkPort : check validity of the new type of * instantiation and that it is not equal to current ones. Update the NetworkPort and delete * the previous instantiation. It is up to the caller to create the new instantiation ! * * @since 0.84 * * @param string $new_instantiation_type the name of the new instaniation type * * @return boolean false on error, true if the previous instantiation is not available * (ie.: invalid instantiation type) or the object of the previous instantiation. **/ function switchInstantiationType($new_instantiation_type) { // First, check if the new instantiation is a valid one ... if (!in_array($new_instantiation_type, self::getNetworkPortInstantiations())) { return false; } // Load the previous instantiation $previousInstantiation = $this->getInstantiation(); // If the previous instantiation is the same than the new one: nothing to do ! if (($previousInstantiation !== false) && ($previousInstantiation->getType() == $new_instantiation_type)) { return $previousInstantiation; } // We update the current NetworkPort $input = $this->fields; $input['instantiation_type'] = $new_instantiation_type; $this->update($input); // Then, we delete the previous instantiation if ($previousInstantiation !== false) { $previousInstantiation->delete($previousInstantiation->fields); return $previousInstantiation; } return true; } function prepareInputForUpdate($input) { if (!isset($input["_no_history"])) { $input['_no_history'] = false; } if (isset($input['_create_children']) && $input['_create_children']) { return $this->splitInputForElements($input); } return $input; } function post_updateItem($history = 1) { global $DB; if (count($this->updates)) { // Update Ticket Tco if (in_array("itemtype", $this->updates) || in_array("items_id", $this->updates)) { $ip = new IPAddress(); // Update IPAddress foreach ($DB->request('glpi_networknames', ['itemtype' => 'NetworkPort', 'items_id' => $this->getID()]) as $dataname) { foreach ($DB->request('glpi_ipaddresses', ['itemtype' => 'NetworkName', 'items_id' => $dataname['id']]) as $data) { $ip->update(['id' => $data['id'], 'mainitemtype' => $this->fields['itemtype'], 'mainitems_id' => $this->fields['items_id']]); } } } } parent::post_updateItem($history); $this->updateDependencies(!$this->input['_no_history']); } function post_clone($source, $history) { parent::post_clone($source, $history); $instantiation = $source->getInstantiation(); if ($instantiation !== false) { $instantiation->fields[$instantiation->getIndexName()] = $this->getID(); return $instantiation->clone([], $history); } } /** * \brief split input fields when validating a port * * The form of the NetworkPort can contain the details of the NetworkPortInstantiation as well as * NetworkName elements (if no more than one name is attached to this port). Feilds from both * NetworkPortInstantiation and NetworkName must not be process by the NetworkPort::add or * NetworkPort::update. But they must be kept for adding or updating these elements. This is * done after creating or updating the current port. Otherwise, its ID may not be known (in case * of new port). * To keep the unused fields, we check each field key. If it is owned by NetworkPort (ie : * exists inside the $this->fields array), then they remain inside $input. If they are prefix by * "Networkname_", then they are added to $this->input_for_NetworkName. Else, they are for the * instantiation and added to $this->input_for_instantiation. * * This method must be call before NetworkPort::add or NetworkPort::update in case of NetworkPort * form. Otherwise, the entry of the database may contain wrong values. * * @since 0.84 * * @param $input * * @see self::updateDependencies() for the update **/ function splitInputForElements($input) { if (isset($this->input_for_instantiation) || isset($this->input_for_NetworkName) || isset($this->input_for_NetworkPortConnect) || !isset($input)) { return; } $this->input_for_instantiation = []; $this->input_for_NetworkName = []; $this->input_for_NetworkPortConnect = []; $clone = clone $this; $clone->getEmpty(); foreach ($input as $field => $value) { if (array_key_exists($field, $clone->fields) || $field[0] == '_') { continue; } if (preg_match('/^NetworkName_/', $field)) { $networkName_field = preg_replace('/^NetworkName_/', '', $field); $this->input_for_NetworkName[$networkName_field] = $value; } else if (preg_match('/^NetworkPortConnect_/', $field)) { $networkName_field = preg_replace('/^NetworkPortConnect_/', '', $field); $this->input_for_NetworkPortConnect[$networkName_field] = $value; } else { $this->input_for_instantiation[$field] = $value; } unset($input[$field]); } return $input; } /** * \brief update all related elements after adding or updating an element * * splitInputForElements() prepare the data for adding or updating NetworkPortInstantiation and * NetworkName. This method will update NetworkPortInstantiation and NetworkName. I must be call * after NetworkPort::add or NetworkPort::update otherwise, the networkport ID will not be known * and the dependencies won't have a valid items_id field. * * @since 0.84 * * @param $history (default 1) * * @see splitInputForElements() for preparing the input **/ function updateDependencies($history = true) { $instantiation = $this->getInstantiation(); if ($instantiation !== false && isset($this->input_for_instantiation) && count($this->input_for_instantiation) > 0) { $this->input_for_instantiation['networkports_id'] = $this->getID(); if ($instantiation->isNewID($instantiation->getID())) { $instantiation->add($this->input_for_instantiation, [], $history); } else { $instantiation->update($this->input_for_instantiation, $history); } } unset($this->input_for_instantiation); if (isset($this->input_for_NetworkName) && count($this->input_for_NetworkName) > 0 && !isset($_POST['several'])) { // Check to see if the NetworkName is empty $empty_networkName = empty($this->input_for_NetworkName['name']) && empty($this->input_for_NetworkName['fqdns_id']); if (($empty_networkName) && is_array($this->input_for_NetworkName['_ipaddresses'])) { foreach ($this->input_for_NetworkName['_ipaddresses'] as $ip_address) { if (!empty($ip_address)) { $empty_networkName = false; break; } } } $network_name = new NetworkName(); if (isset($this->input_for_NetworkName['id'])) { if ($empty_networkName) { // If the NetworkName is empty, then delete it ! $network_name->delete($this->input_for_NetworkName, true, $history); } else { // Else, update it $network_name->update($this->input_for_NetworkName, $history); } } else { if (!$empty_networkName) { // Only create a NetworkName if it is not empty $this->input_for_NetworkName['itemtype'] = 'NetworkPort'; $this->input_for_NetworkName['items_id'] = $this->getID(); $network_name->add($this->input_for_NetworkName, [], $history); } } } unset($this->input_for_NetworkName); if (isset($this->input_for_NetworkPortConnect) && count($this->input_for_NetworkPortConnect) > 0) { if (isset($this->input_for_NetworkPortConnect['networkports_id_1']) && isset($this->input_for_NetworkPortConnect['networkports_id_2']) && !empty($this->input_for_NetworkPortConnect['networkports_id_2'])) { $nn = new NetworkPort_NetworkPort(); $nn->add($this->input_for_NetworkPortConnect, [], $history); } } unset($this->input_for_NetworkPortConnect); } function prepareInputForAdd($input) { if (isset($input["logical_number"]) && (strlen($input["logical_number"]) == 0)) { unset($input["logical_number"]); } if (!isset($input["_no_history"])) { $input['_no_history'] = false; } if (isset($input['_create_children']) && $input['_create_children']) { $input = $this->splitInputForElements($input); } return parent::prepareInputForAdd($input); } function post_addItem() { $this->updateDependencies(!$this->input['_no_history']); } function cleanDBonPurge() { $instantiation = $this->getInstantiation(); if ($instantiation !== false) { $instantiation->cleanDBonItemDelete ($this->getType(), $this->getID()); unset($instantiation); } $this->deleteChildrenAndRelationsFromDb( [ NetworkName::class, NetworkPort_NetworkPort::class, NetworkPort_Vlan::class, ] ); } /** * Get port opposite port ID if linked item * * @param integer $ID networking port ID * * @return integer|false ID of the NetworkPort found, false if not found **/ function getContact($ID) { $wire = new NetworkPort_NetworkPort(); if ($contact_id = $wire->getOppositeContact($ID)) { return $contact_id; } return false; } function defineTabs($options = []) { $ong = []; $this->addDefaultFormTab($ong); $this->addStandardTab('NetworkName', $ong, $options); $this->addStandardTab('NetworkPort_Vlan', $ong, $options); $this->addStandardTab('Log', $ong, $options); $this->addStandardTab('NetworkPortInstantiation', $ong, $options); $this->addStandardTab('NetworkPort', $ong, $options); return $ong; } /** * Delete All connection of the given network port * * @param integer $ID ID of the port * * @return boolean true on success **/ function resetConnections($ID) { } /** * Get available display options array * * @since 0.84 * * @return array all the options **/ static function getAvailableDisplayOptions() { $options = []; $options[__('Global displays')] = ['characteristics' => ['name' => __('Characteristics'), 'default' => true], 'internet' => ['name' => __('Internet information'), 'default' => true], 'dynamic_import' => ['name' => __('Automatic inventory'), 'default' => false]]; $options[__('Common options')] = NetworkPortInstantiation::getGlobalInstantiationNetworkPortDisplayOptions(); $options[__('Internet information')] = ['names' => ['name' => NetworkName::getTypeName(Session::getPluralNumber()), 'default' => false], 'aliases' => ['name' => NetworkAlias::getTypeName(Session::getPluralNumber()), 'default' => false], 'ipaddresses' => ['name' => IPAddress::getTypeName(Session::getPluralNumber()), 'default' => true], 'ipnetworks' => ['name' => IPNetwork::getTypeName(Session::getPluralNumber()), 'default' => true]]; foreach (self::getNetworkPortInstantiations() as $portType) { $portTypeName = $portType::getTypeName(0); $options[$portTypeName] = $portType::getInstantiationNetworkPortDisplayOptions(); } return $options; } /** * Show ports for an item * * @param $item CommonDBTM object * @param $withtemplate integer withtemplate param (default 0) **/ static function showForItem(CommonDBTM $item, $withtemplate = 0) { global $DB; $rand = mt_rand(); $itemtype = $item->getType(); $items_id = $item->getField('id'); if (!NetworkEquipment::canView() || !$item->can($items_id, READ)) { return false; } $netport = new self(); $netport->item = $item; if (($itemtype == 'NetworkPort') || ($withtemplate == 2)) { $canedit = false; } else { $canedit = $item->canEdit($items_id); } $showmassiveactions = false; if ($withtemplate != 2) { $showmassiveactions = $canedit; } // Show Add Form if ($canedit && (empty($withtemplate) || ($withtemplate != 2))) { echo "\n