From d3b63aade31e7a8c3a1a7367e95717e4bb805ff3 Mon Sep 17 00:00:00 2001 From: Thomas Hackl Date: Wed, 9 Jul 2025 11:56:54 +0200 Subject: adjust calculation of descendants --- app/controllers/search/courses.php | 2 +- lib/classes/StudipTreeNode.php | 7 +++++++ lib/classes/StudipTreeNodeCachableTrait.php | 4 +--- lib/models/RangeTreeNode.php | 17 +++++++++++++++++ lib/models/StudipStudyArea.php | 27 +++++++++++++++++++++++---- 5 files changed, 49 insertions(+), 8 deletions(-) diff --git a/app/controllers/search/courses.php b/app/controllers/search/courses.php index f1fa7be..eb32634 100644 --- a/app/controllers/search/courses.php +++ b/app/controllers/search/courses.php @@ -59,7 +59,7 @@ class Search_CoursesController extends AuthenticatedController $this->editUrl = $this->url_for('rangetree/edit'); $title = _('Einrichtungsverzeichnis'); } - $this->startId = Request::option('node_id', $nodeClass . '_root'); + $this->startId = Request::option('node_id', $nodeClass . '_0'); $this->setupSidebar(); PageLayout::setTitle($title); diff --git a/lib/classes/StudipTreeNode.php b/lib/classes/StudipTreeNode.php index 6642493..1d13c99 100644 --- a/lib/classes/StudipTreeNode.php +++ b/lib/classes/StudipTreeNode.php @@ -111,4 +111,11 @@ interface StudipTreeNode */ public function getAncestorNodes(): array; + /** + * Returns an array containing all descendant node IDs. + * + * @return array + */ + public function getDescendantNodeIds(): array; + } diff --git a/lib/classes/StudipTreeNodeCachableTrait.php b/lib/classes/StudipTreeNodeCachableTrait.php index d40cf70..c2c2ccb 100644 --- a/lib/classes/StudipTreeNodeCachableTrait.php +++ b/lib/classes/StudipTreeNodeCachableTrait.php @@ -47,9 +47,7 @@ trait StudipTreeNodeCachableTrait $ids = []; - foreach ($this->getChildNodes() as $child) { - $ids = array_merge($ids, [$child->id], $child->getDescendantIds()); - } + $ids = $this->getDescendantNodeIds(); $cache[$this->id] = $ids; diff --git a/lib/models/RangeTreeNode.php b/lib/models/RangeTreeNode.php index fdea54e..4f7a56b 100644 --- a/lib/models/RangeTreeNode.php +++ b/lib/models/RangeTreeNode.php @@ -198,4 +198,21 @@ class RangeTreeNode extends SimpleORMap implements StudipTreeNode return $path; } + public function getDescendantNodeIds(): array + { + return DBManager::get()->fetchFirst( + "SELECT DISTINCT `item_id` + FROM `range_tree` + WHERE `ancestors` LIKE :inline + OR `ancestors` LIKE :start + OR `ancestors` LIKE :end + ORDER BY `ancestors`, `priority`", + [ + 'inline' => '%|' . $this->id . '|%', + 'start' => $this->id . '|%', + 'end' => '%|' . $this->id + ] + ); + } + } diff --git a/lib/models/StudipStudyArea.php b/lib/models/StudipStudyArea.php index c3121b2..1f532eb 100644 --- a/lib/models/StudipStudyArea.php +++ b/lib/models/StudipStudyArea.php @@ -498,6 +498,23 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode return $result; } + public function getDescendantNodeIds(): array + { + return DBManager::get()->fetchFirst( + "SELECT DISTINCT `sem_tree_id` + FROM `sem_tree` + WHERE `ancestors` LIKE :inline + OR `ancestors` LIKE :start + OR `ancestors` LIKE :end + ORDER BY `ancestors`, `priority`", + [ + 'inline' => '%|' . $this->id . '|%', + 'start' => $this->id . '|%', + 'end' => '%|' . $this->id + ] + ); + } + /** * @see StudipTreeNode::countCourses() */ @@ -519,11 +536,12 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode $query = "SELECT COUNT(DISTINCT t.`seminar_id`) FROM `seminar_sem_tree` t {$condition}"; if ($with_children) { - $query .= " AND (t.`ancestors` LIKE '%|:id|%' OR t.`ancestors` LIKE ':id|%' OR t.`ancestors` LIKE '%|:id')"; + $query .= " AND t.`sem_tree_id` IN (:ids)"; + $parameters['ids'] = $this->getDescendantIds() ?: ['']; } else { $query .= " AND t.`sem_tree_id` = :id"; + $parameters['id'] = $this->id; } - $parameters['id'] = $this->id; return DBManager::get()->fetchColumn($query, $parameters); } @@ -547,11 +565,12 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode $query = "SELECT DISTINCT s.* FROM `seminar_sem_tree` AS t {$condition}"; if ($with_children) { - $query .= " AND (t.`ancestors` LIKE '%|:id|%' OR t.`ancestors` LIKE ':id|%' OR t.`ancestors` LIKE '%|:id')"; + $query .= " AND t.`sem_tree_id` IN (:ids)"; + $parameters['ids'] = $this->getDescendantIds() ?: ['']; } else { $query .= " AND t.`sem_tree_id` = :id"; + $parameters['id'] = $this->id; } - $parameters['id'] = $this->id; $query .= " ORDER BY " . implode(', ', $order_by); -- cgit v1.0