From fb156f20c45e0ac1e2ea5c8627efcb1fe8895faf Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Wed, 13 Nov 2024 15:36:27 +0000
Subject: [PATCH] sort resource request appointments when converting to
 readable strings, fixes #4856

Closes #4856

Merge request studip/studip!3639
---
 app/views/resources/_common/_request_info.php |  5 +++
 lib/models/resources/ResourceRequest.php      | 38 +++++++++++++------
 2 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/app/views/resources/_common/_request_info.php b/app/views/resources/_common/_request_info.php
index 11ff253984a..6d339ca46d6 100644
--- a/app/views/resources/_common/_request_info.php
+++ b/app/views/resources/_common/_request_info.php
@@ -1,3 +1,8 @@
+<?php
+/**
+ * @var ResourceRequest $request
+ */
+?>
 <dl>
     <dt><?= _('Termine') ?>:</dt>
     <dd><?= $request->getDateString() ?></dd>
diff --git a/lib/models/resources/ResourceRequest.php b/lib/models/resources/ResourceRequest.php
index 06a5e79cbe5..b0334a40978 100644
--- a/lib/models/resources/ResourceRequest.php
+++ b/lib/models/resources/ResourceRequest.php
@@ -1452,17 +1452,31 @@ class ResourceRequest extends SimpleORMap implements PrivacyObject, Studip\Calen
         $now = time();
         $strings = [];
         $resource_name = '';
-        if (count($this->appointments)) {
-            $parts  = [];
-            foreach ($this->appointments as $rra) {
-                if (!$with_past_intervals && $rra->appointment->end_time < $now) {
-                    continue;
+        if (count($this->appointments) > 0) {
+            // Filter invalid/not matching items
+            $appointments = $this->appointments->filter(
+                function (ResourceRequestAppointment $appointment) use ($with_past_intervals, $now): bool {
+                    if (!$appointment->appointment) {
+                        return false;
+                    }
+                    return $with_past_intervals
+                        || $appointment->appointment->end_time > $now;
                 }
-                if ($rra->appointment) {
-                    $parts[] = $rra->appointment->getFullName('include-room');
+            );
+
+            // Sort by appointment date
+            $appointments->uasort(
+                function (ResourceRequestAppointment $a, ResourceRequestAppointment $b): int {
+                    return $a->appointment->date - $b->appointment->date;
                 }
-            }
-            $strings[] = implode('; ', $parts);
+            );
+
+            // Get readable string for each appointment
+            $strings = $appointments->map(
+                function (ResourceRequestAppointment $appointment): string {
+                    return $appointment->appointment->getFullName('include-room');
+                },
+            );
         } elseif ($this->termin_id) {
             if ($this->date) {
                 if ($with_past_intervals || $this->date->end_time >= $now) {
@@ -1471,10 +1485,10 @@ class ResourceRequest extends SimpleORMap implements PrivacyObject, Studip\Calen
             }
         } elseif ($this->metadate_id) {
             if ($this->cycle) {
-                $this->cycle->dates->filter(function($date) use($with_past_intervals, $now) {
+                $strings = $this->cycle->dates->filter(function ($date) use($with_past_intervals, $now) {
                     return $with_past_intervals || $date->end_time >= $now;
-                })->map(function($date) use(&$strings) {
-                    $strings[] = $date->getFullName('include-room');
+                })->map(function($date) {
+                    return $date->getFullName('include-room');
                 });
             }
         } elseif ($this->course_id) {
-- 
GitLab