From ca923e5e1d8ed1ab1e3fe88b3a08c2170096d857 Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Thu, 14 Jul 2022 20:21:03 +0000
Subject: [PATCH] fix locking of courses when locking a semester, fixes #1329

Closes #1329

Merge request studip/studip!815
---
 app/controllers/admin/semester.php  | 28 ++++++++++++++++++----------
 lib/models/SemesterCourse.class.php | 11 ++++++++++-
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/app/controllers/admin/semester.php b/app/controllers/admin/semester.php
index b8c3f0a056e..1fbfc7b80d2 100644
--- a/app/controllers/admin/semester.php
+++ b/app/controllers/admin/semester.php
@@ -390,7 +390,6 @@ class Admin_SemesterController extends AuthenticatedController
      * @param  string   $lock_rule     Lock rule to apply (might be null for none)
      * @param  bool     $lock_enroll   Lock enrolment?
      * @param  bool     $degrade_users Degrade users?
-     * @return [type]                  [description]
      */
     private function lockCourses(Semester $semester, $lock_rule, $degrade_users, $lock_enroll)
     {
@@ -398,23 +397,32 @@ class Admin_SemesterController extends AuthenticatedController
         // this
         static $locked_courseset_id = null;
 
+        // Get course ids
+        $query = "SELECT `course_id`
+                  FROM `semester_courses`
+                  JOIN `semester_data` USING (`semester_id`)
+                  GROUP BY `course_id`
+                  HAVING MAX(`beginn`) <= ?";
+        $course_ids = DBManager::get()->fetchFirst($query, [$semester->beginn]);
+
+        // Leave early if no courses are affected
+        if (count($course_ids) === 0) {
+            return;
+        }
+
         // Hide courses and set lock rule
         $query = "UPDATE `seminare`
                   SET `visible` = 0, `lock_rule` = ?
-                  WHERE `Seminar_id` IN (
-                      SELECT course_id FROM semester_courses WHERE semester_courses.semester_id = ?
-                  )";
-        DBManager::get()->execute($query, [$lock_rule, $semester->semester_id]);
+                  WHERE `Seminar_id` IN (?)";
+        DBManager::get()->execute($query, [$lock_rule, $course_ids]);
 
         // Degrade users
         if ($degrade_users) {
             $query = "UPDATE `seminar_user`
                       SET `status` = 'user'
-                      WHERE `Seminar_id` IN (
-                              SELECT course_id FROM semester_courses WHERE semester_courses.semester_id = ?
-                          )
-                          AND `status` = 'autor'";
-            DBManager::get()->execute($query, [$semester->semester_id]);
+                      WHERE `Seminar_id` IN (?)
+                        AND `status` = 'autor'";
+            DBManager::get()->execute($query, [$course_ids]);
         }
 
         // Lock enrolment
diff --git a/lib/models/SemesterCourse.class.php b/lib/models/SemesterCourse.class.php
index e7daf813fd3..0fc6af3f5da 100644
--- a/lib/models/SemesterCourse.class.php
+++ b/lib/models/SemesterCourse.class.php
@@ -21,6 +21,9 @@
  * @property string mkdate The database entry's creation date.
  * @property string chdate The database entry's last modification date.
  *
+ * @property Semester $semester
+ * @property Course $course
+ *
  * The combination of semester_id and course_id form the primary key.
  */
 class SemesterCourse extends SimpleORMap
@@ -30,7 +33,13 @@ class SemesterCourse extends SimpleORMap
         $config['db_table'] = 'semester_courses';
 
         $config['belongs_to']['semester'] = [
-            'class_name' => Semester::class
+            'class_name'  => Semester::class,
+            'foreign_key' => 'semester_id',
+        ];
+
+        $config['belongs_to']['course'] = [
+            'class_name'  => Course::class,
+            'foreign_key' => 'course_id',
         ];
 
         parent::configure($config);
-- 
GitLab