From 57c22c7079d12b5225c6abd622e291bab45b7bde Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Willms <tleilax+studip@gmail.com> Date: Wed, 25 Sep 2024 06:59:40 +0000 Subject: [PATCH] fix export of course dates, fixes #4626 Closes #4626 Merge request studip/studip!3438 --- app/controllers/course/dates.php | 127 ++++++++++++++---------------- app/views/course/dates/export.php | 20 +++-- lib/classes/CourseDateList.php | 42 +++++----- lib/models/CourseDate.php | 2 +- lib/models/resources/Resource.php | 2 +- 5 files changed, 92 insertions(+), 101 deletions(-) diff --git a/app/controllers/course/dates.php b/app/controllers/course/dates.php index 88a61259a1b..3d744c17ad1 100644 --- a/app/controllers/course/dates.php +++ b/app/controllers/course/dates.php @@ -362,52 +362,59 @@ class Course_DatesController extends AuthenticatedController public function export_action() { - $themen = CourseTopic::findBySeminar_id($this->course->id); - $termine = $this->course->getAllDatesInSemester()->getSingleDates(true, true, true); $dates = []; - foreach ($termine as $singledate) { if ($singledate instanceof CourseDate) { - $tmp_ids = $singledate->getIssueIDs(); - $title = $description = ''; - if (is_array($tmp_ids)) { - $title = trim(join("\n", array_map(function ($tid) use ($themen) {return $themen[$tid]->getTitle();}, $tmp_ids))); - $description = trim(join("\n\n", array_map(function ($tid) use ($themen) {return $themen[$tid]->getDescription();}, $tmp_ids))); - } + $title = trim(implode( + "\n", + $singledate->topics->filter(function (CourseTopic $topic): bool { + return trim($topic->title) !== ''; + })->map(function (CourseTopic $topic): string { + return trim($topic->title); + }) + )); + $description = trim(implode( + "\n\n", + $singledate->topics->filter(function (CourseTopic $topic): bool { + return trim($topic->description) !== ''; + })->map(function (CourseTopic $topic): string { + return trim($topic->description); + }) + )); $dates[] = [ - 'date' => $singledate->toString(), - 'title' => $title, - 'description' => $description, - 'start' => $singledate->getStartTime(), - 'related_persons' => $singledate->getRelatedPersons(), - 'groups' => $singledate->getRelatedGroups(), - 'room' => $singledate->getRoom() ?: $singledate->raum, - 'type' => $GLOBALS['TERMIN_TYP'][$singledate->getDateType()]['name'] + 'date' => (string) $singledate, + 'title' => $title, + 'description' => $description, + 'start' => $singledate->date, + 'related_persons' => $singledate->dozenten, + 'groups' => $singledate->statusgruppen, + 'room' => (string) ($singledate->getRoom() ?? $singledate->raum), + 'type' => $GLOBALS['TERMIN_TYP'][$singledate->date_typ]['name'], ]; - } elseif ($singledate->getComment()) { + } elseif ($singledate instanceof CourseExDate && $singledate->content) { $dates[] = [ - 'date' => $singledate->toString(), - 'title' => _('fällt aus') . ' (' . _('Kommentar:') . ' ' . $singledate->getComment() . ')', - 'description' => '', - 'start' => $singledate->getStartTime(), + 'date' => (string) $singledate, + 'title' => _('fällt aus') . ' (' . _('Kommentar:') . ' ' . $singledate->content . ')', + 'description' => '', + 'start' => $singledate->date, 'related_persons' => [], - 'groups' => [], - 'room' => '', - 'type' => $GLOBALS['TERMIN_TYP'][$singledate->getDateType()]['name'] + 'groups' => [], + 'room' => '', + 'type' => $GLOBALS['TERMIN_TYP'][$singledate->date_typ]['name'], ]; } } $factory = $this->get_template_factory(); $template = $factory->open($this->get_default_template('export')); - - $template->set_attribute('dates', $dates); - $template->lecturer_count = $this->course->countMembersWithStatus('dozent'); - $template->group_count = count($this->course->statusgruppen); - $content = $template->render(); + $content = $template->render([ + 'dates' => $dates, + 'lecturer_count' => $this->course->countMembersWithStatus('dozent'), + 'group_count' => count($this->course->statusgruppen), + ]); $content = mb_encode_numericentity($content, [0x80, 0xffff, 0, 0xffff], 'utf-8'); $filename = FileManager::cleanFileName($this->course['name'] . '-' . _('Ablaufplan') . '.doc'); @@ -426,13 +433,6 @@ class Course_DatesController extends AuthenticatedController */ public function export_csv_action() { - $dates = $this->course->getAllDatesInSemester(true, true, true); - $raw_issues = CourseTopic::findBySeminar_id($this->course->id); - $issues = []; - foreach ($raw_issues as $issue) { - $issues[$issue->id] = $issue; - } - $columns = [ _('Wochentag'), _('Termin'), @@ -450,9 +450,10 @@ class Course_DatesController extends AuthenticatedController $data = [$columns]; + $dates = $this->course->getAllDatesInSemester()->getSingleDates(true, true, true); foreach ($dates as $date) { // FIXME this should not be necessary, see https://develop.studip.de/trac/ticket/8101 - if ($date->isExTermin() && $date->getComment() == '') { + if ($date instanceof CourseExDate && trim($date->content) === '') { continue; } @@ -463,49 +464,37 @@ class Course_DatesController extends AuthenticatedController $row[] = strftime('%H:%M', $date->end_time); $row[] = $date->getTypeName(); - if ($date->isExTermin()) { - $row[] = $date->getComment(); + if ($date instanceof CourseExDate) { + $row[] = trim($date->content); $row[] = ''; } else { $issue = $descr = ''; - foreach ((array) $date->getIssueIDs() as $id) { - $issue .= $issues[$id]->getTitle() . "\n"; - $descr .= kill_format($issues[$id]->getDescription()) . "\n"; + foreach ($date->topics as $topic) { + $issue .= trim($topic->title) . "\n"; + $descr .= kill_format($topic->description) . "\n"; } $row[] = trim($issue); $row[] = trim($descr); } - $related_persons = ''; - - if ($date->related_persons) { - foreach ($date->related_persons as $user_id) { - $related_persons .= User::find($user_id)->getFullName() . "\n"; - } - } - - $row[] = trim($related_persons); - - $related_groups = ''; - - if ($date->related_groups) { - foreach ($date->related_groups as $group_id) { - $related_groups .= Statusgruppen::find($group_id)->name . "\n"; - } - } + $row[] = implode( + "\n", + $date->dozenten->map(function (User $user) { + return $user->getFullName(); + }) + ); - $row[] = trim($related_groups); + $row[] = implode( + "\n", + $date->statusgruppen->map(function (Statusgruppen $group) { + return $group->name; + }) + ); - $room = null; - if ($date->resource_id) { - $resource_object = Resource::find($date->resource_id); - if ($resource_object) { - $room = $resource_object->getDerivedClassInstance(); - } - } - if ($room instanceof Room) { + $room = $date->getRoom(); + if ($room) { $row[] = $room->name; $row[] = $room->description; $row[] = $room->seats; diff --git a/app/views/course/dates/export.php b/app/views/course/dates/export.php index 651c4074f08..685748ded9c 100644 --- a/app/views/course/dates/export.php +++ b/app/views/course/dates/export.php @@ -1,5 +1,9 @@ -<? -# Lifter010: TODO +<?php +/** + * @var array<int, array{date: string, description: string, type: string, start: int, groups: Statusgruppen[], related_persons: User[]}> $dates + * @var int $lecturer_count + * @var int $group_count + */ ?> <html> <head> @@ -7,7 +11,7 @@ </head> <body> -<? if (sizeof($dates)) : ?> +<? if (count($dates) > 0) : ?> <table cellspacing="0" cellpadding="0" border="1" width="100%"> <tr> @@ -45,18 +49,18 @@ <td width="20%"><?= htmlReady($date['title']) ?></td> <td width="20%"> <? if (count($date['related_persons']) != $lecturer_count) : ?> - <? foreach ($date['related_persons'] as $key => $user_id) { - echo ($key > 0 ? ", " : "").htmlReady(get_fullname($user_id)); + <? foreach ($date['related_persons'] as $key => $user) { + echo ($key > 0 ? ", " : "").htmlReady($user->getFullName()); } ?> <? endif ?> </td> <td width="20%"> <? if (count($date['groups']) && count($date['groups']) < $group_count) : ?> - <? foreach ($date['groups'] as $key => $statusgruppe_id) { - echo ($key > 0 ? ", " : "").htmlReady(Statusgruppen::find($statusgruppe_id)->name); + <? foreach ($date['groups'] as $key => $statusgruppe) { + echo ($key > 0 ? ", " : "").htmlReady($statusgruppe->name); } ?> <? else : ?> - <?= _("alle") ?> + <?= _('alle') ?> <? endif ?> </td> <td width="20%"><?= htmlReady($date['room']) ?></td> diff --git a/lib/classes/CourseDateList.php b/lib/classes/CourseDateList.php index 881d6da90e2..5f6d4b1f10e 100644 --- a/lib/classes/CourseDateList.php +++ b/lib/classes/CourseDateList.php @@ -138,40 +138,38 @@ class CourseDateList implements Stringable return $this->regular_dates; } + /** + * @param bool $include_regular_dates + * @param bool $include_cancelled_dates + * @param bool $sorted + * @return CourseDate[]|CourseExDate[] + */ public function getSingleDates( bool $include_regular_dates = false, bool $include_cancelled_dates = false, bool $sorted = false ): array { + $all_single_dates = []; + if ($include_regular_dates) { - $all_single_dates = []; foreach ($this->regular_dates as $regular_date) { foreach ($regular_date->dates as $date) { $all_single_dates[] = $date; } } - $all_single_dates = array_merge($all_single_dates, $this->single_dates); - if ($include_cancelled_dates) { - $all_single_dates = array_merge($all_single_dates, $this->cancelled_dates); - } - if ($sorted) { - uasort($all_single_dates, self::compareSingleDatesOrCancelledDates(...)); - } - return $all_single_dates; - } else { - if ($include_cancelled_dates || $sorted) { - $all_single_dates = $this->single_dates; - if ($include_cancelled_dates) { - $all_single_dates = array_merge($all_single_dates, $this->cancelled_dates); - } - if ($sorted) { - uasort($all_single_dates, self::compareSingleDatesOrCancelledDates(...)); - } - return $all_single_dates; - } else { - return $this->single_dates; - } } + + $all_single_dates = array_merge($all_single_dates, $this->single_dates); + + if ($include_cancelled_dates) { + $all_single_dates = array_merge($all_single_dates, $this->cancelled_dates); + } + + if ($sorted) { + uasort($all_single_dates, self::compareSingleDatesOrCancelledDates(...)); + } + + return $all_single_dates; } public function getCancelledDates() : array diff --git a/lib/models/CourseDate.php b/lib/models/CourseDate.php index 943bf237855..46610d557ef 100644 --- a/lib/models/CourseDate.php +++ b/lib/models/CourseDate.php @@ -235,7 +235,7 @@ class CourseDate extends SimpleORMap implements PrivacyObject, Event /** * Returns the assigned room for this date as an object. * - * @return Room Either the object or null if no room is assigned + * @return Resource Either the object or null if no room is assigned */ public function getRoom() { diff --git a/lib/models/resources/Resource.php b/lib/models/resources/Resource.php index e1d8b674296..4dae189b3f9 100644 --- a/lib/models/resources/Resource.php +++ b/lib/models/resources/Resource.php @@ -2817,7 +2817,7 @@ class Resource extends SimpleORMap implements StudipItem /** * Converts a Resource object to an object of a specialised resource class. * - * @return Resource|other An object of a specialised resource class + * @return Resource An object of a specialised resource class * or a Resource object, if the resource is a standard resource * with the class_name 'Resource' in its resource category. * If the derived resource class is not available, an instance of -- GitLab