diff --git a/src/Glpi/Controller/Knowbase/AsideSearchController.php b/src/Glpi/Controller/Knowbase/AsideSearchController.php index aa7812d3e2d0..98b52c513cce 100644 --- a/src/Glpi/Controller/Knowbase/AsideSearchController.php +++ b/src/Glpi/Controller/Knowbase/AsideSearchController.php @@ -67,6 +67,13 @@ public function __invoke(Request $request): JsonResponse // Get article IDs that match this filter $criteria = KnowbaseItem::getListRequest(['contains' => $contains], 'search'); + + // The response is only used for membership tests, so neither the article + // columns (`glpi_knowbaseitems.*` includes `answer`) nor the relevance + // ordering are needed. + $criteria['SELECT'] = [KnowbaseItem::getTableField('id')]; + unset($criteria['ORDERBY']); + $ids = []; foreach ($DB->request($criteria) as $data) { $ids[] = (int) $data['id']; diff --git a/src/Glpi/Knowbase/Aside/Builder.php b/src/Glpi/Knowbase/Aside/Builder.php index 3c7ef88e9a79..cbf036bef3f8 100644 --- a/src/Glpi/Knowbase/Aside/Builder.php +++ b/src/Glpi/Knowbase/Aside/Builder.php @@ -50,8 +50,14 @@ */ final class Builder { - /** @var int[] */ - private array $folded_ids = []; + public const array LIST_COLUMNS = [ + 'glpi_knowbaseitems.id', + 'glpi_knowbaseitems.name', + 'glpi_knowbaseitems.illustration', + ]; + + /** @var array */ + private array $folded_ids_lookup_map = []; public function __construct(private readonly int $current_id = 0) {} @@ -60,10 +66,12 @@ public function buildTree(): Tree global $DB; // Articles the current user has collapsed, restored on each render. - $this->folded_ids = KnowbaseItem::getFoldedIdsForCurrentUser(); + $this->folded_ids_lookup_map = array_fill_keys(KnowbaseItem::getFoldedIdsForCurrentUser(), true); // 1) All articles the current user may see (visibility applied). - $rows = $DB->request(KnowbaseItem::getListRequest([], 'browse')); + $criteria = KnowbaseItem::getListRequest([], 'browse'); + $criteria['SELECT'] = self::LIST_COLUMNS; + $rows = $DB->request($criteria); $data = []; // id => row foreach ($rows as $row) { $data[(int) $row['id']] = $row; @@ -76,15 +84,12 @@ public function buildTree(): Tree // 2) Visible parent -> [visible children] adjacency, and child -> has a visible parent? $children_of = []; // parent_id => int[] child ids $has_visible_parent = []; // child_id => true - foreach ($DB->request([ - 'FROM' => KnowbaseItem_KnowbaseItem::getTable(), - 'WHERE' => [ - 'knowbaseitems_id' => $visible_ids, - 'knowbaseitems_id_parent' => $visible_ids, - ], - ]) as $link) { + foreach ($DB->request(['FROM' => KnowbaseItem_KnowbaseItem::getTable()]) as $link) { $child = (int) $link['knowbaseitems_id']; $parent = (int) $link['knowbaseitems_id_parent']; + if (!isset($data[$child], $data[$parent])) { + continue; // one of the ends is not visible to the current user + } $children_of[$parent][] = $child; $has_visible_parent[$child] = true; } @@ -113,7 +118,7 @@ private function buildArticle(int $id, array $data, array $children_of, array $a illustration: $row['illustration'] ?? '', link: KnowbaseItem::getFormURLWithID($id), is_current: $this->current_id > 0 && $id === $this->current_id, - collapsed: in_array($id, $this->folded_ids, true), + collapsed: isset($this->folded_ids_lookup_map[$id]), ); $ancestors[$id] = true; foreach ($children_of[$id] ?? [] as $child_id) { diff --git a/src/KnowbaseItem.php b/src/KnowbaseItem.php index 11e114a0be4a..491e5a68453f 100644 --- a/src/KnowbaseItem.php +++ b/src/KnowbaseItem.php @@ -3373,6 +3373,7 @@ private function getCurrentArticleAndFavorites(int $current_id = 0): array } $criteria = self::getListRequest([], 'browse'); + $criteria['SELECT'] = Builder::LIST_COLUMNS; $is_favorite_condition = [ self::getTable() . '.id' => new QuerySubQuery([