From 1d8dfc5163da9ebb13c7806cc6867a664aa2e795 Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Tue, 25 Jun 2024 10:21:47 +0000
Subject: [PATCH] fix handling of different LayoutMessage types, fixes #4345

Closes #4345

Merge request studip/studip!3148
---
 lib/classes/LayoutMessage.php |  2 +-
 lib/classes/MessageBox.php    | 12 +++++++++++-
 lib/classes/PageLayout.php    | 21 ++++++++-------------
 templates/layouts/base.php    |  3 ++-
 4 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/lib/classes/LayoutMessage.php b/lib/classes/LayoutMessage.php
index 7072788490f..d93f509c82b 100644
--- a/lib/classes/LayoutMessage.php
+++ b/lib/classes/LayoutMessage.php
@@ -7,7 +7,7 @@
  * @license GPL2 or any later version
  * @since   Stud.IP 4.2
  */
-interface LayoutMessage
+interface LayoutMessage extends Stringable
 {
     /**
      * Renders the message as html.
diff --git a/lib/classes/MessageBox.php b/lib/classes/MessageBox.php
index 3573018d2e6..8c203a5843f 100644
--- a/lib/classes/MessageBox.php
+++ b/lib/classes/MessageBox.php
@@ -31,7 +31,7 @@
  * echo MessageBox::success('Nachricht', ['optional details'], true);
  *
  */
-class MessageBox implements LayoutMessage
+class MessageBox implements LayoutMessage, JsonSerializable
 {
     /**
      * type and contents of the message box
@@ -174,4 +174,14 @@ class MessageBox implements LayoutMessage
             'counter'       => self::$counter++,
         ]);
     }
+
+    public function jsonSerialize(): mixed
+    {
+        return [
+            'type'      => $this->class,
+            'message'   => $this->message,
+            'details'   => $this->details,
+            'closeable' => $this->isCloseable(),
+        ];
+    }
 }
diff --git a/lib/classes/PageLayout.php b/lib/classes/PageLayout.php
index 4d4ef3ad042..ed5e1aefdff 100644
--- a/lib/classes/PageLayout.php
+++ b/lib/classes/PageLayout.php
@@ -600,17 +600,10 @@ class PageLayout
             $_SESSION['messages'] = [];
         }
 
-        $structure = [
-            'type'      => $message->class,
-            'message'   => $message->message,
-            'details'   => $message->details,
-            'closeable' => $message instanceof MessageBox ? $message->isCloseable() : false,
-        ];
-
         if ($id === null) {
-            $_SESSION['messages'][] = $structure;
+            $_SESSION['messages'][] = $message;
         } else {
-            $_SESSION['messages'][$id] = $structure;
+            $_SESSION['messages'][$id] = $message;
         }
     }
 
@@ -713,13 +706,15 @@ class PageLayout
      *
      * @return array    list of MessageBox objects
      */
-    public static function getMessages()
+    public static function getMessages(string $type = LayoutMessage::class)
     {
         $messages = [];
 
-        if (isset($_SESSION['messages'])) {
-            $messages = $_SESSION['messages'];
-            self::clearMessages();
+        foreach ($_SESSION['messages'] ?? [] as $index => $message) {
+            if (is_a($message, $type)) {
+                $messages[$index] = $message;
+                unset($_SESSION['messages'][$index]);
+            }
         }
 
         return $messages;
diff --git a/templates/layouts/base.php b/templates/layouts/base.php
index 1f2ac32e711..077cdf4a2e2 100644
--- a/templates/layouts/base.php
+++ b/templates/layouts/base.php
@@ -92,11 +92,12 @@ $lang_attr = str_replace('_', '-', $_SESSION['_language']);
                     <?= Icon::create('zoom-out2')->asImg(24) ?>
                 </button>
             <? endif; ?>
+            <?= implode(PageLayout::getMessages(QuestionBox::class)) ?>
             <?= $content_for_layout ?>
         </div>
         <system-notification-manager
             id="system-notifications"
-            :notifications='<?= htmlReady(json_encode(PageLayout::getMessages())) ?>'
+            :notifications='<?= htmlReady(json_encode(PageLayout::getMessages(MessageBox::class))) ?>'
             placement="<?= User::findCurrent()?->getConfiguration()->SYSTEM_NOTIFICATIONS_PLACEMENT ?? 'topcenter' ?>"></system-notification-manager>
     </main>
     <!-- End main content -->
-- 
GitLab