API::getItems PHP Method

getItems() protected method

Return a collection of rows of the desired itemtype
protected getItems ( $itemtype, $params = [], &$totalcount ) : array
$itemtype string itemtype (class) of object
$params array with theses options : - 'expand_dropdowns' (default: false): show dropdown's names instead of id. Optionnal - 'get_hateoas' (default: true): show relations of items in a links attribute. Optionnal - 'only_id' (default: false): keep only id in fields list. Optionnal - 'range' (default: 0-50): limit the list to start-end attributes - 'sort' (default: id): sort by the field. - 'order' (default: ASC): ASC(ending) or DESC(ending). - 'searchText' (default: NULL): array of filters to pass on the query (with key = field and value the search)
$totalcount integer output parameter who receive the total count of the query resulat. As this function paginate results (with a mysql LIMIT), we can have the full range. (default 0)
return array collection of fields
    protected function getItems($itemtype, $params = array(), &$totalcount = 0)
    {
        global $DB;
        $this->initEndpoint();
        // default params
        $default = array('expand_dropdowns' => false, 'get_hateoas' => true, 'only_id' => false, 'range' => "0-" . $_SESSION['glpilist_limit'], 'sort' => "id", 'order' => "ASC", 'searchText' => NULL);
        $params = array_merge($default, $params);
        if (!$itemtype::canView()) {
            return $this->messageRightError();
        }
        $found = array();
        $item = new $itemtype();
        $item->getEmpty();
        $table = getTableForItemType($itemtype);
        // transform range parameter in start and limit variables
        if (isset($params['range']) > 0) {
            if (preg_match("/^[0-9]+-[0-9]+\$/", $params['range'])) {
                $range = explode("-", $params['range']);
                $params['start'] = $range[0];
                $params['list_limit'] = $range[1] - $range[0] + 1;
                $params['range'] = $range;
            } else {
                $this->returnError("range must be in format : [start-end] with integers");
            }
        } else {
            $params['range'] = array(0, $_SESSION['glpilist_limit']);
        }
        // check parameters
        if (isset($params['order']) && !in_array(strtoupper($params['order']), array('DESC', 'ASC'))) {
            $this->returnError("order must be DESC or ASC");
        }
        if (!isset($item->fields[$params['sort']])) {
            $this->returnError("sort param is not a field of {$table}");
        }
        //specific case for restriction
        $already_linked_table = array();
        $join = Search::addDefaultJoin($itemtype, $table, $already_linked_table);
        $where = Search::addDefaultWhere($itemtype);
        if ($where == '') {
            $where = "1=1 ";
        }
        // add filter for a parent itemtype
        if (isset($this->parameters['parent_itemtype']) && isset($this->parameters['parent_id'])) {
            // check parent itemtype
            if (!class_exists($this->parameters['parent_itemtype']) || !is_subclass_of($this->parameters['parent_itemtype'], 'CommonDBTM')) {
                $this->returnError(__("parent itemtype not found or not an instance of CommonDBTM"), 400, "ERROR_ITEMTYPE_NOT_FOUND_NOR_COMMONDBTM");
            }
            $fk_parent = getForeignKeyFieldForItemType($this->parameters['parent_itemtype']);
            $fk_child = getForeignKeyFieldForItemType($itemtype);
            // check parent rights
            $parent_item = new $this->parameters['parent_itemtype']();
            if (!$parent_item->getFromDB($this->parameters['parent_id'])) {
                return $this->messageNotfoundError();
            }
            if (!$parent_item->can($this->parameters['parent_id'], READ)) {
                return $this->messageRightError();
            }
            // filter with parents fields
            if (isset($item->fields[$fk_parent])) {
                $where .= " AND `{$table}`.`{$fk_parent}` = " . $this->parameters['parent_id'];
            } else {
                if (isset($item->fields['itemtype']) && isset($item->fields['items_id'])) {
                    $where .= " AND `{$table}`.`itemtype` = '" . $this->parameters['parent_itemtype'] . "'\n                       AND `{$table}`.`items_id` = " . $this->parameters['parent_id'];
                } else {
                    if (isset($parent_item->fields[$fk_child])) {
                        $parentTable = getTableForItemType($this->parameters['parent_itemtype']);
                        $join .= " LEFT JOIN `{$parentTable}` ON `{$parentTable}`.`{$fk_child}` = `{$table}`.`id` ";
                        $where .= " AND `{$parentTable}`.`id` = '" . $this->parameters['parent_id'] . "'";
                    } else {
                        if (isset($parent_item->fields['itemtype']) && isset($parent_item->fields['items_id'])) {
                            $parentTable = getTableForItemType($this->parameters['parent_itemtype']);
                            $join .= " LEFT JOIN `{$parentTable}` ON `itemtype`='{$itemtype}' AND `{$parentTable}`.`items_id` = `{$table}`.`id` ";
                            $where .= " AND `{$parentTable}`.`id` = '" . $this->parameters['parent_id'] . "'";
                        }
                    }
                }
            }
        }
        // filter by searchText parameter
        if (is_array($params['searchText'])) {
            if (array_keys($params['searchText']) == array('all')) {
                $labelfield = "name";
                if ($item instanceof CommonDevice) {
                    $labelfield = "designation";
                } else {
                    if ($item instanceof Item_Devices) {
                        $labelfield = "itemtype";
                    }
                }
                $search_value = $params['searchText']['all'];
                $params['searchText'][$labelfield] = $search_value;
                if (FieldExists($table, 'comment')) {
                    $params['searchText']['comment'] = $search_value;
                }
            }
            // make text search
            foreach ($params['searchText'] as $filter_field => $filter_value) {
                if (!empty($filter_value)) {
                    $search = Search::makeTextSearch($filter_value);
                    $where .= " AND (`{$table}`.`{$filter_field}` {$search}\n                               OR `{$table}`.`id` {$search})";
                }
            }
        }
        // filter with entity
        if ($item->isEntityAssign()) {
            $where .= " AND (" . getEntitiesRestrictRequest("", $itemtype::getTable(), '', $_SESSION['glpiactiveentities'], false, true);
            if ($item instanceof Bookmark) {
                $where .= " OR " . $itemtype::getTable() . ".entities_id = -1";
            }
            $where .= ")";
        }
        // build query
        $query = "SELECT SQL_CALC_FOUND_ROWS DISTINCT `{$table}`.id,  `{$table}`.*\n                FROM `{$table}`\n                {$join}\n                WHERE {$where}\n                ORDER BY " . $params['sort'] . " " . $params['order'] . "\n                LIMIT " . $params['start'] . ", " . $params['list_limit'];
        if ($result = $DB->query($query)) {
            while ($data = $DB->fetch_assoc($result)) {
                $found[] = $data;
            }
        }
        // get result full row counts
        $query_numtotalrow = "Select FOUND_ROWS()";
        $result_numtotalrow = $DB->query($query_numtotalrow);
        $data_numtotalrow = $DB->fetch_assoc($result_numtotalrow);
        $totalcount = $data_numtotalrow['FOUND_ROWS()'];
        if ($params['range'][0] > $totalcount) {
            $this->returnError("Provided range exceed total count of data: " . $totalcount, 400, "ERROR_RANGE_EXCEED_TOTAL");
        }
        foreach ($found as $key => &$fields) {
            // only keep id in field list
            if ($params['only_id']) {
                $fields = array('id' => $fields['id']);
            }
            // avioid disclosure of critical fields
            $item::unsetUndisclosedFields($fields);
            // expand dropdown (retrieve name of dropdowns) and get hateoas
            $fields = self::parseDropdowns($fields, $params);
            // get hateoas from children
            if ($params['get_hateoas']) {
                $hclasses = self::getHatoasClasses($itemtype);
                foreach ($hclasses as $hclass) {
                    $fields['links'][] = array('rel' => $hclass, 'href' => self::$api_url . "/{$itemtype}/" . $fields['id'] . "/{$hclass}/");
                }
            }
        }
        return array_values($found);
    }