diff --git a/lib/classes/StudipTreeNodeCourseTrait.php b/lib/classes/StudipTreeNodeCourseTrait.php new file mode 100644 index 0000000000000000000000000000000000000000..23ea992440a875bc58356b9918a33955bd9543d5 --- /dev/null +++ b/lib/classes/StudipTreeNodeCourseTrait.php @@ -0,0 +1,62 @@ +<?php +trait StudipTreeNodeCourseTrait +{ + protected function getCoursesCondition( + string $alias, + string $semester_id, + $sem_class, + string $searchterm = '', + array $courses = [] + ): array { + $parameters = []; + $order_by = []; + + $condition = " JOIN `seminare` s ON (s.`Seminar_id` = {$alias}.`seminar_id`)"; + + if ($semester_id !== 'all') { + $condition .= " LEFT JOIN `semester_courses` sc ON ({$alias}.`seminar_id` = sc.`course_id`) + LEFT JOIN `semester_data` sd USING (`semester_id`) + WHERE (sc.`semester_id` = :semester OR sc.`semester_id` IS NULL)"; + $parameters[':semester'] = $semester_id; + $order_by[] = 'sd.`beginn`'; + } else { + $condition .= " WHERE 1"; + } + + if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) { + $condition .= " AND s.`visible` = 1"; + } + + if ($sem_class) { + $condition .= " AND s.`status` IN (:types)"; + $parameters['types'] = array_map( + function ($type) { + return $type['id']; + }, + array_filter( + SemType::getTypes(), + function ($t) use ($sem_class) { + return $t['class'] === $sem_class; + } + ) + ); + } + + if ($searchterm) { + $condition .= " AND s.`Name` LIKE :searchterm"; + $parameters['searchterm'] = '%' . trim($searchterm) . '%'; + } + + if ($courses) { + $condition .= " AND {$alias}.`seminar_id` IN (:courses)"; + $parameters['courses'] = $courses; + } + + if (Config::get()->IMPORTANT_SEMNUMBER) { + $order_by[] = 's.`VeranstaltungsNummer`'; + } + $order_by[] = 's.`Name`'; + + return [$condition, $parameters, $order_by]; + } +} diff --git a/lib/models/RangeTreeNode.php b/lib/models/RangeTreeNode.php index 066c021860230d04717558ef695d9be5f96a1755..0d677808b788016051cbc1cd37fb7b60f137ebe4 100644 --- a/lib/models/RangeTreeNode.php +++ b/lib/models/RangeTreeNode.php @@ -30,6 +30,7 @@ class RangeTreeNode extends SimpleORMap implements StudipTreeNode { use StudipTreeNodeCachableTrait; + use StudipTreeNodeCourseTrait; protected static function configure($config = []) { @@ -122,21 +123,18 @@ class RangeTreeNode extends SimpleORMap implements StudipTreeNode */ public function countCourses($semester_id = '', $semclass = 0, $with_children = false): int { - $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 = [ - 'semester' => $semester_id - ]; - } else { - $query .= " JOIN `seminare` s ON (s.`Seminar_id` = i.`seminar_id`) - WHERE 1"; - $parameters = []; + if (!$this->institute && !$with_children) { + return 0; } + [$condition, $parameters] = $this->getCoursesCondition( + 'i', + $semester_id, + $semclass + ); + + $query = "SELECT COUNT(DISTINCT i.`seminar_id`) FROM `seminar_inst` i {$condition}"; + if ($with_children) { $query .= " AND i.`institut_id` IN ( SELECT DISTINCT `studip_object_id` FROM `range_tree` WHERE `item_id` IN (:ids) @@ -147,24 +145,7 @@ class RangeTreeNode extends SimpleORMap implements StudipTreeNode $parameters['id'] = $this->studip_object_id; } - if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) { - $query .= " AND s.`visible` = 1"; - } - - if ($semclass !== 0) { - $query .= " AND s.`status` IN (:types)"; - $parameters['types'] = array_map( - function ($type) { - return $type['id']; - }, - array_filter( - SemType::getTypes(), - function ($t) use ($semclass) { return $t['class'] === $semclass; } - ) - ); - } - - return !$this->institute && !$with_children ? 0 : DBManager::get()->fetchColumn($query, $parameters); + return DBManager::get()->fetchColumn($query, $parameters); } public function getCourses( @@ -175,21 +156,15 @@ class RangeTreeNode extends SimpleORMap implements StudipTreeNode array $courses = [] ): array { - $query = "SELECT DISTINCT s.* FROM `seminar_inst` i"; - $order_by = []; + [$condition, $parameters, $order_by] = $this->getCoursesCondition( + 'i', + $semester_id, + $semclass, + $searchterm, + $courses + ); - 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`) - LEFT JOIN `semester_data` sd USING (`semester_id`) - WHERE sc.`semester_id` = :semester)"; - $parameters = ['semester' => $semester_id]; - $order_by[] = 'sd.`beginn`'; - } else { - $query .= " JOIN `seminare` s ON (s.`Seminar_id` = i.`seminar_id`) - WHERE 1"; - $parameters = []; - } + $query = "SELECT DISTINCT s.* FROM `seminar_inst` AS i {$condition}"; if ($with_children) { $query .= " AND i.`institut_id` IN ( @@ -201,38 +176,6 @@ class RangeTreeNode extends SimpleORMap implements StudipTreeNode $parameters['id'] = $this->studip_object_id; } - if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) { - $query .= " AND s.`visible` = 1"; - } - - if ($semclass !== 0) { - $query .= " AND s.`status` IN (:types)"; - $parameters['types'] = array_map( - function ($type) { - return $type['id']; - }, - array_filter( - SemType::getTypes(), - function ($t) use ($semclass) { return $t['class'] === $semclass; } - ) - ); - } - - 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) { - $order_by[] = 's.`VeranstaltungsNummer`'; - } - $order_by[] = 's.`Name`'; - $query .= " ORDER BY " . implode(', ', $order_by); return DBManager::get()->fetchAll($query, $parameters, 'Course::buildExisting'); diff --git a/lib/models/StudipStudyArea.php b/lib/models/StudipStudyArea.php index d95fe059d2aa0976d8009f7932258d2dc6df1fe8..0bc3d66e7c74dad1c86388208d74440db4c56884 100644 --- a/lib/models/StudipStudyArea.php +++ b/lib/models/StudipStudyArea.php @@ -33,6 +33,7 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode { use StudipTreeNodeCachableTrait; + use StudipTreeNodeCourseTrait; /** * This constant represents the key of the root area. @@ -336,7 +337,7 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode * Get an associative array of all study areas of a course. The array * contains StudipStudyArea instances * - * @param id the course's ID + * @param string $id the course's ID * * @return SimpleCollection a SimpleORMapCollection of that course's study areas */ @@ -504,23 +505,19 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode $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 .= " 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 = [ - 'semester' => $semester_id - ]; - } else { - $query .= " JOIN `seminare` s ON (s.`Seminar_id` = t.`seminar_id`) - WHERE 1"; - $parameters = []; + ): int { + if ($this->id === 'root' && !$with_children) { + return 0; } + [$condition, $parameters] = $this->getCoursesCondition( + 't', + $semester_id, + $semclass + ); + + $query = "SELECT COUNT(DISTINCT t.`seminar_id`) FROM `seminar_sem_tree` t {$condition}"; + if ($with_children) { $query .= " AND t.`sem_tree_id` IN (:ids)"; $parameters['ids'] = array_merge([$this->id], $this->getDescendantIds()); @@ -529,24 +526,7 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode $parameters['id'] = $this->id; } - if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) { - $query .= " AND s.`visible` = 1"; - } - - if ($semclass !== 0) { - $query .= " AND s.`status` IN (:types)"; - $parameters['types'] = array_map( - function ($type) { - return $type['id']; - }, - array_filter( - SemType::getTypes(), - function ($t) use ($semclass) { return $t['class'] === $semclass; } - ) - ); - } - - return $this->id === 'root' && !$with_children ? 0 : DBManager::get()->fetchColumn($query, $parameters); + return DBManager::get()->fetchColumn($query, $parameters); } public function getCourses( @@ -557,21 +537,15 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode array $courses = [] ): array { - $query = "SELECT DISTINCT s.* FROM `seminar_sem_tree` t"; - $order_by = []; + [$condition, $parameters, $order_by] = $this->getCoursesCondition( + 't', + $semester_id, + $semclass, + $searchterm, + $courses + ); - if ($semester_id !== 'all') { - $query .= " JOIN `seminare` s ON (s.`Seminar_id` = t.`seminar_id`) - LEFT JOIN `semester_courses` sc ON (t.`seminar_id` = sc.`course_id`) - LEFT JOIN `semester_data` sd USING (`semester_id`) - WHERE sc.`semester_id` = :semester"; - $parameters = ['semester' => $semester_id]; - $order_by[] = 'sd.`beginn`'; - } else { - $query .= " JOIN `seminare` s ON (s.`Seminar_id` = t.`seminar_id`) - WHERE 1"; - $parameters = []; - } + $query = "SELECT DISTINCT s.* FROM `seminar_sem_tree` AS t {$condition}"; if ($with_children) { $query .= " AND t.`sem_tree_id` IN (:ids)"; @@ -581,38 +555,6 @@ class StudipStudyArea extends SimpleORMap implements StudipTreeNode $parameters['id'] = $this->id; } - if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) { - $query .= " AND s.`visible` = 1"; - } - - if ($semclass !== 0) { - $query .= " AND s.`status` IN (:types)"; - $parameters['types'] = array_map( - function ($type) { - return $type['id']; - }, - array_filter( - SemType::getTypes(), - function ($t) use ($semclass) { return $t['class'] === $semclass; } - ) - ); - } - - 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) { - $order_by[] = 's.`VeranstaltungsNummer`'; - } - $order_by[] = 's.`Name`'; - $query .= " ORDER BY " . implode(', ', $order_by); return DBManager::get()->fetchAll($query, $parameters, 'Course::buildExisting');