aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoritz Strohm <strohm@data-quest.de>2024-09-18 08:33:26 +0000
committerMoritz Strohm <strohm@data-quest.de>2024-09-18 08:33:26 +0000
commitfbf008efa11f009d2b89109e99c213c44c62e024 (patch)
treeee3379b5b28c6ebf4389a3809700b25a4bfa7626
parent1efacbf3fd32325da48d09eabaf4a8d34d4e0de5 (diff)
TIC 4391, closes #4391
Closes #4391 Merge request studip/studip!3211
-rw-r--r--RELEASE-NOTES.md3
-rw-r--r--app/controllers/admin/tree.php4
-rw-r--r--app/controllers/admin/user.php4
-rw-r--r--app/controllers/admission/restricted_courses.php5
-rw-r--r--app/controllers/contents/courseware.php42
-rw-r--r--app/controllers/course/dates.php18
-rw-r--r--app/controllers/course/details.php8
-rw-r--r--app/controllers/lti.php4
-rw-r--r--app/controllers/my_courses.php2
-rw-r--r--app/controllers/news.php144
-rw-r--r--app/views/admission/courseset/configure.php18
-rw-r--r--app/views/admission/restricted_courses/index.php8
-rw-r--r--app/views/course/wizard/steps/basicdata/index.php20
-rw-r--r--app/views/course/wizard/steps/basicdata/index_studygroup.php6
-rw-r--r--app/views/lvgruppen/lvgruppen/details.php9
-rw-r--r--db/migrations/6.0.18_remove_course_mapping_by_timestamps.php30
-rw-r--r--lib/classes/AutoInsert.php9
-rw-r--r--lib/classes/CoursesetModel.php30
-rw-r--r--lib/classes/JsonApi/Routes/Courses/CoursesByUserIndex.php11
-rw-r--r--lib/classes/JsonApi/Routes/Schedule/UserScheduleShow.php11
-rw-r--r--lib/classes/JsonApi/Schemas/Course.php12
-rw-r--r--lib/classes/ModulesNotification.php3
-rw-r--r--lib/classes/MyRealmModel.php4
-rw-r--r--lib/classes/StudipLog.php8
-rw-r--r--lib/classes/admission/CourseSet.php42
-rw-r--r--lib/classes/coursewizardsteps/BasicDataWizardStep.php17
-rw-r--r--lib/classes/coursewizardsteps/LVGroupsWizardStep.php26
-rw-r--r--lib/classes/globalsearch/GlobalSearchCourses.php6
-rw-r--r--lib/extern/ExternPageCourseDetails.php10
-rw-r--r--lib/functions.php255
-rw-r--r--lib/models/Course.php187
-rw-r--r--lib/models/Lvgruppe.php95
32 files changed, 342 insertions, 709 deletions
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index f342076..f90ccb9 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -74,6 +74,9 @@
- Als Ersatz für viele Methoden der Seminar-Klasse dienen die Klassen `Course`, `CourseDate` und `SeminarCycleDate`, sowie die neue `CourseDateList`-Klasse.
- Die Klassen `TreeAbstract`, `TreeView` und `SemBrowse` wurden ausgebaut. ([Issue #4392](https://gitlab.studip.de/studip/studip/-/issues/4392))
- Zur Anzeige von Baumstrukturen können als Ersatz die Implementierungen des `StudipTreeNode`-Interfaces genutzt werden.
+- Die Zuordnung von Veranstaltungen zu Semestern anhand von Timestamps wurde entfernt. In der Datenbank wurden die Spalten `start_time` und `duration_time` der Tabelle `seminare` entfernt. ([Issue #4391]https://gitlab.studip.de/studip/studip/-/issues/4391))
+ - Plugins, die Veranstaltungen anhand von Timestamps laden oder anderweitig verwenden, müssen angepasst werden!
+ - Das Mapping von Veranstaltungen zu Semestern findet nun ausschließlich anhand der Semester-ID über die Verknüpfungstabelle `semester_courses` statt.
## Security related issues
diff --git a/app/controllers/admin/tree.php b/app/controllers/admin/tree.php
index ec35368..320f10e 100644
--- a/app/controllers/admin/tree.php
+++ b/app/controllers/admin/tree.php
@@ -238,8 +238,8 @@ class Admin_TreeController extends AuthenticatedController
$courseIds = Request::optionArray('assign_semtree');
$order = Config::get()->IMPORTANT_SEMNUMBER
- ? "ORDER BY `start_time` DESC, `VeranstaltungsNummer`, `Name`"
- : "ORDER BY `start_time` DESC, `Name`";
+ ? "ORDER BY `VeranstaltungsNummer`, `Name`"
+ : "ORDER BY `Name`";
$this->courses = array_filter(
Course::findMany($courseIds, $order),
function (Course $course): bool {
diff --git a/app/controllers/admin/user.php b/app/controllers/admin/user.php
index 17375d13..bf8b928 100644
--- a/app/controllers/admin/user.php
+++ b/app/controllers/admin/user.php
@@ -1634,8 +1634,8 @@ class Admin_UserController extends AuthenticatedController
$courseIds = Request::optionArray('export_members');
$order = Config::get()->IMPORTANT_SEMNUMBER
- ? "ORDER BY `start_time` DESC, `VeranstaltungsNummer`, `Name`"
- : "ORDER BY `start_time` DESC, `Name`";
+ ? "ORDER BY `VeranstaltungsNummer`, `Name`"
+ : "ORDER BY `Name`";
$this->courses = array_filter(
Course::findMany($courseIds, $order),
function (Course $course): bool {
diff --git a/app/controllers/admission/restricted_courses.php b/app/controllers/admission/restricted_courses.php
index aafb589..371ea5d 100644
--- a/app/controllers/admission/restricted_courses.php
+++ b/app/controllers/admission/restricted_courses.php
@@ -86,6 +86,7 @@ class Admission_RestrictedCoursesController extends AuthenticatedController
_("Endzeitpunkt")];
$data = [];
foreach ($this->courses as $course) {
+ $sorm_course = Course::find($course['seminare.seminar_id']);
$row = [];
$row[] = $course['cs_name'];
$row[] = $course['course_number'];
@@ -96,8 +97,8 @@ class Admission_RestrictedCoursesController extends AuthenticatedController
$row[] = (int)$course['count_prelim'];
$row[] = (int)$course['count_waiting'];
$row[] = $course['distribution_time'] ? strftime('%x %R', $course['distribution_time']) : '';
- $row[] = isset($course['start_time']) ? strftime('%x %R', $course['start_time']) : '';
- $row[] = isset($course['end_time']) ? strftime('%x %R', $course['end_time']) : '';
+ $row[] = $sorm_course?->getStartSemester()?->beginn ?? '';
+ $row[] = $sorm_course?->getEndSemester()?->ende ?? '';
$data[] = $row;
}
diff --git a/app/controllers/contents/courseware.php b/app/controllers/contents/courseware.php
index 0337e6a..00627e9 100644
--- a/app/controllers/contents/courseware.php
+++ b/app/controllers/contents/courseware.php
@@ -171,46 +171,6 @@ class Contents_CoursewareController extends CoursewareController
$this->sem_courses = $this->getCoursewareCourses($sem_key);
}
- public function pdf_export_action($element_id, $with_children): void
- {
- $element = \Courseware\StructuralElement::findOneById($element_id);
-
- $this->render_pdf($element->pdfExport($this->user, $with_children), trim($element->title).'.pdf');
- }
-
- /**
- * To display the shared courseware
- *
- * @param string $entry_element_id the shared struct element id
- */
- public function shared_content_courseware_action($entry_element_id): void
- {
- global $user;
-
- $navigation = new Navigation(_('Geteiltes Lernmaterial'), 'dispatch.php/contents/courseware/shared_content_courseware/' . $entry_element_id);
- Navigation::addItem('/contents/courseware/shared_content_courseware', $navigation);
- Navigation::activateItem('/contents/courseware/shared_content_courseware');
-
- $this->entry_element_id = $entry_element_id;
-
- $struct = \Courseware\StructuralElement::findOneBySQL(
- "id = ? AND range_type = 'user'",
- [$this->entry_element_id]
- );
-
- if (!$struct) {
- throw new Trails\Exception(404, _('Der geteilte Inhalt kann nicht gefunden werden.'));
- }
-
- if (!$struct->canRead($user) && !$struct->canEdit($user)) {
- throw new AccessDeniedException();
- }
-
- $this->user_id = $struct->owner_id;
-
- $this->setCoursewareSidebar();
- }
-
/**
* Return list of coursewares grouped by semester_id
*
@@ -255,7 +215,7 @@ class Contents_CoursewareController extends CoursewareController
$courses = $courses->filter(function (Course $course) use ($semester) {
return $course->isInSemester($semester);
});
- }
+ }
$sem_courses = [];
foreach ($courses as $course) {
$units = Unit::findCoursesUnits($course);
diff --git a/app/controllers/course/dates.php b/app/controllers/course/dates.php
index bd88932..88a6125 100644
--- a/app/controllers/course/dates.php
+++ b/app/controllers/course/dates.php
@@ -102,22 +102,18 @@ class Course_DatesController extends AuthenticatedController
);
$sidebar->addWidget($actions);
- $course_end_time = $this->course->getEnd_Time();
- if (($course_end_time == -1) || ($course_end_time > 0)) {
+ if (count($this->course->semesters) !== 1) {
//The course has more than one semester:
$semester_widget = new SemesterSelectorWidget(
$this->url_for('course/dates/index')
);
- $semester_end_range = $course_end_time;
- if ($semester_end_range == -1) {
- //The end semester is set to unlimited.
- $semester_end_range = PHP_INT_MAX;
- }
$semester_widget->includeAll();
- $semester_widget->setRange(
- $this->course->start_time,
- $semester_end_range
- );
+ if ($this->course->start_semester && $this->course->end_semester) {
+ $semester_widget->setRange(
+ $this->course->start_semester->beginn,
+ $this->course->end_semester->ende
+ );
+ }
$sidebar->addWidget($semester_widget);
}
diff --git a/app/controllers/course/details.php b/app/controllers/course/details.php
index 7f9c078..707b0ed 100644
--- a/app/controllers/course/details.php
+++ b/app/controllers/course/details.php
@@ -98,11 +98,9 @@ class Course_DetailsController extends AuthenticatedController
// Ausgabe der Modulzuordnung MVV
if ($this->course->getSemClass()->offsetGet('module')) {
- $course_start = $this->course->start_time;
- $course_end = ($this->course->end_time < 0 || is_null($this->course->end_time))
- ? PHP_INT_MAX
- : $this->course->end_time;
- // set filter to show only pathes with valid semester data
+ $course_start = $this->course->start_semester?->beginn ?? 0;
+ $course_end = $this->course->end_semester?->ende ?? PHP_INT_MAX;
+ //Set the filter to show only paths with valid semester data:
ModuleManagementModelTreeItem::setObjectFilter('Modul',
function ($modul) use ($course_start, $course_end) {
// check for public status
diff --git a/app/controllers/lti.php b/app/controllers/lti.php
index 070682e..82d9840 100644
--- a/app/controllers/lti.php
+++ b/app/controllers/lti.php
@@ -69,8 +69,10 @@ class LtiController extends AuthenticatedController
];
$sql = "JOIN seminar_user USING(Seminar_id)
+ LEFT JOIN semester_courses sc ON seminare.seminar_id = sc.course_id
+ LEFT JOIN semester_data s USING (semester_id)
WHERE user_id = ? AND seminar_user.status IN ('dozent', 'tutor')
- ORDER BY start_time DESC, Name";
+ ORDER BY s.beginn DESC, Name";
$this->courses = Course::findBySQL($sql, [$GLOBALS['user']->id]);
}
diff --git a/app/controllers/my_courses.php b/app/controllers/my_courses.php
index d21f2d5..b3677ae 100644
--- a/app/controllers/my_courses.php
+++ b/app/controllers/my_courses.php
@@ -577,7 +577,7 @@ class MyCoursesController extends AuthenticatedController
LEFT JOIN archiv USING (seminar_id)
WHERE user_id = :user_id
GROUP BY seminar_id
- ORDER BY start_time DESC, :sortby";
+ ORDER BY mkdate DESC, :sortby";
$statement = DBManager::get()->prepare($query);
$statement->bindValue(':user_id', $GLOBALS['user']->id);
$statement->bindValue(':sortby', $sortby, StudipPDO::PARAM_COLUMN);
diff --git a/app/controllers/news.php b/app/controllers/news.php
index 375f48b..973646e 100644
--- a/app/controllers/news.php
+++ b/app/controllers/news.php
@@ -621,150 +621,6 @@ class NewsController extends StudipController
return strtotime($date);
}
- /**
- * Searchs for studip areas using given search term
- *
- * @param string $term search term
- * @return array area data
- */
- private function search_area($term)
- {
- global $perm;
- $result = $tmp_result = [];
- if (mb_strlen($term) < 3) {
- PageLayout::postError(_('Der Suchbegriff muss mindestens drei Zeichen lang sein.'));
- return $result;
- }
-
- if ($term === '__THIS_SEMESTER__') {
- $current_semester = Semester::findCurrent();
- $query = "SELECT seminare.Name AS sem_name, seminare.Seminar_id, seminare.visible
- FROM seminar_user
- LEFT JOIN seminare USING (Seminar_id)
- LEFT JOIN semester_courses ON (semester_courses.course_id = seminar_user.Seminar_id)
- WHERE seminar_user.user_id = :user_id
- AND seminar_user.status IN('tutor', 'dozent')
- AND (semester_courses.semester_id = :semester_id OR semester_courses.semester_id IS NULL)
- ";
- if (Config::get()->DEPUTIES_ENABLE) {
- $query .= " UNION SELECT CONCAT(seminare.Name, ' ["._("Vertretung")."]') AS sem_name, seminare.Seminar_id,
- seminare.visible
- FROM deputies
- LEFT JOIN seminare ON (deputies.range_id=seminare.Seminar_id)
- LEFT JOIN semester_courses ON (semester_courses.course_id = deputies.range_id)
- WHERE deputies.user_id = :user_id
- AND (semester_courses.semester_id = :semester_id OR semester_courses.semester_id IS NULL)";
- }
- $query .= " ORDER BY sem_name ASC";
- $statement = DBManager::get()->prepare($query);
- $statement->bindValue(':user_id', $GLOBALS['user']->id);
- $statement->bindValue(':semester_id', $current_semester->semester_id);
- $statement->execute();
- $seminars = $statement->fetchAll(PDO::FETCH_ASSOC);
- foreach($seminars as $sem) {
- $tmp_result[$sem['Seminar_id']] = [
- 'name' => $sem['sem_name'],
- 'type' => 'sem',
- ];
- }
- $term = '';
- } elseif ($term === '__NEXT_SEMESTER__') {
- $next_semester = Semester::findNext();
- $query = "SELECT seminare.Name AS sem_name, seminare.Seminar_id, seminare.visible
- FROM seminar_user
- LEFT JOIN seminare USING (Seminar_id)
- LEFT JOIN semester_courses ON (semester_courses.course_id = seminar_user.Seminar_id)
- WHERE seminar_user.user_id = :user_id
- AND seminar_user.status IN('tutor', 'dozent')
- AND (semester_courses.semester_id = :semester_id OR semester_courses.semester_id IS NULL)";
- if (Config::get()->DEPUTIES_ENABLE) {
- $query .= " UNION SELECT CONCAT(seminare.Name, ' ["._("Vertretung")."]') AS sem_name, seminare.Seminar_id,
- seminare.visible
- FROM deputies
- LEFT JOIN seminare ON (deputies.range_id=seminare.Seminar_id)
- LEFT JOIN semester_courses ON (semester_courses.course_id = deputies.range_id)
- WHERE deputies.user_id = :user_id
- AND (semester_courses.semester_id = :semester_id OR semester_courses.semester_id IS NULL)";
- }
- $query .= " ORDER BY sem_name ASC";
- $statement = DBManager::get()->prepare($query);
- $statement->bindValue(':user_id', $GLOBALS['user']->id);
- $statement->bindValue(':semester_id', $next_semester->semester_id);
- $statement->execute();
- $seminars = $statement->fetchAll(PDO::FETCH_ASSOC);
- foreach($seminars as $sem) {
- $tmp_result[$sem['Seminar_id']] = [
- 'name' => $sem['sem_name'],
- 'type' => 'sem',
- ];
- }
- $term = '';
- } elseif ($term === '__MY_INSTITUTES__') {
- $term = '';
- if ($perm->have_perm('root')) {
- $tmp_result['studip'] = [
- 'name' => 'Stud.IP',
- 'type' => 'global'
- ];
- }
- $inst_list = Institute::getMyInstitutes();
- if (count($inst_list)) {
- foreach($inst_list as $data) {
- $tmp_result[$data['Institut_id']] = [
- 'name' => $data['Name'],
- 'type' => $data['is_fak'] ? 'fak' : 'inst'
- ];
- }
- }
- } else {
- $tmp_result = search_range($term, true) ?: [];
- // add users
- if (mb_stripos(get_fullname(), $term) !== false) {
- $tmp_result[$GLOBALS['user']->id] = [
- 'name' => get_fullname(),
- 'type' => 'user'
- ];
- }
- if (Deputy::isEditActivated()) {
- $query = "SELECT DISTINCT a.user_id
- FROM deputies d
- JOIN auth_user_md5 a ON (d.range_id = a.user_id)
- JOIN user_info u ON (a.user_id=u.user_id)
- WHERE d.user_id = ?
- AND CONCAT(u.title_front, ' ', a.Vorname, ' ', a.Nachname, ', ', u.title_rear) LIKE CONCAT('%',?,'%')";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$GLOBALS['user']->id, $term]);
- while ($data = $statement->fetch(PDO::FETCH_ASSOC)) {
- $tmp_result[$data['user_id']] = [
- 'name' => get_fullname($data['user_id']),
- 'type' => 'user',
- ];
- }
- }
- }
- // workaround: apply search term (ignored by search_range below admin)
- if (count($tmp_result) && !$GLOBALS['perm']->have_perm('admin') && $term) {
- foreach ($tmp_result as $id => $data) {
- if (mb_stripos($data['name'], $term) === false) {
- unset($tmp_result[$id]);
- }
- }
- }
- // prepare result
-
- if (count($tmp_result)) {
- foreach ($tmp_result as $id => $data) {
- $index = $data['type'] === 'fak'
- ? 'inst'
- : $data['type'];
- $result[$index][$id] = $data['name'];
- }
- } elseif ($term) {
- PageLayout::postError(_('Zu diesem Suchbegriff wurden keine Bereiche gefunden.'));
- }
- return $result;
- }
-
public function rss_config_action($range_id)
{
if (!Config::get()->NEWS_RSS_EXPORT_ENABLE || !StudipNews::haveRangePermission('edit', $range_id)) {
diff --git a/app/views/admission/courseset/configure.php b/app/views/admission/courseset/configure.php
index 773624e..6380499 100644
--- a/app/views/admission/courseset/configure.php
+++ b/app/views/admission/courseset/configure.php
@@ -158,12 +158,18 @@ if (isset($flash['error'])) {
<?= sprintf(_("%s zugewiesene Veranstaltungen"), count($courseIds)) ?>
<? else : ?>
<?
- Course::findEachMany(function($c) {
- echo htmlReady($c->getFullName('number-name-semester'));
- echo '<br>';
- },
- $courseIds,
- 'ORDER BY start_time,VeranstaltungsNummer,Name');
+ Course::findEachBySQL(
+ function($c) {
+ echo htmlReady($c->getFullName('number-name-semester'));
+ echo '<br>';
+ },
+ "JOIN `semester_courses`
+ ON `seminare`.`seminar_id` = `semester_courses`.`course_id`
+ JOIN `semester_data` USING (`semester_id`)
+ WHERE `seminare`.`seminar_id` IN ( :course_ids )
+ 'ORDER BY `semester_data`.`beginn`, `VeranstaltungsNummer`, `Name`",
+ ['course_ids' => $courseIds],
+ )
?>
<? endif ?>
<? endif ?>
diff --git a/app/views/admission/restricted_courses/index.php b/app/views/admission/restricted_courses/index.php
index a7b1819..a7503e4 100644
--- a/app/views/admission/restricted_courses/index.php
+++ b/app/views/admission/restricted_courses/index.php
@@ -41,11 +41,11 @@
<td style="white-space:nowrap" data-sort-value="<?= (int) $course['distribution_time']?>">
<?= htmlReady($course['distribution_time'] ? strftime('%x %R', $course['distribution_time']) : '-') ?>
</td>
- <td style="white-space:nowrap" data-sort-value="<?= (int) ($course['start_time'] ?? null) ?>">
- <?= htmlReady(isset($course['start_time']) ? strftime('%x %R', $course['start_time']) : '-') ?>
+ <td style="white-space:nowrap" data-sort-value="<?= (int) ($course->start_semester->beginn ?? null) ?>">
+ <?= htmlReady(($course->start_semester instanceof Semester) ? strftime('%x %R', $course->start_semester->beginn) : '-') ?>
</td>
- <td style="white-space:nowrap" data-sort-value="<?= (int) ($course['end_time'] ?? null) ?>">
- <?= htmlReady(isset($course['end_time']) ? strftime('%x %R', $course['end_time']) : '-') ?>
+ <td style="white-space:nowrap" data-sort-value="<?= (int) ($course->end_semester->ende ?? null) ?>">
+ <?= htmlReady(($course->end_semester instanceof Semester) ? strftime('%x %R', $course->end_semester->ende) : '-') ?>
</td>
</tr>
<? endforeach ?>
diff --git a/app/views/course/wizard/steps/basicdata/index.php b/app/views/course/wizard/steps/basicdata/index.php
index f19643a..372d587 100644
--- a/app/views/course/wizard/steps/basicdata/index.php
+++ b/app/views/course/wizard/steps/basicdata/index.php
@@ -1,3 +1,8 @@
+<?php
+/**
+ * @var Semester[] $semesters
+ */
+?>
<legend>
<?= _('Grunddaten') ?>
</legend>
@@ -21,13 +26,18 @@
<label for="wizard-start-time" class="required">
<?= _('Semester') ?>
</label>
- <select name="start_time" id="wizard-start-time" >
- <?php foreach (array_reverse($semesters) as $semester) { ?>
- <? ($values['start_time'] < time()) ? (($semester->beginn <= time() && time() <= $semester->ende) ? $values['start_time'] = $semester->beginn : '' ): '' ?>
- <option value="<?= $semester->beginn ?>"<?= $semester->beginn == $values['start_time'] ? ' selected="selected"' : '' ?>>
+ <select name="semester_id" id="wizard-start-time" >
+ <?php
+ $default_semester = Semester::findDefault();
+ if ($default_semester && empty($values['start_semester'])) {
+ $values['start_semester'] = $default_semester;
+ }
+ ?>
+ <?php foreach (array_reverse($semesters) as $semester) : ?>
+ <option value="<?= htmlReady($semester->id) ?>" <?= $semester->id == $values['start_semester'] ? ' selected' : '' ?>>
<?= htmlReady($semester->name) ?>
</option>
- <?php } ?>
+ <?php endforeach ?>
</select>
</section>
<section>
diff --git a/app/views/course/wizard/steps/basicdata/index_studygroup.php b/app/views/course/wizard/steps/basicdata/index_studygroup.php
index d7417ab..9f75da5 100644
--- a/app/views/course/wizard/steps/basicdata/index_studygroup.php
+++ b/app/views/course/wizard/steps/basicdata/index_studygroup.php
@@ -71,9 +71,9 @@
<?= _('Einverstanden') ?>
</label>
-<input type="hidden" name="institute" value="<?= htmlReady($values['institute']) ?>">
-<input type="hidden" name="start_time" value="<?= htmlReady($values['start_time']) ?>">
+<input type="hidden" name="institute" value="<?= $values['institute'] ?>"/>
+<input type="hidden" name="start_semester" value="<?= htmlReady($values['start_semester']) ?>">
<input type="hidden" name="studygroup" value="1"/>
<?php foreach ($values['lecturers'] as $id => $assigned) : ?>
- <input type="hidden" name="lecturers[<?= htmlReady($id) ?>]" value="1">
+ <input type="hidden" name="lecturers[<?= $id ?>]" value="1"/>
<?php endforeach ?>
diff --git a/app/views/lvgruppen/lvgruppen/details.php b/app/views/lvgruppen/lvgruppen/details.php
index 6a9c3af..ed9dc9a 100644
--- a/app/views/lvgruppen/lvgruppen/details.php
+++ b/app/views/lvgruppen/lvgruppen/details.php
@@ -1,3 +1,8 @@
+<?php
+/**
+ * @var Course[] $courses
+ */
+?>
<td colspan="6">
<table class="default nohover">
<colgroup>
@@ -80,7 +85,7 @@
<? foreach ($courses[$semester->id] as $course) : ?>
<li>
<a href="<?= URLHelper::getLink('dispatch.php/course/details', ['sem_id' => $course['seminar_id']]) ?>">
- <?= htmlReady(($course['VeranstaltungsNummer'] ? $course['VeranstaltungsNummer'] . ' - ' : '') . $course['Name']) ?>
+ <?= htmlReady($course->getFullName('number-name')) ?>
</a>
</li>
<? endforeach; ?>
@@ -99,7 +104,7 @@
<? foreach ($courses[$semester->id] as $course) : ?>
<li>
<a href="<?= URLHelper::getLink('dispatch.php/course/details', ['sem_id' => $course['seminar_id']]) ?>">
- <?= htmlReady(($course['VeranstaltungsNummer'] ? $course['VeranstaltungsNummer'] . ' - ' : '') . $course['Name']) ?>
+ <?= htmlReady($course->getFullName('number-name')) ?>
</a>
</li>
<? endforeach; ?>
diff --git a/db/migrations/6.0.18_remove_course_mapping_by_timestamps.php b/db/migrations/6.0.18_remove_course_mapping_by_timestamps.php
new file mode 100644
index 0000000..015618c
--- /dev/null
+++ b/db/migrations/6.0.18_remove_course_mapping_by_timestamps.php
@@ -0,0 +1,30 @@
+<?php
+
+
+class RemoveCourseMappingByTimestamps extends Migration
+{
+ public function description()
+ {
+ return 'Removes the mapping of courses to semesters by timestamps (by removing seminare.start_time and seminare.duration_time).';
+ }
+
+ public function up()
+ {
+ $db = DBManager::get();
+ $db->exec(
+ "ALTER TABLE `seminare`
+ DROP COLUMN `start_time`,
+ DROP COLUMN `duration_time`"
+ );
+ }
+
+ protected function down()
+ {
+ $db = DBManager::get();
+ $db->exec(
+ "ALTER TABLE `seminare`
+ ADD COLUMN start_time INT(11) UNSIGNED NULL DEFAULT 0,
+ ADD COLUMN duration_time INT(11) NULL DEFAULT NULL"
+ );
+ }
+}
diff --git a/lib/classes/AutoInsert.php b/lib/classes/AutoInsert.php
index 89d87da..a88ec55 100644
--- a/lib/classes/AutoInsert.php
+++ b/lib/classes/AutoInsert.php
@@ -52,7 +52,7 @@ class AutoInsert
private function loadSettings()
{
- $query = "SELECT a.seminar_id, GROUP_CONCAT(a.status,IF(LENGTH(a.domain_id)=0,':keine',CONCAT(':',a.domain_id))) AS domain_status, s.Name, s.Schreibzugriff, s.start_time ";
+ $query = "SELECT a.seminar_id, GROUP_CONCAT(a.status,IF(LENGTH(a.domain_id)=0,':keine',CONCAT(':',a.domain_id))) AS domain_status, s.Name, s.Schreibzugriff ";
$query .= "FROM auto_insert_sem a ";
$query .= "JOIN seminare AS s USING (Seminar_id) ";
$query .= "GROUP BY s.seminar_id ";
@@ -68,8 +68,7 @@ class AutoInsert
$key = $array[1] . '.' . $array[0];
$this->settings[$key][$result['seminar_id']] = ['Seminar_id' => $result['seminar_id'],
'name' => $result['Name'],
- 'Schreibzugriff' => $result['Schreibzugriff'],
- 'start_time' => $result['start_time']];
+ 'Schreibzugriff' => $result['Schreibzugriff']];
}
}
}
@@ -78,7 +77,7 @@ class AutoInsert
private function getUserSeminars($user_id, $seminare)
{
- $statement = DBManager::get()->prepare("SELECT Seminar_id,s.name,s.Schreibzugriff,s.start_time,su.status
+ $statement = DBManager::get()->prepare("SELECT Seminar_id, s.name, s.Schreibzugriff, su.status
FROM seminar_user su
INNER JOIN seminare s USING(Seminar_id)
WHERE user_id = ? AND Seminar_id IN(?)");
@@ -256,7 +255,7 @@ class AutoInsert
$statement = DBManager::get()->query($query);
$results = $statement->fetchAll(PDO::FETCH_COLUMN);
} else {
- $query = "SELECT a.seminar_id, GROUP_CONCAT(a.status,IF(LENGTH(a.domain_id)=0,':keine',CONCAT(':',a.domain_id))) AS domain_status, s.Name, s.Schreibzugriff, s.start_time ";
+ $query = "SELECT a.seminar_id, GROUP_CONCAT(a.status,IF(LENGTH(a.domain_id)=0,':keine',CONCAT(':',a.domain_id))) AS domain_status, s.Name, s.Schreibzugriff ";
$query .= "FROM auto_insert_sem a ";
$query .= "JOIN seminare AS s USING (Seminar_id) ";
diff --git a/lib/classes/CoursesetModel.php b/lib/classes/CoursesetModel.php
index e12d3b9..076355d 100644
--- a/lib/classes/CoursesetModel.php
+++ b/lib/classes/CoursesetModel.php
@@ -46,13 +46,11 @@ class CoursesetModel
INNER JOIN `seminare` s USING (`Seminar_id`)
LEFT JOIN semester_courses ON (semester_courses.course_id = s.Seminar_id)
WHERE s.status NOT IN(?)
- AND s.`start_time` <= ?
AND (semester_courses.semester_id IS NULL OR semester_courses.semester_id = ?)
AND su.`user_id` = ?
GROUP BY su.`Seminar_id` ";
$parameters = [
$excludeTypes,
- $currentSemester->beginn,
$currentSemester->id,
$GLOBALS['user']->id
];
@@ -63,14 +61,13 @@ class CoursesetModel
FROM `seminare` s
INNER JOIN `deputies` d ON (s.`Seminar_id`=d.`range_id`)
LEFT JOIN semester_courses ON (semester_courses.course_id = s.Seminar_id)
- WHERE s.`start_time` <= ?
- AND (semester_courses.semester_id IS NULL OR semester_courses.semester_id = ?)
+ WHERE (semester_courses.semester_id IS NULL OR semester_courses.semester_id = ?)
AND d.`user_id` = ?
GROUP BY s.`Seminar_id`
";
$parameters = array_merge(
$parameters,
- [$currentSemester->beginn, $currentSemester->id, $GLOBALS['user']->id]
+ [$currentSemester->id, $GLOBALS['user']->id]
);
}
$courses = $db->fetchFirst($query, $parameters);
@@ -88,7 +85,6 @@ class CoursesetModel
LEFT JOIN semester_courses ON (semester_courses.course_id = s.Seminar_id)
INNER JOIN auth_user_md5 aum USING (user_id)
WHERE s.status NOT IN (:exclude_types)
- AND s.start_time <= :sembegin
AND (semester_courses.semester_id IS NULL OR semester_courses.semester_id = :semester_id)
AND $sem_inst.Institut_id IN (:institutes)
AND (
@@ -98,7 +94,6 @@ class CoursesetModel
)";
$courses = $db->fetchFirst($query, [
'exclude_types' => $excludeTypes,
- 'sembegin' => $currentSemester->beginn,
'semester_id' => $currentSemester->id,
'institutes' => $instituteIds,
'filter' => '%' . $filter .'%',
@@ -136,13 +131,15 @@ class CoursesetModel
'visible' => $course->visible,
];
- $query = "SELECT type
- FROM seminar_courseset
- INNER JOIN courseset_rule USING (set_id)
- WHERE type IN ('LockedAdmission','PasswordAdmission')
- AND seminar_id = ?";
+ $query = "SELECT `type`
+ FROM `seminar_courseset`
+ JOIN `courseset_rule` USING (`set_id`)
+ LEFT JOIN `semester_courses` ON `seminar_courseset`.`seminar_id` = `semester_courses`.`course_id`
+ LEFT JOIN `semester_data` USING (`semester_id`)
+ WHERE `type` IN ('LockedAdmission','PasswordAdmission')
+ AND `seminar_id` = ?";
if ($coursesetId) {
- $query .= "AND set_id <> ?";
+ $query .= "AND `set_id` <> ?";
}
$data[$course->id]['admission_type'] = DBManager::get()->fetchColumn(
@@ -151,7 +148,7 @@ class CoursesetModel
);
};
- Course::findEachMany($callable, array_unique($courses),"ORDER BY start_time DESC, VeranstaltungsNummer ASC, Name ASC");
+ Course::findEachMany($callable, array_unique($courses),"ORDER BY `semester_data`.`beginn` DESC, `VeranstaltungsNummer` ASC, `Name` ASC");
return $data;
}
@@ -177,6 +174,7 @@ class CoursesetModel
LEFT JOIN courseset_rule cr ON c.set_id = cr.set_id
LEFT JOIN seminar_courseset sc ON c.set_id = sc.set_id
LEFT JOIN seminare s ON s.seminar_id = sc.seminar_id
+ LEFT JOIN semester_courses ON s.seminar_id = semester_courses.course_id
WHERE ci.institute_id = ?";
if ($filter['course_set_name']) {
$query .= " AND c.name LIKE ?";
@@ -187,8 +185,8 @@ class CoursesetModel
$parameters[] = $filter['rule_types'];
}
if ($filter['semester_id']) {
- $query .= " AND s.start_time = ?";
- $parameters[] = Semester::find($filter['semester_id'])->beginn;
+ $query .= " AND semester_courses.semester_id = ?";
+ $parameters[] = $filter['semester_id'];
}
$cs_count_statement = DBManager::get()->prepare($query);
$query = str_replace('ci.institute_id', '1', $query);
diff --git a/lib/classes/JsonApi/Routes/Courses/CoursesByUserIndex.php b/lib/classes/JsonApi/Routes/Courses/CoursesByUserIndex.php
index ba25369..9f0843a 100644
--- a/lib/classes/JsonApi/Routes/Courses/CoursesByUserIndex.php
+++ b/lib/classes/JsonApi/Routes/Courses/CoursesByUserIndex.php
@@ -98,9 +98,14 @@ class CoursesByUserIndex extends JsonApiController
*/
private function findCoursesByUser(User $user, ?Semester $semester): array
{
- $courses = Course::findMany(
- $user->course_memberships->pluck('seminar_id'),
- 'ORDER BY start_time, name'
+ $courses = Course::findBySQL(
+ 'LEFT JOIN `semester_courses`
+ ON `seminare`.`seminar_id` = `semester_courses`.`course_id`
+ LEFT JOIN `semester_data` USING (`semester_id`)
+ WHERE
+ `seminare`.`seminar_id` IN ( :course_ids )
+ ORDER BY `semester_data`.`beginn`, `seminare`.`name`',
+ ['course_ids' => $user->course_memberships->pluck('seminar_id')]
);
if ($semester) {
diff --git a/lib/classes/JsonApi/Routes/Schedule/UserScheduleShow.php b/lib/classes/JsonApi/Routes/Schedule/UserScheduleShow.php
index 033916c..b96a290 100644
--- a/lib/classes/JsonApi/Routes/Schedule/UserScheduleShow.php
+++ b/lib/classes/JsonApi/Routes/Schedule/UserScheduleShow.php
@@ -57,11 +57,12 @@ class UserScheduleShow extends JsonApiController
{
// get all virtually added seminars
$stmt = \DBManager::get()->prepare(
- 'SELECT c.course_id FROM schedule_courses as c
- LEFT JOIN seminare ON seminare.seminar_id = c.course_id
- WHERE user_id = ? AND start_time = ?'
+ 'SELECT c.`course_id` FROM `schedule_courses` as c
+ LEFT JOIN `seminare` ON `seminare`.`seminar_id` = c.`course_id`
+ JOIN `semester_courses` ON `seminare`.`seminar_id` = `semester_courses`.`course_id`
+ WHERE user_id = :user_id AND semester_id = :semester_id'
);
- $stmt->execute([$user->id, $semester['beginn']]);
+ $stmt->execute(['user_id' => $user->id, 'semester_id' => $semester->id]);
$ids = $stmt->fetchFirst();
// fetch seminar-entries
@@ -71,12 +72,10 @@ class UserScheduleShow extends JsonApiController
LEFT JOIN seminare as s USING (seminar_id)
LEFT JOIN semester_courses ON (s.Seminar_id = semester_courses.course_id)
WHERE su.user_id = :userid
- AND s.start_time <= :begin
AND (semester_courses.semester_id IS NULL OR semester_courses.semester_id = :semester_id)
');
$stmt->execute([
'userid' => $user->id,
- 'begin' => $semester->beginn,
'semester_id' => $semester->id,
]);
diff --git a/lib/classes/JsonApi/Schemas/Course.php b/lib/classes/JsonApi/Schemas/Course.php
index b6fe04a..5ffb6ee 100644
--- a/lib/classes/JsonApi/Schemas/Course.php
+++ b/lib/classes/JsonApi/Schemas/Course.php
@@ -107,29 +107,29 @@ class Course extends SchemaProvider
private function getStartSemester(\Course $course)
{
- if (!$semester = \Semester::findByTimestamp($course->start_time)) {
+ if (!$course->start_semester) {
return null;
}
return [
self::RELATIONSHIP_LINKS => [
- Link::RELATED => $this->createLinkToResource($semester),
+ Link::RELATED => $this->createLinkToResource($course->start_semester),
],
- self::RELATIONSHIP_DATA => $semester,
+ self::RELATIONSHIP_DATA => $course->start_semester,
];
}
private function getEndSemester(\Course $course)
{
- if (!$semester = \Semester::findByTimestamp($course->end_time)) {
+ if (!$course->end_semester) {
return null;
}
return [
self::RELATIONSHIP_LINKS => [
- Link::RELATED => $this->createLinkToResource($semester),
+ Link::RELATED => $this->createLinkToResource($course->end_semester),
],
- self::RELATIONSHIP_DATA => $semester,
+ self::RELATIONSHIP_DATA => $course->end_semester,
];
}
diff --git a/lib/classes/ModulesNotification.php b/lib/classes/ModulesNotification.php
index 1dc361c..f16ea12 100644
--- a/lib/classes/ModulesNotification.php
+++ b/lib/classes/ModulesNotification.php
@@ -86,7 +86,7 @@ class ModulesNotification
}
$my_sem = [];
- $query = "SELECT s.Seminar_id, s.Name, s.chdate, s.start_time, IFNULL(visitdate, :threshold) AS visitdate
+ $query = "SELECT s.Seminar_id, s.Name, s.chdate, IFNULL(visitdate, :threshold) AS visitdate
FROM seminar_user_notifications su
JOIN seminar_user USING (user_id, seminar_id)
JOIN seminare s USING (Seminar_id)
@@ -114,7 +114,6 @@ class ModulesNotification
$my_sem[$seminar_id] = [
'name' => $row['Name'],
'chdate' => $row['chdate'],
- 'start_time' => $row['start_time'],
'tools' => new SimpleCollection($tools),
'visitdate' => $row['visitdate'],
'notification' => $notification->notification_data->getArrayCopy(),
diff --git a/lib/classes/MyRealmModel.php b/lib/classes/MyRealmModel.php
index 8997e78..8fe3fee 100644
--- a/lib/classes/MyRealmModel.php
+++ b/lib/classes/MyRealmModel.php
@@ -272,7 +272,7 @@ class MyRealmModel
$show_semester_name = UserConfig::get($GLOBALS['user']->id)->SHOWSEM_ENABLE;
$sem_courses = [];
- $param_array = 'name seminar_id visible veranstaltungsnummer start_time duration_time status visible ';
+ $param_array = 'name seminar_id visible veranstaltungsnummer status visible ';
$param_array .= 'chdate admission_binding modules admission_prelim';
// filtering courses
@@ -826,7 +826,7 @@ class MyRealmModel
)
);
- $data_fields = 'name seminar_id visible veranstaltungsnummer start_time duration_time status visible '
+ $data_fields = 'name seminar_id visible veranstaltungsnummer status visible '
. 'chdate admission_binding admission_prelim';
$studygroup_data = [];
foreach ($studygroup_memberships as $membership) {
diff --git a/lib/classes/StudipLog.php b/lib/classes/StudipLog.php
index 7a520c9..34321b1 100644
--- a/lib/classes/StudipLog.php
+++ b/lib/classes/StudipLog.php
@@ -196,8 +196,12 @@ class StudipLog
$result = [];
// search for active seminars
- $courses = Course::findBySQL("VeranstaltungsNummer LIKE CONCAT('%', :needle, '%')
- OR seminare.Name LIKE CONCAT('%', :needle, '%') ORDER BY start_time DESC",
+ $courses = Course::findBySQL(
+ "JOIN semester_courses ON seminare.seminar_id = semester_courses.course_id
+ JOIN semester USING (semester_id)
+ WHERE
+ VeranstaltungsNummer LIKE CONCAT('%', :needle, '%')
+ OR seminare.Name LIKE CONCAT('%', :needle, '%') ORDER BY semester.beginn DESC",
[':needle' => $needle]);
foreach ($courses as $course) {
diff --git a/lib/classes/admission/CourseSet.php b/lib/classes/admission/CourseSet.php
index cf87667..9d9889e 100644
--- a/lib/classes/admission/CourseSet.php
+++ b/lib/classes/admission/CourseSet.php
@@ -375,6 +375,7 @@ class CourseSet
LEFT JOIN courseset_rule cr ON cr.set_id=ci.set_id
LEFT JOIN seminar_courseset sc ON c.set_id = sc.set_id
LEFT JOIN seminare s ON s.seminar_id = sc.seminar_id
+ LEFT JOIN `semester_courses` ON s.`seminar_id` = `semester_courses`.`course_id`
WHERE ci.`institute_id`=?";
$parameters = [$instituteId];
if (!$GLOBALS['perm']->have_perm('admin')) {
@@ -390,8 +391,8 @@ class CourseSet
$parameters[] = $filter['rule_types'];
}
if (!empty($filter['semester_id'])) {
- $query .= " AND s.start_time = ?";
- $parameters[] = Semester::find($filter['semester_id'])->beginn;
+ $query .= " AND `semester_courses`.`semester_id` = ?";
+ $parameters[] = $filter['semester_id'];
}
if (!empty($filter['course_set_chdate'])) {
$query .= " AND c.chdate > ?";
@@ -415,8 +416,11 @@ class CourseSet
LEFT JOIN courseset_institute ci ON ci.`set_id`=c.`set_id`
LEFT JOIN courseset_rule cr ON cr.set_id=ci.set_id
LEFT JOIN seminar_courseset sc ON c.set_id = sc.set_id
- LEFT JOIN seminare s ON s.seminar_id = sc.seminar_id
- WHERE ci.institute_id IS NULL";
+ LEFT JOIN seminare s ON s.seminar_id = sc.seminar_id ";
+ if (!empty($filter['semester_id'])) {
+ $query .= "JOIN `semester_courses` ON s.`seminar_id` = `semester_courses`.`course_id` ";
+ }
+ $query .= "WHERE ci.institute_id IS NULL ";
$parameters = [];
$query .= " AND (c.`private`=0 OR c.`user_id`=?)";
$parameters[] = $GLOBALS['user']->id;
@@ -429,8 +433,8 @@ class CourseSet
$parameters[] = $filter['rule_types'];
}
if (!empty($filter['semester_id'])) {
- $query .= " AND s.start_time = ?";
- $parameters[] = Semester::find($filter['semester_id'])->beginn;
+ $query .= " AND `semester_courses`.`semester_id` = ?";
+ $parameters[] = $filter['semester_id'];
}
if (!empty($filter['course_set_chdate'])) {
$query .= " AND c.chdate > ?";
@@ -1026,15 +1030,23 @@ class CourseSet
$tpl->set_attribute('institutes', $institutes);
}
if (!$short || $this->hasAdmissionRule('LimitedAdmission')) {
- $courses = Course::findAndMapMany(function($c) {
- return [
- 'id' => $c->id,
- 'name' => $c->getFullName('number-name-semester'),
- 'visible' => $c->visible
- ];
- },
- array_keys($this->courses),
- 'ORDER BY start_time,VeranstaltungsNummer,Name');
+ $courses = Course::findAndMapBySQL(
+ function($c) {
+ return [
+ 'id' => $c->id,
+ 'name' => $c->getFullName('number-name-semester'),
+ 'visible' => $c->visible
+ ];
+ },
+ "LEFT JOIN `semester_courses` ON `seminare`.`seminar_id` = `semester_courses`.`course_id`
+ LEFT JOIN `semester_data` USING (`semester_id`)
+ WHERE
+ `seminare`.`seminar_id` IN ( :course_ids )
+ 'ORDER BY `semester_data`.`beginn`, `VeranstaltungsNummer`, `Name`'",
+ [
+ 'course_ids' => array_keys($this->courses)
+ ]
+ );
if (!$GLOBALS['perm']->have_perm(Config::get()->SEM_VISIBILITY_PERM)) {
$courses = array_filter($courses,
function ($c) {
diff --git a/lib/classes/coursewizardsteps/BasicDataWizardStep.php b/lib/classes/coursewizardsteps/BasicDataWizardStep.php
index d9e7960..e6f5518 100644
--- a/lib/classes/coursewizardsteps/BasicDataWizardStep.php
+++ b/lib/classes/coursewizardsteps/BasicDataWizardStep.php
@@ -84,17 +84,17 @@ class BasicDataWizardStep implements CourseWizardStep
if ($GLOBALS['perm']->have_perm("admin")) {
if (
$s->id == $GLOBALS['user']->cfg->MY_COURSES_SELECTED_CYCLE
- && empty($values['start_time'])
+ && empty($values['start_semester'])
&& Request::isXhr()
) {
- $values['start_time'] = $s->beginn;
+ $values['start_semester'] = $s->id;
}
}
$semesters[] = $s;
}
}
- if (empty($values['start_time'])) {
- $values['start_time'] = Semester::findDefault()->beginn;
+ if (empty($values['start_semester'])) {
+ $values['start_semester'] = Semester::findDefault()->id;
}
if (!empty($values['studygroup']) && (!count($typestruct) || empty($values['institute'])) ) {
$message = sprintf(_('Die Konfiguration der Studiengruppen ist unvollständig. ' .
@@ -107,8 +107,8 @@ class BasicDataWizardStep implements CourseWizardStep
if (count($semesters) > 0) {
$tpl->set_attribute('semesters', array_reverse($semesters));
// If no semester is set, use current as selected default.
- if (empty($values['start_time'])) {
- $values['start_time'] = Semester::findCurrent()->beginn;
+ if (empty($values['start_semester'])) {
+ $values['start_semester'] = Semester::findCurrent()->id;
}
} else {
$message = sprintf(_('Veranstaltungen können nur ' .
@@ -414,7 +414,7 @@ class BasicDataWizardStep implements CourseWizardStep
$course->name = new I18NString($values['name'], $values['name_i18n'] ?? []);
$course->veranstaltungsnummer = $values['number'] ?? null;
$course->beschreibung = new I18NString($values['description'], $values['description_i18n'] ?? []);
- $course->start_semester = Semester::findByTimestamp($values['start_time']);
+ $course->start_semester = Semester::find($values['start_semester']);
$course->institut_id = $values['institute'];
$semclass = $course->getSemClass();
@@ -426,7 +426,6 @@ class BasicDataWizardStep implements CourseWizardStep
// Studygroups: access and description.
if (in_array($values['coursetype'], studygroup_sem_types())) {
$course->visible = 1;
- $course->duration_time = -1;
switch ($values['access']) {
case 'all':
$course->admission_prelim = 0;
@@ -516,7 +515,7 @@ class BasicDataWizardStep implements CourseWizardStep
{
$data = [
'coursetype' => $course->status,
- 'start_time' => $course->start_time,
+ 'start_semester' => $course->start_semester->id ?? '',
'name' => $course->name,
'name_i18n' => is_object($course->name) ? $course->name->toArray() : $course->name,
'number' => $course->veranstaltungsnummer,
diff --git a/lib/classes/coursewizardsteps/LVGroupsWizardStep.php b/lib/classes/coursewizardsteps/LVGroupsWizardStep.php
index c651714..a901b6c 100644
--- a/lib/classes/coursewizardsteps/LVGroupsWizardStep.php
+++ b/lib/classes/coursewizardsteps/LVGroupsWizardStep.php
@@ -33,7 +33,7 @@ class LVGroupsWizardStep implements CourseWizardStep
->classname;
// store start time of semester selected in first step
- $course_start_time = $values[$step_one_class]['start_time'];
+ $course_start_semester = $values[$step_one_class]['start_semester'];
// We only need our own stored values here.
$values = $values[__CLASS__] ?? [];
@@ -56,8 +56,8 @@ class LVGroupsWizardStep implements CourseWizardStep
$selection_details = $values['lvgruppe_selection']['area_details'] ?? null;
if (
- isset($_SESSION[__CLASS__]['course_start_time'])
- && $_SESSION[__CLASS__]['course_start_time'] != $course_start_time
+ isset($_SESSION[__CLASS__]['course_start_semester'])
+ && $_SESSION[__CLASS__]['course_start_semester'] != $course_start_semester
) {
// don't store previously opened nodes
// because we get in trouble if the semester has changed
@@ -66,7 +66,7 @@ class LVGroupsWizardStep implements CourseWizardStep
$open_nodes = !empty($values['open_lvg_nodes']) ? $values['open_lvg_nodes'] : [];
}
- $_SESSION[__CLASS__]['course_start_time'] = $course_start_time;
+ $_SESSION[__CLASS__]['course_start_semester'] = $course_start_semester;
$tpl->open_lvg_nodes = $open_nodes;
$tpl->selection = $selection;
@@ -124,10 +124,10 @@ class LVGroupsWizardStep implements CourseWizardStep
$course = Course::findCurrent();
if ($course) {
- $course_start = $course->start_time;
- $course_end = ($course->end_time < 0 || is_null($course->end_time)) ? PHP_INT_MAX : $course->end_time;
+ $course_start = $course->start_semester?->beginn ?? 0;
+ $course_end = $course->end_semester?->ende ?? PHP_INT_MAX;
} else {
- $semester = Semester::findByTimestamp($_SESSION[__CLASS__]['course_start_time']);
+ $semester = Semester::find($_SESSION[__CLASS__]['course_start_semester']);
$course_start = $semester->beginn;
$course_end = $semester->ende;
}
@@ -192,10 +192,10 @@ class LVGroupsWizardStep implements CourseWizardStep
$course = Course::findCurrent();
if ($course) {
- $course_start = $course->start_time;
- $course_end = ($course->end_time < 0 || is_null($course->end_time)) ? PHP_INT_MAX : $course->end_time;
+ $course_start = $course->start_semester?->beginn ?? 0;
+ $course_end = $course->end_semester?->ende ?? PHP_INT_MAX;
} else {
- $semester = Semester::findByTimestamp($_SESSION[__CLASS__]['course_start_time']);
+ $semester = Semester::find($_SESSION[__CLASS__]['course_start_semester']);
$course_start = $semester->beginn;
$course_end = $semester->ende;
}
@@ -243,10 +243,10 @@ class LVGroupsWizardStep implements CourseWizardStep
$course = Course::findCurrent();
if ($course) {
- $course_start = $course->start_time;
- $course_end = ($course->end_time < 0 || is_null($course->end_time)) ? PHP_INT_MAX : $course->end_time;
+ $course_start = $course->start_semester?->beginn ?? 0;
+ $course_end = $course->end_semester?->ende ?? PHP_INT_MAX;
} else {
- $semester = Semester::findByTimestamp($_SESSION[__CLASS__]['course_start_time']);
+ $semester = Semester::find($_SESSION[__CLASS__]['course_start_semester']);
$course_start = $semester->beginn;
$course_end = $semester->ende;
}
diff --git a/lib/classes/globalsearch/GlobalSearchCourses.php b/lib/classes/globalsearch/GlobalSearchCourses.php
index 1379f1a..cb1fbae 100644
--- a/lib/classes/globalsearch/GlobalSearchCourses.php
+++ b/lib/classes/globalsearch/GlobalSearchCourses.php
@@ -100,10 +100,12 @@ class GlobalSearchCourses extends GlobalSearchModule implements GlobalSearchFull
}
}
- $sql = "SELECT SQL_CALC_FOUND_ROWS courses.`Seminar_id`, courses.`start_time`,
+ $sql = "SELECT SQL_CALC_FOUND_ROWS courses.`Seminar_id`,
{$language_name} AS `Name`,
courses.`VeranstaltungsNummer`, courses.`status`
FROM `seminare` AS courses
+ JOIN `semester_courses` ON courses.`seminar_id` = `semester_courses`.`course_id`
+ JOIN `semester` USING (`semester_id`)
{$language_join}
JOIN `seminar_user` u ON (u.`Seminar_id` = courses.`Seminar_id` AND u.`status` = 'dozent')
JOIN `auth_user_md5` a ON (a.`user_id` = u.`user_id`)
@@ -118,7 +120,7 @@ class GlobalSearchCourses extends GlobalSearchModule implements GlobalSearchFull
{$seminar_type_condition}
{$semester_condition}
GROUP BY courses.Seminar_id
- ORDER BY start_time DESC";
+ ORDER BY `semester`.`beginn` DESC";
if (Config::get()->IMPORTANT_SEMNUMBER) {
$sql .= ", courses.`VeranstaltungsNummer`";
diff --git a/lib/extern/ExternPageCourseDetails.php b/lib/extern/ExternPageCourseDetails.php
index d9e64d9..05ecd24 100644
--- a/lib/extern/ExternPageCourseDetails.php
+++ b/lib/extern/ExternPageCourseDetails.php
@@ -205,14 +205,16 @@ class ExternPageCourseDetails extends ExternPage
if (!$GLOBALS['MVV_MODUL']['STATUS']['values'][$modul->stat]['public']) {
return false;
}
+ $course_start = $course->start_semester->beginn ?? 0;
+ $course_end = $course->end_semester->ende ?? PHP_INT_MAX;
$modul_start = Semester::find($modul->start)->beginn ?: 0;
$modul_end = Semester::find($modul->end)->beginn ?: PHP_INT_MAX;
- return ($course->start_time <= $modul_end)
+ return ($course_start <= $modul_end)
&& (
- ($course->start_time >= $modul_start)
+ ($course_start >= $modul_start)
|| $course->isOpenEnded()
- || $course->getEndSemester()->ende <= $modul_end
- || $course->getEndSemester()->ende >= $modul_start
+ || $course_end <= $modul_end
+ || $course_end >= $modul_start
);
});
ModuleManagementModelTreeItem::setObjectFilter('StgteilVersion', function ($version) {
diff --git a/lib/functions.php b/lib/functions.php
index 5659aa5..97d0e70 100644
--- a/lib/functions.php
+++ b/lib/functions.php
@@ -653,261 +653,6 @@ function check_ticket($studipticket)
}
/**
- * searches
- *
- * @global array $perm
- * @global object $user
- * @global array $_fullname_sql
- *
- * @param string $search_str optional search-string
- * @param string $search_user optional user to search for
- * @param bool $show_sem if true, the seminar is added to the result
- *
- * @return array
- */
-function search_range($search_str = false, $search_user = false, $show_sem = true)
-{
- global $_fullname_sql;
-
- // Helper function that obtains the correct name for an entity taking
- // in account whether the semesters should be displayed or not
- $formatName = function ($row) use ($show_sem) {
- $name = $row['Name'];
- if ($show_sem) {
- $name = sprintf('%s (%s%s)',
- $name,
- $row['startsem'],
- $row['startsem'] != $row['endsem'] ? ' - ' . $row['endsem'] : '');
- }
- return $name;
- };
-
- $search_result = [];
- $show_sem_sql1 = ", s.start_time, (SELECT semester_data.name FROM semester_data WHERE s.start_time >= semester_data.`beginn` AND s.start_time <= semester_data.`ende` LIMIT 1) AS startsem, IF(semester_courses.semester_id IS NULL, '"._("unbegrenzt")."', (SELECT semester_data.name FROM semester_data LEFT JOIN semester_courses USING (semester_id) WHERE semester_courses.course_id = s.Seminar_id ORDER BY semester_data.`beginn` DESC LIMIT 1)) AS endsem ";
- $show_sem_sql2 = "LEFT JOIN semester_courses ON (semester_courses.course_id = s.Seminar_id) ";
-
-
- if ($search_str && $GLOBALS['perm']->have_perm('root')) {
- if ($search_user) {
- $query = "SELECT user_id, CONCAT({$_fullname_sql['full']}, ' (', username, ')') AS name
- FROM auth_user_md5 AS a
- LEFT JOIN user_info USING (user_id)
- WHERE CONCAT(Vorname, ' ', Nachname, ' ', username) LIKE CONCAT('%', ?, '%')
- ORDER BY Nachname, Vorname";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$search_str]);
- while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
- $search_result[$row['user_id']] = [
- 'type' => 'user',
- 'name' => $row['name'],
- ];
- }
- }
-
- $_hidden = _('(versteckt)');
- $query = "SELECT Seminar_id, IF(s.visible = 0, CONCAT(s.Name, ' {$_hidden}'), s.Name) AS Name %s
- FROM seminare AS s %s
- WHERE s.Name LIKE CONCAT('%%', ?, '%%')
- GROUP BY s.Seminar_id
- ORDER BY start_time DESC, Name";
- $query = $show_sem
- ? sprintf($query, $show_sem_sql1, $show_sem_sql2)
- : sprintf($query, '', '');
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$search_str]);
- while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
- $search_result[$row['Seminar_id']] = [
- 'type' => 'sem',
- 'name' => $formatName($row),
- 'starttime' => $row['start_time'],
- 'startsem' => $row['startsem'],
- ];
- }
-
- $query = "SELECT Institut_id, Name, IF(Institut_id = fakultaets_id, 'fak', 'inst') AS type
- FROM Institute
- WHERE Name LIKE CONCAT('%', ?, '%')
- ORDER BY Name";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$search_str]);
- while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
- $search_result[$row['Institut_id']] = [
- 'type' => $row['type'],
- 'name' => $row['Name'],
- ];
- }
- } elseif ($search_str && $GLOBALS['perm']->have_perm('admin')) {
- $_hidden = _('(versteckt)');
- $query = "SELECT s.Seminar_id, IF(s.visible = 0, CONCAT(s.Name, ' {$_hidden}'), s.Name) AS Name %s
- FROM user_inst AS a
- JOIN seminare AS s USING (Institut_id) %s
- WHERE a.user_id = ? AND a.inst_perms = 'admin' AND s.Name LIKE CONCAT('%%', ?, '%%')
- ORDER BY start_time";
- $query = $show_sem
- ? sprintf($query, $show_sem_sql1, $show_sem_sql2)
- : sprintf($query, '', '');
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$GLOBALS['user']->id, $search_str]);
- while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
- $search_result[$row['Seminar_id']] = [
- 'type' => 'sem',
- 'name' => $formatName($row),
- 'starttime' => $row['start_time'],
- 'startsem' => $row['startsem'],
- ];
- }
-
- $query = "SELECT b.Institut_id, b.Name
- FROM user_inst AS a
- JOIN Institute AS b USING (Institut_id)
- WHERE a.user_id = ? AND a.inst_perms = 'admin'
- AND a.institut_id != b.fakultaets_id AND b.Name LIKE CONCAT('%', ?, '%')
- ORDER BY Name";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$GLOBALS['user']->id, $search_str]);
- while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
- $search_result[$row['Institut_id']] = [
- 'type' => 'inst',
- 'name' => $row['Name'],
- ];
- }
- if ($GLOBALS['perm']->is_fak_admin()) {
- $_hidden = _('(versteckt)');
- $query = "SELECT s.Seminar_id, IF(s.visible = 0, CONCAT(s.Name, ' {$_hidden}'), s.Name) AS Name %s
- FROM user_inst AS a
- JOIN Institute AS b ON (a.Institut_id = b.Institut_id AND b.Institut_id = b.fakultaets_id)
- JOIN Institute AS c ON (c.fakultaets_id = b.Institut_id AND c.fakultaets_id != c.Institut_id)
- JOIN seminare AS s ON (s.Institut_id = c.Institut_id) %s
- WHERE a.user_id = ? AND a.inst_perms = 'admin'
- AND s.Name LIKE CONCAT('%%', ?, '%%')
- ORDER BY start_time DESC, Name";
- $query = $show_sem
- ? sprintf($query, $show_sem_sql1, $show_sem_sql2)
- : sprintf($query, '', '');
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$GLOBALS['user']->id, $search_str]);
- while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
- $search_result[$row['Seminar_id']] = [
- 'type' => 'sem',
- 'name' => $formatName($row),
- 'starttime' => $row['start_time'],
- 'startsem' => $row['startsem'],
- ];
- }
-
- $query = "SELECT c.Institut_id, c.Name
- FROM user_inst AS a
- JOIN Institute AS b ON (a.Institut_id = b.Institut_id AND b.Institut_id = b.fakultaets_id)
- JOIN Institute AS c ON (c.fakultaets_id = b.institut_id AND c.fakultaets_id != c.institut_id)
- WHERE a.user_id = ? AND a.inst_perms = 'admin'
- AND c.Name LIKE CONCAT('%', ?, '%')
- ORDER BY Name";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$GLOBALS['user']->id, $search_str]);
- while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
- $search_result[$row['Institut_id']] = [
- 'type' => 'inst',
- 'name' => $row['Name'],
- ];
- }
-
- $query = "SELECT b.Institut_id, b.Name
- FROM user_inst AS a
- JOIN Institute AS b ON (a.Institut_id = b.Institut_id AND b.Institut_id = b.fakultaets_id)
- WHERE a.user_id = ? AND a.inst_perms = 'admin'
- AND b.Name LIKE CONCAT('%', ?, '%')
- ORDER BY Name";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$GLOBALS['user']->id, $search_str]);
- while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
- $search_result[$row['Institut_id']] = [
- 'type' => 'inst',
- 'name' => $row['Name'],
- ];
- }
- }
- } elseif ($GLOBALS['perm']->have_perm('tutor') || $GLOBALS['perm']->have_perm('autor')) {
- // autors my also have news in studygroups with proper rights
- $_hidden = _('(versteckt)');
- $query = "SELECT s.Seminar_id, IF(s.visible = 0, CONCAT(s.Name, ' {$_hidden}'), s.Name) AS Name %s
- FROM seminar_user AS a
- JOIN seminare AS s USING (Seminar_id) %s
- WHERE a.user_id = ? AND a.status IN ('tutor', 'dozent')
- ORDER BY start_time DESC, Name";
- $query = $show_sem
- ? sprintf($query, $show_sem_sql1, $show_sem_sql2)
- : sprintf($query, '', '');
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$GLOBALS['user']->id]);
- while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
- $search_result[$row['Seminar_id']] = [
- 'type' => 'sem',
- 'name' => $formatName($row),
- 'starttime' => $row['start_time'],
- 'startsem' => $row['startsem'],
- ];
- }
-
- $query = "SELECT Institut_id, b.Name,
- IF (Institut_id = fakultaets_id, 'fak', 'inst') AS type
- FROM user_inst AS a
- JOIN Institute AS b USING (Institut_id)
- WHERE a.user_id = ? AND a.inst_perms IN ('dozent','tutor')
- ORDER BY Name";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$GLOBALS['user']->id]);
- while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
- $search_result[$row['Institut_id']] = [
- 'name' => $row['Name'],
- 'type' => $row['type'],
- ];
- }
- }
-
- if (Config::get()->DEPUTIES_ENABLE) {
- $_hidden = _('(versteckt)');
- $_deputy = _('Vertretung');
- $query = "SELECT s.Seminar_id,
- CONCAT(IF(s.visible = 0, CONCAT(s.Name, ' {$_hidden}'), s.Name), ' [{$_deputy}]') AS Name %s
- FROM seminare AS s
- JOIN deputies AS d ON (s.Seminar_id = d.range_id) %s
- WHERE d.user_id = ?
- ORDER BY s.start_time DESC, Name";
- $query = $show_sem
- ? sprintf($query, $show_sem_sql1, $show_sem_sql2)
- : sprintf($query, '', '');
- $statement = DBManager::get()->prepare($query);
- $statement->execute([$GLOBALS['user']->id]);
- while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
- $search_result[$row['Seminar_id']] = [
- 'type' => 'sem',
- 'name' => $formatName($row),
- 'starttime' => $row['start_time'],
- 'startsem' => $row['startsem'],
- ];
- }
- if (Deputy::isEditActivated()) {
- $query = "SELECT a.user_id, a.username, 'user' AS type,
- CONCAT({$_fullname_sql['full']}, ' (', username, ')') AS name
- FROM auth_user_md5 AS a
- JOIN user_info USING (user_id)
- JOIN deputies AS d ON (a.user_id = d.range_id)
- WHERE d.user_id = ?
- ORDER BY name ASC";
- $statement = DBManager::get()->prepare($query);
- $statement->execute([
- $GLOBALS['user']->id
- ]);
- while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
- $search_result[$row['user_id']] = $row;
- }
- }
- }
-
- return $search_result ?: null;
-}
-
-/**
* format_help_url($keyword)
* returns URL for given help keyword
*
diff --git a/lib/models/Course.php b/lib/models/Course.php
index 25350db..9607b91 100644
--- a/lib/models/Course.php
+++ b/lib/models/Course.php
@@ -25,8 +25,6 @@
* @property string|null $sonstiges database column
* @property int $lesezugriff database column
* @property int $schreibzugriff database column
- * @property int|null $start_time database column
- * @property int|null $duration_time database column
* @property I18NString|null $art database column
* @property I18NString|null $teilnehmer database column
* @property I18NString|null $vorrausetzungen database column
@@ -82,6 +80,16 @@
class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, FeedbackRange, Studip\Calendar\Owner
{
+ /**
+ * @var Semester initial start semester.
+ */
+ protected $initial_start_semester;
+
+ /**
+ * @var Semester initial end semester.
+ */
+ protected $initial_end_semester;
+
protected static function configure($config = [])
{
$config['db_table'] = 'seminare';
@@ -261,7 +269,6 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe
$config['default_values']['lesezugriff'] = 1;
$config['default_values']['schreibzugriff'] = 1;
- $config['default_values']['duration_time'] = 0;
$config['additional_fields']['teachers'] = [
'get' => 'getTeachers'
@@ -299,8 +306,7 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe
$config['i18n_fields']['leistungsnachweis'] = true;
$config['i18n_fields']['ort'] = true;
- $config['registered_callbacks']['before_update'][] = 'logStore';
- $config['registered_callbacks']['before_store'][] = 'cbSetStartAndDurationTime';
+ $config['registered_callbacks']['before_store'][] = 'logStore';
$config['registered_callbacks']['after_create'][] = 'setDefaultTools';
$config['registered_callbacks']['after_delete'][] = function ($course) {
CourseAvatar::getAvatar($course->id)->reset();
@@ -367,6 +373,31 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe
parent::configure($config);
}
+ /**
+ * @param string $relation
+ */
+ public function initRelation($relation): void
+ {
+ if ($relation === 'semesters' && $this->relations[$relation] === null) {
+ parent::initRelation($relation);
+ $this->initial_start_semester = $this->getStartSemester();
+ $this->initial_end_semester = $this->getEndSemester();
+ }
+ parent::initRelation($relation);
+ }
+
+ /**
+ * Override of SimpleORMap::cbAfterInitialize for resetting the flags that indicate semester changes.
+ *
+ * @see SimpleORMap::cbAfterInitialize
+ */
+ protected function cbAfterInitialize($cb_type): void
+ {
+ parent::cbAfterInitialize($cb_type);
+ //Reset the flags for the start and end semester:
+ $this->initial_start_semester = null;
+ $this->initial_end_semester = null;
+ }
/**
* Returns the currently active course or false if none is active.
@@ -411,22 +442,6 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe
});
}
- public function getEnd_Time()
- {
- return $this->duration_time == -1 ? -1 : $this->start_time + $this->duration_time;
- }
-
- public function setEnd_Time($value)
- {
- if ($value == -1) {
- $this->duration_time = -1;
- } elseif ($this->start_time > 0 && $value > $this->start_time) {
- $this->duration_time = $value - $this->start_time;
- } else {
- $this->duration_time = 0;
- }
- }
-
public function _set_semester($field, $value)
{
$method = 'set' . ($field === 'start_semester' ? 'StartSemester' : 'EndSemester');
@@ -497,11 +512,11 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe
*/
public function getStartSemester()
{
- if (count($this->semesters) > 0) {
- return $this->semesters->first();
- } else {
- return Semester::findCurrent();
+ //this is called by __get() and therefore using magic properties is not always safe
+ if ($this->relations['semesters'] === null) {
+ $this->initRelation('semesters');
}
+ return $this->relations['semesters']->first() ?? Semester::findCurrent();
}
/**
@@ -512,9 +527,11 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe
*/
public function getEndSemester()
{
- if (count($this->semesters) > 0) {
- return $this->semesters->last();
+ //this is called by __get() and therefore using magic properties is not always safe
+ if ($this->relations['semesters'] === null) {
+ $this->initRelation('semesters');
}
+ return $this->relations['semesters']->last();
}
/**
@@ -2133,86 +2150,66 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe
*/
protected function logStore()
{
- if ($this->isFieldDirty('start_time')) {
- //Log change of start semester:
- StudipLog::log('SEM_SET_STARTSEMESTER', $this->id, isset($this->start_semester) ? $this->start_semester->name : _('unbegrenzt'));
- NotificationCenter::postNotification('CourseDidChangeSchedule', $this);
- }
- if ($this->isFieldDirty('duration_time')) {
- StudipLog::log('SEM_SET_ENDSEMESTER', $this->id, $this->getTextualSemester());
- NotificationCenter::postNotification('CourseDidChangeSchedule', $this);
- }
-
- $log = [];
- if ($this->isFieldDirty('admission_prelim')) {
- $log[] = $this->admission_prelim ? _('Neuer Anmeldemodus: Vorläufiger Eintrag') : _('Neuer Anmeldemodus: Direkter Eintrag');
- }
+ if (!$this->isNew()) {
+ if ($this->initial_start_semester?->id !== $this->start_semester?->id) {
+ //Log change of start semester:
+ StudipLog::log('SEM_SET_STARTSEMESTER', $this->id, isset($this->start_semester) ? $this->start_semester->name : _('unbegrenzt'));
+ NotificationCenter::postNotification('CourseDidChangeSchedule', $this);
+ }
+ if ($this->initial_end_semester?->id !== $this->end_semester?->id) {
+ StudipLog::log('SEM_SET_ENDSEMESTER', $this->id, $this->getTextualSemester());
+ NotificationCenter::postNotification('CourseDidChangeSchedule', $this);
+ }
- if ($this->isFieldDirty('admission_binding')) {
- $log[] = $this->admission_binding? _('Anmeldung verbindlich') : _('Anmeldung unverbindlich');
- }
+ $log = [];
+ if ($this->isFieldDirty('admission_prelim')) {
+ $log[] = $this->admission_prelim ? _('Neuer Anmeldemodus: Vorläufiger Eintrag') : _('Neuer Anmeldemodus: Direkter Eintrag');
+ }
- if ($this->isFieldDirty('admission_turnout')) {
- $log[] = sprintf(_('Neue Teilnehmerzahl: %s'), (int)$this->admission_turnout);
- }
+ if ($this->isFieldDirty('admission_binding')) {
+ $log[] = $this->admission_binding ? _('Anmeldung verbindlich') : _('Anmeldung unverbindlich');
+ }
- if ($this->isFieldDirty('admission_disable_waitlist')) {
- $log[] = $this->admission_disable_waitlist ? _('Warteliste aktiviert') : _('Warteliste deaktiviert');
- }
+ if ($this->isFieldDirty('admission_turnout')) {
+ $log[] = sprintf(_('Neue Teilnehmerzahl: %s'), (int)$this->admission_turnout);
+ }
- if ($this->isFieldDirty('admission_waitlist_max')) {
- $log[] = sprintf(_('Plätze auf der Warteliste geändert: %u'), (int)$this->admission_waitlist_max);
- }
+ if ($this->isFieldDirty('admission_disable_waitlist')) {
+ $log[] = $this->admission_disable_waitlist ? _('Warteliste aktiviert') : _('Warteliste deaktiviert');
+ }
- if ($this->isFieldDirty('admission_disable_waitlist_move')) {
- $log[] = $this->admission_disable_waitlist ? _('Nachrücken aktiviert') : _('Nachrücken deaktiviert');
- }
+ if ($this->isFieldDirty('admission_waitlist_max')) {
+ $log[] = sprintf(_('Plätze auf der Warteliste geändert: %u'), (int)$this->admission_waitlist_max);
+ }
- if ($this->isFieldDirty('admission_prelim_txt')) {
- if ($this->admission_prelim_txt) {
- $log[] = sprintf(_('Neuer Hinweistext bei vorläufigen Eintragungen: %s'), strip_tags(kill_format($this->admission_prelim_txt)));
- } else {
- $log[] = _('Hinweistext bei vorläufigen Eintragungen wurde entfert');
+ if ($this->isFieldDirty('admission_disable_waitlist_move')) {
+ $log[] = $this->admission_disable_waitlist ? _('Nachrücken aktiviert') : _('Nachrücken deaktiviert');
}
- }
- if (!empty($log)) {
- StudipLog::log(
- 'SEM_CHANGED_ACCESS',
- $this->id,
- null,
- '',
- implode(' - ', $log)
- );
- }
+ if ($this->isFieldDirty('admission_prelim_txt')) {
+ if ($this->admission_prelim_txt) {
+ $log[] = sprintf(_('Neuer Hinweistext bei vorläufigen Eintragungen: %s'), strip_tags(kill_format($this->admission_prelim_txt)));
+ } else {
+ $log[] = _('Hinweistext bei vorläufigen Eintragungen wurde entfert');
+ }
+ }
- if ($this->isFieldDirty('visible')) {
- StudipLog::log($this->visible ? 'SEM_VISIBLE' : 'SEM_INVISIBLE', $this->id);
- }
- }
+ if (!empty($log)) {
+ StudipLog::log(
+ 'SEM_CHANGED_ACCESS',
+ $this->id,
+ null,
+ '',
+ implode(' - ', $log)
+ );
+ }
- /**
- * Called directly before storing the object to edit the columns start_time and duration_time
- * which are both deprecated but are still in use for older plugins.
- */
- public function cbSetStartAndDurationTime()
- {
- if ($this->isFieldDirty('start_time')) {
- $this->setStartSemester(Semester::findByTimestamp($this->start_time));
- }
- if ($this->isFieldDirty('duration_time')) {
- $this->setEndSemester($this->duration_time == -1 ? null : Semester::findByTimestamp($this->start_time + $this->duration_time));
- }
- if ($this->isOpenEnded()) {
- $this->start_time = $this->start_time ?: Semester::findCurrent()->beginn ?? time();
- $this->duration_time = -1;
- } else {
- $this->start_time = $this->getStartSemester()->beginn;
- $this->duration_time = $this->getEndSemester()->beginn - $this->start_time;
+ if ($this->isFieldDirty('visible')) {
+ StudipLog::log($this->visible ? 'SEM_VISIBLE' : 'SEM_INVISIBLE', $this->id);
+ }
}
}
-
//StudipItem interface implementation:
public function getItemName($long_format = true)
@@ -2342,7 +2339,7 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe
"LEFT JOIN semester_courses ON (semester_courses.course_id = seminare.Seminar_id)
WHERE Seminar_id IN (?)
GROUP BY seminare.Seminar_id
- ORDER BY semester_courses.semester_id IS NULL DESC, start_time DESC, {$name_sort}",
+ ORDER BY semester_courses.semester_id IS NULL DESC, {$name_sort}",
[$seminar_ids]
);
}
diff --git a/lib/models/Lvgruppe.php b/lib/models/Lvgruppe.php
index 05f3b59..bdd9f0b 100644
--- a/lib/models/Lvgruppe.php
+++ b/lib/models/Lvgruppe.php
@@ -126,14 +126,10 @@ class Lvgruppe extends ModuleManagementModelTreeItem
$semester = Semester::find($semester_id);
if ($semester) {
$filter_sql = trim($filter_sql) ? $filter_sql . ' AND' : $filter_sql . ' WHERE';
- $filter_sql .= ' seminare.start_time <= :beginn '
- . 'AND (semester_courses.semester_id IS NULL OR semester_courses.semester_id = :semester_id) '
- . 'AND (start_sem.beginn <= :ende AND '
- . 'IF(ISNULL(end_sem.ende), 1, end_sem.ende >= :beginn)) ';
+ $filter_sql .= ' semester_courses.semester_id = :semester_id '
+ . 'AND (semester_courses.semester_id IS NULL OR semester_courses.semester_id = :semester_id) ';
$params = [
- ':semester_id' => $semester->semester_id,
- ':beginn' => $semester->beginn,
- ':ende' => $semester->ende
+ ':semester_id' => $semester->semester_id
];
$semester_join = 'LEFT JOIN mvv_modul ON mvv_modul.modul_id = mvv_modulteil.modul_id '
. 'LEFT JOIN semester_data as start_sem ON start_sem.semester_id = mvv_modul.start '
@@ -197,14 +193,10 @@ class Lvgruppe extends ModuleManagementModelTreeItem
}
$filter_sql = trim($filter_sql) ? $filter_sql : ' AND';
- $filter_sql .= ' seminare.start_time <= :beginn '
- . 'AND (semester_courses.semester_id IS NULL OR semester_courses.semester_id = :semester_id) '
- . 'AND (start_sem.beginn <= :ende AND '
- . 'IF(ISNULL(end_sem.ende), 1, end_sem.ende >= :beginn)) ';
+ $filter_sql .= ' semester_courses.semester_id = :semester_id '
+ . 'AND (semester_courses.semester_id IS NULL OR semester_courses.semester_id = :semester_id) ';
$params = [
- ':semester_id' => $semester->semester_id,
- ':beginn' => $semester->beginn,
- ':ende' => $semester->ende
+ ':semester_id' => $semester->semester_id
];
$semester_join = 'LEFT JOIN mvv_modul ON mvv_modul.modul_id = mvv_modulteil.modul_id '
. 'LEFT JOIN semester_data as start_sem ON start_sem.semester_id = mvv_modul.start '
@@ -517,48 +509,61 @@ class Lvgruppe extends ModuleManagementModelTreeItem
*
* @param bool $only_visible Return only visible courses.
* @param string $semester_id Return only this semester.
- * @return array All assigned courses grouped by semesters.
+ * @return Course[] All assigned courses grouped by semesters.
*/
public function getAllAssignedCourses($only_visible = false, $semester_id = null)
{
- $sem_start_times = [];
-
+ $conditions_sql = '';
+ if ($only_visible) {
+ $conditions_sql .= " AND `seminare`.`visible` = '1'";
+ }
if ($semester_id) {
$semester = Semester::find($semester_id);
if (!$semester) {
return [];
}
- $sem_start_times[$semester->id] = $semester->beginn;
+
+ //Find only courses that lie in that semester.
+ $courses = Course::findBySQL(
+ 'LEFT JOIN `semester_courses` sc
+ ON `seminare`.`seminar_id` = sc.`course_id`
+ JOIN `mvv_lvgruppe_seminar` mls USING (`seminar_id`)
+ WHERE
+ mls.`lvgruppe_id` = :group_id
+ AND (sc.`semester_id` = :semester_id OR sc.`semester_id` IS NULL)'
+ . $conditions_sql . '
+ ORDER BY `seminare`.`Name`',
+ [
+ 'group_id' => $this->id,
+ 'semester_id' => $semester->id
+ ]
+ );
+ return [$semester->id => $courses];
} else {
- $sem_start_times = SimpleORMapCollection::createFromArray(
- Semester::getAll())->toGroupedArray('id', 'beginn');
- $sem_start_times = array_map(
- function ($sem) { return $sem['beginn']; }
- , $sem_start_times);
- }
- $visible_sql = $only_visible ? ' AND visible = 1' : '';
- $courses = [];
- $stmt = DBManager::get()->prepare('SELECT seminar_id, Name, '
- . 'VeranstaltungsNummer, visible, INTERVAL(start_time,'
- . join(',', $sem_start_times)
- . ') AS sem_number, '
- . 'IF(duration_time=-1,' . count($sem_start_times)
- . ',INTERVAL(start_time+duration_time,'
- . join(',', $sem_start_times)
- . ')) AS sem_number_end FROM seminare '
- . 'INNER JOIN mvv_lvgruppe_seminar USING(seminar_id) '
- . 'WHERE lvgruppe_id = ? ' . $visible_sql
- . ' AND start_time <= ' . end($sem_start_times)
- . ' ORDER BY sem_number DESC, Name');
- $stmt->execute([$this->getId()]);
- $sem_ids = array_keys($sem_start_times);
- foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $course) {
- if ($course['sem_number'] == 0) $course['sem_number'] = 1;
- for ($i = $course['sem_number']; $i <= $course['sem_number_end']; $i++) {
- $courses[$sem_ids[$i-1]][] = $course;
+ //No semester specified. Find courses from all semesters.
+ $courses = Course::findBySQL(
+ 'JOIN `mvv_lvgruppe_seminar` mls USING (`seminar_id`)
+ WHERE
+ mls.`lvgruppe_id` = :group_id '
+ . $conditions_sql . '
+ ORDER BY `seminare`.`Name`',
+ [
+ 'group_id' => $this->id
+ ]
+ );
+ $data = [];
+ foreach ($courses as $course) {
+ if (!$course->start_semester) {
+ //An invalid course that cannot be grouped by a semester.
+ continue;
+ }
+ if (!array_key_exists($course->start_semester->id, $data)) {
+ $data[$course->start_semester->id] = [];
+ }
+ $data[$course->start_semester->id][] = $course;
}
+ return $data;
}
- return $courses;
}
/**