From 9315424f1ff73d9a5d9461c37d00991bf6047484 Mon Sep 17 00:00:00 2001
From: Thomas Hackl <hackl@data-quest.de>
Date: Thu, 21 Mar 2024 08:04:46 +0000
Subject: [PATCH] Resolve "Anzahl der Veranstaltungen in der Unterebene beim
 VVZ passt nicht"

Closes #3852

Merge request studip/studip!2714
---
 lib/models/RangeTreeNode.php         | 101 ++++++++++++---------------
 lib/models/StudipStudyArea.class.php |  66 +++++++++--------
 2 files changed, 80 insertions(+), 87 deletions(-)

diff --git a/lib/models/RangeTreeNode.php b/lib/models/RangeTreeNode.php
index 4c4ae0df6c6..29d4bcdabd9 100644
--- a/lib/models/RangeTreeNode.php
+++ b/lib/models/RangeTreeNode.php
@@ -122,33 +122,28 @@ class RangeTreeNode extends SimpleORMap implements StudipTreeNode
      */
     public function countCourses($semester_id = '', $semclass = 0, $with_children = false): int
     {
-        if ($semester_id) {
-            $query = "SELECT COUNT(DISTINCT i.`seminar_id`)
-                      FROM `seminar_inst` i
-                      JOIN `seminare` s ON (s.`Seminar_id` = i.`seminar_id`)
-                      LEFT JOIN `semester_courses` sc ON (i.`seminar_id` = sc.`course_id`)
-                      WHERE i.`institut_id` IN (
-                          SELECT DISTINCT `studip_object_id`
-                          FROM `range_tree`
-                          WHERE `item_id` IN (:ids)
-                      ) AND (
-                          sc.`semester_id` = :semester
-                          OR sc.`semester_id` IS NULL
-                      )";
+        $query = "SELECT COUNT(DISTINCT i.`seminar_id`) FROM `seminar_inst` i";
+
+        if ($semester_id !== 'all') {
+            $query .= " JOIN `seminare` s ON (s.`Seminar_id` = i.`seminar_id`)
+                  LEFT JOIN `semester_courses` sc ON (i.`seminar_id` = sc.`course_id`)
+                  WHERE sc.`semester_id` = :semester";
             $parameters = [
-                'ids' => $with_children ? $this->getDescendantIds() : [$this->id],
                 'semester' => $semester_id
             ];
         } else {
-            $query = "SELECT COUNT(DISTINCT `seminar_id`)
-                      FROM `seminar_inst` i
-                      JOIN `seminare` s ON (s.`Seminar_id` = i.`seminar_id`)
-                      WHERE `institut_id` IN (
-                          SELECT DISTINCT `studip_object_id`
-                          FROM `range_tree`
-                          WHERE `item_id` IN (:ids)
-                      )";
-            $parameters = ['ids' => $with_children ? $this->getDescendantIds() : [$this->id]];
+            $query .= " JOIN `seminare` s ON (s.`Seminar_id` = i.`seminar_id`)";
+            $parameters = [];
+        }
+
+        if ($with_children) {
+            $query .= " AND i.`institut_id` IN (
+                    SELECT DISTINCT `studip_object_id` FROM `range_tree` WHERE `item_id` IN (:ids)
+                )";
+            $parameters['ids'] = array_merge([$this->id], $this->getDescendantIds());
+        } else {
+            $query .= " AND i.`institut_id` = :id";
+            $parameters['id'] = $this->studip_object_id;
         }
 
         if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) {
@@ -179,48 +174,32 @@ class RangeTreeNode extends SimpleORMap implements StudipTreeNode
         array $courses = []
     ): array
     {
-        if ($semester_id !== 'all') {
-            $query = "SELECT DISTINCT s.*
-                      FROM `seminare` s
-                      JOIN `seminar_inst` i ON (i.`seminar_id` = s.`Seminar_id`)
-                      LEFT JOIN `semester_courses` sem ON (sem.`course_id` = s.`Seminar_id`)
-                      WHERE i.`institut_id` IN (
-                          SELECT DISTINCT `studip_object_id`
-                          FROM `range_tree`
-                          WHERE `item_id` IN (:ids)
-                      ) AND (
-                          sem.`semester_id` = :semester
-                          OR sem.`semester_id` IS NULL
-                      )";
+        $query = "SELECT DISTINCT s.* FROM `seminar_inst` i";
 
+        if ($semester_id !== 'all') {
+            $query .= " JOIN `seminare` s ON (s.`Seminar_id` = i.`seminar_id`)
+                  LEFT JOIN `semester_courses` sc ON (i.`seminar_id` = sc.`course_id`)
+                  WHERE sc.`semester_id` = :semester";
             $parameters = [
-                'ids' => $with_children ? $this->getDescendantIds() : [$this->id],
                 'semester' => $semester_id
             ];
         } else {
-            $query = "SELECT DISTINCT s.*
-                      FROM `seminare` s
-                      JOIN `seminar_inst` i ON (i.`seminar_id` = s.`Seminar_id`)
-                      WHERE i.`institut_id` IN (
-                          SELECT DISTINCT `studip_object_id`
-                          FROM `range_tree`
-                          WHERE `item_id` IN (:ids)
-                      )";
-            $parameters = ['ids' => $with_children ? $this->getDescendantIds() : [$this->id]];
+            $query .= " JOIN `seminare` s ON (s.`Seminar_id` = i.`seminar_id`)";
+            $parameters = [];
         }
 
-        if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) {
-            $query .= " AND s.`visible` = 1";
-        }
-
-        if ($searchterm) {
-            $query .= " AND s.`Name` LIKE :searchterm";
-            $parameters['searchterm'] = '%' . trim($searchterm) . '%';
+        if ($with_children) {
+            $query .= " AND i.`institut_id` IN (
+                    SELECT DISTINCT `studip_object_id` FROM `range_tree` WHERE `item_id` IN (:ids)
+                )";
+            $parameters['ids'] = array_merge([$this->id], $this->getDescendantIds());
+        } else {
+            $query .= " AND i.`institut_id` = :id";
+            $parameters['id'] = $this->studip_object_id;
         }
 
-        if ($courses) {
-            $query .= " AND s.`Seminar_id` IN (:courses)";
-            $parameters['courses'] = $courses;
+        if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) {
+            $query .= " AND s.`visible` = 1";
         }
 
         if ($semclass !== 0) {
@@ -236,6 +215,16 @@ class RangeTreeNode extends SimpleORMap implements StudipTreeNode
             );
         }
 
+        if ($searchterm) {
+            $query .= " AND s.`Name` LIKE :searchterm";
+            $parameters['searchterm'] = '%' . trim($searchterm) . '%';
+        }
+
+        if ($courses) {
+            $query .= " AND t.`seminar_id` IN (:courses)";
+            $parameters['courses'] = $courses;
+        }
+
         if (Config::get()->IMPORTANT_SEMNUMBER) {
             $query .= " ORDER BY s.`start_time`, s.`VeranstaltungsNummer`, s.`Name`";
         } else {
diff --git a/lib/models/StudipStudyArea.class.php b/lib/models/StudipStudyArea.class.php
index 2d13b186eff..8da8e169262 100644
--- a/lib/models/StudipStudyArea.class.php
+++ b/lib/models/StudipStudyArea.class.php
@@ -481,28 +481,32 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode
     /**
      * @see StudipTreeNode::countCourses()
      */
-    public function countCourses($semester_id = 'all', $semclass = 0, $with_children = false) :int
+    public function countCourses(
+        $semester_id = 'all',
+        $semclass = 0,
+        $with_children = false
+    ) :int
     {
+        $query = "SELECT COUNT(DISTINCT t.`seminar_id`) FROM `seminar_sem_tree` t";
+
         if ($semester_id !== 'all') {
-            $query = "SELECT COUNT(DISTINCT t.`seminar_id`)
-                      FROM `seminar_sem_tree` t
-                      JOIN `seminare` s ON (s.`Seminar_id` = t.`seminar_id`)
-                      LEFT JOIN `semester_courses` sc ON (t.`seminar_id` = sc.`course_id`)
-                      WHERE t.`sem_tree_id` IN (:ids)
-                        AND (
-                          sc.`semester_id` = :semester
-                          OR sc.`semester_id` IS NULL
-                        )";
+            $query .= " JOIN `seminare` s ON (s.`Seminar_id` = t.`seminar_id`)
+                  LEFT JOIN `semester_courses` sc ON (t.`seminar_id` = sc.`course_id`)
+                  WHERE sc.`semester_id` = :semester";
             $parameters = [
-                'ids' => $with_children ? array_merge([$this->id], $this->getDescendantIds()) : [$this->id],
                 'semester' => $semester_id
             ];
         } else {
-            $query = "SELECT COUNT(DISTINCT t.`seminar_id`)
-                      FROM `seminar_sem_tree` t
-                      JOIN `seminare` s ON (s.`Seminar_id` = t.`seminar_id`)
-                      WHERE `sem_tree_id` IN (:ids)";
-            $parameters = ['ids' => $with_children ? array_merge([$this->id], $this->getDescendantIds()) : [$this->id]];
+            $query .= " JOIN `seminare` s ON (s.`Seminar_id` = t.`seminar_id`)";
+            $parameters = [];
+        }
+
+        if ($with_children) {
+            $query .= " AND t.`sem_tree_id` IN (:ids)";
+            $parameters['ids'] = array_merge([$this->id], $this->getDescendantIds());
+        } else {
+            $query .= " AND t.`sem_tree_id` = :id";
+            $parameters['id'] = $this->id;
         }
 
         if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) {
@@ -533,26 +537,26 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode
         array $courses = []
     ): array
     {
+        $query = "SELECT DISTINCT s.* FROM `seminar_sem_tree` t";
+
         if ($semester_id !== 'all') {
-            $query = "SELECT DISTINCT s.*
-                      FROM `seminare` s
-                      JOIN `seminar_sem_tree` t ON (t.`seminar_id` = s.`Seminar_id`)
-                      LEFT JOIN `semester_courses` sem ON (sem.`course_id` = s.`Seminar_id`)
-                      WHERE t.`sem_tree_id` IN (:ids)
-                        AND (
-                          sem.`semester_id` = :semester
-                          OR sem.`semester_id` IS NULL
-                        )";
+            $query .= " JOIN `seminare` s ON (s.`Seminar_id` = t.`seminar_id`)
+                  LEFT JOIN `semester_courses` sc ON (t.`seminar_id` = sc.`course_id`)
+                  WHERE sc.`semester_id` = :semester";
             $parameters = [
-                'ids' => $with_children ? $this->getDescendantIds() : [$this->id],
                 'semester' => $semester_id
             ];
         } else {
-            $query = "SELECT DISTINCT s.*
-                      FROM `seminare` s
-                      JOIN `seminar_sem_tree` t ON (t.`seminar_id` = s.`Seminar_id`)
-                      WHERE t.`sem_tree_id` IN (:ids)";
-            $parameters = ['ids' => $with_children ? $this->getDescendantIds() : [$this->id]];
+            $query .= " JOIN `seminare` s ON (s.`Seminar_id` = t.`seminar_id`)";
+            $parameters = [];
+        }
+
+        if ($with_children) {
+            $query .= " AND t.`sem_tree_id` IN (:ids)";
+            $parameters['ids'] = array_merge([$this->id], $this->getDescendantIds());
+        } else {
+            $query .= " AND t.`sem_tree_id` = :id";
+            $parameters['id'] = $this->id;
         }
 
         if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) {
-- 
GitLab