.
* ---------------------------------------------------------------------
*/
if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access this file directly");
}
/**
* Computer_Item Class
*
* Relation between Computer and Items (monitor, printer, phone, peripheral only)
**/
class Computer_Item extends CommonDBRelation{
// From CommonDBRelation
static public $itemtype_1 = 'Computer';
static public $items_id_1 = 'computers_id';
static public $itemtype_2 = 'itemtype';
static public $items_id_2 = 'items_id';
static public $checkItem_2_Rights = self::HAVE_VIEW_RIGHT_ON_ITEM;
function getForbiddenStandardMassiveAction() {
$forbidden = parent::getForbiddenStandardMassiveAction();
$forbidden[] = 'update';
return $forbidden;
}
/**
* Count connection for a Computer and an itemtype
*
* @since 0.84
*
* @param $comp Computer object
* @param $item CommonDBTM object
*
* @return integer: count
**/
static function countForAll(Computer $comp, CommonDBTM $item) {
return countElementsInTable('glpi_computers_items',
['computers_id' => $comp->getField('id'),
'itemtype' => $item->getType(),
'items_id' => $item->getField('id')]);
}
function prepareInputForAdd($input) {
global $CFG_GLPI;
$item = static::getItemFromArray(static::$itemtype_2, static::$items_id_2, $input);
if (!($item instanceof CommonDBTM)
|| (($item->getField('is_global') == 0)
&& ($this->countForItem($item) > 0))) {
return false;
}
$comp = static::getItemFromArray(static::$itemtype_1, static::$items_id_1, $input);
if (!($comp instanceof Computer)
|| (self::countForAll($comp, $item) >0)) {
// no duplicates
return false;
}
if (!$item->getField('is_global')) {
// Autoupdate some fields - should be in post_addItem (here to avoid more DB access)
$updates = [];
if ($CFG_GLPI["is_location_autoupdate"]
&& ($comp->fields['locations_id'] != $item->getField('locations_id'))) {
$updates['locations_id'] = addslashes($comp->fields['locations_id']);
Session::addMessageAfterRedirect(
__('Location updated. The connected items have been moved in the same location.'),
true);
}
if (($CFG_GLPI["is_user_autoupdate"]
&& ($comp->fields['users_id'] != $item->getField('users_id')))
|| ($CFG_GLPI["is_group_autoupdate"]
&& ($comp->fields['groups_id'] != $item->getField('groups_id')))) {
if ($CFG_GLPI["is_user_autoupdate"]) {
$updates['users_id'] = $comp->fields['users_id'];
}
if ($CFG_GLPI["is_group_autoupdate"]) {
$updates['groups_id'] = $comp->fields['groups_id'];
}
Session::addMessageAfterRedirect(
__('User or group updated. The connected items have been moved in the same values.'),
true);
}
if ($CFG_GLPI["is_contact_autoupdate"]
&& (($comp->fields['contact'] != $item->getField('contact'))
|| ($comp->fields['contact_num'] != $item->getField('contact_num')))) {
$updates['contact'] = addslashes($comp->fields['contact']);
$updates['contact_num'] = addslashes($comp->fields['contact_num']);
Session::addMessageAfterRedirect(
__('Alternate username updated. The connected items have been updated using this alternate username.'),
true);
}
if (($CFG_GLPI["state_autoupdate_mode"] < 0)
&& ($comp->fields['states_id'] != $item->getField('states_id'))) {
$updates['states_id'] = $comp->fields['states_id'];
Session::addMessageAfterRedirect(
__('Status updated. The connected items have been updated using this status.'),
true);
}
if (($CFG_GLPI["state_autoupdate_mode"] > 0)
&& ($item->getField('states_id') != $CFG_GLPI["state_autoupdate_mode"])) {
$updates['states_id'] = $CFG_GLPI["state_autoupdate_mode"];
}
if (count($updates)) {
$updates['id'] = $input['items_id'];
$history = true;
if (isset($input['_no_history']) && $input['_no_history']) {
$history = false;
}
$item->update($updates, $history);
}
}
return parent::prepareInputForAdd($input);
}
function cleanDBonPurge() {
global $CFG_GLPI;
if (!isset($this->input['_no_auto_action'])) {
//Get the computer name
$computer = new Computer();
$computer->getFromDB($this->fields['computers_id']);
//Get device fields
if ($device = getItemForItemtype($this->fields['itemtype'])) {
if ($device->getFromDB($this->fields['items_id'])) {
if (!$device->getField('is_global')) {
$updates = [];
if ($CFG_GLPI["is_location_autoclean"] && $device->isField('locations_id')) {
$updates['locations_id'] = 0;
}
if ($CFG_GLPI["is_user_autoclean"] && $device->isField('users_id')) {
$updates['users_id'] = 0;
}
if ($CFG_GLPI["is_group_autoclean"] && $device->isField('groups_id')) {
$updates['groups_id'] = 0;
}
if ($CFG_GLPI["is_contact_autoclean"] && $device->isField('contact')) {
$updates['contact'] = "";
}
if ($CFG_GLPI["is_contact_autoclean"] && $device->isField('contact_num')) {
$updates['contact_num'] = "";
}
if (($CFG_GLPI["state_autoclean_mode"] < 0)
&& $device->isField('states_id')) {
$updates['states_id'] = 0;
}
if (($CFG_GLPI["state_autoclean_mode"] > 0)
&& $device->isField('states_id')
&& ($device->getField('states_id') != $CFG_GLPI["state_autoclean_mode"])) {
$updates['states_id'] = $CFG_GLPI["state_autoclean_mode"];
}
if (count($updates)) {
$updates['id'] = $this->fields['items_id'];
$device->update($updates);
}
}
}
}
}
}
static function getMassiveActionsForItemtype(array &$actions, $itemtype, $is_deleted = 0,
CommonDBTM $checkitem = null) {
$action_prefix = __CLASS__.MassiveAction::CLASS_ACTION_SEPARATOR;
$specificities = self::getRelationMassiveActionsSpecificities();
if (in_array($itemtype, $specificities['itemtypes'])) {
$actions[$action_prefix.'add'] = "".
_x('button', 'Connect');
$actions[$action_prefix.'remove'] = _x('button', 'Disconnect');
}
parent::getMassiveActionsForItemtype($actions, $itemtype, $is_deleted, $checkitem);
}
static function getRelationMassiveActionsSpecificities() {
$specificities = parent::getRelationMassiveActionsSpecificities();
$specificities['itemtypes'] = ['Monitor', 'Peripheral', 'Phone', 'Printer'];
$specificities['select_items_options_2']['entity_restrict'] = $_SESSION['glpiactive_entity'];
$specificities['select_items_options_2']['onlyglobal'] = true;
$specificities['only_remove_all_at_once'] = true;
// Set the labels for add_item and remove_item
$specificities['button_labels']['add'] = _sx('button', 'Connect');
$specificities['button_labels']['remove'] = _sx('button', 'Disconnect');
return $specificities;
}
/**
* Disconnect an item to its computer
*
* @param $item CommonDBTM object: the Monitor/Phone/Peripheral/Printer
*
* @return boolean : action succeeded
*/
function disconnectForItem(CommonDBTM $item) {
global $DB;
if ($item->getField('id')) {
$iterator = $DB->request([
'SELECT' => ['id'],
'FROM' => $this->getTable(),
'WHERE' => [
'itemtype' => $item->getType(),
'items_id' => $item->getID()
]
]);
if (count($iterator) > 0) {
$ok = true;
while ($data = $iterator->next()) {
if ($this->can($data["id"], UPDATE)) {
$ok &= $this->delete($data);
}
}
return $ok;
}
}
return false;
}
/**
*
* Print the form for computers or templates connections to printers, screens or peripherals
*
* @param Computer $comp Computer object
* @param boolean $withtemplate Template or basic item (default 0)
*
* @return void
**/
static function showForComputer(Computer $comp, $withtemplate = 0) {
global $CFG_GLPI;
$ID = $comp->fields['id'];
$canedit = $comp->canEdit($ID);
$rand = mt_rand();
$datas = [];
$used = [];
foreach ($CFG_GLPI["directconnect_types"] as $itemtype) {
$item = new $itemtype();
if ($item->canView()) {
$iterator = self::getTypeItems($ID, $itemtype);
while ($data = $iterator->next()) {
$data['assoc_itemtype'] = $itemtype;
$datas[] = $data;
$used[$itemtype][] = $data['id'];
}
}
}
$number = count($datas);
if ($canedit
&& !(!empty($withtemplate) && ($withtemplate == 2))) {
echo "
";
}
if ($number) {
echo "";
if ($canedit) {
Html::openMassiveActionsForm('mass'.__CLASS__.$rand);
$massiveactionparams
= ['num_displayed'
=> min($_SESSION['glpilist_limit'], $number),
'specific_actions'
=> ['purge' => _x('button', 'Disconnect')],
'container'
=> 'mass'.__CLASS__.$rand];
Html::showMassiveActions($massiveactionparams);
}
echo "
";
$header_begin = "";
$header_top = '';
$header_bottom = '';
$header_end = '';
if ($canedit) {
$header_top .= "| ".Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
$header_top .= " | ";
$header_bottom .= "".Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
$header_bottom .= " | ";
}
$header_end .= ""._n('Type', 'Types', 1)." | ";
$header_end .= "".__('Name')." | ";
if (Plugin::haveImport()) {
$header_end .= "".__('Automatic inventory')." | ";
}
$header_end .= "".Entity::getTypeName(1)." | ";
$header_end .= "".__('Serial number')." | ";
$header_end .= "".__('Inventory number')." | ";
$header_end .= "
";
echo $header_begin.$header_top.$header_end;
foreach ($datas as $data) {
$linkname = $data["name"];
$itemtype = $data['assoc_itemtype'];
if ($_SESSION["glpiis_ids_visible"] || empty($data["name"])) {
$linkname = sprintf(__('%1$s (%2$s)'), $linkname, $data["id"]);
}
$link = $itemtype::getFormURLWithID($data["id"]);
$name = "".$linkname."";
echo "";
if ($canedit) {
echo "| ";
Html::showMassiveActionCheckBox(__CLASS__, $data["linkid"]);
echo " | ";
}
echo "".$data['assoc_itemtype']::getTypeName(1)." | ";
echo "".$name." | ";
if (Plugin::haveImport()) {
echo "".Dropdown::getYesNo($data['is_dynamic'])." | ";
}
echo "".Dropdown::getDropdownName("glpi_entities",
$data['entities_id']);
echo " | ";
echo "".
(isset($data["serial"])? "".$data["serial"]."" :"-")." | ";
echo "".
(isset($data["otherserial"])? "".$data["otherserial"]."" :"-")." | ";
echo "
";
}
echo $header_begin.$header_bottom.$header_end;
echo "
";
if ($canedit && $number) {
$massiveactionparams['ontop'] = false;
Html::showMassiveActions($massiveactionparams);
Html::closeForm();
}
echo "
";
}
}
/**
* Prints a direct connection to a computer
*
* @param $item CommonDBTM object: the Monitor/Phone/Peripheral/Printer
* @param $withtemplate integer withtemplate param (default 0)
*
* @return void
**/
static function showForItem(CommonDBTM $item, $withtemplate = 0) {
// Prints a direct connection to a computer
global $DB;
$comp = new Computer();
$ID = $item->getField('id');
if (!$item->can($ID, READ)) {
return;
}
$canedit = $item->canEdit($ID);
$rand = mt_rand();
// Is global connection ?
$global = $item->getField('is_global');
$used = [];
$compids = [];
$dynamic = [];
$result = $DB->request(
[
'SELECT' => ['id', 'computers_id', 'is_dynamic'],
'FROM' => self::getTable(),
'WHERE' => [
'itemtype' => $item->getType(),
'items_id' => $ID,
'is_deleted' => 0,
]
]
);
foreach ($result as $data) {
$compids[$data['id']] = $data['computers_id'];
$dynamic[$data['id']] = $data['is_dynamic'];
$used['Computer'][] = $data['computers_id'];
}
$number = count($compids);
if ($canedit
&& ($global || !$number)
&& !(!empty($withtemplate) && ($withtemplate == 2))) {
echo "";
}
echo "";
if ($canedit && $number) {
Html::openMassiveActionsForm('mass'.__CLASS__.$rand);
$massiveactionparams
= ['num_displayed'
=> min($_SESSION['glpilist_limit'], $number),
'specific_actions'
=> ['purge' => _x('button', 'Disconnect')],
'container'
=> 'mass'.__CLASS__.$rand];
Html::showMassiveActions($massiveactionparams);
}
echo "
";
if ($number > 0) {
$header_begin = "";
$header_top = '';
$header_bottom = '';
$header_end = '';
if ($canedit) {
$header_top .= "| ".Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
$header_top .= " | ";
$header_bottom .= "".Html::getCheckAllAsCheckbox('mass'.__CLASS__.$rand);
$header_bottom .= " | ";
}
$header_end .= "".__('Name')." | ";
if (Plugin::haveImport()) {
$header_end .= "".__('Automatic inventory')." | ";
}
$header_end .= "".Entity::getTypeName(1)." | ";
$header_end .= "".__('Serial number')." | ";
$header_end .= "".__('Inventory number')." | ";
$header_end .= "
";
echo $header_begin.$header_top.$header_end;
foreach ($compids as $key => $compid) {
$comp->getFromDB($compid);
echo "";
if ($canedit) {
echo "| ";
Html::showMassiveActionCheckBox(__CLASS__, $key);
echo " | ";
}
echo "getField('is_deleted')?"class='tab_bg_2_2'":"").
">".$comp->getLink()." | ";
if (Plugin::haveImport()) {
echo "".Dropdown::getYesNo($dynamic[$key])." | ";
}
echo "".Dropdown::getDropdownName("glpi_entities",
$comp->getField('entities_id'));
echo " | ";
echo "".$comp->getField('serial')." | ";
echo "".$comp->getField('otherserial')." | ";
echo "
";
}
echo $header_begin.$header_bottom.$header_end;
} else {
echo "| ".__('Not connected')."";
echo " |
";
}
echo "
";
if ($canedit && $number) {
$massiveactionparams['ontop'] = false;
Html::showMassiveActions($massiveactionparams);
Html::closeForm();
}
echo "
";
}
/**
* Unglobalize an item : duplicate item and connections
*
* @param $item CommonDBTM object to unglobalize
**/
static function unglobalizeItem(CommonDBTM $item) {
global $DB;
// Update item to unit management :
if ($item->getField('is_global')) {
$input = ['id' => $item->fields['id'],
'is_global' => 0];
$item->update($input);
// Get connect_wire for this connection
$iterator = $DB->request([
'SELECT' => ['id'],
'FROM' => self::getTable(),
'WHERE' => [
'items_id' => $item->getID(),
'itemtype' => $item->getType()
]
]);
$first = true;
while ($data = $iterator->next()) {
if ($first) {
$first = false;
unset($input['id']);
$conn = new self();
} else {
$temp = clone $item;
unset($temp->fields['id']);
if ($newID=$temp->add($temp->fields)) {
$conn->update(['id' => $data['id'],
'items_id' => $newID]);
}
}
}
}
}
/**
* Make a select box for connections
*
* @since 0.84
*
* @param string $fromtype from where the connection is
* @param string $myname select name
* @param integer|integer[] $entity_restrict Restrict to a defined entity (default = -1)
* @param boolean $onlyglobal display only global devices (used for templates) (default 0)
* @param integer[] $used Already used items ID: not to display in dropdown
*
* @return integer Random generated number used for select box ID (select box HTML is printed)
*/
static function dropdownAllConnect($fromtype, $myname, $entity_restrict = -1,
$onlyglobal = 0, $used = []) {
global $CFG_GLPI;
$rand = mt_rand();
$options = [];
$options['checkright'] = true;
$options['name'] = 'itemtype';
$rand = Dropdown::showItemType($CFG_GLPI['directconnect_types'], $options);
if ($rand) {
$params = ['itemtype' => '__VALUE__',
'fromtype' => $fromtype,
'value' => 0,
'myname' => $myname,
'onlyglobal' => $onlyglobal,
'entity_restrict' => $entity_restrict,
'used' => $used];
if ($onlyglobal) {
$params['condition'] = ['is_global' => 1];
}
Ajax::updateItemOnSelectEvent("dropdown_itemtype$rand", "show_$myname$rand",
$CFG_GLPI["root_doc"]."/ajax/dropdownConnect.php", $params);
echo "
\n";
}
return $rand;
}
/**
* Make a select box for connections
*
* @param string $itemtype type to connect
* @param string $fromtype from where the connection is
* @param string $myname select name
* @param integer|integer[] $entity_restrict Restrict to a defined entity (default = -1)
* @param boolean $onlyglobal display only global devices (used for templates) (default 0)
* @param integer[] $used Already used items ID: not to display in dropdown
*
* @return integer Random generated number used for select box ID (select box HTML is printed)
*/
static function dropdownConnect($itemtype, $fromtype, $myname, $entity_restrict = -1,
$onlyglobal = 0, $used = []) {
global $CFG_GLPI;
$rand = mt_rand();
$field_id = Html::cleanId("dropdown_".$myname.$rand);
$param = ['entity_restrict' => $entity_restrict,
'fromtype' => $fromtype,
'itemtype' => $itemtype,
'onlyglobal' => $onlyglobal,
'used' => $used];
echo Html::jsAjaxDropdown($myname, $field_id,
$CFG_GLPI['root_doc']."/ajax/getDropdownConnect.php",
$param);
return $rand;
}
function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) {
// can exists for Template
if ($item->can($item->getField('id'), READ)) {
$nb = 0;
switch ($item->getType()) {
case 'Phone' :
case 'Printer' :
case 'Peripheral' :
case 'Monitor' :
if (Computer::canView()) {
if ($_SESSION['glpishow_count_on_tabs']) {
$nb = self::countForItem($item);
}
return self::createTabEntry(_n('Connection', 'Connections', Session::getPluralNumber()),
$nb);
}
break;
case 'Computer' :
if (Phone::canView()
|| Printer::canView()
|| Peripheral::canView()
|| Monitor::canView()) {
if ($_SESSION['glpishow_count_on_tabs']) {
$nb = self::countForMainItem($item);
}
return self::createTabEntry(_n('Connection', 'Connections', Session::getPluralNumber()),
$nb);
}
break;
}
}
return '';
}
static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) {
switch ($item->getType()) {
case 'Phone' :
case 'Printer' :
case 'Peripheral' :
case 'Monitor' :
self::showForItem($item, $withtemplate);
return true;
case 'Computer' :
self::showForComputer($item, $withtemplate);
return true;
}
}
/**
* Duplicate connected items to computer from an item template to its clone
*
* @deprecated 9.5
* @since 0.84
*
* @param integer $oldid ID of the item to clone
* @param integer $newid ID of the item cloned
**/
static function cloneComputer($oldid, $newid) {
global $DB;
Toolbox::deprecated('Use clone');
$iterator = $DB->request([
'FROM' => self::getTable(),
'WHERE' => ['computers_id' => $oldid]
]);
while ($data = $iterator->next()) {
$conn = new Computer_Item();
$conn->add(['computers_id' => $newid,
'itemtype' => $data["itemtype"],
'items_id' => $data["items_id"]]);
}
}
/**
* Duplicate connected items to item from an item template to its clone
*
* @deprecated 9.5
* @since 0.83.3
*
* @param string $itemtype type of the item to clone
* @param integer $oldid ID of the item to clone
* @param integer $newid ID of the item cloned
**/
static function cloneItem($itemtype, $oldid, $newid) {
global $DB;
Toolbox::deprecated('Use clone');
$iterator = $DB->request([
'FROM' => self::getTable(),
'WHERE' => [
'itemtype' => $itemtype,
'items_id' => $oldid
]
]);
while ($data = $iterator->next()) {
$conn = new self();
$conn->add(['computers_id' => $data["computers_id"],
'itemtype' => $data["itemtype"],
'items_id' => $newid]);
}
}
/**
* @since 9.1.7
*
* @param CommonDBTM $item item linked to the computer to check
* @param integer[] $entities entities to check
*
* @return boolean
**/
static function canUnrecursSpecif(CommonDBTM $item, $entities) {
global $DB;
// RELATION : computers -> items
$iterator = $DB->request([
'SELECT' => [
'itemtype',
new \QueryExpression('GROUP_CONCAT(DISTINCT '.$DB->quoteName('items_id').') AS ids'),
'computers_id'
],
'FROM' => self::getTable(),
'WHERE' => [
'itemtype' => $item->getType(),
'items_id' => $item->fields['id']
],
'GROUP' => 'itemtype'
]);
while ($data = $iterator->next()) {
if (countElementsInTable("glpi_computers",
['id' => $data["computers_id"],
'NOT' => ['entities_id' => $entities]]) > 0) {
return false;
}
}
return true;
}
protected static function getListForItemParams(CommonDBTM $item, $noent = false) {
$params = parent::getListForItemParams($item, $noent);
$params['WHERE'][self::getTable() . '.is_deleted'] = 0;
return $params;
}
}