$id, 'type' => $type, 'message' => $message, 'scope' => $scope, 'key' => $key, ]; return $id; } public static function success(string $message, ?string $scope = null, ?string $key = null): string { return self::add('success', $message, $scope, $key); } public static function error(string $message, ?string $scope = null, ?string $key = null): string { return self::add('error', $message, $scope, $key); } public static function info(string $message, ?string $scope = null, ?string $key = null): string { return self::add('info', $message, $scope, $key); } public static function peek(?string $scope = null): array { self::ensureSession(); $messages = $_SESSION[self::SESSION_KEY] ?? []; if ($scope === null) { return $messages; } return array_values(array_filter($messages, function ($message) use ($scope) { $messageScope = $message['scope'] ?? null; return $messageScope === null || $messageScope === $scope; })); } /** * Consume (read + remove) all messages that match any of the provided scopes. * Global messages (scope=null) are included for every scope set. * * @param array $scopes * @return array> */ public static function consumeForScopes(array $scopes): array { self::ensureSession(); $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 { self::ensureSession(); $messages = $_SESSION[self::SESSION_KEY] ?? []; $messages = array_values(array_filter($messages, function ($message) use ($id) { return ($message['id'] ?? '') !== $id; })); if ($messages) { $_SESSION[self::SESSION_KEY] = $messages; } else { unset($_SESSION[self::SESSION_KEY]); } } /** * Remove all flash messages matching a given key (and optionally scope). */ public static function dismissByKey(string $key, ?string $scope = null): void { self::ensureSession(); $messages = $_SESSION[self::SESSION_KEY] ?? []; $messages = array_values(array_filter($messages, function ($message) use ($key, $scope) { if (($message['key'] ?? null) !== $key) { return true; } if ($scope !== null && ($message['scope'] ?? null) !== $scope) { return true; } return false; })); if ($messages) { $_SESSION[self::SESSION_KEY] = $messages; } else { unset($_SESSION[self::SESSION_KEY]); } } }