870 lines
24 KiB
PHP
870 lines
24 KiB
PHP
<?php
|
|
/**
|
|
* ---------------------------------------------------------------------
|
|
* GLPI - Gestionnaire Libre de Parc Informatique
|
|
* Copyright (C) 2015-2020 Teclib' and contributors.
|
|
*
|
|
* http://glpi-project.org
|
|
*
|
|
* based on GLPI - Gestionnaire Libre de Parc Informatique
|
|
* Copyright (C) 2003-2014 by the INDEPNET Development Team.
|
|
*
|
|
* ---------------------------------------------------------------------
|
|
*
|
|
* LICENSE
|
|
*
|
|
* This file is part of GLPI.
|
|
*
|
|
* GLPI 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 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* GLPI 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 GLPI. If not, see <http://www.gnu.org/licenses/>.
|
|
* ---------------------------------------------------------------------
|
|
*/
|
|
|
|
if (!defined('GLPI_ROOT')) {
|
|
die("Sorry. You can't access this file directly");
|
|
}
|
|
|
|
/// Common DataBase Relation Table Manager Class
|
|
abstract class CommonDBChild extends CommonDBConnexity {
|
|
|
|
// Mapping between DB fields
|
|
// * definition
|
|
static public $itemtype; // Class name or field name (start with itemtype) for link to Parent
|
|
static public $items_id; // Field name
|
|
// * rights
|
|
static public $checkParentRights = self::HAVE_SAME_RIGHT_ON_ITEM;
|
|
static public $mustBeAttached = true;
|
|
// * log
|
|
static public $logs_for_parent = true;
|
|
static public $log_history_add = Log::HISTORY_ADD_SUBITEM;
|
|
static public $log_history_update = Log::HISTORY_UPDATE_SUBITEM;
|
|
static public $log_history_delete = Log::HISTORY_DELETE_SUBITEM;
|
|
static public $log_history_lock = Log::HISTORY_LOCK_SUBITEM;
|
|
static public $log_history_unlock = Log::HISTORY_UNLOCK_SUBITEM;
|
|
|
|
|
|
/**
|
|
* Get request cirteria to search for an item
|
|
*
|
|
* @since 9.4
|
|
*
|
|
* @param string $itemtype Item type
|
|
* @param integer $items_id Item ID
|
|
*
|
|
* @return array|null
|
|
**/
|
|
static function getSQLCriteriaToSearchForItem($itemtype, $items_id) {
|
|
$criteria = [
|
|
'SELECT' => [
|
|
static::getIndexName(),
|
|
static::$items_id . ' AS items_id'
|
|
],
|
|
'FROM' => static::getTable(),
|
|
'WHERE' => [
|
|
static::$items_id => $items_id
|
|
]
|
|
];
|
|
|
|
// Check item 1 type
|
|
$request = false;
|
|
if (preg_match('/^itemtype/', static::$itemtype)) {
|
|
$criteria['SELECT'][] = static::$itemtype . ' AS itemtype';
|
|
$criteria['WHERE'][static::$itemtype] = $itemtype;
|
|
$request = true;
|
|
} else {
|
|
$criteria['SELECT'][] = new \QueryExpression("'" . static::$itemtype . "' AS itemtype");
|
|
if (($itemtype == static::$itemtype)
|
|
|| is_subclass_of($itemtype, static::$itemtype)) {
|
|
$request = true;
|
|
}
|
|
}
|
|
if ($request === true) {
|
|
return $criteria;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
**/
|
|
static function canCreate() {
|
|
|
|
if ((static::$rightname) && (!Session::haveRight(static::$rightname, CREATE))) {
|
|
return false;
|
|
}
|
|
return static::canChild('canUpdate');
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
**/
|
|
static function canView() {
|
|
if ((static::$rightname) && (!Session::haveRight(static::$rightname, READ))) {
|
|
return false;
|
|
}
|
|
return static::canChild('canView');
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
**/
|
|
static function canUpdate() {
|
|
if ((static::$rightname) && (!Session::haveRight(static::$rightname, UPDATE))) {
|
|
return false;
|
|
}
|
|
return static::canChild('canUpdate');
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
**/
|
|
static function canDelete() {
|
|
if ((static::$rightname) && (!Session::haveRight(static::$rightname, DELETE))) {
|
|
return false;
|
|
}
|
|
return static::canChild('canUpdate');
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.85
|
|
**/
|
|
static function canPurge() {
|
|
if ((static::$rightname) && (!Session::haveRight(static::$rightname, PURGE))) {
|
|
return false;
|
|
}
|
|
return static::canChild('canUpdate');
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
**/
|
|
function canCreateItem() {
|
|
return $this->canChildItem('canUpdateItem', 'canUpdate');
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
**/
|
|
function canViewItem() {
|
|
return $this->canChildItem('canViewItem', 'canView');
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
**/
|
|
function canUpdateItem() {
|
|
return $this->canChildItem('canUpdateItem', 'canUpdate');
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
**/
|
|
function canDeleteItem() {
|
|
return $this->canChildItem('canUpdateItem', 'canUpdate');
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
*
|
|
* @param $method
|
|
**/
|
|
static function canChild($method) {
|
|
|
|
return static::canConnexity($method, static::$checkParentRights, static::$itemtype,
|
|
static::$items_id);
|
|
}
|
|
|
|
|
|
/**
|
|
* @since 0.84
|
|
*
|
|
* @param $methodItem
|
|
* @param $methodNotItem
|
|
*
|
|
* @return boolean
|
|
**/
|
|
function canChildItem($methodItem, $methodNotItem) {
|
|
|
|
try {
|
|
return $this->canConnexityItem($methodItem, $methodNotItem, static::$checkParentRights,
|
|
static::$itemtype, static::$items_id);
|
|
} catch (CommonDBConnexityItemNotFound $e) {
|
|
return !static::$mustBeAttached;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the item associated with the current object. Rely on CommonDBConnexity::getItemFromArray()
|
|
*
|
|
* @since 0.84
|
|
*
|
|
* @param $getFromDB (true by default)
|
|
* @param $getEmpty (true by default)
|
|
*
|
|
* @return object of the concerned item or false on error
|
|
**/
|
|
function getItem($getFromDB = true, $getEmpty = true) {
|
|
|
|
return $this->getConnexityItem(static::$itemtype, static::$items_id,
|
|
$getFromDB, $getEmpty);
|
|
}
|
|
|
|
|
|
/**
|
|
* \brief recursively display the items of this
|
|
*
|
|
* @param array $recursiveItems items of the current elements (see recursivelyGetItems())
|
|
* @param string $elementToDisplay what to display : 'Type', 'Name', 'Link'
|
|
**/
|
|
static function displayRecursiveItems(array $recursiveItems, $elementToDisplay) {
|
|
|
|
if ((!is_array($recursiveItems)) || (count($recursiveItems) == 0)) {
|
|
echo __('Item not linked to an object');
|
|
return;
|
|
}
|
|
|
|
switch ($elementToDisplay) {
|
|
case 'Type' :
|
|
$masterItem = $recursiveItems[count($recursiveItems) - 1];
|
|
echo $masterItem->getTypeName(1);
|
|
break;
|
|
|
|
case 'Name' :
|
|
case 'Link' :
|
|
$items_elements = [];
|
|
foreach ($recursiveItems as $item) {
|
|
if ($elementToDisplay == 'Name') {
|
|
$items_elements[] = $item->getName();
|
|
} else {
|
|
$items_elements[] = $item->getLink();
|
|
}
|
|
}
|
|
echo implode(' < ', $items_elements);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Get all the items associated with the current object by recursive requests
|
|
*
|
|
* @since 0.84
|
|
*
|
|
* @return array
|
|
**/
|
|
function recursivelyGetItems() {
|
|
|
|
$item = $this->getItem();
|
|
if ($item !== false) {
|
|
if ($item instanceof CommonDBChild) {
|
|
return array_merge([$item], $item->recursivelyGetItems());
|
|
}
|
|
return [$item];
|
|
}
|
|
return [];
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the ID of entity assigned to the object
|
|
*
|
|
* @return integer ID of the entity
|
|
**/
|
|
function getEntityID () {
|
|
|
|
// Case of Duplicate Entity info to child
|
|
if (parent::isEntityAssign()) {
|
|
return parent::getEntityID();
|
|
}
|
|
|
|
$item = $this->getItem();
|
|
if (($item !== false) && ($item->isEntityAssign())) {
|
|
|
|
return $item->getEntityID();
|
|
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
function isEntityAssign() {
|
|
|
|
// Case of Duplicate Entity info to child
|
|
if (parent::isEntityAssign()) {
|
|
return true;
|
|
}
|
|
|
|
$item = $this->getItem(false);
|
|
|
|
if ($item !== false) {
|
|
return $item->isEntityAssign();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Is the object may be recursive
|
|
*
|
|
* @return boolean
|
|
**/
|
|
function maybeRecursive() {
|
|
|
|
// Case of Duplicate Entity info to child
|
|
if (parent::maybeRecursive()) {
|
|
return true;
|
|
}
|
|
|
|
$item = $this->getItem(false);
|
|
|
|
if ($item !== false) {
|
|
return $item->maybeRecursive();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Is the object recursive
|
|
*
|
|
* @return boolean
|
|
**/
|
|
function isRecursive () {
|
|
|
|
// Case of Duplicate Entity info to child
|
|
if (parent::maybeRecursive()) {
|
|
return parent::isRecursive();
|
|
}
|
|
|
|
$item = $this->getItem();
|
|
|
|
if ($item !== false) {
|
|
return $item->isRecursive();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
function addNeededInfoToInput($input) {
|
|
|
|
// is entity missing and forwarding on ?
|
|
if ($this->tryEntityForwarding() && !isset($input['entities_id'])) {
|
|
// Merge both arrays to ensure all the fields are defined for the following checks
|
|
$completeinput = array_merge($this->fields, $input);
|
|
// Set the item to allow parent::prepareinputforadd to get the right item ...
|
|
if ($itemToGetEntity = static::getItemFromArray(static::$itemtype, static::$items_id,
|
|
$completeinput)) {
|
|
if (($itemToGetEntity instanceof CommonDBTM)
|
|
&& $itemToGetEntity->isEntityForwardTo(get_called_class())) {
|
|
|
|
$input['entities_id'] = $itemToGetEntity->getEntityID();
|
|
$input['is_recursive'] = intval($itemToGetEntity->isRecursive());
|
|
|
|
} else {
|
|
// No entity link : set default values
|
|
$input['entities_id'] = 0;
|
|
$input['is_recursive'] = 0;
|
|
}
|
|
}
|
|
}
|
|
return $input;
|
|
}
|
|
|
|
|
|
function prepareInputForAdd($input) {
|
|
|
|
if (!is_array($input)) {
|
|
return false;
|
|
}
|
|
|
|
// Check item exists
|
|
if (static::$mustBeAttached
|
|
&& !$this->getItemFromArray(static::$itemtype, static::$items_id, $input)) {
|
|
return false;
|
|
}
|
|
|
|
return $this->addNeededInfoToInput($input);
|
|
}
|
|
|
|
|
|
function prepareInputForUpdate($input) {
|
|
|
|
if (!is_array($input)) {
|
|
return false;
|
|
}
|
|
|
|
// True if item changed
|
|
if (!$this->checkAttachedItemChangesAllowed($input, [static::$itemtype,
|
|
static::$items_id])) {
|
|
return false;
|
|
}
|
|
|
|
return parent::addNeededInfoToInput($input);
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the history name of item
|
|
*
|
|
* @param CommonDBTM $item the other item
|
|
* @param string $case : can be overwrite by object
|
|
* - 'add' when this CommonDBChild is added (to and item)
|
|
* - 'update item previous' transfert : this is removed from the old item
|
|
* - 'update item next' transfert : this is added to the new item
|
|
* - 'delete' when this CommonDBChild is remove (from an item)
|
|
*
|
|
* @return string the name of the entry for the database (ie. : correctly slashed)
|
|
**/
|
|
function getHistoryNameForItem(CommonDBTM $item, $case) {
|
|
|
|
return $this->getNameID(['forceid' => true,
|
|
'additional' => true]);
|
|
}
|
|
|
|
|
|
/**
|
|
* Actions done after the ADD of the item in the database
|
|
*
|
|
* @return void
|
|
**/
|
|
function post_addItem() {
|
|
|
|
if ((isset($this->input['_no_history']) && $this->input['_no_history'])
|
|
|| !static::$logs_for_parent) {
|
|
return;
|
|
}
|
|
|
|
$item = $this->getItem();
|
|
|
|
if (($item !== false)
|
|
&& $item->dohistory) {
|
|
$changes = [
|
|
'0',
|
|
'',
|
|
$this->getHistoryNameForItem($item, 'add'),
|
|
];
|
|
Log::history($item->getID(), $item->getType(), $changes, $this->getType(),
|
|
static::$log_history_add);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Actions done after the UPDATE of the item in the database
|
|
*
|
|
* @since 0.84
|
|
*
|
|
* @param integer|boolean $history store changes history ?
|
|
*
|
|
* @return void
|
|
**/
|
|
function post_updateItem($history = 1) {
|
|
|
|
if ((isset($this->input['_no_history']) && $this->input['_no_history'])
|
|
|| !static::$logs_for_parent) {
|
|
return;
|
|
}
|
|
|
|
$items_for_log = $this->getItemsForLog(static::$itemtype, static::$items_id);
|
|
|
|
// Whatever case : we log the changes
|
|
$oldvalues = $this->oldvalues;
|
|
unset($oldvalues[static::$itemtype]);
|
|
unset($oldvalues[static::$items_id]);
|
|
$item = $items_for_log['new'];
|
|
if (($item !== false)
|
|
&& $item->dohistory) {
|
|
foreach (array_keys($oldvalues) as $field) {
|
|
$changes = $this->getHistoryChangeWhenUpdateField($field);
|
|
if ((!is_array($changes)) || (count($changes) != 3)) {
|
|
continue;
|
|
}
|
|
Log::history($item->getID(), $item->getType(), $changes, $this->getType(),
|
|
static::$log_history_update);
|
|
}
|
|
}
|
|
|
|
if (isset($items_for_log['previous'])) {
|
|
// Have updated the connexity relation
|
|
|
|
$prevItem = $items_for_log['previous'];
|
|
$newItem = $items_for_log['new'];
|
|
|
|
if (($prevItem !== false)
|
|
&& $prevItem->dohistory) {
|
|
$changes[0] = '0';
|
|
$changes[1] = addslashes($this->getHistoryNameForItem($prevItem, 'update item previous'));
|
|
$changes[2] = '';
|
|
Log::history($prevItem->getID(), $prevItem->getType(), $changes, $this->getType(),
|
|
static::$log_history_delete);
|
|
}
|
|
|
|
if (($newItem !== false)
|
|
&& $newItem->dohistory) {
|
|
$changes[0] = '0';
|
|
$changes[1] = '';
|
|
$changes[2] = addslashes($this->getHistoryNameForItem($newItem, 'update item next'));
|
|
Log::history($newItem->getID(), $newItem->getType(), $changes, $this->getType(),
|
|
static::$log_history_add);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Actions done after the DELETE of the item in the database
|
|
*
|
|
* @return void
|
|
**/
|
|
function post_deleteFromDB() {
|
|
|
|
if ((isset($this->input['_no_history']) && $this->input['_no_history'])
|
|
|| !static::$logs_for_parent) {
|
|
return;
|
|
}
|
|
|
|
$item = $this->getItem();
|
|
|
|
if (($item !== false)
|
|
&& $item->dohistory) {
|
|
$changes = [
|
|
'0',
|
|
];
|
|
|
|
if (static::$log_history_delete == Log::HISTORY_LOG_SIMPLE_MESSAGE) {
|
|
$changes[1] = '';
|
|
$changes[2] = addslashes($this->getHistoryNameForItem($item, 'delete'));
|
|
} else {
|
|
$changes[1] = addslashes($this->getHistoryNameForItem($item, 'delete'));
|
|
$changes[2] = '';
|
|
}
|
|
Log::history($item->getID(), $item->getType(), $changes, $this->getType(),
|
|
static::$log_history_delete);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Actions done when item flag deleted is set to an item
|
|
*
|
|
* @since 0.84
|
|
*
|
|
* @return void
|
|
**/
|
|
function cleanDBonMarkDeleted() {
|
|
|
|
if ((isset($this->input['_no_history']) && $this->input['_no_history'])
|
|
|| !static::$logs_for_parent) {
|
|
return;
|
|
}
|
|
|
|
if ($this->useDeletedToLockIfDynamic()
|
|
&& $this->isDynamic()) {
|
|
$item = $this->getItem();
|
|
|
|
if (($item !== false)
|
|
&& $item->dohistory) {
|
|
$changes = [
|
|
'0',
|
|
addslashes($this->getHistoryNameForItem($item, 'lock')),
|
|
'',
|
|
];
|
|
Log::history($item->getID(), $item->getType(), $changes, $this->getType(),
|
|
static::$log_history_lock);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Actions done after the restore of the item
|
|
*
|
|
* @since 0.84
|
|
*
|
|
* @return void
|
|
**/
|
|
|
|
function post_restoreItem() {
|
|
if ((isset($this->input['_no_history']) && $this->input['_no_history'])
|
|
|| !static::$logs_for_parent) {
|
|
return;
|
|
}
|
|
|
|
if ($this->useDeletedToLockIfDynamic()
|
|
&& $this->isDynamic()) {
|
|
$item = $this->getItem();
|
|
|
|
if (($item !== false)
|
|
&& $item->dohistory) {
|
|
$changes = [
|
|
'0',
|
|
'',
|
|
addslashes($this->getHistoryNameForItem($item, 'unlock')),
|
|
];
|
|
Log::history($item->getID(), $item->getType(), $changes, $this->getType(),
|
|
static::$log_history_unlock);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* get the Javascript "code" to add to the form when clicking on "+"
|
|
*
|
|
* @since 0.84
|
|
*
|
|
* @see showAddChildButtonForItemForm()
|
|
*
|
|
* @param string $field_name the name of the HTML field inside Item's form
|
|
* @param string $child_count_js_var the name of the javascript variable containing current child
|
|
* number of items
|
|
*
|
|
* @return string
|
|
**/
|
|
static function getJSCodeToAddForItemChild($field_name, $child_count_js_var) {
|
|
return "<input type=\'text\' size=\'40\' ". "name=\'" . $field_name .
|
|
"[-'+$child_count_js_var+']\'>";
|
|
}
|
|
|
|
|
|
/**
|
|
* display the field of a given child
|
|
*
|
|
* @since 0.84
|
|
*
|
|
* @see showChildsForItemForm()
|
|
*
|
|
* @param boolean $canedit true if we can edit the child
|
|
* @param string $field_name the name of the HTML field inside Item's form
|
|
* @param integer $id id of the child
|
|
*
|
|
* @return void
|
|
**/
|
|
function showChildForItemForm($canedit, $field_name, $id) {
|
|
|
|
if ($this->isNewID($this->getID())) {
|
|
$value = '';
|
|
} else {
|
|
$value = $this->getName();
|
|
}
|
|
$field_name = $field_name."[$id]";
|
|
if ($canedit) {
|
|
echo "<input type='text' size='40' name='$field_name' value='$value'>";
|
|
} else {
|
|
echo "<input type='hidden' name='$field_name' value='$value'>$value";
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* We can add several single CommonDBChild to a given Item. In such case, we display a "+"
|
|
* button and the fields already entered
|
|
* This method display the "+" button
|
|
*
|
|
* @since 0.84
|
|
*
|
|
* @todo study if we cannot use these methods for the user emails
|
|
* @see showChildsForItemForm(CommonDBTM $item, $field_name)
|
|
*
|
|
* @param CommonDBTM $item the item on which to add the current CommenDBChild
|
|
* @param string $field_name the name of the HTML field inside Item's form
|
|
* @param boolean|null $canedit boolean to force rights, NULL to use default behaviour
|
|
* @param boolean $display true display or false to return the button HTML code
|
|
*
|
|
*
|
|
* @return void|string the button HTML code if $display is true, void otherwise
|
|
**/
|
|
static function showAddChildButtonForItemForm(CommonDBTM $item, $field_name, $canedit = null,
|
|
$display = true) {
|
|
|
|
$items_id = $item->getID();
|
|
|
|
if (is_null($canedit)) {
|
|
if ($item->isNewItem()) {
|
|
if (!$item->canCreate()) {
|
|
return false;
|
|
}
|
|
$canedit = $item->canUpdate();
|
|
} else {
|
|
if (!$item->can($items_id, READ)) {
|
|
return false;
|
|
}
|
|
|
|
$canedit = $item->can($items_id, UPDATE);
|
|
}
|
|
}
|
|
|
|
$result = '';
|
|
|
|
if ($canedit) {
|
|
$lower_name = strtolower(get_called_class());
|
|
$child_count_js_var = 'nb'.$lower_name.'s';
|
|
$div_id = "add_".$lower_name."_to_".$item->getType()."_".$items_id;
|
|
|
|
// Beware : -1 is for the first element added ...
|
|
$result = " <script type='text/javascript'>var $child_count_js_var=2; </script>";
|
|
$result .= "<span id='add".$lower_name."button' class='fa fa-plus pointer'".
|
|
" title=\"".__s('Add')."\"" .
|
|
"\" onClick=\"var row = ".Html::jsGetElementByID($div_id).";
|
|
row.append('<br>" .
|
|
static::getJSCodeToAddForItemChild($field_name, $child_count_js_var)."');
|
|
$child_count_js_var++;\"
|
|
><span class='sr-only'>" . __s('Add') . "</span></span>";
|
|
}
|
|
if ($display) {
|
|
echo $result;
|
|
} else {
|
|
return $result;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* We can add several single CommonDBChild to a given Item. In such case, we display a "+"
|
|
* button and the fields already entered.
|
|
* This method display the fields
|
|
*
|
|
* @since 0.84
|
|
*
|
|
* @todo study if we cannot use these methods for the user emails
|
|
* @see showAddChildButtonForItemForm()
|
|
*
|
|
* @param CommonDBTM $item the item on which to add the current CommenDBChild
|
|
* @param string $field_name the name of the HTML field inside Item's form
|
|
* @param boolean|null $canedit boolean to force rights, NULL to use default behaviour
|
|
*
|
|
* @return void
|
|
**/
|
|
static function showChildsForItemForm(CommonDBTM $item, $field_name, $canedit = null) {
|
|
global $DB;
|
|
|
|
$items_id = $item->getID();
|
|
|
|
if (is_null($canedit)) {
|
|
if ($item->isNewItem()) {
|
|
if (!$item->canCreate()) {
|
|
return false;
|
|
}
|
|
$canedit = $item->canUpdate();
|
|
} else {
|
|
if (!$item->can($items_id, READ)) {
|
|
return false;
|
|
}
|
|
|
|
$canedit = $item->can($items_id, UPDATE);
|
|
}
|
|
}
|
|
|
|
$lower_name = strtolower(get_called_class());
|
|
$div_id = "add_".$lower_name."_to_".$item->getType()."_".$items_id;
|
|
|
|
// To be sure not to load bad datas from this table
|
|
if ($items_id == 0) {
|
|
$items_id = -99;
|
|
}
|
|
|
|
$query = [
|
|
'FROM' => static::getTable(),
|
|
'WHERE' => [
|
|
static::$items_id => $item->getID()
|
|
]
|
|
];
|
|
|
|
if (preg_match('/^itemtype/', static::$itemtype)) {
|
|
$query['WHERE']['itemtype'] = $item->getType();
|
|
}
|
|
|
|
$current_item = new static();
|
|
|
|
if ($current_item->maybeDeleted()) {
|
|
$query['WHERE']['is_deleted'] = 0;
|
|
}
|
|
|
|
$iterator = $DB->request($query);
|
|
$count = 0;
|
|
while ($data = $iterator->next()) {
|
|
|
|
$current_item->fields = $data;
|
|
|
|
if ($count) {
|
|
echo '<br>';
|
|
}
|
|
$count++;
|
|
|
|
$current_item->showChildForItemForm($canedit, $field_name, $current_item->getID());
|
|
|
|
}
|
|
|
|
if ($canedit) {
|
|
echo "<div id='$div_id'>";
|
|
// No Child display field
|
|
if ($count == 0) {
|
|
$current_item->getEmpty();
|
|
$current_item->showChildForItemForm($canedit, $field_name, -1);
|
|
}
|
|
echo "</div>";
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Affect a CommonDBChild to a given item. By default, unaffect it
|
|
*
|
|
* @param $id integer the id of the CommonDBChild to affect
|
|
* @param $items_id integer the id of the new item (default 0)
|
|
* @param $itemtype string the type of the new item (default '')
|
|
*
|
|
* @return boolean : true on success
|
|
**/
|
|
function affectChild($id, $items_id = 0, $itemtype = '') {
|
|
|
|
$input = [static::getIndexName() => $id,
|
|
static::$items_id => $items_id];
|
|
|
|
if (preg_match('/^itemtype/', static::$itemtype)) {
|
|
$input[static::$itemtype] = $itemtype;
|
|
}
|
|
|
|
return $this->update($input);
|
|
}
|
|
|
|
public static final function getItemField($itemtype): string {
|
|
if (is_subclass_of($itemtype, 'Rule')) {
|
|
$itemtype = 'Rule';
|
|
}
|
|
|
|
if (isset(static::$items_id) && getItemtypeForForeignKeyField(static::$items_id) == $itemtype) {
|
|
return static::$items_id;
|
|
}
|
|
|
|
if (isset (static::$itemtype) && preg_match('/^itemtype/', static::$itemtype)) {
|
|
return static::$items_id;
|
|
}
|
|
|
|
throw new \RuntimeException('Cannot guess ');
|
|
}
|
|
}
|