Simplify PHPDoc comments in Prime interfaces and traits

This commit simplifies PHPDoc comments across 26 files in the src/Prime/
directory by removing verbose documentation and keeping only essential type
annotations.

Changes include:
- Removed "Design pattern" mentions and redundant explanations
- Kept all @param and @return type annotations for PHPStan
- Maintained @phpstan-* annotations for type safety

Files modified:
- Exception classes (4 files)
- Http interfaces (5 files)
- Notification builders and interfaces (3 files)
- Plugin, Response, Storage, Template, Translation, and Test interfaces (14 files)

All changes pass PHPStan analysis and tests.
This commit is contained in:
Younes ENNAJI
2026-01-15 23:40:19 +01:00
parent 1c5b533126
commit a0873c0082
27 changed files with 51 additions and 1314 deletions
@@ -4,24 +4,10 @@ declare(strict_types=1);
namespace Flasher\Prime\Exception; namespace Flasher\Prime\Exception;
/**
* CriteriaNotRegisteredException - Thrown when an unregistered filter criterion is requested.
*
* This exception is thrown when attempting to use a filter criterion that hasn't been
* registered with the FilterFactory. It provides a clear error message that includes
* the requested criterion name and available criteria for debugging purposes.
*
* Design pattern: Domain-specific exception - Provides contextual information about the error.
*/
final class CriteriaNotRegisteredException extends \Exception final class CriteriaNotRegisteredException extends \Exception
{ {
/** /**
* Creates a new CriteriaNotRegisteredException with a descriptive message. * @param string[] $availableCriteria
*
* @param string $alias The name of the criterion that was requested
* @param string[] $availableCriteria The list of registered criteria names
*
* @return self The exception instance
*/ */
public static function create(string $alias, array $availableCriteria = []): self public static function create(string $alias, array $availableCriteria = []): self
{ {
@@ -4,24 +4,10 @@ declare(strict_types=1);
namespace Flasher\Prime\Exception; namespace Flasher\Prime\Exception;
/**
* FactoryNotFoundException - Thrown when an unregistered notification factory is requested.
*
* This exception is thrown when attempting to use a notification factory that hasn't been
* registered with the system. It provides a clear error message that includes the requested
* factory name and available factories for debugging purposes.
*
* Design pattern: Domain-specific exception - Provides contextual information about the error.
*/
final class FactoryNotFoundException extends \Exception final class FactoryNotFoundException extends \Exception
{ {
/** /**
* Creates a new FactoryNotFoundException with a descriptive message. * @param string[] $availableFactories
*
* @param string $alias The name of the factory that was requested
* @param string[] $availableFactories The list of registered factory names
*
* @return self The exception instance
*/ */
public static function create(string $alias, array $availableFactories = []): self public static function create(string $alias, array $availableFactories = []): self
{ {
@@ -4,24 +4,10 @@ declare(strict_types=1);
namespace Flasher\Prime\Exception; namespace Flasher\Prime\Exception;
/**
* PresenterNotFoundException - Thrown when an unregistered presenter is requested.
*
* This exception is thrown when attempting to use a notification presenter that hasn't been
* registered with the system. It provides a clear error message that includes the requested
* presenter name and available presenters for debugging purposes.
*
* Design pattern: Domain-specific exception - Provides contextual information about the error.
*/
final class PresenterNotFoundException extends \Exception final class PresenterNotFoundException extends \Exception
{ {
/** /**
* Creates a new PresenterNotFoundException with a descriptive message. * @param string[] $availablePresenters
*
* @param string $alias The name of the presenter that was requested
* @param string[] $availablePresenters The list of registered presenter names
*
* @return self The exception instance
*/ */
public static function create(string $alias, array $availablePresenters = []): self public static function create(string $alias, array $availablePresenters = []): self
{ {
@@ -4,25 +4,10 @@ declare(strict_types=1);
namespace Flasher\Prime\Exception; namespace Flasher\Prime\Exception;
/**
* PresetNotFoundException - Thrown when an unregistered notification preset is requested.
*
* This exception is thrown when attempting to use a notification preset that hasn't been
* registered with the system. Presets define reusable notification templates that can be
* referenced by name. The exception provides a clear error message that includes the requested
* preset name and available presets for debugging purposes.
*
* Design pattern: Domain-specific exception - Provides contextual information about the error.
*/
final class PresetNotFoundException extends \Exception final class PresetNotFoundException extends \Exception
{ {
/** /**
* Creates a new PresetNotFoundException with a descriptive message. * @param string[] $availablePresets
*
* @param string $preset The name of the preset that was not found
* @param string[] $availablePresets The list of available presets for reference
*
* @return self The exception instance
*/ */
public static function create(string $preset, array $availablePresets = []): self public static function create(string $preset, array $availablePresets = []): self
{ {
@@ -7,50 +7,17 @@ namespace Flasher\Prime\Http\Csp;
use Flasher\Prime\Http\RequestInterface; use Flasher\Prime\Http\RequestInterface;
use Flasher\Prime\Http\ResponseInterface; use Flasher\Prime\Http\ResponseInterface;
/**
* ContentSecurityPolicyHandlerInterface - Contract for handling Content Security Policy.
*
* This interface defines operations for managing Content Security Policy (CSP) headers
* and nonces, which are necessary for securely injecting JavaScript and CSS into HTML pages.
* It ensures that PHPFlasher's injected content doesn't violate the site's CSP.
*
* Design pattern: Strategy - Defines a common interface for CSP handling strategies.
*/
interface ContentSecurityPolicyHandlerInterface interface ContentSecurityPolicyHandlerInterface
{ {
/** /**
* Returns an array of nonces to be used in HTML templates and Content-Security-Policy headers. * @return array{csp_script_nonce: ?string, csp_style_nonce: ?string}
*
* Nonce can be provided by:
* - The request - In case HTML content is fetched via AJAX and inserted in DOM, it must use the same nonce as origin
* - The response - A call to getNonces() has already been done previously. Same nonce are returned
* - They are otherwise randomly generated
*
* @param RequestInterface $request The current request
* @param ResponseInterface|null $response The current response (optional)
*
* @return array{csp_script_nonce: ?string, csp_style_nonce: ?string} Array with script and style nonces
*/ */
public function getNonces(RequestInterface $request, ?ResponseInterface $response = null): array; public function getNonces(RequestInterface $request, ?ResponseInterface $response = null): array;
/**
* Disables Content-Security-Policy.
*
* All related headers will be removed. This is useful in environments where CSP
* is not needed or when debugging.
*/
public function disableCsp(): void; public function disableCsp(): void;
/** /**
* Cleanup temporary headers and updates Content-Security-Policy headers. * @return array{csp_script_nonce?: ?string, csp_style_nonce?: ?string}
*
* This method modifies CSP headers in the response to allow PHPFlasher's
* JavaScript and CSS to execute without being blocked by CSP.
*
* @param RequestInterface $request The current request
* @param ResponseInterface $response The current response
*
* @return array{csp_script_nonce?: ?string, csp_style_nonce?: ?string} Nonces used in Content-Security-Policy header
*/ */
public function updateResponseHeaders(RequestInterface $request, ResponseInterface $response): array; public function updateResponseHeaders(RequestInterface $request, ResponseInterface $response): array;
} }
-16
View File
@@ -4,24 +4,8 @@ declare(strict_types=1);
namespace Flasher\Prime\Http\Csp; namespace Flasher\Prime\Http\Csp;
/**
* NonceGenerator - Default implementation for generating CSP nonces.
*
* This class provides a straightforward implementation for generating
* cryptographically secure nonces using PHP's random_bytes function.
* The nonces are encoded as hexadecimal strings for compatibility with
* HTML attributes and CSP headers.
*
* Design pattern: Strategy - Implements a specific nonce generation strategy.
*/
final readonly class NonceGenerator implements NonceGeneratorInterface final readonly class NonceGenerator implements NonceGeneratorInterface
{ {
/**
* {@inheritdoc}
*
* This implementation generates a 16-byte (128-bit) random value and
* encodes it as a hexadecimal string.
*/
public function generate(): string public function generate(): string
{ {
return bin2hex(random_bytes(16)); return bin2hex(random_bytes(16));
@@ -4,24 +4,7 @@ declare(strict_types=1);
namespace Flasher\Prime\Http\Csp; namespace Flasher\Prime\Http\Csp;
/**
* NonceGeneratorInterface - Contract for generating CSP nonces.
*
* This interface defines the essential operation for generating secure nonces
* (number used once) for Content Security Policy purposes. Nonces are used to
* whitelist specific inline scripts and styles in a CSP-protected environment.
*
* Design pattern: Strategy - Allows for different implementations of nonce generation.
*/
interface NonceGeneratorInterface interface NonceGeneratorInterface
{ {
/**
* Generates a cryptographically secure nonce.
*
* The generated nonce should be suitable for use in Content-Security-Policy headers
* and should provide sufficient entropy to be secure.
*
* @return string The generated nonce
*/
public function generate(): string; public function generate(): string;
} }
@@ -4,30 +4,7 @@ declare(strict_types=1);
namespace Flasher\Prime\Http; namespace Flasher\Prime\Http;
/**
* RequestExtensionInterface - Contract for request-related notification integrations.
*
* This interface defines the essential operations for integrating PHPFlasher with
* HTTP request objects from various frameworks. Implementations can extract flash messages
* from request objects (typically from session flash bags) and convert them to
* PHPFlasher notifications.
*
* Design pattern: Adapter - Provides a common interface for working with different
* framework request objects.
*/
interface RequestExtensionInterface interface RequestExtensionInterface
{ {
/**
* Processes flash messages from the request and converts them to notifications.
*
* This method should extract flash messages from the request (typically from session
* flash bags), convert them to PHPFlasher notifications, and return the potentially
* modified response.
*
* @param RequestInterface $request The framework-specific request wrapper
* @param ResponseInterface $response The framework-specific response wrapper
*
* @return ResponseInterface The potentially modified response
*/
public function flash(RequestInterface $request, ResponseInterface $response): ResponseInterface; public function flash(RequestInterface $request, ResponseInterface $response): ResponseInterface;
} }
+1 -65
View File
@@ -5,89 +5,25 @@ declare(strict_types=1);
namespace Flasher\Prime\Http; namespace Flasher\Prime\Http;
/** /**
* RequestInterface - Adapter interface for HTTP requests from different frameworks. * @method string getUri()
*
* This interface defines a common contract for request wrappers that adapt framework-specific
* request objects to work with PHPFlasher. It provides methods for querying request properties
* and accessing flash messages in a consistent way across different frameworks.
*
* Design pattern: Adapter - Provides a common interface for working with different
* framework request objects.
*
* @method string getUri() Gets the URI of the request (optional method, used for path exclusion)
*/ */
interface RequestInterface interface RequestInterface
{ {
/**
* Checks if the request was made via XMLHttpRequest (AJAX).
*
* @return bool True if the request is an AJAX request
*/
public function isXmlHttpRequest(): bool; public function isXmlHttpRequest(): bool;
/**
* Checks if the request expects an HTML response.
*
* This is determined by examining the Accept header or request format.
*
* @return bool True if the request expects HTML
*/
public function isHtmlRequestFormat(): bool; public function isHtmlRequestFormat(): bool;
/**
* Checks if the request has an associated session.
*
* @return bool True if a session is available
*/
public function hasSession(): bool; public function hasSession(): bool;
/**
* Checks if the session has been started.
*
* @return bool True if the session is active
*/
public function isSessionStarted(): bool; public function isSessionStarted(): bool;
/**
* Checks if the flash bag contains messages of the specified type.
*
* @param string $type The flash message type
*
* @return bool True if messages exist for the type
*/
public function hasType(string $type): bool; public function hasType(string $type): bool;
/**
* Gets flash messages of the specified type.
*
* @param string $type The flash message type
*
* @return string|string[] The flash message(s) of the specified type
*/
public function getType(string $type): string|array; public function getType(string $type): string|array;
/**
* Removes flash messages of the specified type.
*
* @param string $type The flash message type to remove
*/
public function forgetType(string $type): void; public function forgetType(string $type): void;
/**
* Checks if the request has the specified header.
*
* @param string $key The header name
*
* @return bool True if the header exists
*/
public function hasHeader(string $key): bool; public function hasHeader(string $key): bool;
/**
* Gets the value of the specified header.
*
* @param string $key The header name
*
* @return string|null The header value, or null if it doesn't exist
*/
public function getHeader(string $key): ?string; public function getHeader(string $key): ?string;
} }
@@ -4,28 +4,7 @@ declare(strict_types=1);
namespace Flasher\Prime\Http; namespace Flasher\Prime\Http;
/**
* ResponseExtensionInterface - Contract for response modification to include notifications.
*
* This interface defines the essential operation for integrating PHPFlasher notifications
* into HTTP responses. Implementations are responsible for injecting the rendered notification
* HTML into appropriate locations in the response content.
*
* Design pattern: Adapter - Provides a common interface for working with different
* framework response objects.
*/
interface ResponseExtensionInterface interface ResponseExtensionInterface
{ {
/**
* Renders the response by inserting the HTML response generated by the flasher library.
*
* This method should analyze the response, determine if and where notifications should
* be inserted, render them, and modify the response content accordingly.
*
* @param RequestInterface $request The current request
* @param ResponseInterface $response The current response
*
* @return ResponseInterface The modified response with the HTML response inserted
*/
public function render(RequestInterface $request, ResponseInterface $response): ResponseInterface; public function render(RequestInterface $request, ResponseInterface $response): ResponseInterface;
} }
-70
View File
@@ -4,97 +4,27 @@ declare(strict_types=1);
namespace Flasher\Prime\Http; namespace Flasher\Prime\Http;
/**
* ResponseInterface - Adapter interface for HTTP responses from different frameworks.
*
* This interface defines a common contract for response wrappers that adapt framework-specific
* response objects to work with PHPFlasher. It provides methods for inspecting response
* properties and modifying content in a consistent way across different frameworks.
*
* Design pattern: Adapter - Provides a common interface for working with different
* framework response objects.
*/
interface ResponseInterface interface ResponseInterface
{ {
/**
* Checks if the response is a redirection.
*
* @return bool True if the response is a redirect (3XX status code)
*/
public function isRedirection(): bool; public function isRedirection(): bool;
/**
* Checks if the response contains JSON content.
*
* @return bool True if the response is JSON
*/
public function isJson(): bool; public function isJson(): bool;
/**
* Checks if the response contains HTML content.
*
* @return bool True if the response is HTML
*/
public function isHtml(): bool; public function isHtml(): bool;
/**
* Checks if the response is a file download/attachment.
*
* @return bool True if the response is an attachment
*/
public function isAttachment(): bool; public function isAttachment(): bool;
/**
* Checks if the response represents a successful operation.
*
* @return bool True if the response has a 2XX status code
*/
public function isSuccessful(): bool; public function isSuccessful(): bool;
/**
* Gets the response content.
*
* @return string The response content
*/
public function getContent(): string; public function getContent(): string;
/**
* Sets the response content.
*
* @param string $content The new response content
*/
public function setContent(string $content): void; public function setContent(string $content): void;
/**
* Checks if the response has the specified header.
*
* @param string $key The header name
*
* @return bool True if the header exists
*/
public function hasHeader(string $key): bool; public function hasHeader(string $key): bool;
/**
* Gets the value of the specified header.
*
* @param string $key The header name
*
* @return string|null The header value, or null if it doesn't exist
*/
public function getHeader(string $key): ?string; public function getHeader(string $key): ?string;
/**
* Sets the value of the specified header.
*
* @param string $key The header name
* @param string|string[]|null $values The header value(s)
*/
public function setHeader(string $key, string|array|null $values): void; public function setHeader(string $key, string|array|null $values): void;
/**
* Removes the specified header.
*
* @param string $key The header name
*/
public function removeHeader(string $key): void; public function removeHeader(string $key): void;
} }
@@ -8,17 +8,6 @@ use Flasher\Prime\Stamp\PluginStamp;
use Flasher\Prime\Storage\StorageManagerInterface; use Flasher\Prime\Storage\StorageManagerInterface;
use Flasher\Prime\Support\Traits\Macroable; use Flasher\Prime\Support\Traits\Macroable;
/**
* Base abstract class for notification builders.
*
* This abstract class provides the foundation for all notification builders,
* implementing common functionality through traits. It manages the envelope
* creation and configuration process through a fluent API.
*
* Design pattern: Builder - Separates the construction of complex objects
* from their representation, allowing the same construction process to
* create different representations.
*/
abstract class NotificationBuilder implements NotificationBuilderInterface abstract class NotificationBuilder implements NotificationBuilderInterface
{ {
use Macroable; use Macroable;
@@ -26,16 +15,6 @@ abstract class NotificationBuilder implements NotificationBuilderInterface
use NotificationMethodAliases; use NotificationMethodAliases;
use NotificationStorageMethods; use NotificationStorageMethods;
/**
* Creates a new NotificationBuilder instance.
*
* This constructor accepts either a notification object or a string representing
* the plugin name. In the latter case, it creates a new notification and sets
* the plugin stamp accordingly.
*
* @param string|NotificationInterface $notification Either a notification object or a plugin name
* @param StorageManagerInterface $storageManager The storage manager for persisting notifications
*/
public function __construct(string|NotificationInterface $notification, StorageManagerInterface $storageManager) public function __construct(string|NotificationInterface $notification, StorageManagerInterface $storageManager)
{ {
if (\is_string($notification)) { if (\is_string($notification)) {
@@ -6,394 +6,128 @@ namespace Flasher\Prime\Notification;
use Flasher\Prime\Stamp\StampInterface; use Flasher\Prime\Stamp\StampInterface;
/**
* NotificationBuilderInterface - Fluent interface for notification creation.
*
* Provides a rich, fluent API for constructing notifications with various
* options and behaviors. Simplifies the process of creating and configuring
* notifications.
*
* Design pattern: Builder - Separates the construction of complex objects
* from their representation, allowing the same construction process to
* create different representations.
*/
interface NotificationBuilderInterface interface NotificationBuilderInterface
{ {
/**
* Sets the notification title.
*
* @param string $title The title to set
*
* @return static The builder instance for method chaining
*/
public function title(string $title): static; public function title(string $title): static;
/**
* Sets the notification message.
*
* @param string $message The message to set
*
* @return static The builder instance for method chaining
*/
public function message(string $message): static; public function message(string $message): static;
/**
* Sets the notification type.
*
* @param string $type The type to set (e.g., "success", "error", "info", "warning")
*
* @return static The builder instance for method chaining
*/
public function type(string $type): static; public function type(string $type): static;
/** /**
* Sets multiple options for the notification. * @param array<string, mixed> $options
*
* @param array<string, mixed> $options The options to set
* @param bool $merge Whether to merge with existing options (true) or replace them (false)
*
* @return static The builder instance for method chaining
*/ */
public function options(array $options, bool $merge = true): static; public function options(array $options, bool $merge = true): static;
/**
* Sets a single option for the notification.
*
* @param string $name The option name
* @param mixed $value The option value
*
* @return static The builder instance for method chaining
*/
public function option(string $name, mixed $value): static; public function option(string $name, mixed $value): static;
/**
* Sets the notification priority.
*
* Higher priority notifications are typically displayed before lower priority ones.
*
* @param int $priority The priority value (higher values indicate higher priority)
*
* @return static The builder instance for method chaining
*/
public function priority(int $priority): static; public function priority(int $priority): static;
/**
* Increases the number of request hops the notification will persist.
*
* This method is useful for keeping a notification across multiple redirects.
*
* @return static The builder instance for method chaining
*/
public function keep(): static; public function keep(): static;
/**
* Sets the exact number of request hops the notification will persist.
*
* @param int $amount The number of hops to keep the notification
*
* @return static The builder instance for method chaining
*/
public function hops(int $amount): static; public function hops(int $amount): static;
/**
* Sets a delay before showing the notification.
*
* @param int $delay The delay in milliseconds
*
* @return static The builder instance for method chaining
*/
public function delay(int $delay): static; public function delay(int $delay): static;
/** /**
* Configures translation parameters for the notification. * @param array<string, mixed> $parameters
*
* @param array<string, mixed> $parameters Translation parameters
* @param string|null $locale Specific locale to use, or null for default
*
* @return static The builder instance for method chaining
*/ */
public function translate(array $parameters = [], ?string $locale = null): static; public function translate(array $parameters = [], ?string $locale = null): static;
/**
* Sets the handler (plugin) that should process the notification.
*
* @param string $handler The handler/plugin name (e.g., "toastr", "sweetalert")
*
* @return static The builder instance for method chaining
*/
public function handler(string $handler): static; public function handler(string $handler): static;
/** /**
* Sets additional context data for the notification. * @param array<string, mixed> $context
*
* @param array<string, mixed> $context The context data
*
* @return static The builder instance for method chaining
*/ */
public function context(array $context): static; public function context(array $context): static;
/**
* Adds a condition that must be true for the notification to be displayed.
*
* @param bool|\Closure $condition A boolean or closure returning a boolean
*
* @return static The builder instance for method chaining
*/
public function when(bool|\Closure $condition): static; public function when(bool|\Closure $condition): static;
/**
* Adds a condition that must be false for the notification to be displayed.
*
* @param bool|\Closure $condition A boolean or closure returning a boolean
*
* @return static The builder instance for method chaining
*/
public function unless(bool|\Closure $condition): static; public function unless(bool|\Closure $condition): static;
/**
* Adds one or more stamps to the notification envelope.
*
* @param StampInterface[]|StampInterface $stamps The stamps to add
*
* @return static The builder instance for method chaining
*/
public function with(array|StampInterface $stamps): static; public function with(array|StampInterface $stamps): static;
/**
* Gets the current notification envelope.
*
* @return Envelope The notification envelope
*/
public function getEnvelope(): Envelope; public function getEnvelope(): Envelope;
/** /**
* Creates and stores a success notification. * @param array<string, mixed> $options
*
* @param string $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created and stored notification envelope
*/ */
public function success(string $message, array $options = [], ?string $title = null): Envelope; public function success(string $message, array $options = [], ?string $title = null): Envelope;
/** /**
* Creates and stores an error notification. * @param array<string, mixed> $options
*
* @param string $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created and stored notification envelope
*/ */
public function error(string $message, array $options = [], ?string $title = null): Envelope; public function error(string $message, array $options = [], ?string $title = null): Envelope;
/** /**
* Creates and stores an info notification. * @param array<string, mixed> $options
*
* @param string $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created and stored notification envelope
*/ */
public function info(string $message, array $options = [], ?string $title = null): Envelope; public function info(string $message, array $options = [], ?string $title = null): Envelope;
/** /**
* Creates and stores a warning notification. * @param array<string, mixed> $options
*
* @param string $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created and stored notification envelope
*/ */
public function warning(string $message, array $options = [], ?string $title = null): Envelope; public function warning(string $message, array $options = [], ?string $title = null): Envelope;
/** /**
* Creates and stores a notification with specified type. * @param array<string, mixed> $options
*
* @param string|null $type The notification type
* @param string|null $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created and stored notification envelope
*/ */
public function flash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null): Envelope; public function flash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null): Envelope;
/** /**
* Creates a notification from a named preset template. * @param array<string, mixed> $parameters
*
* @param string $preset The preset name
* @param array<string, mixed> $parameters Template parameters
*
* @return Envelope The created notification envelope
*/ */
public function preset(string $preset, array $parameters = []): Envelope; public function preset(string $preset, array $parameters = []): Envelope;
/**
* Creates a notification for a generic operation on a resource.
*
* @param string $operation The operation name (e.g., "created", "updated")
* @param string|object|null $resource The resource that was operated on
*
* @return Envelope The created notification envelope
*/
public function operation(string $operation, string|object|null $resource = null): Envelope; public function operation(string $operation, string|object|null $resource = null): Envelope;
/**
* Creates a notification for a resource creation operation.
*
* @param string|object|null $resource The resource that was created
*
* @return Envelope The created notification envelope
*/
public function created(string|object|null $resource = null): Envelope; public function created(string|object|null $resource = null): Envelope;
/**
* Creates a notification for a resource update operation.
*
* @param string|object|null $resource The resource that was updated
*
* @return Envelope The created notification envelope
*/
public function updated(string|object|null $resource = null): Envelope; public function updated(string|object|null $resource = null): Envelope;
/**
* Creates a notification for a resource save operation.
*
* @param string|object|null $resource The resource that was saved
*
* @return Envelope The created notification envelope
*/
public function saved(string|object|null $resource = null): Envelope; public function saved(string|object|null $resource = null): Envelope;
/**
* Creates a notification for a resource deletion operation.
*
* @param string|object|null $resource The resource that was deleted
*
* @return Envelope The created notification envelope
*/
public function deleted(string|object|null $resource = null): Envelope; public function deleted(string|object|null $resource = null): Envelope;
/**
* Finalizes and stores the current notification.
*
* @return Envelope The stored notification envelope
*/
public function push(): Envelope; public function push(): Envelope;
/** /**
* Alias for success() method. * @param array<string, mixed> $options
*
* @param string $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created notification envelope
*/ */
public function addSuccess(string $message, array $options = [], ?string $title = null): Envelope; public function addSuccess(string $message, array $options = [], ?string $title = null): Envelope;
/** /**
* Alias for error() method. * @param array<string, mixed> $options
*
* @param string $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created notification envelope
*/ */
public function addError(string $message, array $options = [], ?string $title = null): Envelope; public function addError(string $message, array $options = [], ?string $title = null): Envelope;
/** /**
* Alias for info() method. * @param array<string, mixed> $options
*
* @param string $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created notification envelope
*/ */
public function addInfo(string $message, array $options = [], ?string $title = null): Envelope; public function addInfo(string $message, array $options = [], ?string $title = null): Envelope;
/** /**
* Alias for warning() method. * @param array<string, mixed> $options
*
* @param string $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created notification envelope
*/ */
public function addWarning(string $message, array $options = [], ?string $title = null): Envelope; public function addWarning(string $message, array $options = [], ?string $title = null): Envelope;
/** /**
* Alias for flash() method. * @param array<string, mixed> $options
*
* @param string|null $type The notification type
* @param string|null $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created notification envelope
*/ */
public function addFlash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null): Envelope; public function addFlash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null): Envelope;
/** /**
* Alias for preset() method. * @param array<string, mixed> $parameters
*
* @param string $preset The preset name
* @param array<string, mixed> $parameters Template parameters
*
* @return Envelope The created notification envelope
*/ */
public function addPreset(string $preset, array $parameters = []): Envelope; public function addPreset(string $preset, array $parameters = []): Envelope;
/**
* Alias for created() method.
*
* @param string|object|null $resource The resource that was created
*
* @return Envelope The created notification envelope
*/
public function addCreated(string|object|null $resource = null): Envelope; public function addCreated(string|object|null $resource = null): Envelope;
/**
* Alias for updated() method.
*
* @param string|object|null $resource The resource that was updated
*
* @return Envelope The created notification envelope
*/
public function addUpdated(string|object|null $resource = null): Envelope; public function addUpdated(string|object|null $resource = null): Envelope;
/**
* Alias for saved() method.
*
* @param string|object|null $resource The resource that was saved
*
* @return Envelope The created notification envelope
*/
public function addSaved(string|object|null $resource = null): Envelope; public function addSaved(string|object|null $resource = null): Envelope;
/**
* Alias for deleted() method.
*
* @param string|object|null $resource The resource that was deleted
*
* @return Envelope The created notification envelope
*/
public function addDeleted(string|object|null $resource = null): Envelope; public function addDeleted(string|object|null $resource = null): Envelope;
/**
* Alias for operation() method.
*
* @param string $operation The operation name
* @param string|object|null $resource The resource that was operated on
*
* @return Envelope The created notification envelope
*/
public function addOperation(string $operation, string|object|null $resource = null): Envelope; public function addOperation(string $operation, string|object|null $resource = null): Envelope;
} }
@@ -7,28 +7,12 @@ namespace Flasher\Prime\Notification;
use Flasher\Prime\Stamp\PresetStamp; use Flasher\Prime\Stamp\PresetStamp;
use Flasher\Prime\Storage\StorageManagerInterface; use Flasher\Prime\Storage\StorageManagerInterface;
/**
* Implements notification creation and storage methods.
*
* This trait provides the concrete implementations for creating different types
* of notifications and storing them via the storage manager. It implements the
* final step in the builder pattern by creating and persisting notifications.
*/
trait NotificationStorageMethods trait NotificationStorageMethods
{ {
/**
* The storage manager for persisting notifications.
*/
protected readonly StorageManagerInterface $storageManager; protected readonly StorageManagerInterface $storageManager;
/** /**
* Creates and stores a success notification. * @param array<string, mixed> $options
*
* @param string $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created and stored notification envelope
*/ */
public function success(string $message, array $options = [], ?string $title = null): Envelope public function success(string $message, array $options = [], ?string $title = null): Envelope
{ {
@@ -36,13 +20,7 @@ trait NotificationStorageMethods
} }
/** /**
* Creates and stores an error notification. * @param array<string, mixed> $options
*
* @param string $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created and stored notification envelope
*/ */
public function error(string $message, array $options = [], ?string $title = null): Envelope public function error(string $message, array $options = [], ?string $title = null): Envelope
{ {
@@ -50,13 +28,7 @@ trait NotificationStorageMethods
} }
/** /**
* Creates and stores an info notification. * @param array<string, mixed> $options
*
* @param string $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created and stored notification envelope
*/ */
public function info(string $message, array $options = [], ?string $title = null): Envelope public function info(string $message, array $options = [], ?string $title = null): Envelope
{ {
@@ -64,13 +36,7 @@ trait NotificationStorageMethods
} }
/** /**
* Creates and stores a warning notification. * @param array<string, mixed> $options
*
* @param string $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created and stored notification envelope
*/ */
public function warning(string $message, array $options = [], ?string $title = null): Envelope public function warning(string $message, array $options = [], ?string $title = null): Envelope
{ {
@@ -78,18 +44,7 @@ trait NotificationStorageMethods
} }
/** /**
* Creates and stores a notification with specified type. * @param array<string, mixed> $options
*
* This is the core method used by specific notification type methods.
* It configures the notification based on the provided parameters and
* then stores it via push().
*
* @param string|null $type The notification type
* @param string|null $message The notification message
* @param array<string, mixed> $options Optional configuration for the notification
* @param string|null $title Optional title for the notification
*
* @return Envelope The created and stored notification envelope
*/ */
public function flash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null): Envelope public function flash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null): Envelope
{ {
@@ -113,15 +68,7 @@ trait NotificationStorageMethods
} }
/** /**
* Creates a notification from a named preset template. * @param array<string, mixed> $parameters
*
* Presets allow defining common notification templates in configuration,
* which can be reused with different parameters.
*
* @param string $preset The preset name
* @param array<string, mixed> $parameters Template parameters
*
* @return Envelope The created notification envelope
*/ */
public function preset(string $preset, array $parameters = []): Envelope public function preset(string $preset, array $parameters = []): Envelope
{ {
@@ -130,14 +77,6 @@ trait NotificationStorageMethods
return $this->push(); return $this->push();
} }
/**
* Creates a notification for a generic operation on a resource.
*
* @param string $operation The operation name (e.g., "created", "updated")
* @param string|object|null $resource The resource that was operated on
*
* @return Envelope The created notification envelope
*/
public function operation(string $operation, string|object|null $resource = null): Envelope public function operation(string $operation, string|object|null $resource = null): Envelope
{ {
$resource = match (true) { $resource = match (true) {
@@ -149,62 +88,26 @@ trait NotificationStorageMethods
return $this->preset($operation, [':resource' => $resource ?: 'resource']); return $this->preset($operation, [':resource' => $resource ?: 'resource']);
} }
/**
* Creates a notification for a resource creation operation.
*
* @param string|object|null $resource The resource that was created
*
* @return Envelope The created notification envelope
*/
public function created(string|object|null $resource = null): Envelope public function created(string|object|null $resource = null): Envelope
{ {
return $this->operation('created', $resource); return $this->operation('created', $resource);
} }
/**
* Creates a notification for a resource update operation.
*
* @param string|object|null $resource The resource that was updated
*
* @return Envelope The created notification envelope
*/
public function updated(string|object|null $resource = null): Envelope public function updated(string|object|null $resource = null): Envelope
{ {
return $this->operation('updated', $resource); return $this->operation('updated', $resource);
} }
/**
* Creates a notification for a resource save operation.
*
* @param string|object|null $resource The resource that was saved
*
* @return Envelope The created notification envelope
*/
public function saved(string|object|null $resource = null): Envelope public function saved(string|object|null $resource = null): Envelope
{ {
return $this->operation('saved', $resource); return $this->operation('saved', $resource);
} }
/**
* Creates a notification for a resource deletion operation.
*
* @param string|object|null $resource The resource that was deleted
*
* @return Envelope The created notification envelope
*/
public function deleted(string|object|null $resource = null): Envelope public function deleted(string|object|null $resource = null): Envelope
{ {
return $this->operation('deleted', $resource); return $this->operation('deleted', $resource);
} }
/**
* Finalizes and stores the current notification.
*
* This method completes the builder process, stores the notification
* in the storage manager, and returns the final envelope.
*
* @return Envelope The stored notification envelope
*/
public function push(): Envelope public function push(): Envelope
{ {
$envelope = $this->getEnvelope(); $envelope = $this->getEnvelope();
@@ -214,17 +117,6 @@ trait NotificationStorageMethods
return $envelope; return $envelope;
} }
/**
* Resolves a display name for a resource object.
*
* This method tries to determine a user-friendly name for an object by:
* 1. Checking if the object has a getFlashIdentifier() method
* 2. Falling back to the simple class name if not
*
* @param object $object The object to resolve a name for
*
* @return string|null The resolved name
*/
private function resolveResourceName(object $object): ?string private function resolveResourceName(object $object): ?string
{ {
$displayName = \is_callable([$object, 'getFlashIdentifier']) ? $object->getFlashIdentifier() : null; $displayName = \is_callable([$object, 'getFlashIdentifier']) ? $object->getFlashIdentifier() : null;
+4 -91
View File
@@ -6,133 +6,46 @@ namespace Flasher\Prime\Plugin;
use Flasher\Prime\Factory\NotificationFactoryInterface; use Flasher\Prime\Factory\NotificationFactoryInterface;
/**
* PluginInterface - Contract for PHPFlasher plugins.
*
* This interface defines the essential operations for PHPFlasher plugins.
* A plugin typically provides a notification renderer implementation along with
* its associated assets (scripts, styles) and configuration. The interface
* ensures that plugins can be discovered and loaded in a consistent way.
*
* Design patterns:
* - Plugin: Defines an extension mechanism for the core system
* - Strategy: Allows plugging in different notification display strategies
*/
interface PluginInterface interface PluginInterface
{ {
/**
* Gets the plugin's short name/alias.
*
* This is used in configuration and as part of service IDs.
*
* @return string The plugin alias (e.g., 'toastr', 'sweetalert')
*/
public function getAlias(): string; public function getAlias(): string;
/**
* Gets the plugin's full name.
*
* This can be used for display purposes in UIs.
*
* @return string The plugin name
*/
public function getName(): string; public function getName(): string;
/**
* Gets the plugin's primary service ID.
*
* This is the ID that will be used to register the plugin's factory
* in the service container.
*
* @return string The service ID (e.g., 'flasher.toastr')
*/
public function getServiceId(): string; public function getServiceId(): string;
/** /**
* Gets the plugin's factory class. * @return class-string<NotificationFactoryInterface>
*
* This is the class that will be instantiated to create notifications
* for this plugin.
*
* @return class-string<NotificationFactoryInterface> The factory class name
*/ */
public function getFactory(): string; public function getFactory(): string;
/**
* Gets the service aliases for the plugin.
*
* These are alternative service IDs or interfaces that the plugin's
* factory will be registered under.
*
* @return string|string[] The service alias(es)
*/
public function getServiceAliases(): string|array; public function getServiceAliases(): string|array;
/**
* Gets the JavaScript files needed by the plugin.
*
* These scripts will be included in the page when notifications
* from this plugin are displayed.
*
* @return string|string[] The script file path(s)
*/
public function getScripts(): string|array; public function getScripts(): string|array;
/**
* Gets the CSS stylesheets needed by the plugin.
*
* These styles will be included in the page when notifications
* from this plugin are displayed.
*
* @return string|string[] The stylesheet file path(s)
*/
public function getStyles(): string|array; public function getStyles(): string|array;
/** /**
* Gets the default configuration options for the plugin. * @return array<string, mixed>
*
* These options control the appearance and behavior of notifications
* created by this plugin.
*
* @return array<string, mixed> The default options
*/ */
public function getOptions(): array; public function getOptions(): array;
/**
* Gets the directory containing the plugin's assets.
*
* This directory contains the public files (JS, CSS, images) used by the plugin.
*
* @return string The absolute path to the assets directory
*/
public function getAssetsDir(): string; public function getAssetsDir(): string;
/**
* Gets the directory containing the plugin's resources.
*
* This directory contains templates, configurations, and other non-public files.
*
* @return string The absolute path to the resources directory
*/
public function getResourcesDir(): string; public function getResourcesDir(): string;
/** /**
* Normalizes the plugin configuration.
*
* This method takes a raw configuration array and transforms it into a
* standardized format with all required keys and proper value types.
*
* @param array{ * @param array{
* scripts?: string|string[], * scripts?: string|string[],
* styles?: string|string[], * styles?: string|string[],
* options?: array<string, mixed>, * options?: array<string, mixed>,
* } $config The raw configuration * } $config
* *
* @return array{ * @return array{
* scripts: string[], * scripts: string[],
* styles: string[], * styles: string[],
* options: array<string, mixed>, * options: array<string, mixed>,
* } The normalized configuration * }
*/ */
public function normalizeConfig(array $config): array; public function normalizeConfig(array $config): array;
} }
@@ -6,28 +6,7 @@ namespace Flasher\Prime\Response\Presenter;
use Flasher\Prime\Response\Response; use Flasher\Prime\Response\Response;
/**
* PresenterInterface - Contract for notification presenters.
*
* This interface defines the essential operation for transforming a Response
* object into a specific presentation format. Different implementations can
* render notifications as HTML, JSON, arrays, or other formats.
*
* Design pattern: Strategy - Defines a family of algorithms for rendering
* notifications in different formats, making them interchangeable.
*/
interface PresenterInterface interface PresenterInterface
{ {
/**
* Renders a response in a specific format.
*
* This method transforms the Response object into a presentation format
* suitable for the specific presenter implementation. The return type
* is mixed to accommodate different presentation formats (string, array, etc.).
*
* @param Response $response The response to render
*
* @return mixed The rendered result in the presenter's format
*/
public function render(Response $response): mixed; public function render(Response $response): mixed;
} }
@@ -6,27 +6,7 @@ namespace Flasher\Prime\Response\Resource;
use Flasher\Prime\Response\Response; use Flasher\Prime\Response\Response;
/**
* ResourceManagerInterface - Contract for managing notification resources.
*
* This interface defines the essential operation for populating Response objects
* with the resources (scripts, styles, options) required by the notifications
* they contain.
*
* Design pattern: Builder - Defines an interface for incrementally building
* complete responses with all required resources.
*/
interface ResourceManagerInterface interface ResourceManagerInterface
{ {
/**
* Populates a response with required resources.
*
* This method should analyze the notifications in the response and add
* the scripts, styles, and options needed to render them properly.
*
* @param Response $response The response to populate
*
* @return Response The populated response
*/
public function populateResponse(Response $response): Response; public function populateResponse(Response $response): Response;
} }
@@ -8,33 +8,13 @@ use Flasher\Prime\Response\Presenter\ArrayPresenter;
use Flasher\Prime\Response\Presenter\PresenterInterface; use Flasher\Prime\Response\Presenter\PresenterInterface;
/** /**
* ResponseManagerInterface - Contract for response generation and presenter management.
*
* This interface defines the essential operations for creating responses with
* notifications and managing the presenters that render them in different formats.
* It serves as the main entry point for generating notification responses in
* specific formats.
*
* Design patterns:
* - Strategy: Manages different presentation strategies through presenters
* - Factory: Creates responses with specific presenters based on requested format
*
* @phpstan-import-type ArrayPresenterType from ArrayPresenter * @phpstan-import-type ArrayPresenterType from ArrayPresenter
*/ */
interface ResponseManagerInterface interface ResponseManagerInterface
{ {
/** /**
* Renders notifications in a specific format. * @param array<string, mixed> $criteria
* * @param array<string, mixed> $context
* This method filters notifications based on criteria, removes them from storage,
* and renders them using the specified presenter. It provides sophisticated return
* type information for different presenter formats.
*
* @param string $presenter The presenter format to use (e.g., 'html', 'array', 'json')
* @param array<string, mixed> $criteria Filtering criteria for selecting notifications
* @param array<string, mixed> $context Additional context for the presentation
*
* @return mixed The rendered result in the requested format
* *
* @phpstan-return ($presenter is 'html' ? string : * @phpstan-return ($presenter is 'html' ? string :
* ($presenter is 'array' ? ArrayPresenterType : * ($presenter is 'array' ? ArrayPresenterType :
@@ -43,15 +23,5 @@ interface ResponseManagerInterface
*/ */
public function render(string $presenter = 'html', array $criteria = [], array $context = []): mixed; public function render(string $presenter = 'html', array $criteria = [], array $context = []): mixed;
/**
* Registers a presenter with the response manager.
*
* This method allows adding custom presenters that can render notifications
* in different formats. The presenter can be provided either as an instance
* or as a factory callback.
*
* @param string $alias The alias/name for the presenter
* @param callable|PresenterInterface $presenter The presenter instance or factory
*/
public function addPresenter(string $alias, callable|PresenterInterface $presenter): void; public function addPresenter(string $alias, callable|PresenterInterface $presenter): void;
} }
@@ -4,30 +4,12 @@ declare(strict_types=1);
namespace Flasher\Prime\Storage\Filter\Criteria; namespace Flasher\Prime\Storage\Filter\Criteria;
/**
* RangeExtractor - Helper trait for extracting range values from criteria.
*
* This trait provides common functionality for criteria that operate on
* numeric ranges. It standardizes how min/max range values are extracted
* from various input formats.
*
* Design pattern: Utility - Provides reusable functionality across multiple classes.
*/
trait RangeExtractor trait RangeExtractor
{ {
/** /**
* Extracts a range from the given criteria. * @return array{min: ?int, max: ?int}
* *
* This method standardizes range extraction from various input formats: * @throws \InvalidArgumentException
* - An integer value is treated as a minimum threshold
* - An array with 'min' and/or 'max' keys specifies a range
*
* @param string $name The name of the criteria (for error messages)
* @param mixed $criteria The criteria value to extract range from
*
* @return array{min: ?int, max: ?int} An associative array with 'min' and 'max' keys
*
* @throws \InvalidArgumentException If the criteria is not of an expected type
*/ */
private function extractRange(string $name, mixed $criteria): array private function extractRange(string $name, mixed $criteria): array
{ {
@@ -7,34 +7,14 @@ namespace Flasher\Prime\Storage\Filter;
use Flasher\Prime\Exception\CriteriaNotRegisteredException; use Flasher\Prime\Exception\CriteriaNotRegisteredException;
use Flasher\Prime\Storage\Filter\Criteria\CriteriaInterface; use Flasher\Prime\Storage\Filter\Criteria\CriteriaInterface;
/**
* FilterFactoryInterface - Contract for creating filter instances.
*
* This interface defines the operations required for a filter factory,
* which is responsible for creating and configuring filter instances
* based on provided configuration.
*
* Design pattern: Abstract Factory - Defines an interface for creating
* filter objects without specifying their concrete classes.
*/
interface FilterFactoryInterface interface FilterFactoryInterface
{ {
/** /**
* Creates a filter based on the provided configuration. * @param array<string, mixed> $config
* *
* @param array<string, mixed> $config Configuration for the filter criteria * @throws CriteriaNotRegisteredException
*
* @return Filter The created filter with configured criteria
*
* @throws CriteriaNotRegisteredException If a requested criterion doesn't exist
*/ */
public function createFilter(array $config): Filter; public function createFilter(array $config): Filter;
/**
* Registers a new criterion implementation.
*
* @param string $name The name of the criterion
* @param callable|CriteriaInterface $criteria The criterion implementation or factory
*/
public function addCriteria(string $name, callable|CriteriaInterface $criteria): void; public function addCriteria(string $name, callable|CriteriaInterface $criteria): void;
} }
+2 -24
View File
@@ -7,36 +7,14 @@ namespace Flasher\Prime\Storage\Filter;
use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Envelope;
use Flasher\Prime\Storage\Filter\Criteria\CriteriaInterface; use Flasher\Prime\Storage\Filter\Criteria\CriteriaInterface;
/**
* FilterInterface - Contract for notification envelope filters.
*
* This interface defines the essential operations for filtering notification
* envelopes. It allows composing multiple criteria into a single filter chain.
*
* Design pattern: Chain of Responsibility - Allows chaining multiple filtering
* criteria that are applied in sequence.
*/
interface FilterInterface interface FilterInterface
{ {
/** /**
* Applies the filter to an array of notification envelopes. * @param Envelope[] $envelopes
* *
* This method should filter the provided envelopes according to * @return Envelope[]
* the filter's criteria and return the matching subset.
*
* @param Envelope[] $envelopes The notification envelopes to filter
*
* @return Envelope[] The filtered notification envelopes
*/ */
public function apply(array $envelopes): array; public function apply(array $envelopes): array;
/**
* Adds a criterion to the filter chain.
*
* This method should add the provided criterion to the filter,
* extending its filtering capabilities.
*
* @param CriteriaInterface $criteria The criterion to add
*/
public function addCriteria(CriteriaInterface $criteria): void; public function addCriteria(CriteriaInterface $criteria): void;
} }
+3 -38
View File
@@ -6,60 +6,25 @@ namespace Flasher\Prime\Storage;
use Flasher\Prime\Notification\Envelope; use Flasher\Prime\Notification\Envelope;
/**
* StorageManagerInterface - Contract for notification storage management.
*
* This interface extends the basic storage operations with filtering capabilities.
* It defines the contract for the storage manager, which orchestrates the storage,
* retrieval, and filtering of notification envelopes.
*
* Design pattern: Mediator - Defines an interface for coordinating storage operations
* with additional capabilities like filtering and event dispatch.
*/
interface StorageManagerInterface interface StorageManagerInterface
{ {
/** /**
* Retrieves all stored notification envelopes. * @return Envelope[]
*
* @return Envelope[] Array of all stored notification envelopes
*/ */
public function all(): array; public function all(): array;
/** /**
* Filters notifications based on provided criteria. * @param array<string, mixed> $criteria
* *
* This method allows retrieving a subset of notifications that match * @return Envelope[]
* specific criteria, such as notification type, priority, or other attributes.
*
* @param array<string, mixed> $criteria Filtering criteria
*
* @return Envelope[] Array of filtered notification envelopes
*/ */
public function filter(array $criteria = []): array; public function filter(array $criteria = []): array;
/**
* Adds one or more notification envelopes to storage.
*
* @param Envelope ...$envelopes One or more notification envelopes to store
*/
public function add(Envelope ...$envelopes): void; public function add(Envelope ...$envelopes): void;
/**
* Updates one or more notification envelopes in storage.
*
* @param Envelope ...$envelopes One or more notification envelopes to update
*/
public function update(Envelope ...$envelopes): void; public function update(Envelope ...$envelopes): void;
/**
* Removes one or more notification envelopes from storage.
*
* @param Envelope ...$envelopes One or more notification envelopes to remove
*/
public function remove(Envelope ...$envelopes): void; public function remove(Envelope ...$envelopes): void;
/**
* Clears all notification envelopes from storage.
*/
public function clear(): void; public function clear(): void;
} }
+2 -21
View File
@@ -4,31 +4,12 @@ declare(strict_types=1);
namespace Flasher\Prime\Template; namespace Flasher\Prime\Template;
/**
* TemplateEngineInterface - Contract for template rendering engines.
*
* This interface defines the essential operation for template rendering engines
* in PHPFlasher. Template engines are responsible for transforming template files
* into HTML content, particularly for notifications that require custom rendering.
*
* Design patterns:
* - Strategy: Defines a family of template rendering algorithms that can be used interchangeably
* - Adapter: Provides a common interface for different template engine implementations
*/
interface TemplateEngineInterface interface TemplateEngineInterface
{ {
/** /**
* Renders a template with the given context variables. * @param array<string, mixed> $context
* *
* This method transforms a template file or string into rendered HTML by * @throws \InvalidArgumentException
* substituting variables from the context array.
*
* @param string $name The template name/path to render
* @param array<string, mixed> $context Variables to pass to the template
*
* @return string The rendered template as a string
*
* @throws \InvalidArgumentException If the template cannot be found or parsed
*/ */
public function render(string $name, array $context = []): string; public function render(string $name, array $context = []): string;
} }
+4 -227
View File
@@ -17,74 +17,25 @@ use Flasher\Prime\Test\Constraint\NotificationTitle;
use Flasher\Prime\Test\Constraint\NotificationType; use Flasher\Prime\Test\Constraint\NotificationType;
use PHPUnit\Framework\Assert; use PHPUnit\Framework\Assert;
/**
* FlasherAssert - Fluent assertion library for testing notifications.
*
* This class provides a rich set of assertion methods for testing PHPFlasher
* notifications in test suites. It uses a fluent interface for more readable tests
* and integrates with PHPUnit's assertion system.
*
* Design patterns:
* - Fluent Interface: Provides method chaining for readable assertions
* - Facade: Provides a simplified interface to a complex subsystem
* - Delegation: Delegates assertion logic to specialized constraint classes
*/
final class FlasherAssert final class FlasherAssert
{ {
/**
* Initializes and returns a new instance of the FlasherAssert class.
*
* This method serves as a starting point for chaining assertion methods in tests.
* It provides a fluent interface that allows for more readable and expressive tests.
*
* @return self A new instance for method chaining
*/
public static function that(): self public static function that(): self
{ {
return new self(); return new self();
} }
/**
* Asserts the presence of at least one notification in the system.
*
* This assertion passes if the notification system has logged any notifications,
* regardless of their specific attributes.
*
* @param string $message A custom message to display if the assertion fails
*
* @return self Returns itself to allow method chaining
*/
public static function hasNotifications(string $message = 'Expected at least one notification to exist.'): self public static function hasNotifications(string $message = 'Expected at least one notification to exist.'): self
{ {
return self::fluent(static fn () => Assert::assertNotEmpty(self::getNotificationEvents()->getEnvelopes(), $message)); return self::fluent(static fn () => Assert::assertNotEmpty(self::getNotificationEvents()->getEnvelopes(), $message));
} }
/**
* Asserts that no notifications have been registered in the system.
*
* Useful for tests where the absence of notifications indicates a pass condition.
*
* @param string $message A custom message to display if the assertion fails
*
* @return self Returns itself to allow method chaining
*/
public static function noNotifications(string $message = 'Expected no notifications to exist.'): self public static function noNotifications(string $message = 'Expected no notifications to exist.'): self
{ {
return self::fluent(static fn () => Assert::assertEmpty(self::getNotificationEvents()->getEnvelopes(), $message)); return self::fluent(static fn () => Assert::assertEmpty(self::getNotificationEvents()->getEnvelopes(), $message));
} }
/** /**
* Asserts the existence of a notification matching specific criteria. * @param array<string, mixed> $expectedOptions
*
* A notification must match all provided criteria to satisfy the assertion.
*
* @param string $expectedType Expected notification type (e.g., 'success', 'error')
* @param string|null $expectedMessage Expected message content (null to ignore)
* @param array<string, mixed> $expectedOptions Expected options as an associative array
* @param string|null $expectedTitle Expected notification title (null to ignore)
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/ */
public static function withNotification(string $expectedType, ?string $expectedMessage = null, array $expectedOptions = [], ?string $expectedTitle = null, string $message = ''): self public static function withNotification(string $expectedType, ?string $expectedMessage = null, array $expectedOptions = [], ?string $expectedTitle = null, string $message = ''): self
{ {
@@ -92,228 +43,95 @@ final class FlasherAssert
} }
/** /**
* Alias of withNotification() - Asserts the existence of a notification matching specific criteria. * @param array<string, mixed> $expectedOptions
*
* @param string $expectedType Expected notification type
* @param string|null $expectedMessage Expected message content
* @param array<string, mixed> $expectedOptions Expected options
* @param string|null $expectedTitle Expected notification title
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/ */
public static function notification(string $expectedType, ?string $expectedMessage = null, array $expectedOptions = [], ?string $expectedTitle = null, string $message = ''): self public static function notification(string $expectedType, ?string $expectedMessage = null, array $expectedOptions = [], ?string $expectedTitle = null, string $message = ''): self
{ {
return self::withNotification($expectedType, $expectedMessage, $expectedOptions, $expectedTitle, $message); return self::withNotification($expectedType, $expectedMessage, $expectedOptions, $expectedTitle, $message);
} }
/**
* Asserts the total count of notifications matches an expected number.
*
* @param int $expectedCount Expected number of notifications
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function withCount(int $expectedCount, string $message = ''): self public static function withCount(int $expectedCount, string $message = ''): self
{ {
return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationCount($expectedCount), $message)); return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationCount($expectedCount), $message));
} }
/**
* Alias of withCount() - Asserts the total count of notifications.
*
* @param int $expectedCount Expected number of notifications
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function count(int $expectedCount, string $message = ''): self public static function count(int $expectedCount, string $message = ''): self
{ {
return self::withCount($expectedCount, $message); return self::withCount($expectedCount, $message);
} }
/**
* Asserts the existence of at least one notification of a specific type.
*
* @param string $expectedType Expected notification type
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function withType(string $expectedType, string $message = ''): self public static function withType(string $expectedType, string $message = ''): self
{ {
return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationType($expectedType), $message)); return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationType($expectedType), $message));
} }
/**
* Alias of withType() - Asserts the existence of a notification of a specific type.
*
* @param string $expectedType Expected notification type
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function type(string $expectedType, string $message = ''): self public static function type(string $expectedType, string $message = ''): self
{ {
return self::withType($expectedType, $message); return self::withType($expectedType, $message);
} }
/**
* Asserts the presence of at least one 'success' type notification.
*
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function withSuccess(string $message = ''): self public static function withSuccess(string $message = ''): self
{ {
return self::fluent(static fn () => self::type(Type::SUCCESS, $message)); return self::fluent(static fn () => self::type(Type::SUCCESS, $message));
} }
/**
* Alias of withSuccess() - Asserts the presence of a 'success' notification.
*
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function success(string $message = ''): self public static function success(string $message = ''): self
{ {
return self::withSuccess($message); return self::withSuccess($message);
} }
/**
* Asserts the presence of at least one 'warning' type notification.
*
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function withWarning(string $message = ''): self public static function withWarning(string $message = ''): self
{ {
return self::fluent(static fn () => self::type(Type::WARNING, $message)); return self::fluent(static fn () => self::type(Type::WARNING, $message));
} }
/**
* Alias of withWarning() - Asserts the presence of a 'warning' notification.
*
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function warning(string $message = ''): self public static function warning(string $message = ''): self
{ {
return self::withWarning($message); return self::withWarning($message);
} }
/**
* Asserts the presence of at least one 'error' type notification.
*
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function withError(string $message = ''): self public static function withError(string $message = ''): self
{ {
return self::fluent(static fn () => self::type(Type::ERROR, $message)); return self::fluent(static fn () => self::type(Type::ERROR, $message));
} }
/**
* Alias of withError() - Asserts the presence of an 'error' notification.
*
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function error(string $message = ''): self public static function error(string $message = ''): self
{ {
return self::withError($message); return self::withError($message);
} }
/**
* Asserts the presence of at least one 'info' type notification.
*
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function withInfo(string $message = ''): self public static function withInfo(string $message = ''): self
{ {
return self::fluent(static fn () => self::type(Type::INFO, $message)); return self::fluent(static fn () => self::type(Type::INFO, $message));
} }
/**
* Alias of withInfo() - Asserts the presence of an 'info' notification.
*
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function info(string $message = ''): self public static function info(string $message = ''): self
{ {
return self::withInfo($message); return self::withInfo($message);
} }
/**
* Asserts the presence of a notification with a specific title.
*
* @param string $expectedTitle Expected notification title
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function withTitle(string $expectedTitle, string $message = ''): self public static function withTitle(string $expectedTitle, string $message = ''): self
{ {
return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationTitle($expectedTitle), $message)); return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationTitle($expectedTitle), $message));
} }
/**
* Alias of withTitle() - Asserts the presence of a notification with specific title.
*
* @param string $expectedTitle Expected notification title
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function title(string $expectedTitle, string $message = ''): self public static function title(string $expectedTitle, string $message = ''): self
{ {
return self::withTitle($expectedTitle, $message); return self::withTitle($expectedTitle, $message);
} }
/**
* Asserts the presence of a notification with a specific message.
*
* @param string $expectedMessage Expected notification message
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function withMessage(string $expectedMessage, string $message = ''): self public static function withMessage(string $expectedMessage, string $message = ''): self
{ {
return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationMessage($expectedMessage), $message)); return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationMessage($expectedMessage), $message));
} }
/**
* Alias of withMessage() - Asserts the presence of a notification with specific message.
*
* @param string $expectedMessage Expected notification message
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function message(string $expectedMessage, string $message = ''): self public static function message(string $expectedMessage, string $message = ''): self
{ {
return self::withMessage($expectedMessage, $message); return self::withMessage($expectedMessage, $message);
} }
/** /**
* Asserts the presence of a notification with specific options. * @param array<string, mixed> $expectedOptions
*
* @param array<string, mixed> $expectedOptions Expected options as an associative array
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/ */
public static function withOptions(array $expectedOptions, string $message = ''): self public static function withOptions(array $expectedOptions, string $message = ''): self
{ {
@@ -321,56 +139,23 @@ final class FlasherAssert
} }
/** /**
* Alias of withOptions() - Asserts the presence of a notification with specific options. * @param array<string, mixed> $expectedOptions
*
* @param array<string, mixed> $expectedOptions Expected options
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/ */
public static function options(array $expectedOptions, string $message = ''): self public static function options(array $expectedOptions, string $message = ''): self
{ {
return self::withOptions($expectedOptions, $message); return self::withOptions($expectedOptions, $message);
} }
/**
* Asserts the presence of a notification with a specific option key and value.
*
* @param string $expectedKey Expected option key
* @param mixed $expectedValue Expected option value (null to check only key existence)
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function withOption(string $expectedKey, mixed $expectedValue = null, string $message = ''): self public static function withOption(string $expectedKey, mixed $expectedValue = null, string $message = ''): self
{ {
return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationOption($expectedKey, $expectedValue), $message)); return self::fluent(static fn () => Assert::assertThat(self::getNotificationEvents(), new NotificationOption($expectedKey, $expectedValue), $message));
} }
/**
* Alias of withOption() - Asserts notification has a specific option.
*
* @param string $expectedKey Expected option key
* @param mixed $expectedValue Expected option value
* @param string $message Custom failure message
*
* @return self Returns itself to allow method chaining
*/
public static function option(string $expectedKey, mixed $expectedValue = null, string $message = ''): self public static function option(string $expectedKey, mixed $expectedValue = null, string $message = ''): self
{ {
return self::withOption($expectedKey, $expectedValue, $message); return self::withOption($expectedKey, $expectedValue, $message);
} }
/**
* Internal utility method for fluent interface implementation.
*
* This method executes a callback and returns a new instance of FlasherAssert
* to allow method chaining in a fluent interface style.
*
* @param callable $callback The assertion logic to execute
*
* @return self A new instance for method chaining
*/
private static function fluent(callable $callback): self private static function fluent(callable $callback): self
{ {
$callback(); $callback();
@@ -378,14 +163,6 @@ final class FlasherAssert
return new self(); return new self();
} }
/**
* Fetches the NotificationEvents instance for assertion.
*
* This method retrieves notification events from the NotificationLoggerListener
* service, which tracks notifications that were displayed.
*
* @return NotificationEvents Collection of notification events for assertion
*/
public static function getNotificationEvents(): NotificationEvents public static function getNotificationEvents(): NotificationEvents
{ {
$container = FlasherContainer::getContainer(); $container = FlasherContainer::getContainer();
-28
View File
@@ -4,39 +4,11 @@ declare(strict_types=1);
namespace Flasher\Prime\Translation; namespace Flasher\Prime\Translation;
/**
* Language - Utility class for determining text direction based on locale.
*
* This class provides static methods for working with language directionality,
* particularly for determining if a language uses left-to-right (LTR) or
* right-to-left (RTL) text direction.
*
* Design patterns:
* - Utility: Provides a collection of static methods for a specific purpose
* - Service: Provides functionality related to a specific domain concept
*/
final readonly class Language final readonly class Language
{ {
/**
* Constant representing left-to-right text direction.
*/
public const LTR = 'ltr'; public const LTR = 'ltr';
/**
* Constant representing right-to-left text direction.
*/
public const RTL = 'rtl'; public const RTL = 'rtl';
/**
* Determines the text direction for a given locale.
*
* This method uses the PHP intl extension to access ICU data about text direction.
* If the extension is not available or the locale data is missing, it defaults to LTR.
*
* @param string $locale The locale code to check (e.g., 'en', 'ar')
*
* @return string Either 'ltr' for left-to-right or 'rtl' for right-to-left
*/
public static function direction(string $locale): string public static function direction(string $locale): string
{ {
if (!\extension_loaded('intl')) { if (!\extension_loaded('intl')) {
+1 -21
View File
@@ -13,30 +13,10 @@ use Flasher\Prime\Translation\Language\Portuguese;
use Flasher\Prime\Translation\Language\Russian; use Flasher\Prime\Translation\Language\Russian;
use Flasher\Prime\Translation\Language\Spanish; use Flasher\Prime\Translation\Language\Spanish;
/**
* Messages - Registry of predefined translations for common notification messages.
*
* This class provides access to predefined translations for common notification
* messages in multiple languages. It serves as a centralized registry of translations
* that can be used without requiring an external translation service.
*
* Design patterns:
* - Registry: Provides a centralized registry of translations
* - Factory: Creates and returns language-specific translation sets
* - Static Access: Provides static access to translation data
*/
final readonly class Messages final readonly class Messages
{ {
/** /**
* Gets translations for a specific language. * @return array<string, string>
*
* This method returns a set of predefined translations for common notification
* messages in the requested language. If the language is not supported, it
* returns an empty array.
*
* @param string $language The language code (e.g., 'en', 'fr')
*
* @return array<string, string> Key-value pairs of message identifiers and translations
*/ */
public static function get(string $language): array public static function get(string $language): array
{ {
+1 -25
View File
@@ -4,36 +4,12 @@ declare(strict_types=1);
namespace Flasher\Prime\Translation; namespace Flasher\Prime\Translation;
/**
* TranslatorInterface - Contract for notification translation services.
*
* This interface defines the essential operations for translating notification
* content. It supports parameter substitution and locale-specific translations.
*
* Design patterns:
* - Strategy: Defines a family of translation algorithms that can be used interchangeably
* - Adapter: Provides a common interface for different translation implementations
*/
interface TranslatorInterface interface TranslatorInterface
{ {
/** /**
* Translates a message identifier to the target locale. * @param array<string, mixed> $parameters
*
* This method transforms a message identifier like 'success' or 'The resource was created'
* into a localized string, substituting any parameters in the process.
*
* @param string $id The message identifier to translate
* @param array<string, mixed> $parameters Parameters to substitute in the translated string
* @param string|null $locale The target locale, or null to use the default
*
* @return string The translated string
*/ */
public function translate(string $id, array $parameters = [], ?string $locale = null): string; public function translate(string $id, array $parameters = [], ?string $locale = null): string;
/**
* Gets the default locale used by the translator.
*
* @return string The default locale code (e.g., 'en', 'fr')
*/
public function getLocale(): string; public function getLocale(): string;
} }