forked from fa/breadcrumb-the-shire
fix(flash): make flash messages one-shot per request
This commit is contained in:
@@ -8,7 +8,6 @@ use MintyPHP\Session;
|
||||
class Flash
|
||||
{
|
||||
private const SESSION_KEY = 'flash_messages';
|
||||
private const KEEP_KEY = 'flash_keep';
|
||||
|
||||
private static function ensureSession()
|
||||
{
|
||||
@@ -74,10 +73,50 @@ class Flash
|
||||
}));
|
||||
}
|
||||
|
||||
public static function has(): bool
|
||||
/**
|
||||
* Consume (read + remove) all messages that match any of the provided scopes.
|
||||
* Global messages (scope=null) are included for every scope set.
|
||||
*
|
||||
* @param array<int, string> $scopes
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public static function consumeForScopes(array $scopes): array
|
||||
{
|
||||
self::ensureSession();
|
||||
return !empty($_SESSION[self::SESSION_KEY]);
|
||||
$messages = $_SESSION[self::SESSION_KEY] ?? [];
|
||||
if ($messages === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$scopeSet = [];
|
||||
foreach ($scopes as $scope) {
|
||||
$scopeSet[$scope] = true;
|
||||
}
|
||||
if ($scopeSet === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$consumed = [];
|
||||
$remaining = [];
|
||||
foreach ($messages as $message) {
|
||||
$messageScope = $message['scope'] ?? null;
|
||||
$matchesScope = $messageScope === null || isset($scopeSet[(string) $messageScope]);
|
||||
|
||||
if ($matchesScope) {
|
||||
$consumed[] = $message;
|
||||
continue;
|
||||
}
|
||||
|
||||
$remaining[] = $message;
|
||||
}
|
||||
|
||||
if ($remaining !== []) {
|
||||
$_SESSION[self::SESSION_KEY] = $remaining;
|
||||
} else {
|
||||
unset($_SESSION[self::SESSION_KEY]);
|
||||
}
|
||||
|
||||
return $consumed;
|
||||
}
|
||||
|
||||
public static function dismiss(string $id): void
|
||||
@@ -118,13 +157,4 @@ class Flash
|
||||
unset($_SESSION[self::SESSION_KEY]);
|
||||
}
|
||||
}
|
||||
|
||||
// Prevents messages from being cleared on the next render — useful when a redirect chain crosses multiple pages.
|
||||
public static function keep(int $times = 1)
|
||||
{
|
||||
self::ensureSession();
|
||||
$times = max(1, $times);
|
||||
$current = (int) ($_SESSION[self::KEEP_KEY] ?? 0);
|
||||
$_SESSION[self::KEEP_KEY] = max($current, $times);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,17 @@ function flashFormErrors(FormErrors $errors, ?string $scope = null, string $keyP
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume and remove flash messages matching any provided scope.
|
||||
*
|
||||
* @param array<int, string> $scopes
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
function flashConsumeForScopes(array $scopes): array
|
||||
{
|
||||
return Flash::consumeForScopes($scopes);
|
||||
}
|
||||
|
||||
function requestExtractNestedReturnValue(mixed $value): string
|
||||
{
|
||||
if (is_string($value)) {
|
||||
|
||||
Reference in New Issue
Block a user