Skip to content

Commit

Permalink
Alert messages are now translated at read time
Browse files Browse the repository at this point in the history
  • Loading branch information
lcharette committed Dec 17, 2023
1 parent 21cb842 commit dd98b7f
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 192 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
- Update to Laravel 10
- Update to PHPUnit 10

### Alert
- Messages are now translated at read time ([#1156](https://github.com/userfrosting/UserFrosting/pull/1156), [#811](https://github.com/userfrosting/UserFrosting/issues/811)). Messages will be translated when using `messages` and `getAndClearMessages`. `addMessage` now accept the optional placeholders, which will be stored with the alert message. `addMessageTranslated` is **deprecated**.
- Translator is not optional anymore. `setTranslator` method has been removed.

## [5.0.0](https://github.com/userfrosting/framework/compare/4.6.1...5.0.0)
With version 5, this repo can be used as a bare bone Slim & Symfony Console application. It include the necessary routing class, [PHP-DI](https://php-di.org) as the Dependency Injection Container, a PSR EventDispatcher, etc. SprinkleManager has also been moved from Core/System Sprinkle and completely rewritten.

Expand Down
95 changes: 46 additions & 49 deletions src/Alert/AlertStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

namespace UserFrosting\Alert;

use RuntimeException;
use UserFrosting\Fortress\ServerSideValidator;
use UserFrosting\I18n\Translator;

Expand All @@ -24,46 +23,29 @@ abstract class AlertStream
/**
* Create a new message stream.
*
* @param string $messagesKey
* @param Translator|null $translator
* @param Translator $translator
*/
public function __construct(
protected string $messagesKey,
protected ?Translator $translator = null
protected Translator $translator
) {
}

/**
* Set the translator to be used for all message streams. Must be done
* before `addMessageTranslated` can be used.
*
* @param Translator|null $translator
*
* @return static
*/
public function setTranslator(?Translator $translator = null): static
{
$this->translator = $translator;

return $this;
}

/**
* Adds a raw text message to the cache message stream.
*
* @param string $type The type of message, indicating how it will be styled when outputted. Should be set to "success", "danger", "warning", or "info".
* @param string $message The message to be added to the message stream.
* @param string $type The type of message, indicating how it will be styled when outputted. Should be set to "success", "danger", "warning", or "info".
* @param string $message The message to be added to the message stream.
* @param mixed[]|int $placeholders An optional hash of placeholder names => placeholder values to substitute into the translated message.
*
* @return static
*/
public function addMessage(string $type, string $message): static
public function addMessage(string $type, string $message, array|int $placeholders = []): static
{
$messages = $this->messages();
$messages[] = [
'type' => $type,
'message' => $message,
];
$this->saveMessages($messages);
$this->storeMessage([
'type' => $type,
'message' => $message,
'placeholders' => $placeholders,
]);

return $this;
}
Expand All @@ -72,22 +54,16 @@ public function addMessage(string $type, string $message): static
* Adds a text message to the cache message stream, translated into the currently selected language.
*
* @param string $type The type of message, indicating how it will be styled when outputted. Should be set to "success", "danger", "warning", or "info".
* @param string $messageId The message id for the message to be added to the message stream.
* @param string $message The message id for the message to be added to the message stream.
* @param mixed[]|int $placeholders An optional hash of placeholder names => placeholder values to substitute into the translated message.
*
* @throws RuntimeException
*
* @return static
*
* @deprecated 5.1 Use `addMessage` instead.
*/
public function addMessageTranslated(string $type, string $messageId, array|int $placeholders = []): static
public function addMessageTranslated(string $type, string $message, array|int $placeholders = []): static
{
if ($this->translator === null) {
throw new RuntimeException('No translator has been set! Please call MessageStream::setTranslator first.');
}

$message = $this->translator->translate($messageId, $placeholders);

return $this->addMessage($type, $message);
return $this->addMessage($type, $message, $placeholders);
}

/**
Expand All @@ -97,7 +73,7 @@ public function addMessageTranslated(string $type, string $messageId, array|int
* This is useful, because typically we don't want to view the same messages more than once.
* Returns an array of messages, each of which is itself an array containing "type" and "message" fields.
*
* @return array<int, array{type: string, message: string}>
* @return array<int, array{type: string, message: string, placeholders: mixed[]|int}>
*/
public function getAndClearMessages(): array
{
Expand All @@ -107,6 +83,19 @@ public function getAndClearMessages(): array
return $messages;
}

/**
* Get the messages from this message stream.
*
* @return array<int, array{type: string, message: string, placeholders: mixed[]|int}>
*/
public function messages(): array
{
$messages = $this->retrieveMessages();
$messages = $this->translateMessages($messages);

return $messages;
}

/**
* Add error messages from a ServerSideValidator object to the message stream.
*
Expand All @@ -123,21 +112,29 @@ public function addValidationErrors(ServerSideValidator $validator): void
}

/**
* Return the translator for this message stream.
* Translates messages that have a message id instead of a message.
*
* @return Translator|null The translator for this message stream.
* @param array<int, array{type: string, message: string, placeholders: mixed[]|int}> $messages
*
* @return array<int, array{type: string, message: string, placeholders: mixed[]|int}>
*/
public function translator(): ?Translator
protected function translateMessages(array $messages): array
{
return $this->translator;
$translated = [];
foreach ($messages as $message) {
$message['message'] = $this->translator->translate($message['message'], $message['placeholders']);
$translated[] = $message;
}

return $translated;
}

/**
* Get the messages from this message stream.
*
* @return array<int, array{type: string, message: string}> An array of messages, each of which is itself an array containing "type" and "message" fields.
* @return array<int, array{type: string, message: string, placeholders: mixed[]|int}> An array of messages, each of which is itself an array containing "type" and "message" fields.
*/
abstract public function messages(): array;
abstract protected function retrieveMessages(): array;

/**
* Clear all messages from this message stream.
Expand All @@ -147,7 +144,7 @@ abstract public function resetMessageStream(): void;
/**
* Save messages to the stream.
*
* @param array<int, array{type: string, message: string}> $messages
* @param array{type: string, message: string, placeholders: mixed[]|int} $message
*/
abstract protected function saveMessages(array $messages): void;
abstract protected function storeMessage(array $message): void;
}
39 changes: 17 additions & 22 deletions src/Alert/CacheAlertStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,35 +24,27 @@
*/
class CacheAlertStream extends AlertStream
{
/**
* @var Cache Object We use the cache object so that added messages will automatically appear in the cache.
*/
protected Cache $cache;

/**
* @var string Session id tied to the alert stream.
*/
protected string $session_id;

/**
* Create a new message stream.
*
* @param string $messagesKey Store the messages under this key
* @param Translator|null $translator
* @param Cache $cache
* @param string $sessionId
* @param string $messagesKey Store the messages under this key
* @param Translator $translator
* @param Cache $cache Object We use the cache object so that added messages will automatically appear in the cache.
* @param string $tag Cache tag id tied to the alert stream. Usually tied to the session ID.
*/
public function __construct(string $messagesKey, ?Translator $translator, Cache $cache, string $sessionId)
{
$this->cache = $cache;
$this->session_id = $sessionId;
parent::__construct($messagesKey, $translator);
public function __construct(
protected string $messagesKey,
protected Translator $translator,
protected Cache $cache,
protected string $tag,
) {
parent::__construct($translator);
}

/**
* {@inheritDoc}
*/
public function messages(): array
protected function retrieveMessages(): array
{
if ($this->getCache()->has($this->messagesKey)) {
$data = $this->getCache()->get($this->messagesKey);
Expand All @@ -74,8 +66,11 @@ public function resetMessageStream(): void
/**
* {@inheritDoc}
*/
protected function saveMessages(array $messages): void
protected function storeMessage(array $message): void
{
$messages = $this->retrieveMessages();
$messages[] = $message;

$this->getCache()->forever($this->messagesKey, $messages);
}

Expand All @@ -84,6 +79,6 @@ protected function saveMessages(array $messages): void
*/
protected function getCache(): TaggedCache
{
return $this->cache->tags('_s' . $this->session_id);
return $this->cache->tags('_s' . $this->tag);
}
}
28 changes: 14 additions & 14 deletions src/Alert/SessionAlertStream.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,25 @@
*/
class SessionAlertStream extends AlertStream
{
/**
* @var Session We use the session object so that added messages will automatically appear in the session.
*/
protected Session $session;

/**
* Create a new message stream.
*
* @param string $messagesKey Store the messages under this key
* @param Translator|null $translator
* @param Session $session
* @param string $messagesKey Store the messages under this key
* @param Session $session We use the session object so that added messages will automatically appear in the session.
* @param Translator $translator
*/
public function __construct(string $messagesKey, ?Translator $translator, Session $session)
{
$this->session = $session;
parent::__construct($messagesKey, $translator);
public function __construct(
protected string $messagesKey,
protected Translator $translator,
protected Session $session,
) {
parent::__construct($translator);
}

/**
* {@inheritDoc}
*/
public function messages(): array
protected function retrieveMessages(): array
{
$data = $this->session->get($this->messagesKey);

Expand All @@ -60,8 +57,11 @@ public function resetMessageStream(): void
/**
* {@inheritDoc}
*/
protected function saveMessages(array $messages): void
protected function storeMessage(array $message): void
{
$messages = $this->retrieveMessages();
$messages[] = $message;

$this->session->set($this->messagesKey, $messages);
}
}
Loading

0 comments on commit dd98b7f

Please sign in to comment.