Linux server.jmdstrack.com 3.10.0-1160.119.1.el7.tuxcare.els10.x86_64 #1 SMP Fri Oct 11 21:40:41 UTC 2024 x86_64
/ home/ jmdstrac/ public_html/ devices/ src/ |
|
<?php /** * --------------------------------------------------------------------- * * GLPI - Gestionnaire Libre de Parc Informatique * * http://glpi-project.org * * @copyright 2015-2023 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 <https://www.gnu.org/licenses/>. * * --------------------------------------------------------------------- */ /** * Computer_Item Class * * Relation between Computer and Items (monitor, printer, phone, peripheral only) **/ class Computer_Item extends CommonDBRelation { // From CommonDBRelation public static $itemtype_1 = 'Computer'; public static $items_id_1 = 'computers_id'; public static $itemtype_2 = 'itemtype'; public static $items_id_2 = 'items_id'; public static $checkItem_2_Rights = self::HAVE_VIEW_RIGHT_ON_ITEM; public 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 **/ public 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') ] ); } public function prepareInputForAdd($input) { global $CFG_GLPI; $item = static::getItemFromArray(static::$itemtype_2, static::$items_id_2, $input); if ( !($item instanceof CommonDBTM) || (!$item->isGlobal() && ($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->isGlobal()) { // 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'] ?? ''); $updates['is_dynamic'] = $comp->fields['is_dynamic'] ?? 0; 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); } public 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']); $is_mainitem_dynamic = (bool) ($computer->fields['is_dynamic'] ?? false); //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)) { //propage is_dynamic value if needed to prevent locked fields if ((bool) ($device->fields['is_dynamic'] ?? false) && $is_mainitem_dynamic) { $updates['is_dynamic'] = 1; } $updates['id'] = $this->fields['items_id']; $device->update($updates); } } } } } } public 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'] = "<i class='fa-fw fas fa-plug'></i>" . _x('button', 'Connect'); $actions[$action_prefix . 'remove'] = _x('button', 'Disconnect'); } parent::getMassiveActionsForItemtype($actions, $itemtype, $is_deleted, $checkitem); } public static function getRelationMassiveActionsSpecificities() { global $CFG_GLPI; $specificities = parent::getRelationMassiveActionsSpecificities(); $specificities['itemtypes'] = $CFG_GLPI['directconnect_types']; $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 */ public 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; foreach ($iterator as $data) { 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 **/ public 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); foreach ($iterator as $data) { $data['assoc_itemtype'] = $itemtype; $datas[] = $data; $used[$itemtype][] = $data['id']; } } } $number = count($datas); if ( $canedit && !(!empty($withtemplate) && ($withtemplate == 2)) ) { echo "<div class='firstbloc'>"; echo "<form name='computeritem_form$rand' id='computeritem_form$rand' method='post' action='" . Toolbox::getItemTypeFormURL(__CLASS__) . "'>"; echo "<table class='tab_cadre_fixe'>"; echo "<tr class='tab_bg_2'><th colspan='2'>" . __('Connect an item') . "</th></tr>"; echo "<tr class='tab_bg_1'><td>"; if (!empty($withtemplate)) { echo "<input type='hidden' name='_no_history' value='1'>"; } $entities = $comp->fields["entities_id"]; if ($comp->isRecursive()) { $entities = getSonsOf("glpi_entities", $comp->getEntityID()); } self::dropdownAllConnect('Computer', "items_id", $entities, $withtemplate, $used); echo "</td><td class='center' width='20%'>"; echo "<input type='submit' name='add' value=\"" . _sx('button', 'Connect') . "\" class='btn btn-primary'>"; echo "<input type='hidden' name='computers_id' value='" . $comp->fields['id'] . "'>"; echo "</td></tr>"; echo "</table>"; Html::closeForm(); echo "</div>"; } if ($number) { echo "<div class='spaced table-responsive'>"; 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 "<table class='tab_cadre_fixehov'>"; $header_begin = "<tr>"; $header_top = ''; $header_bottom = ''; $header_end = ''; if ($canedit) { $header_top .= "<th width='10'>" . Html::getCheckAllAsCheckbox('mass' . __CLASS__ . $rand); $header_top .= "</th>"; $header_bottom .= "<th width='10'>" . Html::getCheckAllAsCheckbox('mass' . __CLASS__ . $rand); $header_bottom .= "</th>"; } $header_end .= "<th>" . _n('Type', 'Types', 1) . "</th>"; $header_end .= "<th>" . __('Name') . "</th>"; $header_end .= "<th>" . __('Automatic inventory') . "</th>"; $header_end .= "<th>" . Entity::getTypeName(1) . "</th>"; $header_end .= "<th>" . __('Serial number') . "</th>"; $header_end .= "<th>" . __('Inventory number') . "</th>"; $header_end .= "</tr>"; 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 = "<a href=\"" . $link . "\">" . $linkname . "</a>"; echo "<tr class='tab_bg_1'>"; if ($canedit) { echo "<td width='10'>"; Html::showMassiveActionCheckBox(__CLASS__, $data["linkid"]); echo "</td>"; } echo "<td>" . $data['assoc_itemtype']::getTypeName(1) . "</td>"; echo "<td " . ((isset($data['is_deleted']) && $data['is_deleted']) ? "class='tab_bg_2_2'" : "") . ">" . $name . "</td>"; $dynamic_field = static::getTable() . '_is_dynamic'; echo "<td>" . Dropdown::getYesNo($data[$dynamic_field]) . "</td>"; echo "<td>" . Dropdown::getDropdownName( "glpi_entities", $data['entities_id'] ); echo "</td>"; echo "<td>" . (isset($data["serial"]) ? "" . $data["serial"] . "" : "-") . "</td>"; echo "<td>" . (isset($data["otherserial"]) ? "" . $data["otherserial"] . "" : "-") . "</td>"; echo "</tr>"; } echo $header_begin . $header_bottom . $header_end; echo "</table>"; if ($canedit && $number) { $massiveactionparams['ontop'] = false; Html::showMassiveActions($massiveactionparams); Html::closeForm(); } echo "</div>"; } } /** * 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 **/ public 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 "<div class='firstbloc'>"; echo "<form name='computeritem_form$rand' id='computeritem_form$rand' method='post' action='" . Toolbox::getItemTypeFormURL(__CLASS__) . "'>"; echo "<table class='tab_cadre_fixe'>"; echo "<tr class='tab_bg_2'><th colspan='2'>" . __('Connect a computer') . "</th></tr>"; echo "<tr class='tab_bg_1'><td class='right'>"; echo "<input type='hidden' name='items_id' value='$ID'>"; echo "<input type='hidden' name='itemtype' value='" . $item->getType() . "'>"; if ($item->isRecursive()) { self::dropdownConnect( 'Computer', $item->getType(), "computers_id", getSonsOf("glpi_entities", $item->getEntityID()), 0, $used ); } else { self::dropdownConnect( 'Computer', $item->getType(), "computers_id", $item->getEntityID(), 0, $used ); } echo "</td><td class='center'>"; echo "<input type='submit' name='add' value=\"" . _sx('button', 'Connect') . "\" class='btn btn-primary'>"; echo "</td></tr>"; echo "</table>"; Html::closeForm(); echo "</div>"; } echo "<div class='spaced table-responsive'>"; 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 "<table class='tab_cadre_fixehov'>"; if ($number > 0) { $header_begin = "<tr>"; $header_top = ''; $header_bottom = ''; $header_end = ''; if ($canedit) { $header_top .= "<th width='10'>" . Html::getCheckAllAsCheckbox('mass' . __CLASS__ . $rand); $header_top .= "</th>"; $header_bottom .= "<th width='10'>" . Html::getCheckAllAsCheckbox('mass' . __CLASS__ . $rand); $header_bottom .= "</th>"; } $header_end .= "<th>" . __('Name') . "</th>"; $header_end .= "<th>" . __('Automatic inventory') . "</th>"; $header_end .= "<th>" . Entity::getTypeName(1) . "</th>"; $header_end .= "<th>" . __('Serial number') . "</th>"; $header_end .= "<th>" . __('Inventory number') . "</th>"; $header_end .= "</tr>"; echo $header_begin . $header_top . $header_end; foreach ($compids as $key => $compid) { $comp->getFromDB($compid); echo "<tr class='tab_bg_1'>"; if ($canedit) { echo "<td width='10'>"; Html::showMassiveActionCheckBox(__CLASS__, $key); echo "</td>"; } echo "<td " . ($comp->getField('is_deleted') ? "class='tab_bg_2_2'" : "") . ">" . $comp->getLink() . "</td>"; echo "<td>" . Dropdown::getYesNo($dynamic[$key]) . "</td>"; echo "<td class='center'>" . Dropdown::getDropdownName( "glpi_entities", $comp->getField('entities_id') ); echo "</td>"; echo "<td class='center'>" . $comp->getField('serial') . "</td>"; echo "<td class='center'>" . $comp->getField('otherserial') . "</td>"; echo "</tr>"; } echo $header_begin . $header_bottom . $header_end; } else { echo "<tr><td class='tab_bg_1 b'><i>" . __('Not connected') . "</i>"; echo "</td></tr>"; } echo "</table>"; if ($canedit && $number) { $massiveactionparams['ontop'] = false; Html::showMassiveActions($massiveactionparams); Html::closeForm(); } echo "</div>"; } /** * Unglobalize an item : duplicate item and connections * * @param $item CommonDBTM object to unglobalize **/ public 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; foreach ($iterator as $data) { 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) */ public 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 "<br><div id='show_$myname$rand'> </div>\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) */ public 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, '_idor_token' => Session::getNewIDORToken($itemtype, [ 'entity_restrict' => $entity_restrict, ]), ]; echo Html::jsAjaxDropdown( $myname, $field_id, $CFG_GLPI['root_doc'] . "/ajax/getDropdownConnect.php", $param ); return $rand; } public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { global $CFG_GLPI; // can exists for Template if ($item->can($item->getField('id'), READ)) { $nb = 0; $canview = false; if ($item->getType() == Computer::getType()) { foreach ($CFG_GLPI['directconnect_types'] as $type) { if ($type::canView()) { $canview = true; break; } } if ($canview) { if ($_SESSION['glpishow_count_on_tabs']) { $nb = self::countForMainItem($item); } } } if (in_array($item->getType(), $CFG_GLPI['directconnect_types']) && Computer::canView()) { $canview = true; if ($_SESSION['glpishow_count_on_tabs']) { $nb = self::countForItem($item); } } if ($canview) { return self::createTabEntry( _n('Connection', 'Connections', Session::getPluralNumber()), $nb ); } } return ''; } public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { global $CFG_GLPI; if ($item->getType() == Computer::getType()) { self::showForComputer($item, $withtemplate); return true; } if (in_array($item->getType(), $CFG_GLPI['directconnect_types'])) { self::showForItem($item, $withtemplate); return true; } throw new \RuntimeException( sprintf( 'Cannot link a computer with a %s', $item->getType() ) ); } /** * @since 9.1.7 * * @param CommonDBTM $item item linked to the computer to check * @param integer[] $entities entities to check * * @return boolean **/ public static function canUnrecursSpecif(CommonDBTM $item, $entities) { global $DB; if ($item instanceof Computer) { // RELATION : items -> computers $iterator = $DB->request([ 'SELECT' => [ 'itemtype', new \QueryExpression('GROUP_CONCAT(DISTINCT ' . $DB->quoteName('items_id') . ') AS ids'), ], 'FROM' => self::getTable(), 'WHERE' => [ 'computers_id' => $item->fields['id'] ], 'GROUP' => 'itemtype' ]); while ($data = $iterator->next()) { if (!class_exists($data['itemtype'])) { continue; } if (countElementsInTable($data['itemtype']::getTable(), ['id' => $data['ids'], 'NOT' => ['entities_id' => $entities]]) > 0) { return false; } } } else { // 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' ]); foreach ($iterator as $data) { 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; } /** * Get SELECT param for getTypeItemsQueryParams * * @param CommonDBTM $item * * @return array */ public static function getTypeItemsQueryParams_Select(CommonDBTM $item): array { $table = static::getTable(); $select = parent::getTypeItemsQueryParams_Select($item); $select[] = "$table.is_dynamic AS {$table}_is_dynamic"; return $select; } }