From fb47f10e4e0fb350219a70f1b6ae16c83d72b934 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Noack?= <noack@data-quest.de>
Date: Fri, 2 Feb 2024 12:42:33 +0000
Subject: [PATCH] Resolve #3193  "Keine unbegrenzten Veranstaltungen mehr in
 der Kategorie Lehre"

Closes #3193

Merge request studip/studip!2160
---
 app/controllers/admin/sem_classes.php         |  1 +
 app/views/admin/sem_classes/details.php       | 14 +++++++---
 app/views/course/timesrooms/editSemester.php  |  8 +++---
 .../5.5.26_tic3193_no_unlimited_courses.php   | 26 +++++++++++++++++++
 lib/classes/SemClass.class.php                |  4 ++-
 .../assets/javascripts/lib/admin_sem_class.js |  3 ++-
 6 files changed, 47 insertions(+), 9 deletions(-)
 create mode 100644 db/migrations/5.5.26_tic3193_no_unlimited_courses.php

diff --git a/app/controllers/admin/sem_classes.php b/app/controllers/admin/sem_classes.php
index aef3e8487d4..c0b098f89d8 100644
--- a/app/controllers/admin/sem_classes.php
+++ b/app/controllers/admin/sem_classes.php
@@ -125,6 +125,7 @@ class Admin_SemClassesController extends AuthenticatedController
         $sem_class->set('admission_type_default', Request::int("admission_type_default"));
         $sem_class->set('show_raumzeit', Request::int("show_raumzeit"));
         $sem_class->set('is_group', Request::int("is_group"));
+        $sem_class->set('unlimited_forbidden', Request::bool('unlimited_forbidden'));
         $sem_class->store();
         foreach (array_keys($sem_class->getModules()) as $module_name) {
             if ($sem_class->isModuleMandatory($module_name) && !$old_data_sem_class->isModuleMandatory($module_name)) {
diff --git a/app/views/admin/sem_classes/details.php b/app/views/admin/sem_classes/details.php
index b6b8a35ee12..54f4f903353 100644
--- a/app/views/admin/sem_classes/details.php
+++ b/app/views/admin/sem_classes/details.php
@@ -196,14 +196,20 @@
         </label>
 
         <label>
-            <?= _("Kurzer Beschreibungstext zum Anlegen einer Veranstaltung") ?>
-            <textarea id="create_description" maxlength="200" style="width: 100%"><?= htmlReady($sem_class['create_description']) ?></textarea>
+            <input type="checkbox" id="is_group" value="1" <?= $sem_class['is_group'] ? 'checked' : '' ?>>
+            <?= _('Kann Unterveranstaltungen haben') ?>
+        </label>
+
+        <label>
+            <input type="checkbox" id="unlimited_forbidden" value="1" <?= $sem_class['unlimited_forbidden'] ? 'checked' : '' ?>>
+            <?= _('Unbegrenzte Laufzeit verbieten') ?>
         </label>
 
         <label>
-            <input type="checkbox" id="is_group" value="1"<?= $sem_class['is_group'] ? " checked" : "" ?>>
-            <?= _("Kann Unterveranstaltungen haben") ?>
+            <?= _('Kurzer Beschreibungstext zum Anlegen einer Veranstaltung') ?>
+            <textarea id="create_description" maxlength="200" style="width: 100%"><?= htmlReady($sem_class['create_description']) ?></textarea>
         </label>
+
     </fieldset>
 
     <fieldset class="attribute_table">
diff --git a/app/views/course/timesrooms/editSemester.php b/app/views/course/timesrooms/editSemester.php
index 0ac8d1d212c..84b654c85be 100644
--- a/app/views/course/timesrooms/editSemester.php
+++ b/app/views/course/timesrooms/editSemester.php
@@ -37,9 +37,11 @@
                         </option>
                     <? endif ?>
                 <? endforeach ?>
-                <option value="-1"<?= $course->isOpenEnded() ? 'selected' : '' ?>>
-                    <?= _('Unbegrenzt') ?>
-                </option>
+                <? if (!$course->getSemClass()['unlimited_forbidden']) : ?>
+                    <option value="-1"<?= $course->isOpenEnded() ? 'selected' : '' ?>>
+                        <?= _('Unbegrenzt') ?>
+                    </option>
+                <? endif ?>
             </select>
         </label>
     </fieldset>
diff --git a/db/migrations/5.5.26_tic3193_no_unlimited_courses.php b/db/migrations/5.5.26_tic3193_no_unlimited_courses.php
new file mode 100644
index 00000000000..ef45bced3ab
--- /dev/null
+++ b/db/migrations/5.5.26_tic3193_no_unlimited_courses.php
@@ -0,0 +1,26 @@
+<?php
+
+final class Tic3193NoUnlimitedCourses extends Migration
+{
+    public function description()
+    {
+        return 'adds option to forbid unlimited courses';
+    }
+
+    public function up()
+    {
+        DBManager::get()->exec("
+            ALTER TABLE `sem_classes` ADD `unlimited_forbidden` TINYINT UNSIGNED NOT NULL DEFAULT 0 AFTER `is_group`
+        ");
+        $cache = StudipCacheFactory::getCache();
+        $cache->expire('DB_SEM_CLASSES_ARRAY');
+    }
+
+    public function down()
+    {
+        DBManager::get()->exec("ALTER TABLE `sem_classes` DROP `unlimited_forbidden`");
+        $cache = StudipCacheFactory::getCache();
+        $cache->expire('DB_SEM_CLASSES_ARRAY');
+    }
+}
+
diff --git a/lib/classes/SemClass.class.php b/lib/classes/SemClass.class.php
index cec05cc0ef0..09580e20444 100644
--- a/lib/classes/SemClass.class.php
+++ b/lib/classes/SemClass.class.php
@@ -383,6 +383,7 @@ class SemClass implements ArrayAccess
                 "admission_type_default = :admission_type_default, " .
                 "show_raumzeit = :show_raumzeit, " .
                 "is_group = :is_group, " .
+                "unlimited_forbidden = :unlimited_forbidden, " .
                 "chdate = UNIX_TIMESTAMP() " .
             "WHERE id = :id ".
         "");
@@ -425,7 +426,8 @@ class SemClass implements ArrayAccess
             'admission_prelim_default' => (int)$this->data['admission_prelim_default'],
             'admission_type_default' => (int)$this->data['admission_type_default'],
             'show_raumzeit' => (int) $this->data['show_raumzeit'],
-            'is_group' => (int) $this->data['is_group']
+            'is_group' => (int) $this->data['is_group'],
+            'unlimited_forbidden' => (int) $this->data['unlimited_forbidden'],
         ]);
     }
 
diff --git a/resources/assets/javascripts/lib/admin_sem_class.js b/resources/assets/javascripts/lib/admin_sem_class.js
index 698a8d6b277..5ac95324681 100644
--- a/resources/assets/javascripts/lib/admin_sem_class.js
+++ b/resources/assets/javascripts/lib/admin_sem_class.js
@@ -65,7 +65,8 @@ const admin_sem_class = {
                 admission_prelim_default: jQuery('#admission_prelim_default').val(),
                 admission_type_default: jQuery('#admission_type_default').val(),
                 show_raumzeit: jQuery('#show_raumzeit').is(':checked') ? 1 : 0,
-                is_group: jQuery('#is_group').is(':checked') ? 1 : 0
+                is_group: jQuery('#is_group').is(':checked') ? 1 : 0,
+                unlimited_forbidden: jQuery('#unlimited_forbidden').is(':checked') ? 1 : 0
             },
             type: 'POST',
             dataType: 'json',
-- 
GitLab