Commit 35f6e8ba authored by Benni Mack's avatar Benni Mack Committed by Andreas Fernandez
Browse files

[FEATURE] Store Flash Messages as JsonSerializable

Flash Messages which should be stored in sessions,
are now stored as stringified JsonSerializable instead of
their objects themselves.

The huge advantages over the previous functionality
is that the FlashMessage objects are not instantiated during the process
when a session is loaded, but actually only when the FlashMessages
are needed, bringing a bit of performance for Backend functionality.

Resolves: #93063
Releases: master
Change-Id: Ie2da3b3d0a3fbb14416fd5743b3109221d30d28d
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/67098

Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
parent d4ad0dd8
......@@ -17,6 +17,8 @@ declare(strict_types=1);
namespace TYPO3\CMS\Core\Messaging;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* A class representing flash messages.
*/
......@@ -45,6 +47,23 @@ class FlashMessage extends AbstractMessage
$this->setStoreInSession($storeInSession);
}
/**
* Factory method. Useful when creating flash messages from a jsonSerialize json_decode() call.
*
* @param array<string, string|int|bool> $data
* @return static
*/
public static function createFromArray(array $data): self
{
return GeneralUtility::makeInstance(
static::class,
(string)$data['message'],
(string)($data['title'] ?? ''),
(int)($data['severity'] ?? AbstractMessage::OK),
(bool)($data['storeInSession'] ?? false)
);
}
/**
* Gets the message's storeInSession flag.
*
......@@ -64,4 +83,14 @@ class FlashMessage extends AbstractMessage
{
$this->storeInSession = (bool)$storeInSession;
}
/**
* @return array Data which can be serialized by json_encode()
*/
public function jsonSerialize(): array
{
$data = parent::jsonSerialize();
$data['storeInSession'] = $this->storeInSession;
return $data;
}
}
......@@ -152,6 +152,9 @@ class FlashMessageQueue extends \SplQueue implements \JsonSerializable
*/
protected function storeFlashMessagesInSession(array $flashMessages = null)
{
if (is_array($flashMessages)) {
$flashMessages = array_map('json_encode', $flashMessages);
}
$this->getUserByContext()->setAndSaveSessionData($this->identifier, $flashMessages);
}
......@@ -189,8 +192,11 @@ class FlashMessageQueue extends \SplQueue implements \JsonSerializable
$sessionMessages = [];
$user = $this->getUserByContext();
if ($user instanceof AbstractUserAuthentication) {
$sessionMessages = $user->getSessionData($this->identifier);
$sessionMessages = is_array($sessionMessages) ? $sessionMessages : [];
$messagesFromSession = $user->getSessionData($this->identifier);
$messagesFromSession = is_array($messagesFromSession) ? $messagesFromSession : [];
foreach ($messagesFromSession as $messageData) {
$sessionMessages[] = FlashMessage::createFromArray(json_decode($messageData, true));
}
}
return $sessionMessages;
}
......
.. include:: ../../Includes.txt
=========================================================================
Feature: #93063 - FlashMessages are stored in session as JsonSerializable
=========================================================================
See :issue:`93063`
Description
===========
FlashMessages which are used to show information across backend
modules and frontend plugins / forms, are mostly stored in the
session data of a user session.
They are now stored as json_encoded data, using the already existing
:php:`JsonSerializable` functionality of AbstractMessage.
Impact
======
This way, the FlashMessage objects are only built when they are
needed and not on every PHP call the user session is started,
making e.g. AJAX calls a tiny bit faster.
.. index:: PHP-API, ext:core
......@@ -35,6 +35,7 @@ class FlashMessageTest extends UnitTestCase
'severity' => FlashMessage::INFO,
'title' => 'aTitle',
'message' => 'aMessage',
'storeInSession' => false,
];
self::assertEquals($expected, $message->jsonSerialize());
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment