mirror of
https://github.com/php-flasher/php-flasher.git
synced 2026-03-31 15:07:47 +01:00
Simplify PHPDoc comments in Prime classes
Remove verbose documentation pattern references and redundant explanations, keeping only essential type annotations.
This commit is contained in:
@@ -4,45 +4,19 @@ declare(strict_types=1);
|
||||
|
||||
namespace Flasher\Prime\Asset;
|
||||
|
||||
/**
|
||||
* AssetManager - Manages asset files and their versioning via a manifest file.
|
||||
*
|
||||
* This class provides functionality for handling asset versioning through a manifest
|
||||
* file that maps original asset paths to versioned paths with hash parameters.
|
||||
* The asset versioning helps with cache busting by appending a content hash to the URL.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Resource Manager: Centralized management of web asset resources
|
||||
* - Cache Buster: Handles versioning of assets to ensure browser cache invalidation
|
||||
*/
|
||||
final class AssetManager implements AssetManagerInterface
|
||||
{
|
||||
/**
|
||||
* Cached manifest entries mapping original paths to versioned paths.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private array $entries = [];
|
||||
|
||||
/**
|
||||
* Creates a new AssetManager instance.
|
||||
*
|
||||
* @param string $publicDir The public directory where assets are located
|
||||
* @param string $manifestPath The path to the manifest file
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly string $publicDir,
|
||||
private readonly string $manifestPath,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* This implementation first checks for an exact match in the manifest,
|
||||
* then tries with directory separators normalized, and falls back to the
|
||||
* original path if no match is found.
|
||||
*/
|
||||
public function getPath(string $path): string
|
||||
{
|
||||
$entriesData = $this->getEntriesData();
|
||||
@@ -55,16 +29,6 @@ final class AssetManager implements AssetManagerInterface
|
||||
return array_map(fn (string $path) => $this->getPath($path), $paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* This method:
|
||||
* 1. Processes each file to calculate its content hash
|
||||
* 2. Creates a mapping from relative paths to versioned paths
|
||||
* 3. Writes the mapping to the manifest file as JSON
|
||||
*
|
||||
* @throws \RuntimeException If unable to write to the manifest file
|
||||
*/
|
||||
public function createManifest(array $files): void
|
||||
{
|
||||
foreach ($files as $file) {
|
||||
@@ -87,14 +51,7 @@ final class AssetManager implements AssetManagerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and returns the entries from the manifest file.
|
||||
*
|
||||
* This method lazily loads the manifest data and caches it for subsequent calls.
|
||||
* If no manifest file exists or it cannot be parsed, an empty array is returned.
|
||||
*
|
||||
* @return array<string, string> The manifest entries mapping original to versioned paths
|
||||
*
|
||||
* @throws \InvalidArgumentException If the manifest file contains invalid JSON
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function getEntriesData(): array
|
||||
{
|
||||
@@ -116,16 +73,6 @@ final class AssetManager implements AssetManagerInterface
|
||||
return $this->entries = $entries; // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a hash for a file based on its contents.
|
||||
*
|
||||
* This method normalizes line endings to ensure consistent hashing
|
||||
* across different platforms.
|
||||
*
|
||||
* @param string $path The path to the file
|
||||
*
|
||||
* @return string The MD5 hash of the file contents or empty string if file cannot be read
|
||||
*/
|
||||
private function computeHash(string $path): string
|
||||
{
|
||||
$contents = file_get_contents($path);
|
||||
|
||||
@@ -4,49 +4,19 @@ declare(strict_types=1);
|
||||
|
||||
namespace Flasher\Prime\Asset;
|
||||
|
||||
/**
|
||||
* AssetManagerInterface - Contract for asset management services.
|
||||
*
|
||||
* This interface defines the essential operations for managing web assets,
|
||||
* particularly focusing on path resolution and manifest generation for versioning.
|
||||
*
|
||||
* Design pattern: Strategy - Defines a common interface for different asset
|
||||
* management strategies that can be used interchangeably.
|
||||
*/
|
||||
interface AssetManagerInterface
|
||||
{
|
||||
/**
|
||||
* Resolves the given path to its hashed version if available in the manifest.
|
||||
*
|
||||
* This method should look up the original path in a manifest of versioned assets
|
||||
* and return the versioned path if found. Otherwise, it should return the original path.
|
||||
*
|
||||
* @param string $path The original file path
|
||||
*
|
||||
* @return string The resolved file path with version hash or the original path if not found
|
||||
*/
|
||||
public function getPath(string $path): string;
|
||||
|
||||
/**
|
||||
* Resolves multiple paths to their hashed versions if available.
|
||||
* @param string[] $paths
|
||||
*
|
||||
* This is a batch version of getPath() that processes multiple paths at once.
|
||||
*
|
||||
* @param string[] $paths Array of original file paths
|
||||
*
|
||||
* @return string[] Array of resolved file paths in the same order
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPaths(array $paths): array;
|
||||
|
||||
/**
|
||||
* Generates a JSON manifest from given files.
|
||||
*
|
||||
* This method should create a mapping between original file paths and
|
||||
* versioned paths (typically with content hashes) and save it to a manifest file.
|
||||
*
|
||||
* @param string[] $files Array of file paths to include in the manifest
|
||||
*
|
||||
* @throws \RuntimeException If the manifest cannot be created
|
||||
* @param string[] $files
|
||||
*/
|
||||
public function createManifest(array $files): void;
|
||||
}
|
||||
|
||||
@@ -5,28 +5,7 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime;
|
||||
|
||||
/**
|
||||
* Configuration for PHPFlasher.
|
||||
*
|
||||
* This class provides type-safe access to PHPFlasher's configuration structure.
|
||||
* It uses PHPStan annotations to define the complex nested configuration schema,
|
||||
* ensuring configuration consistency and enabling IDE autocompletion.
|
||||
*
|
||||
* Design pattern: Type-safe Configuration - Uses PHP's type system to validate
|
||||
* and document complex configuration structures.
|
||||
*
|
||||
* The configuration array structure contains:
|
||||
* - default: The default notification adapter to use
|
||||
* - main_script: Main JavaScript file path
|
||||
* - scripts: Additional JavaScript files to include
|
||||
* - styles: CSS stylesheets to include
|
||||
* - inject_assets: Whether to auto-inject assets in responses
|
||||
* - translate: Whether to translate notifications
|
||||
* - excluded_paths: Paths where notifications shouldn't be displayed
|
||||
* - options: Global notification options
|
||||
* - filter: Default filtering criteria
|
||||
* - flash_bag: Flash bag configuration for framework integration
|
||||
* - presets: Notification templates/presets with type, title, message and options
|
||||
* - plugins: Plugin-specific configuration with scripts, styles and options
|
||||
* Type-safe configuration for PHPFlasher.
|
||||
*
|
||||
* @phpstan-type ConfigType array{
|
||||
* default: string,
|
||||
@@ -55,11 +34,6 @@ namespace Flasher\Prime;
|
||||
final class Configuration
|
||||
{
|
||||
/**
|
||||
* Validates and returns the configuration array.
|
||||
*
|
||||
* This method serves as a type-safe wrapper around configuration arrays,
|
||||
* ensuring that they match the expected schema defined in the PHPStan annotations.
|
||||
*
|
||||
* @phpstan-param ConfigType $config
|
||||
*
|
||||
* @phpstan-return ConfigType
|
||||
|
||||
@@ -9,80 +9,33 @@ use Flasher\Prime\FlasherInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* FlasherContainer - Service locator for PHPFlasher services using PSR-11 containers.
|
||||
*
|
||||
* This class provides static access to Flasher services through a PSR-11 compatible
|
||||
* container. It manages a singleton instance that wraps the container and provides
|
||||
* type-safe access to Flasher services.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Service Locator: Provides a centralized registry for accessing services
|
||||
* - Singleton: Maintains a single, global instance of the container wrapper
|
||||
* - Adapter: Adapts a PSR-11 container to provide Flasher-specific service access
|
||||
*
|
||||
* @internal This class is not part of the public API and may change without notice
|
||||
* @internal
|
||||
*/
|
||||
final class FlasherContainer
|
||||
{
|
||||
/**
|
||||
* The singleton instance of this class.
|
||||
*/
|
||||
private static ?self $instance = null;
|
||||
|
||||
/**
|
||||
* Private constructor to prevent direct instantiation.
|
||||
*
|
||||
* @param ContainerInterface|\Closure $container A ContainerInterface instance or factory
|
||||
*/
|
||||
private function __construct(private readonly ContainerInterface|\Closure $container)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the container with a PSR-11 container or a factory.
|
||||
*
|
||||
* This method initializes the singleton instance if it doesn't exist yet.
|
||||
* It accepts either a direct ContainerInterface implementation or a closure
|
||||
* that will return one when invoked.
|
||||
*
|
||||
* @param ContainerInterface|\Closure $container A ContainerInterface instance or factory
|
||||
*/
|
||||
public static function from(ContainerInterface|\Closure $container): void
|
||||
{
|
||||
self::$instance ??= new self($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the container instance.
|
||||
*
|
||||
* This method clears the singleton instance, effectively removing all
|
||||
* service references. Useful for testing or situations that require
|
||||
* container replacement.
|
||||
*/
|
||||
public static function reset(): void
|
||||
{
|
||||
self::$instance = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns an instance of a Flasher service by ID.
|
||||
*
|
||||
* This method retrieves a service from the container and ensures it
|
||||
* implements the appropriate interface. It provides type-safe access
|
||||
* to various Flasher services with PHPStan return type specifications.
|
||||
*
|
||||
* @param string $id The service identifier (e.g., 'flasher', 'flasher.toastr')
|
||||
*
|
||||
* @return FlasherInterface|NotificationFactoryInterface The requested service
|
||||
*
|
||||
* @phpstan-return ($id is 'flasher' ? \Flasher\Prime\FlasherInterface :
|
||||
* ($id is 'flasher.noty' ? \Flasher\Noty\Prime\NotyInterface :
|
||||
* ($id is 'flasher.notyf' ? \Flasher\Notyf\Prime\NotyfInterface :
|
||||
* ($id is 'flasher.sweetalert' ? \Flasher\SweetAlert\Prime\SweetAlertInterface :
|
||||
* ($id is 'flasher.toastr' ? \Flasher\Toastr\Prime\ToastrInterface :
|
||||
* \Flasher\Prime\Factory\NotificationFactoryInterface)))))
|
||||
*
|
||||
* @throws \InvalidArgumentException If the service doesn't exist or has an invalid type
|
||||
*/
|
||||
public static function create(string $id): FlasherInterface|NotificationFactoryInterface
|
||||
{
|
||||
@@ -99,28 +52,11 @@ final class FlasherContainer
|
||||
return $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a service exists in the container.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
*
|
||||
* @return bool True if the service exists, false otherwise
|
||||
*/
|
||||
public static function has(string $id): bool
|
||||
{
|
||||
return self::getContainer()->has($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the container, resolving it if necessary.
|
||||
*
|
||||
* If the container was provided as a factory closure, this method
|
||||
* invokes it to get the actual container instance.
|
||||
*
|
||||
* @return ContainerInterface The resolved container instance
|
||||
*
|
||||
* @throws \InvalidArgumentException If the resolved container is not a ContainerInterface
|
||||
*/
|
||||
public static function getContainer(): ContainerInterface
|
||||
{
|
||||
$container = self::getInstance()->container;
|
||||
@@ -134,13 +70,6 @@ final class FlasherContainer
|
||||
return $resolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the singleton instance, throws if not initialized.
|
||||
*
|
||||
* @return self The singleton instance
|
||||
*
|
||||
* @throws \LogicException If the instance hasn't been initialized yet
|
||||
*/
|
||||
private static function getInstance(): self
|
||||
{
|
||||
if (!self::$instance instanceof self) {
|
||||
|
||||
@@ -9,19 +9,13 @@ use Flasher\Prime\Storage\Filter\Filter;
|
||||
use Flasher\Prime\Storage\Filter\FilterInterface;
|
||||
|
||||
/**
|
||||
* FilterEvent - Event dispatched when notifications are being filtered.
|
||||
*
|
||||
* This event is dispatched during the filtering process, allowing listeners
|
||||
* to modify the filter, the envelopes being filtered, or the filter criteria.
|
||||
* Event dispatched when notifications are being filtered.
|
||||
*/
|
||||
final class FilterEvent
|
||||
{
|
||||
/**
|
||||
* Creates a new FilterEvent instance.
|
||||
*
|
||||
* @param FilterInterface $filter The filter being applied
|
||||
* @param Envelope[] $envelopes The notification envelopes to filter
|
||||
* @param array<string, mixed> $criteria The filtering criteria
|
||||
* @param Envelope[] $envelopes
|
||||
* @param array<string, mixed> $criteria
|
||||
*/
|
||||
public function __construct(
|
||||
private FilterInterface $filter,
|
||||
@@ -30,32 +24,18 @@ final class FilterEvent
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the filter being applied.
|
||||
*
|
||||
* @return FilterInterface The filter
|
||||
*/
|
||||
public function getFilter(): FilterInterface
|
||||
{
|
||||
return $this->filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the filter to be applied.
|
||||
*
|
||||
* This allows listeners to replace the filter with a custom implementation.
|
||||
*
|
||||
* @param Filter $filter The new filter
|
||||
*/
|
||||
public function setFilter(Filter $filter): void
|
||||
{
|
||||
$this->filter = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the notification envelopes being filtered.
|
||||
*
|
||||
* @return Envelope[] The notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function getEnvelopes(): array
|
||||
{
|
||||
@@ -63,11 +43,7 @@ final class FilterEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the notification envelopes to be filtered.
|
||||
*
|
||||
* This allows listeners to modify the collection of envelopes before filtering.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to filter
|
||||
* @param Envelope[] $envelopes
|
||||
*/
|
||||
public function setEnvelopes(array $envelopes): void
|
||||
{
|
||||
@@ -75,11 +51,7 @@ final class FilterEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the filtering criteria.
|
||||
*
|
||||
* These criteria determine how notifications will be filtered.
|
||||
*
|
||||
* @return array<string, mixed> The filtering criteria
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getCriteria(): array
|
||||
{
|
||||
|
||||
@@ -7,31 +7,17 @@ namespace Flasher\Prime\EventDispatcher\Event;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* NotificationEvents - Collector for notification envelopes.
|
||||
* Collector for notification envelopes.
|
||||
*
|
||||
* This class provides a simple container for collecting notification envelopes
|
||||
* during various system processes. It's primarily used by logging and debugging
|
||||
* listeners to track which notifications were dispatched or displayed.
|
||||
*
|
||||
* Design pattern: Collection - Provides a way to collect and access notification
|
||||
* envelopes in a consistent manner.
|
||||
*
|
||||
* @internal This class is not part of the public API and may change without notice
|
||||
* @internal
|
||||
*/
|
||||
final class NotificationEvents
|
||||
{
|
||||
/**
|
||||
* The collected notification envelopes.
|
||||
*
|
||||
* @var Envelope[]
|
||||
*/
|
||||
private array $envelopes = [];
|
||||
|
||||
/**
|
||||
* Adds multiple notification envelopes to the collection.
|
||||
*
|
||||
* @param Envelope ...$notifications The notification envelopes to add
|
||||
*/
|
||||
public function add(Envelope ...$notifications): void
|
||||
{
|
||||
foreach ($notifications as $notification) {
|
||||
@@ -39,20 +25,13 @@ final class NotificationEvents
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a single notification envelope to the collection.
|
||||
*
|
||||
* @param Envelope $notification The notification envelope to add
|
||||
*/
|
||||
public function addEnvelope(Envelope $notification): void
|
||||
{
|
||||
$this->envelopes[] = $notification;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the collected notification envelopes.
|
||||
*
|
||||
* @return Envelope[] The collected notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function getEnvelopes(): array
|
||||
{
|
||||
|
||||
@@ -7,26 +7,19 @@ namespace Flasher\Prime\EventDispatcher\Event;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* PersistEvent - Event dispatched when notifications are being persisted.
|
||||
*
|
||||
* This event is dispatched when notifications are about to be added to storage.
|
||||
* It allows listeners to modify the notifications before they are stored.
|
||||
* Event dispatched when notifications are being persisted.
|
||||
*/
|
||||
final class PersistEvent
|
||||
{
|
||||
/**
|
||||
* Creates a new PersistEvent instance.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to be persisted
|
||||
* @param Envelope[] $envelopes
|
||||
*/
|
||||
public function __construct(private array $envelopes)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the notification envelopes to be persisted.
|
||||
*
|
||||
* @return Envelope[] The notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function getEnvelopes(): array
|
||||
{
|
||||
@@ -34,11 +27,7 @@ final class PersistEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the notification envelopes to be persisted.
|
||||
*
|
||||
* This allows listeners to filter or modify the notifications before storage.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to persist
|
||||
* @param Envelope[] $envelopes
|
||||
*/
|
||||
public function setEnvelopes(array $envelopes): void
|
||||
{
|
||||
|
||||
@@ -7,26 +7,19 @@ namespace Flasher\Prime\EventDispatcher\Event;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* PostPersistEvent - Event dispatched after notifications are persisted.
|
||||
*
|
||||
* This event is dispatched after notification envelopes have been added to storage.
|
||||
* It allows listeners to perform actions after notifications have been successfully stored.
|
||||
* Event dispatched after notifications are persisted.
|
||||
*/
|
||||
final readonly class PostPersistEvent
|
||||
{
|
||||
/**
|
||||
* Creates a new PostPersistEvent instance.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes that were persisted
|
||||
* @param Envelope[] $envelopes
|
||||
*/
|
||||
public function __construct(private array $envelopes)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the notification envelopes that were persisted.
|
||||
*
|
||||
* @return Envelope[] The persisted notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function getEnvelopes(): array
|
||||
{
|
||||
|
||||
@@ -7,19 +7,13 @@ namespace Flasher\Prime\EventDispatcher\Event;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* PostRemoveEvent - Event dispatched after notifications are removed.
|
||||
*
|
||||
* This event is dispatched after notification envelopes have been removed from or
|
||||
* kept in storage. It provides information about which envelopes were removed
|
||||
* and which were kept.
|
||||
* Event dispatched after notifications are removed.
|
||||
*/
|
||||
final readonly class PostRemoveEvent
|
||||
{
|
||||
/**
|
||||
* Creates a new PostRemoveEvent instance.
|
||||
*
|
||||
* @param Envelope[] $envelopesToRemove The notification envelopes that were removed
|
||||
* @param Envelope[] $envelopesToKeep The notification envelopes that were kept
|
||||
* @param Envelope[] $envelopesToRemove
|
||||
* @param Envelope[] $envelopesToKeep
|
||||
*/
|
||||
public function __construct(
|
||||
private array $envelopesToRemove = [],
|
||||
@@ -28,9 +22,7 @@ final readonly class PostRemoveEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the notification envelopes that were removed.
|
||||
*
|
||||
* @return Envelope[] The removed notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function getEnvelopesToRemove(): array
|
||||
{
|
||||
@@ -38,9 +30,7 @@ final readonly class PostRemoveEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the notification envelopes that were kept.
|
||||
*
|
||||
* @return Envelope[] The kept notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function getEnvelopesToKeep(): array
|
||||
{
|
||||
|
||||
@@ -7,26 +7,19 @@ namespace Flasher\Prime\EventDispatcher\Event;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* PostUpdateEvent - Event dispatched after notification envelopes are updated.
|
||||
*
|
||||
* This event is dispatched after notification envelopes have been updated in storage.
|
||||
* It allows listeners to perform actions based on the updated notifications.
|
||||
* Event dispatched after notification envelopes are updated.
|
||||
*/
|
||||
final readonly class PostUpdateEvent
|
||||
{
|
||||
/**
|
||||
* Creates a new PostUpdateEvent instance.
|
||||
*
|
||||
* @param Envelope[] $envelopes The updated notification envelopes
|
||||
* @param Envelope[] $envelopes
|
||||
*/
|
||||
public function __construct(private array $envelopes)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the updated notification envelopes.
|
||||
*
|
||||
* @return Envelope[] The updated notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function getEnvelopes(): array
|
||||
{
|
||||
|
||||
@@ -7,19 +7,13 @@ namespace Flasher\Prime\EventDispatcher\Event;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* PresentationEvent - Event dispatched when notifications are being prepared for presentation.
|
||||
*
|
||||
* This event is dispatched during the rendering process, before notifications are
|
||||
* converted to their final format. It allows listeners to modify notifications
|
||||
* right before they are presented to the user (e.g., for translation or formatting).
|
||||
* Event dispatched when notifications are being prepared for presentation.
|
||||
*/
|
||||
final readonly class PresentationEvent
|
||||
{
|
||||
/**
|
||||
* Creates a new PresentationEvent instance.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes being presented
|
||||
* @param array<string, mixed> $context Additional context for presentation
|
||||
* @param Envelope[] $envelopes
|
||||
* @param array<string, mixed> $context
|
||||
*/
|
||||
public function __construct(
|
||||
private array $envelopes,
|
||||
@@ -28,9 +22,7 @@ final readonly class PresentationEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the notification envelopes being presented.
|
||||
*
|
||||
* @return Envelope[] The notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function getEnvelopes(): array
|
||||
{
|
||||
@@ -38,12 +30,7 @@ final readonly class PresentationEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the presentation context.
|
||||
*
|
||||
* This context provides additional information that may be useful
|
||||
* for listeners during the presentation process.
|
||||
*
|
||||
* @return array<string, mixed> The presentation context
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getContext(): array
|
||||
{
|
||||
|
||||
@@ -7,35 +7,24 @@ namespace Flasher\Prime\EventDispatcher\Event;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* RemoveEvent - Event dispatched when notifications are being removed.
|
||||
*
|
||||
* This event is dispatched when notifications are about to be removed from storage.
|
||||
* It allows listeners to modify which notifications should be removed and which
|
||||
* should be kept. This is used for implementing hopping behavior where notifications
|
||||
* can persist across multiple requests.
|
||||
* Event dispatched when notifications are being removed.
|
||||
*/
|
||||
final class RemoveEvent
|
||||
{
|
||||
/**
|
||||
* Notification envelopes that should be kept in storage.
|
||||
*
|
||||
* @var Envelope[]
|
||||
*/
|
||||
private array $envelopesToKeep = [];
|
||||
|
||||
/**
|
||||
* Creates a new RemoveEvent instance.
|
||||
*
|
||||
* @param Envelope[] $envelopesToRemove The notification envelopes initially marked for removal
|
||||
* @param Envelope[] $envelopesToRemove
|
||||
*/
|
||||
public function __construct(private array $envelopesToRemove)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the notification envelopes marked for removal.
|
||||
*
|
||||
* @return Envelope[] The notification envelopes to remove
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function getEnvelopesToRemove(): array
|
||||
{
|
||||
@@ -43,9 +32,7 @@ final class RemoveEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the notification envelopes to be removed.
|
||||
*
|
||||
* @param Envelope[] $envelopesToRemove The notification envelopes to remove
|
||||
* @param Envelope[] $envelopesToRemove
|
||||
*/
|
||||
public function setEnvelopesToRemove(array $envelopesToRemove): void
|
||||
{
|
||||
@@ -53,9 +40,7 @@ final class RemoveEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the notification envelopes that should be kept in storage.
|
||||
*
|
||||
* @return Envelope[] The notification envelopes to keep
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function getEnvelopesToKeep(): array
|
||||
{
|
||||
@@ -63,9 +48,7 @@ final class RemoveEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the notification envelopes that should be kept in storage.
|
||||
*
|
||||
* @param Envelope[] $envelopesToKeep The notification envelopes to keep
|
||||
* @param Envelope[] $envelopesToKeep
|
||||
*/
|
||||
public function setEnvelopesToKeep(array $envelopesToKeep): void
|
||||
{
|
||||
|
||||
@@ -5,54 +5,26 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* ResponseEvent - Event dispatched when a response is being prepared.
|
||||
*
|
||||
* This event is dispatched during the response rendering process. It allows
|
||||
* listeners to modify the rendered response before it's returned to the client.
|
||||
* This is particularly useful for adapting the response format or adding
|
||||
* additional data.
|
||||
* Event dispatched when a response is being prepared.
|
||||
*/
|
||||
final class ResponseEvent
|
||||
{
|
||||
/**
|
||||
* Creates a new ResponseEvent instance.
|
||||
*
|
||||
* @param mixed $response The response data that has been rendered
|
||||
* @param string $presenter The name of the presenter that rendered the response
|
||||
*/
|
||||
public function __construct(
|
||||
private mixed $response,
|
||||
private readonly string $presenter,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current response data.
|
||||
*
|
||||
* @return mixed The response data
|
||||
*/
|
||||
public function getResponse(): mixed
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the response data.
|
||||
*
|
||||
* This allows listeners to modify or replace the response content.
|
||||
*
|
||||
* @param mixed $response The new response data
|
||||
*/
|
||||
public function setResponse(mixed $response): void
|
||||
{
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the presenter that rendered the response.
|
||||
*
|
||||
* @return string The presenter name (e.g., 'html', 'json')
|
||||
*/
|
||||
public function getPresenter(): string
|
||||
{
|
||||
return $this->presenter;
|
||||
|
||||
@@ -5,24 +5,9 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* StoppableEventInterface - Contract for events that can stop propagation.
|
||||
*
|
||||
* This interface marks an event as being able to stop propagation through the
|
||||
* event dispatcher. Once an event's propagation is stopped, no further listeners
|
||||
* will be called for that event.
|
||||
*
|
||||
* Design pattern: Circuit Breaker - Provides a mechanism to halt the normal
|
||||
* flow of execution when certain conditions are met.
|
||||
* Contract for events that can stop propagation.
|
||||
*/
|
||||
interface StoppableEventInterface
|
||||
{
|
||||
/**
|
||||
* Checks if event propagation should be stopped.
|
||||
*
|
||||
* This method returns true if event propagation should be stopped,
|
||||
* false otherwise.
|
||||
*
|
||||
* @return bool True if event propagation should stop, false otherwise
|
||||
*/
|
||||
public function isPropagationStopped(): bool;
|
||||
}
|
||||
|
||||
@@ -7,26 +7,19 @@ namespace Flasher\Prime\EventDispatcher\Event;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* UpdateEvent - Event dispatched when notifications are being updated.
|
||||
*
|
||||
* This event is dispatched when notifications are about to be updated in storage.
|
||||
* It allows listeners to modify the notifications before they are committed to storage.
|
||||
* Event dispatched when notifications are being updated.
|
||||
*/
|
||||
final class UpdateEvent
|
||||
{
|
||||
/**
|
||||
* Creates a new UpdateEvent instance.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to be updated
|
||||
* @param Envelope[] $envelopes
|
||||
*/
|
||||
public function __construct(private array $envelopes)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the notification envelopes to be updated.
|
||||
*
|
||||
* @return Envelope[] The notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function getEnvelopes(): array
|
||||
{
|
||||
@@ -34,11 +27,7 @@ final class UpdateEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the notification envelopes to be updated.
|
||||
*
|
||||
* This allows listeners to modify which notifications will be updated.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to update
|
||||
* @param Envelope[] $envelopes
|
||||
*/
|
||||
public function setEnvelopes(array $envelopes): void
|
||||
{
|
||||
|
||||
@@ -11,35 +11,15 @@ use Flasher\Prime\EventDispatcher\EventListener\EnvelopeRemovalListener;
|
||||
use Flasher\Prime\EventDispatcher\EventListener\EventListenerInterface;
|
||||
|
||||
/**
|
||||
* EventDispatcher - Default implementation of the event dispatcher interface.
|
||||
*
|
||||
* This class provides the core event dispatching functionality for PHPFlasher.
|
||||
* It allows registering listeners for specific events and dispatches events
|
||||
* to all relevant listeners. It also comes pre-configured with the essential
|
||||
* system listeners that implement core notification behaviors.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Observer: Implements the observer pattern for event notification
|
||||
* - Chain of Responsibility: Passes events through a chain of listeners
|
||||
* Default implementation of the event dispatcher interface.
|
||||
*/
|
||||
final class EventDispatcher implements EventDispatcherInterface
|
||||
{
|
||||
/**
|
||||
* Mapping of event names to listeners.
|
||||
*
|
||||
* @var array<string, EventListenerInterface[]>
|
||||
*/
|
||||
private array $listeners = [];
|
||||
|
||||
/**
|
||||
* Creates a new EventDispatcher with default system listeners.
|
||||
*
|
||||
* This constructor automatically registers the core system listeners
|
||||
* that are essential for proper notification handling:
|
||||
* - EnvelopeRemovalListener: Manages notification lifetime across requests
|
||||
* - AttachDefaultStampsListener: Adds required stamps to notifications
|
||||
* - AddToStorageListener: Filters notifications before storage
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->addListener(new EnvelopeRemovalListener());
|
||||
@@ -48,12 +28,6 @@ final class EventDispatcher implements EventDispatcherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* This implementation supports event propagation stopping for events
|
||||
* that implement StoppableEventInterface. It calls each listener in
|
||||
* registration order until all listeners are called or propagation is stopped.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function dispatch(object $event): object
|
||||
|
||||
@@ -6,55 +6,21 @@ namespace Flasher\Prime\EventDispatcher;
|
||||
|
||||
use Flasher\Prime\EventDispatcher\EventListener\EventListenerInterface;
|
||||
|
||||
/**
|
||||
* EventDispatcherInterface - Contract for event dispatching services.
|
||||
*
|
||||
* This interface defines the essential operations for dispatching events to
|
||||
* registered listeners. It provides a simple but powerful event system where
|
||||
* listeners can react to various events in the notification lifecycle.
|
||||
*
|
||||
* Design pattern: Observer - Defines a one-to-many dependency between objects
|
||||
* where multiple observers are notified of state changes in the subject.
|
||||
*/
|
||||
interface EventDispatcherInterface
|
||||
{
|
||||
/**
|
||||
* Dispatches an event to all registered listeners.
|
||||
*
|
||||
* This method notifies all listeners subscribed to the event's class.
|
||||
* It passes the event object to each listener for processing and returns
|
||||
* the potentially modified event object.
|
||||
*
|
||||
* @template T of object
|
||||
*
|
||||
* @param T $event The event to dispatch
|
||||
*
|
||||
* @phpstan-param T $event
|
||||
*
|
||||
* @return T The event after it has been processed by all listeners
|
||||
*
|
||||
* @phpstan-return T
|
||||
*/
|
||||
public function dispatch(object $event): object;
|
||||
|
||||
/**
|
||||
* Registers a listener with the dispatcher.
|
||||
*
|
||||
* This method registers a listener that will be notified when events
|
||||
* it's interested in are dispatched.
|
||||
*
|
||||
* @param EventListenerInterface $listener The listener to register
|
||||
*/
|
||||
public function addListener(EventListenerInterface $listener): void;
|
||||
|
||||
/**
|
||||
* Gets all listeners for a specific event.
|
||||
*
|
||||
* This method retrieves all listeners that are registered for the given event name.
|
||||
*
|
||||
* @param string $eventName The event class name
|
||||
*
|
||||
* @return EventListenerInterface[] Array of listeners for the event
|
||||
* @return EventListenerInterface[]
|
||||
*/
|
||||
public function getListeners(string $eventName): array;
|
||||
}
|
||||
|
||||
@@ -10,25 +10,10 @@ use Flasher\Prime\Stamp\UnlessStamp;
|
||||
use Flasher\Prime\Stamp\WhenStamp;
|
||||
|
||||
/**
|
||||
* AddToStorageListener - Filters notifications before storage based on conditions.
|
||||
*
|
||||
* This listener is responsible for checking whether notifications should be stored
|
||||
* based on their WhenStamp and UnlessStamp conditions. It allows for conditional
|
||||
* notifications that only appear when certain criteria are met.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Filter Chain: Acts as a filter in the notification processing pipeline
|
||||
* - Strategy: Applies different filtering strategies based on stamp conditions
|
||||
* Filters notifications before storage based on conditions.
|
||||
*/
|
||||
final readonly class AddToStorageListener implements EventListenerInterface
|
||||
{
|
||||
/**
|
||||
* Handles persist events by filtering notifications based on conditions.
|
||||
*
|
||||
* This method filters out notifications that don't meet their when/unless conditions.
|
||||
*
|
||||
* @param PersistEvent $event The persist event
|
||||
*/
|
||||
public function __invoke(PersistEvent $event): void
|
||||
{
|
||||
$envelopes = array_filter($event->getEnvelopes(), $this->isEligibleForStorage(...));
|
||||
@@ -41,33 +26,11 @@ final readonly class AddToStorageListener implements EventListenerInterface
|
||||
return PersistEvent::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an envelope is eligible for storage based on its conditions.
|
||||
*
|
||||
* An envelope is eligible if:
|
||||
* - It passes its when condition (if any)
|
||||
* - It passes its unless condition (if any)
|
||||
*
|
||||
* @param Envelope $envelope The envelope to check
|
||||
*
|
||||
* @return bool True if the envelope should be stored, false otherwise
|
||||
*/
|
||||
private function isEligibleForStorage(Envelope $envelope): bool
|
||||
{
|
||||
return $this->whenCondition($envelope) && $this->unlessCondition($envelope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the envelope passes its when condition.
|
||||
*
|
||||
* The envelope passes if:
|
||||
* - It has no WhenStamp, or
|
||||
* - Its WhenStamp condition evaluates to true
|
||||
*
|
||||
* @param Envelope $envelope The envelope to check
|
||||
*
|
||||
* @return bool True if the envelope passes its when condition
|
||||
*/
|
||||
private function whenCondition(Envelope $envelope): bool
|
||||
{
|
||||
$whenStamp = $envelope->get(WhenStamp::class);
|
||||
@@ -75,17 +38,6 @@ final readonly class AddToStorageListener implements EventListenerInterface
|
||||
return !($whenStamp instanceof WhenStamp && !$whenStamp->getCondition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the envelope passes its unless condition.
|
||||
*
|
||||
* The envelope passes if:
|
||||
* - It has no UnlessStamp, or
|
||||
* - Its UnlessStamp condition evaluates to false
|
||||
*
|
||||
* @param Envelope $envelope The envelope to check
|
||||
*
|
||||
* @return bool True if the envelope passes its unless condition
|
||||
*/
|
||||
private function unlessCondition(Envelope $envelope): bool
|
||||
{
|
||||
$unlessStamp = $envelope->get(UnlessStamp::class);
|
||||
|
||||
@@ -10,15 +10,7 @@ use Flasher\Prime\Notification\Envelope;
|
||||
use Flasher\Prime\Stamp\PresetStamp;
|
||||
|
||||
/**
|
||||
* ApplyPresetListener - Applies preset configurations to notifications.
|
||||
*
|
||||
* This listener is responsible for applying predefined notification templates (presets)
|
||||
* to envelopes that contain a PresetStamp. Presets allow defining common notification
|
||||
* patterns that can be reused across an application.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Template Method: Applies predefined templates to notifications
|
||||
* - Strategy: Uses different preset configurations based on the preset name
|
||||
* Applies preset configurations to notifications.
|
||||
*
|
||||
* @phpstan-type PresetType array{
|
||||
* type: string,
|
||||
@@ -30,20 +22,14 @@ use Flasher\Prime\Stamp\PresetStamp;
|
||||
final readonly class ApplyPresetListener implements EventListenerInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new ApplyPresetListener with the specified presets.
|
||||
*
|
||||
* @param array<string, PresetType> $presets Map of preset names to their configurations
|
||||
* @param array<string, PresetType> $presets
|
||||
*/
|
||||
public function __construct(private array $presets)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles persist events by applying presets to envelopes with PresetStamps.
|
||||
*
|
||||
* @param PersistEvent $event The persist event
|
||||
*
|
||||
* @throws PresetNotFoundException If a requested preset doesn't exist
|
||||
* @throws PresetNotFoundException
|
||||
*/
|
||||
public function __invoke(PersistEvent $event): void
|
||||
{
|
||||
@@ -58,14 +44,7 @@ final readonly class ApplyPresetListener implements EventListenerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies preset settings to an envelope if applicable.
|
||||
*
|
||||
* This method checks if the envelope has a PresetStamp and if so, applies
|
||||
* the corresponding preset configuration.
|
||||
*
|
||||
* @param Envelope $envelope The envelope to process
|
||||
*
|
||||
* @throws PresetNotFoundException If the requested preset doesn't exist
|
||||
* @throws PresetNotFoundException
|
||||
*/
|
||||
private function applyPreset(Envelope $envelope): void
|
||||
{
|
||||
@@ -84,11 +63,7 @@ final readonly class ApplyPresetListener implements EventListenerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves preset data with default values for missing fields.
|
||||
*
|
||||
* @param string $alias The preset key
|
||||
*
|
||||
* @return PresetType The preset data with defaults for missing fields
|
||||
* @return PresetType
|
||||
*/
|
||||
private function getPreset(string $alias): array
|
||||
{
|
||||
@@ -102,14 +77,7 @@ final readonly class ApplyPresetListener implements EventListenerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the envelope with the provided preset data.
|
||||
*
|
||||
* This method applies the preset data to the envelope, but only for fields
|
||||
* that aren't already set. Envelope-specific settings take precedence over
|
||||
* preset defaults.
|
||||
*
|
||||
* @param Envelope $envelope The envelope to update
|
||||
* @param PresetType $preset The preset data to apply
|
||||
* @param PresetType $preset
|
||||
*/
|
||||
private function updateEnvelope(Envelope $envelope, array $preset): void
|
||||
{
|
||||
|
||||
@@ -14,23 +14,10 @@ use Flasher\Prime\Stamp\IdStamp;
|
||||
use Flasher\Prime\Stamp\PriorityStamp;
|
||||
|
||||
/**
|
||||
* AttachDefaultStampsListener - Ensures notifications have required stamps.
|
||||
*
|
||||
* This listener is responsible for ensuring that all notification envelopes
|
||||
* have the required system stamps. These stamps provide essential functionality
|
||||
* like identification, timing, and lifecycle management.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Decorator: Adds default stamps to notification envelopes
|
||||
* - Template Method: Defines a standard set of stamps for all notifications
|
||||
* Ensures notifications have required stamps.
|
||||
*/
|
||||
final readonly class AttachDefaultStampsListener implements EventListenerInterface
|
||||
{
|
||||
/**
|
||||
* Handles persist and update events by attaching default stamps.
|
||||
*
|
||||
* @param PersistEvent|UpdateEvent $event The event to handle
|
||||
*/
|
||||
public function __invoke(PersistEvent|UpdateEvent $event): void
|
||||
{
|
||||
foreach ($event->getEnvelopes() as $envelope) {
|
||||
@@ -39,11 +26,6 @@ final readonly class AttachDefaultStampsListener implements EventListenerInterfa
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* This listener subscribes to both persist and update events to ensure
|
||||
* that stamps are attached to notifications in both scenarios.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getSubscribedEvents(): array
|
||||
@@ -54,18 +36,6 @@ final readonly class AttachDefaultStampsListener implements EventListenerInterfa
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches default stamps to an envelope if they don't already exist.
|
||||
*
|
||||
* The default stamps are:
|
||||
* - CreatedAtStamp: Records when the notification was created
|
||||
* - IdStamp: Provides a unique identifier
|
||||
* - DelayStamp: Controls display timing (default: immediate)
|
||||
* - HopsStamp: Controls persistence across requests (default: 1 request)
|
||||
* - PriorityStamp: Controls display order (default: normal priority)
|
||||
*
|
||||
* @param Envelope $envelope The envelope to attach stamps to
|
||||
*/
|
||||
private function attachStamps(Envelope $envelope): void
|
||||
{
|
||||
$envelope->withStamp(new CreatedAtStamp(), false);
|
||||
|
||||
@@ -9,27 +9,10 @@ use Flasher\Prime\Notification\Envelope;
|
||||
use Flasher\Prime\Stamp\HopsStamp;
|
||||
|
||||
/**
|
||||
* EnvelopeRemovalListener - Manages notification lifecycle across requests.
|
||||
*
|
||||
* This listener is responsible for implementing the "hops" feature, which allows
|
||||
* notifications to persist across multiple page loads or redirects. When a notification
|
||||
* is removed, this listener checks if it has remaining hops and if so, decrements
|
||||
* the hop count and keeps the notification in storage.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Chain of Responsibility: Processes each envelope and decides its fate
|
||||
* - State: Manages the state transition of notifications across requests
|
||||
* Manages notification lifecycle across requests.
|
||||
*/
|
||||
final readonly class EnvelopeRemovalListener implements EventListenerInterface
|
||||
{
|
||||
/**
|
||||
* Handles remove events by categorizing envelopes into keep and remove groups.
|
||||
*
|
||||
* This method processes the envelopes marked for removal, checking if any should
|
||||
* be kept based on their hop count.
|
||||
*
|
||||
* @param RemoveEvent $event The remove event
|
||||
*/
|
||||
public function __invoke(RemoveEvent $event): void
|
||||
{
|
||||
[$envelopesToKeep, $envelopesToRemove] = $this->categorizeEnvelopes($event->getEnvelopesToRemove());
|
||||
@@ -44,15 +27,9 @@ final readonly class EnvelopeRemovalListener implements EventListenerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Categorizes envelopes into those to keep and those to remove.
|
||||
* @param Envelope[] $envelopes
|
||||
*
|
||||
* For each envelope:
|
||||
* - If it has a HopsStamp with a count > 1, decrement the count and keep it
|
||||
* - Otherwise, mark it for removal
|
||||
*
|
||||
* @param Envelope[] $envelopes The envelopes to categorize
|
||||
*
|
||||
* @return array<Envelope[]> Array with [0] => envelopes to keep, [1] => envelopes to remove
|
||||
* @return array<Envelope[]>
|
||||
*/
|
||||
private function categorizeEnvelopes(array $envelopes): array
|
||||
{
|
||||
|
||||
@@ -5,44 +5,12 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\EventDispatcher\EventListener;
|
||||
|
||||
/**
|
||||
* EventListenerInterface - Contract for event listeners.
|
||||
*
|
||||
* This interface defines the essential operations for event listeners in the
|
||||
* PHPFlasher event system. Implementers should define an __invoke method that
|
||||
* processes events they're interested in and declare which events they listen to.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Observer: Defines a contract for objects that observe and respond to events
|
||||
* - Visitor: Allows operations to be performed on event objects
|
||||
*
|
||||
* Example implementation:
|
||||
* ```php
|
||||
* class MyListener implements EventListenerInterface
|
||||
* {
|
||||
* public function __invoke(MyEvent $event): void
|
||||
* {
|
||||
* // Handle the event
|
||||
* }
|
||||
*
|
||||
* public function getSubscribedEvents(): string
|
||||
* {
|
||||
* return MyEvent::class;
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @method void __invoke(object $event) Method that handles the event
|
||||
* Contract for event listeners.
|
||||
*/
|
||||
interface EventListenerInterface
|
||||
{
|
||||
/**
|
||||
* Returns a list of event names this listener wants to listen to.
|
||||
*
|
||||
* The returned value can be:
|
||||
* - A string: Single event class name
|
||||
* - An array: Multiple event class names
|
||||
*
|
||||
* @return string|string[] The event class name(s) this listener subscribes to
|
||||
* @return string|string[]
|
||||
*/
|
||||
public function getSubscribedEvents(): string|array;
|
||||
}
|
||||
|
||||
@@ -9,56 +9,28 @@ use Flasher\Prime\EventDispatcher\Event\PersistEvent;
|
||||
use Flasher\Prime\EventDispatcher\Event\PresentationEvent;
|
||||
|
||||
/**
|
||||
* NotificationLoggerListener - Logs all notifications that are dispatched and displayed.
|
||||
* Logs all notifications that are dispatched and displayed.
|
||||
*
|
||||
* This listener keeps track of all notification envelopes that are dispatched to storage
|
||||
* and those that are actually displayed to users. It's useful for debugging and testing
|
||||
* to see which notifications were created vs which were actually shown.
|
||||
*
|
||||
* @internal This class is not part of the public API and may change without notice
|
||||
* @internal
|
||||
*/
|
||||
final class NotificationLoggerListener implements EventListenerInterface
|
||||
{
|
||||
/**
|
||||
* Collection of envelopes that were dispatched to storage.
|
||||
*/
|
||||
private NotificationEvents $dispatchedEnvelopes;
|
||||
|
||||
/**
|
||||
* Collection of envelopes that were displayed to users.
|
||||
*/
|
||||
private NotificationEvents $displayedEnvelopes;
|
||||
|
||||
/**
|
||||
* Creates a new NotificationLoggerListener instance.
|
||||
*
|
||||
* Initializes empty collections for tracking dispatched and displayed notifications.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->dispatchedEnvelopes = new NotificationEvents();
|
||||
$this->displayedEnvelopes = new NotificationEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the listener, clearing all tracked notifications.
|
||||
*
|
||||
* This is useful for testing or when you want to start with a clean slate.
|
||||
*/
|
||||
public function reset(): void
|
||||
{
|
||||
$this->dispatchedEnvelopes = new NotificationEvents();
|
||||
$this->displayedEnvelopes = new NotificationEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles incoming events by delegating to specialized methods.
|
||||
*
|
||||
* This method implements the __invoke method required by the EventListenerInterface.
|
||||
* It routes events to the appropriate handler method based on their type.
|
||||
*
|
||||
* @param object $event The event to handle
|
||||
*/
|
||||
public function __invoke(object $event): void
|
||||
{
|
||||
if ($event instanceof PersistEvent) {
|
||||
@@ -70,41 +42,21 @@ final class NotificationLoggerListener implements EventListenerInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles persist events by logging the notifications being stored.
|
||||
*
|
||||
* @param PersistEvent $event The persist event
|
||||
*/
|
||||
public function onPersist(PersistEvent $event): void
|
||||
{
|
||||
$this->dispatchedEnvelopes->add(...$event->getEnvelopes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles presentation events by logging the notifications being displayed.
|
||||
*
|
||||
* @param PresentationEvent $event The presentation event
|
||||
*/
|
||||
public function onPresentation(PresentationEvent $event): void
|
||||
{
|
||||
$this->displayedEnvelopes->add(...$event->getEnvelopes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the collection of envelopes that were dispatched to storage.
|
||||
*
|
||||
* @return NotificationEvents Collection of dispatched notification envelopes
|
||||
*/
|
||||
public function getDispatchedEnvelopes(): NotificationEvents
|
||||
{
|
||||
return $this->dispatchedEnvelopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the collection of envelopes that were displayed to users.
|
||||
*
|
||||
* @return NotificationEvents Collection of displayed notification envelopes
|
||||
*/
|
||||
public function getDisplayedEnvelopes(): NotificationEvents
|
||||
{
|
||||
return $this->displayedEnvelopes;
|
||||
|
||||
@@ -13,41 +13,17 @@ use Flasher\Prime\Translation\Language;
|
||||
use Flasher\Prime\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* TranslationListener - Applies translations to notifications during presentation.
|
||||
*
|
||||
* This listener is responsible for translating notification titles and messages
|
||||
* before they are displayed to users. It also sets RTL mode for right-to-left
|
||||
* languages and translates preset parameters.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Decorator: Adds translation functionality to notifications
|
||||
* - Strategy: Uses pluggable translation strategies via TranslatorInterface
|
||||
* Applies translations to notifications during presentation.
|
||||
*/
|
||||
final readonly class TranslationListener implements EventListenerInterface
|
||||
{
|
||||
/**
|
||||
* The translator to use for translating notification content.
|
||||
*/
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
/**
|
||||
* Creates a new TranslationListener instance.
|
||||
*
|
||||
* If no translator is provided, falls back to the EchoTranslator which simply
|
||||
* returns the input strings unchanged.
|
||||
*
|
||||
* @param TranslatorInterface|null $translator The translator to use
|
||||
*/
|
||||
public function __construct(?TranslatorInterface $translator = null)
|
||||
{
|
||||
$this->translator = $translator ?: new EchoTranslator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles presentation events by translating all notifications.
|
||||
*
|
||||
* @param PresentationEvent $event The presentation event
|
||||
*/
|
||||
public function __invoke(PresentationEvent $event): void
|
||||
{
|
||||
foreach ($event->getEnvelopes() as $envelope) {
|
||||
@@ -60,17 +36,6 @@ final readonly class TranslationListener implements EventListenerInterface
|
||||
return PresentationEvent::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a notification envelope.
|
||||
*
|
||||
* This method:
|
||||
* 1. Determines the appropriate locale
|
||||
* 2. Gathers translation parameters
|
||||
* 3. Applies translations to title and message
|
||||
* 4. Sets RTL mode if needed
|
||||
*
|
||||
* @param Envelope $envelope The notification envelope to translate
|
||||
*/
|
||||
private function translateEnvelope(Envelope $envelope): void
|
||||
{
|
||||
$translationStamp = $envelope->get(TranslationStamp::class);
|
||||
@@ -88,14 +53,9 @@ final readonly class TranslationListener implements EventListenerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts and translates parameters from preset stamps.
|
||||
* @return array<string, mixed>
|
||||
*
|
||||
* @param Envelope $envelope The notification envelope
|
||||
* @param string $locale The locale to use
|
||||
*
|
||||
* @return array<string, mixed> The translated parameters
|
||||
*
|
||||
* @throws \InvalidArgumentException If a parameter value is not a string
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
private function getParameters(Envelope $envelope, string $locale): array
|
||||
{
|
||||
@@ -118,13 +78,7 @@ final readonly class TranslationListener implements EventListenerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies translations to the notification title and message.
|
||||
*
|
||||
* If the title is empty, the notification type is used as a fallback.
|
||||
*
|
||||
* @param Envelope $envelope The notification envelope
|
||||
* @param string $locale The locale to use
|
||||
* @param array<string, mixed> $parameters The translation parameters
|
||||
* @param array<string, mixed> $parameters
|
||||
*/
|
||||
private function applyTranslations(Envelope $envelope, string $locale, array $parameters): void
|
||||
{
|
||||
|
||||
@@ -10,25 +10,10 @@ use Flasher\Prime\Notification\NotificationBuilderInterface;
|
||||
/**
|
||||
* Default implementation of FlasherFactoryInterface.
|
||||
*
|
||||
* This factory creates FlasherBuilder instances for constructing notifications
|
||||
* with the default PHPFlasher implementation. It extends the base NotificationFactory
|
||||
* to inherit common factory functionality.
|
||||
*
|
||||
* Design pattern: Factory Method - Defines an interface for creating objects,
|
||||
* but lets subclasses decide which class to instantiate.
|
||||
*
|
||||
* @mixin \Flasher\Prime\Notification\FlasherBuilder
|
||||
*/
|
||||
final class FlasherFactory extends NotificationFactory implements FlasherFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new FlasherBuilder instance.
|
||||
*
|
||||
* This implementation returns a FlasherBuilder configured with the current plugin name.
|
||||
* The builder provides a fluent API for constructing notifications with type-safe methods.
|
||||
*
|
||||
* @return NotificationBuilderInterface The created notification builder
|
||||
*/
|
||||
public function createNotificationBuilder(): NotificationBuilderInterface
|
||||
{
|
||||
return new FlasherBuilder($this->plugin ?? 'flasher', $this->storageManager);
|
||||
|
||||
@@ -7,11 +7,6 @@ namespace Flasher\Prime\Factory;
|
||||
/**
|
||||
* Factory interface for creating Flasher-specific notification builders.
|
||||
*
|
||||
* This interface extends the base NotificationFactoryInterface to provide
|
||||
* type safety when working specifically with the default Flasher implementation.
|
||||
* It ensures that methods like createNotificationBuilder() return Flasher-specific
|
||||
* builder instances.
|
||||
*
|
||||
* @mixin \Flasher\Prime\Notification\FlasherBuilder
|
||||
*/
|
||||
interface FlasherFactoryInterface extends NotificationFactoryInterface
|
||||
|
||||
@@ -10,26 +10,12 @@ use Flasher\Prime\Support\Traits\ForwardsCalls;
|
||||
/**
|
||||
* Base abstract class for notification factories.
|
||||
*
|
||||
* This abstract class provides common functionality for all notification factories,
|
||||
* such as storage management and method forwarding to notification builders.
|
||||
* Specific factory implementations should extend this class and implement
|
||||
* the createNotificationBuilder() method.
|
||||
*
|
||||
* Design pattern: Template Method - Defines the skeleton of an algorithm,
|
||||
* deferring some steps to subclasses.
|
||||
*
|
||||
* @mixin \Flasher\Prime\Notification\NotificationBuilderInterface
|
||||
*/
|
||||
abstract class NotificationFactory implements NotificationFactoryInterface
|
||||
{
|
||||
use ForwardsCalls;
|
||||
|
||||
/**
|
||||
* Creates a new NotificationFactory instance.
|
||||
*
|
||||
* @param StorageManagerInterface $storageManager The storage manager for persisting notifications
|
||||
* @param string|null $plugin The plugin/adapter name (e.g., 'toastr', 'sweetalert')
|
||||
*/
|
||||
public function __construct(
|
||||
protected StorageManagerInterface $storageManager,
|
||||
protected ?string $plugin = null,
|
||||
@@ -37,24 +23,7 @@ abstract class NotificationFactory implements NotificationFactoryInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically forwards method calls to a notification builder instance.
|
||||
*
|
||||
* This magic method allows calling notification builder methods directly on the factory,
|
||||
* creating a more fluent API for client code.
|
||||
*
|
||||
* Example:
|
||||
* ```php
|
||||
* // Instead of:
|
||||
* $factory->createNotificationBuilder()->success('Message');
|
||||
*
|
||||
* // You can do:
|
||||
* $factory->success('Message');
|
||||
* ```
|
||||
*
|
||||
* @param string $method The method name to call
|
||||
* @param mixed[] $parameters The parameters to pass to the method
|
||||
*
|
||||
* @return mixed The result of the method call
|
||||
* @param mixed[] $parameters
|
||||
*/
|
||||
public function __call(string $method, array $parameters): mixed
|
||||
{
|
||||
|
||||
@@ -7,26 +7,11 @@ namespace Flasher\Prime\Factory;
|
||||
use Flasher\Prime\Notification\NotificationBuilderInterface;
|
||||
|
||||
/**
|
||||
* NotificationFactoryInterface - Core factory abstraction.
|
||||
*
|
||||
* Defines the contract for all notification factories that can create
|
||||
* notification builders. This interface enables the system to work
|
||||
* with different notification implementations through a common API.
|
||||
*
|
||||
* Design pattern: Abstract Factory - Provides an interface for creating
|
||||
* families of related objects without specifying concrete classes.
|
||||
* Core factory abstraction.
|
||||
*
|
||||
* @mixin \Flasher\Prime\Notification\NotificationBuilderInterface
|
||||
*/
|
||||
interface NotificationFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Creates a notification builder instance.
|
||||
*
|
||||
* Each implementation of this method should return a builder tailored
|
||||
* to the specific notification library or system that the factory supports.
|
||||
*
|
||||
* @return NotificationBuilderInterface A builder for constructing notifications
|
||||
*/
|
||||
public function createNotificationBuilder(): NotificationBuilderInterface;
|
||||
}
|
||||
|
||||
@@ -7,35 +7,17 @@ namespace Flasher\Prime\Factory;
|
||||
use Flasher\Prime\Exception\FactoryNotFoundException;
|
||||
|
||||
/**
|
||||
* NotificationFactoryLocator - Registry of available factories.
|
||||
*
|
||||
* Maintains a registry of all available notification factories, allowing
|
||||
* the system to look up the appropriate factory by name at runtime.
|
||||
* Factories can be registered as instances or lazy-loaded through callbacks.
|
||||
*
|
||||
* Design pattern: Service Locator - Centralizes factory discovery and
|
||||
* instantiation, enabling loose coupling between components.
|
||||
* Registry of available factories.
|
||||
*/
|
||||
final class NotificationFactoryLocator implements NotificationFactoryLocatorInterface
|
||||
{
|
||||
/**
|
||||
* Map of factory aliases to instances or factory callbacks.
|
||||
*
|
||||
* @var array<string, callable|NotificationFactoryInterface>
|
||||
*/
|
||||
private array $factories = [];
|
||||
|
||||
/**
|
||||
* Gets a notification factory by its identifier.
|
||||
*
|
||||
* If the factory was registered as a callback, it will be invoked to create
|
||||
* the actual factory instance on first access.
|
||||
*
|
||||
* @param string $id The identifier for the factory to retrieve
|
||||
*
|
||||
* @return NotificationFactoryInterface The requested notification factory
|
||||
*
|
||||
* @throws FactoryNotFoundException If no factory is registered with the given identifier
|
||||
* @throws FactoryNotFoundException
|
||||
*/
|
||||
public function get(string $id): NotificationFactoryInterface
|
||||
{
|
||||
@@ -48,38 +30,11 @@ final class NotificationFactoryLocator implements NotificationFactoryLocatorInte
|
||||
return \is_callable($factory) ? $factory() : $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a notification factory exists for the given identifier.
|
||||
*
|
||||
* @param string $id The identifier to check
|
||||
*
|
||||
* @return bool True if a factory exists for the given identifier, false otherwise
|
||||
*/
|
||||
public function has(string $id): bool
|
||||
{
|
||||
return \array_key_exists($id, $this->factories);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a custom notification factory.
|
||||
*
|
||||
* This method allows registering either a factory instance directly or a callback
|
||||
* that creates the factory when needed (lazy-loading).
|
||||
*
|
||||
* Example:
|
||||
* ```php
|
||||
* // Register a factory instance
|
||||
* $locator->addFactory('custom', new CustomFactory($storageManager));
|
||||
*
|
||||
* // Register a factory with lazy-loading
|
||||
* $locator->addFactory('custom', function() use ($storageManager) {
|
||||
* return new ExpensiveFactory($storageManager);
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param string $alias The identifier for the factory
|
||||
* @param callable|NotificationFactoryInterface $factory The factory instance or a callback that returns one
|
||||
*/
|
||||
public function addFactory(string $alias, callable|NotificationFactoryInterface $factory): void
|
||||
{
|
||||
$this->factories[$alias] = $factory;
|
||||
|
||||
@@ -6,33 +6,10 @@ namespace Flasher\Prime\Factory;
|
||||
|
||||
/**
|
||||
* Interface for the notification factory locator service.
|
||||
*
|
||||
* This interface defines the contract for a service that locates and
|
||||
* provides notification factories by their identifiers. It allows the
|
||||
* system to resolve factories at runtime without directly coupling to
|
||||
* specific implementations.
|
||||
*
|
||||
* Design pattern: Service Locator - Provides a centralized registry
|
||||
* for finding and accessing services.
|
||||
*/
|
||||
interface NotificationFactoryLocatorInterface
|
||||
{
|
||||
/**
|
||||
* Checks if a notification factory exists for the given identifier.
|
||||
*
|
||||
* @param string $id The identifier to check
|
||||
*
|
||||
* @return bool True if a factory exists for the given identifier, false otherwise
|
||||
*/
|
||||
public function has(string $id): bool;
|
||||
|
||||
/**
|
||||
* Gets a notification factory by its identifier.
|
||||
*
|
||||
* @param string $id The identifier for the factory to retrieve
|
||||
*
|
||||
* @return NotificationFactoryInterface The requested notification factory
|
||||
*
|
||||
* @phpstan-return ($id is 'flasher' ? \Flasher\Prime\Factory\FlasherFactoryInterface :
|
||||
* ($id is 'noty' ? \Flasher\Noty\Prime\NotyInterface :
|
||||
* ($id is 'notyf' ? \Flasher\Notyf\Prime\NotyfInterface :
|
||||
@@ -40,7 +17,9 @@ interface NotificationFactoryLocatorInterface
|
||||
* ($id is 'toastr' ? \Flasher\Toastr\Prime\ToastrInterface :
|
||||
* \Flasher\Prime\Factory\NotificationFactoryInterface)))))
|
||||
*
|
||||
* @throws \Flasher\Prime\Exception\FactoryNotFoundException If no factory is registered with the given identifier
|
||||
* @throws \Flasher\Prime\Exception\FactoryNotFoundException
|
||||
*/
|
||||
public function get(string $id): NotificationFactoryInterface;
|
||||
|
||||
public function has(string $id): bool;
|
||||
}
|
||||
|
||||
+4
-54
@@ -12,33 +12,14 @@ use Flasher\Prime\Storage\StorageManagerInterface;
|
||||
use Flasher\Prime\Support\Traits\ForwardsCalls;
|
||||
|
||||
/**
|
||||
* Core implementation of the FlasherInterface.
|
||||
*
|
||||
* This class serves as the central hub for the notification system, managing
|
||||
* factories, storage, and response handling. It implements the Façade pattern
|
||||
* to provide a clean, simple API for client code while coordinating complex
|
||||
* subsystems behind the scenes.
|
||||
*
|
||||
* Design pattern: Façade - Provides a simplified interface to a complex system,
|
||||
* delegating to specialized components for specific functionality.
|
||||
* @mixin \Flasher\Prime\Notification\NotificationBuilder
|
||||
*/
|
||||
final readonly class Flasher implements FlasherInterface
|
||||
{
|
||||
use ForwardsCalls;
|
||||
|
||||
/**
|
||||
* Current version of PHPFlasher.
|
||||
*/
|
||||
public const VERSION = '2.4.0';
|
||||
|
||||
/**
|
||||
* Creates a new Flasher instance.
|
||||
*
|
||||
* @param string $default The default factory to use when none is specified
|
||||
* @param NotificationFactoryLocatorInterface $factoryLocator Service locator for notification factories
|
||||
* @param ResponseManagerInterface $responseManager Manager for rendering notifications
|
||||
* @param StorageManagerInterface $storageManager Manager for storing notifications
|
||||
*/
|
||||
public function __construct(
|
||||
private string $default,
|
||||
private NotificationFactoryLocatorInterface $factoryLocator,
|
||||
@@ -47,13 +28,6 @@ final readonly class Flasher implements FlasherInterface
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* This implementation tries to resolve the requested factory from the
|
||||
* factory locator. If not found, it falls back to creating a generic
|
||||
* FlasherFactory with the given alias.
|
||||
*/
|
||||
public function use(?string $alias): NotificationFactoryInterface
|
||||
{
|
||||
$alias = trim($alias ?: $this->default);
|
||||
@@ -69,20 +43,14 @@ final readonly class Flasher implements FlasherInterface
|
||||
return new FlasherFactory($this->storageManager, $alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* This is an alias for the use() method.
|
||||
*/
|
||||
public function create(?string $alias): NotificationFactoryInterface
|
||||
{
|
||||
return $this->use($alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Delegates rendering to the response manager.
|
||||
* @param array<string, mixed> $criteria
|
||||
* @param array<string, mixed> $context
|
||||
*/
|
||||
public function render(string $presenter = 'html', array $criteria = [], array $context = []): mixed
|
||||
{
|
||||
@@ -90,25 +58,7 @@ final readonly class Flasher implements FlasherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically call methods on the default factory instance.
|
||||
*
|
||||
* This magic method enables using the Flasher instance directly with
|
||||
* notification methods like success(), error(), etc., without explicitly
|
||||
* calling use() first.
|
||||
*
|
||||
* Example:
|
||||
* ```php
|
||||
* // Instead of:
|
||||
* $flasher->use('flasher')->success('Message');
|
||||
*
|
||||
* // You can do:
|
||||
* $flasher->success('Message');
|
||||
* ```
|
||||
*
|
||||
* @param string $method The method name to call
|
||||
* @param mixed[] $parameters The parameters to pass to the method
|
||||
*
|
||||
* @return mixed The result of the method call
|
||||
* @param mixed[] $parameters
|
||||
*/
|
||||
public function __call(string $method, array $parameters): mixed
|
||||
{
|
||||
|
||||
@@ -8,15 +8,6 @@ use Flasher\Prime\Factory\NotificationFactoryInterface;
|
||||
use Flasher\Prime\Response\Presenter\ArrayPresenter;
|
||||
|
||||
/**
|
||||
* FlasherInterface - The primary entry point to the notification system.
|
||||
*
|
||||
* This interface defines the contract for the notification service,
|
||||
* providing methods to access notification factories and render
|
||||
* notifications. It's the main touchpoint for client code.
|
||||
*
|
||||
* Design pattern: Façade Pattern - Provides a simplified interface
|
||||
* to the complex notification subsystems.
|
||||
*
|
||||
* @mixin \Flasher\Prime\Notification\NotificationBuilder
|
||||
*
|
||||
* @phpstan-import-type ArrayPresenterType from ArrayPresenter
|
||||
@@ -24,78 +15,28 @@ use Flasher\Prime\Response\Presenter\ArrayPresenter;
|
||||
interface FlasherInterface
|
||||
{
|
||||
/**
|
||||
* Get a notification factory instance by its alias.
|
||||
*
|
||||
* This method provides access to specific notification factories (like Toastr, SweetAlert, etc.)
|
||||
* through a unified interface. It allows you to use specialized notification features
|
||||
* while maintaining a consistent API.
|
||||
*
|
||||
* Example:
|
||||
* ```php
|
||||
* $flasher->use('toastr')->success('Message using Toastr library');
|
||||
* ```
|
||||
*
|
||||
* @param string $alias The alias of the factory to retrieve (e.g., 'toastr', 'sweetalert')
|
||||
*
|
||||
* @phpstan-return ($alias is 'flasher' ? \Flasher\Prime\Factory\FlasherFactoryInterface :
|
||||
* ($alias is 'noty' ? \Flasher\Noty\Prime\NotyInterface :
|
||||
* ($alias is 'notyf' ? \Flasher\Notyf\Prime\NotyfInterface :
|
||||
* ($alias is 'sweetalert' ? \Flasher\SweetAlert\Prime\SweetAlertInterface :
|
||||
* ($alias is 'toastr' ? \Flasher\Toastr\Prime\ToastrInterface :
|
||||
* \Flasher\Prime\Factory\NotificationFactoryInterface)))))
|
||||
*
|
||||
* @throws \InvalidArgumentException When the requested factory cannot be resolved
|
||||
*/
|
||||
public function use(string $alias): NotificationFactoryInterface;
|
||||
|
||||
/**
|
||||
* Get a notification factory instance by its alias (alias for use()).
|
||||
*
|
||||
* This method is identical to use() but provides a more intuitive name
|
||||
* for creating new notification factories.
|
||||
*
|
||||
* Example:
|
||||
* ```php
|
||||
* $flasher->create('sweetalert')->success('Message using SweetAlert library');
|
||||
* ```
|
||||
*
|
||||
* @param string $alias The alias of the factory to retrieve (e.g., 'toastr', 'sweetalert')
|
||||
*
|
||||
* @phpstan-return ($alias is 'flasher' ? \Flasher\Prime\Factory\FlasherFactoryInterface :
|
||||
* ($alias is 'noty' ? \Flasher\Noty\Prime\NotyInterface :
|
||||
* ($alias is 'notyf' ? \Flasher\Notyf\Prime\NotyfInterface :
|
||||
* ($alias is 'sweetalert' ? \Flasher\SweetAlert\Prime\SweetAlertInterface :
|
||||
* ($alias is 'toastr' ? \Flasher\Toastr\Prime\ToastrInterface :
|
||||
* \Flasher\Prime\Factory\NotificationFactoryInterface)))))
|
||||
*
|
||||
* @throws \InvalidArgumentException When the requested factory cannot be resolved
|
||||
*/
|
||||
public function create(string $alias): NotificationFactoryInterface;
|
||||
|
||||
/**
|
||||
* Renders the flash notifications based on the specified criteria, presenter, and context.
|
||||
*
|
||||
* This method retrieves notifications from storage and formats them for display.
|
||||
* Different presenter formats can be specified (html, json, array) to support
|
||||
* various output requirements.
|
||||
*
|
||||
* Example:
|
||||
* ```php
|
||||
* // Render as HTML
|
||||
* $html = $flasher->render('html');
|
||||
*
|
||||
* // Render as JSON (for API responses)
|
||||
* $json = $flasher->render('json');
|
||||
*
|
||||
* // Render with filtering criteria
|
||||
* $errors = $flasher->render('html', ['type' => 'error']);
|
||||
* ```
|
||||
*
|
||||
* @param string $presenter The format to render notifications in ('html', 'json', 'array')
|
||||
* @param array<string, mixed> $criteria Optional filtering criteria for notifications
|
||||
* @param array<string, mixed> $context Additional context or options for rendering
|
||||
*
|
||||
* @return mixed The rendered notifications in the requested format
|
||||
* @param array<string, mixed> $criteria
|
||||
* @param array<string, mixed> $context
|
||||
*
|
||||
* @phpstan-return ($presenter is 'html' ? string :
|
||||
* ($presenter is 'array' ? ArrayPresenterType :
|
||||
|
||||
@@ -9,31 +9,19 @@ use Flasher\Prime\Stamp\StampInterface;
|
||||
use Flasher\Prime\Support\Traits\ForwardsCalls;
|
||||
|
||||
/**
|
||||
* Envelope - A wrapper for notifications with metadata.
|
||||
*
|
||||
* Wraps a notification object with "stamps" that provide additional
|
||||
* metadata and behavior. This allows attaching cross-cutting concerns
|
||||
* to notifications without modifying the notification itself.
|
||||
*
|
||||
* Design pattern: Decorator + Envelope - Extends functionality of
|
||||
* notifications by wrapping them in a container with additional capabilities.
|
||||
* Wraps a notification with metadata stamps.
|
||||
*/
|
||||
final class Envelope implements NotificationInterface
|
||||
{
|
||||
use ForwardsCalls;
|
||||
|
||||
/**
|
||||
* Collection of stamps attached to this envelope, indexed by class name.
|
||||
*
|
||||
* @var array<class-string<StampInterface>, StampInterface>
|
||||
*/
|
||||
private array $stamps = [];
|
||||
|
||||
/**
|
||||
* Creates a new Envelope instance.
|
||||
*
|
||||
* @param NotificationInterface $notification The notification to wrap
|
||||
* @param StampInterface[]|StampInterface $stamps One or more stamps to attach to the envelope
|
||||
* @param StampInterface[]|StampInterface $stamps
|
||||
*/
|
||||
public function __construct(private readonly NotificationInterface $notification, array|StampInterface $stamps = [])
|
||||
{
|
||||
@@ -43,23 +31,7 @@ final class Envelope implements NotificationInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a notification in an Envelope and adds the given stamps.
|
||||
*
|
||||
* This static factory method provides a convenient way to create and configure
|
||||
* an envelope in a single operation.
|
||||
*
|
||||
* Example:
|
||||
* ```php
|
||||
* $envelope = Envelope::wrap(new Notification(), [
|
||||
* new PriorityStamp(10),
|
||||
* new HopsStamp(2)
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* @param NotificationInterface $notification The notification to wrap
|
||||
* @param StampInterface[]|StampInterface $stamps One or more stamps to attach to the envelope
|
||||
*
|
||||
* @return self The created envelope
|
||||
* @param StampInterface[]|StampInterface $stamps
|
||||
*/
|
||||
public static function wrap(NotificationInterface $notification, array|StampInterface $stamps = []): self
|
||||
{
|
||||
@@ -71,11 +43,6 @@ final class Envelope implements NotificationInterface
|
||||
return $envelope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds multiple stamps to the envelope.
|
||||
*
|
||||
* @param StampInterface ...$stamps The stamps to add
|
||||
*/
|
||||
public function with(StampInterface ...$stamps): void
|
||||
{
|
||||
foreach ($stamps as $stamp) {
|
||||
@@ -83,18 +50,6 @@ final class Envelope implements NotificationInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds or replaces a stamp in the envelope.
|
||||
*
|
||||
* Each stamp class can only have one instance in the envelope at a time.
|
||||
* When adding a stamp of a class that already exists, the behavior depends
|
||||
* on the $replace parameter:
|
||||
* - If true (default), the new stamp replaces the existing one
|
||||
* - If false, the existing stamp is preserved
|
||||
*
|
||||
* @param StampInterface $stamp The stamp to add
|
||||
* @param bool $replace Whether to replace an existing stamp of the same type
|
||||
*/
|
||||
public function withStamp(StampInterface $stamp, bool $replace = true): void
|
||||
{
|
||||
if (!isset($this->stamps[$stamp::class]) || $replace) {
|
||||
@@ -102,11 +57,6 @@ final class Envelope implements NotificationInterface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes specified stamps from the envelope.
|
||||
*
|
||||
* @param StampInterface ...$stamps The stamps to remove
|
||||
*/
|
||||
public function without(StampInterface ...$stamps): void
|
||||
{
|
||||
foreach ($stamps as $stamp) {
|
||||
@@ -115,9 +65,7 @@ final class Envelope implements NotificationInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a specific type of stamp from the envelope.
|
||||
*
|
||||
* @param class-string<StampInterface>|StampInterface $type The type of stamp to remove
|
||||
* @param class-string<StampInterface>|StampInterface $type
|
||||
*/
|
||||
public function withoutStamp(string|StampInterface $type): void
|
||||
{
|
||||
@@ -127,13 +75,9 @@ final class Envelope implements NotificationInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a stamp by its type.
|
||||
*
|
||||
* @template T of StampInterface
|
||||
*
|
||||
* @phpstan-param class-string<T> $type The class name of the stamp to retrieve
|
||||
*
|
||||
* @return StampInterface|null The stamp if found, null otherwise
|
||||
* @phpstan-param class-string<T> $type
|
||||
*
|
||||
* @phpstan-return T|null
|
||||
*/
|
||||
@@ -146,148 +90,81 @@ final class Envelope implements NotificationInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all stamps by their class name.
|
||||
*
|
||||
* @return array<class-string<StampInterface>, StampInterface> Map of stamp class names to stamp instances
|
||||
* @return array<class-string<StampInterface>, StampInterface>
|
||||
*/
|
||||
public function all(): array
|
||||
{
|
||||
return $this->stamps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original notification contained in the envelope.
|
||||
*
|
||||
* @return NotificationInterface The wrapped notification
|
||||
*/
|
||||
public function getNotification(): NotificationInterface
|
||||
{
|
||||
return $this->notification;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Delegates to the wrapped notification.
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->notification->getTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Delegates to the wrapped notification.
|
||||
*/
|
||||
public function setTitle(string $title): void
|
||||
{
|
||||
$this->notification->setTitle($title);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Delegates to the wrapped notification.
|
||||
*/
|
||||
public function getMessage(): string
|
||||
{
|
||||
return $this->notification->getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Delegates to the wrapped notification.
|
||||
*/
|
||||
public function setMessage(string $message): void
|
||||
{
|
||||
$this->notification->setMessage($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Delegates to the wrapped notification.
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->notification->getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Delegates to the wrapped notification.
|
||||
*/
|
||||
public function setType(string $type): void
|
||||
{
|
||||
$this->notification->setType($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Delegates to the wrapped notification.
|
||||
*/
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->notification->getOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Delegates to the wrapped notification.
|
||||
*/
|
||||
public function setOptions(array $options): void
|
||||
{
|
||||
$this->notification->setOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Delegates to the wrapped notification.
|
||||
*/
|
||||
public function getOption(string $name, mixed $default = null): mixed
|
||||
{
|
||||
return $this->notification->getOption($name, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Delegates to the wrapped notification.
|
||||
*/
|
||||
public function setOption(string $name, mixed $value): void
|
||||
{
|
||||
$this->notification->setOption($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Delegates to the wrapped notification.
|
||||
*/
|
||||
public function unsetOption(string $name): void
|
||||
{
|
||||
$this->notification->unsetOption($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the envelope and its contents to an array format.
|
||||
*
|
||||
* This method combines the notification data with metadata from all
|
||||
* presentable stamps attached to the envelope.
|
||||
*
|
||||
* @return array{
|
||||
* title: string,
|
||||
* message: string,
|
||||
* type: string,
|
||||
* options: array<string, mixed>,
|
||||
* metadata: array<string, mixed>,
|
||||
* } The notification data with metadata
|
||||
* }
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
@@ -306,15 +183,7 @@ final class Envelope implements NotificationInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically call methods on the wrapped notification.
|
||||
*
|
||||
* This magic method allows calling methods directly on the envelope
|
||||
* which will be forwarded to the wrapped notification.
|
||||
*
|
||||
* @param string $method The method name to call
|
||||
* @param mixed[] $parameters The parameters to pass to the method
|
||||
*
|
||||
* @return mixed The result of the method call
|
||||
* @param mixed[] $parameters
|
||||
*/
|
||||
public function __call(string $method, array $parameters): mixed
|
||||
{
|
||||
|
||||
@@ -5,14 +5,6 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Notification;
|
||||
|
||||
/**
|
||||
* FlasherBuilder - Default implementation of the notification builder.
|
||||
*
|
||||
* Provides methods for building and configuring flasher-specific notifications.
|
||||
* Extends the core builder with additional type-safety and convenience methods.
|
||||
*
|
||||
* Design pattern: Concrete Builder - Implements the builder interface
|
||||
* with specific behaviors for flasher notifications.
|
||||
*
|
||||
* @phpstan-type NotificationType "success"|"info"|"warning"|"error"
|
||||
* @phpstan-type OptionsType array{
|
||||
* timeout?: int,
|
||||
@@ -28,8 +20,6 @@ namespace Flasher\Prime\Notification;
|
||||
final class FlasherBuilder extends NotificationBuilder
|
||||
{
|
||||
/**
|
||||
* Sets the notification type.
|
||||
*
|
||||
* @phpstan-param NotificationType $type
|
||||
*/
|
||||
public function type(string $type): static
|
||||
@@ -38,8 +28,6 @@ final class FlasherBuilder extends NotificationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and stores a success notification.
|
||||
*
|
||||
* @param OptionsType $options
|
||||
*/
|
||||
public function success(string $message, array $options = [], ?string $title = null): Envelope
|
||||
@@ -48,8 +36,6 @@ final class FlasherBuilder extends NotificationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and stores an error notification.
|
||||
*
|
||||
* @param OptionsType $options
|
||||
*/
|
||||
public function error(string $message, array $options = [], ?string $title = null): Envelope
|
||||
@@ -58,8 +44,6 @@ final class FlasherBuilder extends NotificationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and stores an info notification.
|
||||
*
|
||||
* @param OptionsType $options
|
||||
*/
|
||||
public function info(string $message, array $options = [], ?string $title = null): Envelope
|
||||
@@ -68,8 +52,6 @@ final class FlasherBuilder extends NotificationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and stores a warning notification.
|
||||
*
|
||||
* @param OptionsType $options
|
||||
*/
|
||||
public function warning(string $message, array $options = [], ?string $title = null): Envelope
|
||||
@@ -78,10 +60,8 @@ final class FlasherBuilder extends NotificationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and stores a notification with specified type.
|
||||
*
|
||||
* @phpstan-param NotificationType|null $type
|
||||
* @phpstan-param OptionsType $options
|
||||
* @phpstan-param OptionsType $options
|
||||
*/
|
||||
public function flash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null): Envelope
|
||||
{
|
||||
@@ -89,8 +69,6 @@ final class FlasherBuilder extends NotificationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets multiple options.
|
||||
*
|
||||
* @param OptionsType $options
|
||||
*/
|
||||
public function options(array $options, bool $append = true): static
|
||||
@@ -99,12 +77,10 @@ final class FlasherBuilder extends NotificationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a single option.
|
||||
*
|
||||
* @template T of OptionsType
|
||||
* @template K of key-of<T>
|
||||
*
|
||||
* @phpstan-param K $name
|
||||
* @phpstan-param K $name
|
||||
* @phpstan-param T[K] $value
|
||||
*/
|
||||
public function option(string $name, mixed $value): static
|
||||
@@ -112,9 +88,6 @@ final class FlasherBuilder extends NotificationBuilder
|
||||
return parent::option($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the display timeout.
|
||||
*/
|
||||
public function timeout(int $milliseconds): self
|
||||
{
|
||||
$this->option('timeout', $milliseconds);
|
||||
@@ -123,8 +96,6 @@ final class FlasherBuilder extends NotificationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stacking direction.
|
||||
*
|
||||
* @param "top"|"bottom" $direction
|
||||
*/
|
||||
public function direction(string $direction): self
|
||||
@@ -135,8 +106,6 @@ final class FlasherBuilder extends NotificationBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the display position.
|
||||
*
|
||||
* @phpstan-param OptionsType['position'] $position
|
||||
*/
|
||||
public function position(string $position): self
|
||||
|
||||
@@ -6,89 +6,51 @@ namespace Flasher\Prime\Notification;
|
||||
|
||||
/**
|
||||
* Default implementation of NotificationInterface.
|
||||
*
|
||||
* This class represents a notification with its basic properties: title, message,
|
||||
* type, and options. It provides the core functionality for storing and
|
||||
* manipulating notification data.
|
||||
*
|
||||
* Design pattern: Value Object - Represents a simple entity with equality based
|
||||
* on attribute values rather than identity.
|
||||
*/
|
||||
final class Notification implements NotificationInterface
|
||||
{
|
||||
/**
|
||||
* The notification title.
|
||||
*/
|
||||
private string $title = '';
|
||||
|
||||
/**
|
||||
* The notification message content.
|
||||
*/
|
||||
private string $message = '';
|
||||
|
||||
/**
|
||||
* The notification type (e.g., "success", "error", "warning", "info").
|
||||
*/
|
||||
private string $type = '';
|
||||
|
||||
/**
|
||||
* Configuration options for the notification.
|
||||
*
|
||||
* @var array<string, mixed>
|
||||
*/
|
||||
private array $options = [];
|
||||
|
||||
/**
|
||||
* Gets the title.
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title.
|
||||
*/
|
||||
public function setTitle(string $title): void
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message.
|
||||
*/
|
||||
public function getMessage(): string
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message.
|
||||
*/
|
||||
public function setMessage(string $message): void
|
||||
{
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type.
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type.
|
||||
*/
|
||||
public function setType(string $type): void
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all options.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getOptions(): array
|
||||
@@ -97,21 +59,13 @@ final class Notification implements NotificationInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or updates the options of the notification.
|
||||
*
|
||||
* This method merges the provided options with existing ones,
|
||||
* with new values taking precedence over existing values.
|
||||
*
|
||||
* @param array<string, mixed> $options The options to set or update
|
||||
* @param array<string, mixed> $options
|
||||
*/
|
||||
public function setOptions(array $options): void
|
||||
{
|
||||
$this->options = array_replace($this->options, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a specific option with a default fallback.
|
||||
*/
|
||||
public function getOption(string $name, mixed $default = null): mixed
|
||||
{
|
||||
return \array_key_exists($name, $this->options)
|
||||
@@ -119,17 +73,11 @@ final class Notification implements NotificationInterface
|
||||
: $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a specific option.
|
||||
*/
|
||||
public function setOption(string $name, mixed $value): void
|
||||
{
|
||||
$this->options[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets a specific option.
|
||||
*/
|
||||
public function unsetOption(string $name): void
|
||||
{
|
||||
unset($this->options[$name]);
|
||||
|
||||
@@ -4,109 +4,43 @@ declare(strict_types=1);
|
||||
|
||||
namespace Flasher\Prime\Notification;
|
||||
|
||||
/**
|
||||
* NotificationInterface - The core notification contract.
|
||||
*
|
||||
* Defines the essential properties and behaviors of a notification.
|
||||
* All notification implementations must adhere to this interface.
|
||||
*
|
||||
* Design pattern: Component Interface - Establishes a common contract
|
||||
* for notification objects throughout the system.
|
||||
*/
|
||||
interface NotificationInterface
|
||||
{
|
||||
/**
|
||||
* Gets the title of the notification.
|
||||
*
|
||||
* @return string The notification title
|
||||
*/
|
||||
public function getTitle(): string;
|
||||
|
||||
/**
|
||||
* Sets the title of the notification.
|
||||
*
|
||||
* @param string $title The title to set
|
||||
*/
|
||||
public function setTitle(string $title): void;
|
||||
|
||||
/**
|
||||
* Gets the message content of the notification.
|
||||
*
|
||||
* @return string The notification message
|
||||
*/
|
||||
public function getMessage(): string;
|
||||
|
||||
/**
|
||||
* Sets the message content of the notification.
|
||||
*
|
||||
* @param string $message The message to set
|
||||
*/
|
||||
public function setMessage(string $message): void;
|
||||
|
||||
/**
|
||||
* Gets the type of the notification.
|
||||
*
|
||||
* Common types include "success", "error", "info", and "warning".
|
||||
*
|
||||
* @return string The notification type
|
||||
*/
|
||||
public function getType(): string;
|
||||
|
||||
/**
|
||||
* Sets the type of the notification.
|
||||
*
|
||||
* @param string $type The type to set
|
||||
*/
|
||||
public function setType(string $type): void;
|
||||
|
||||
/**
|
||||
* Gets all options of the notification.
|
||||
*
|
||||
* @return array<string, mixed> The notification options
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getOptions(): array;
|
||||
|
||||
/**
|
||||
* Sets or updates the options of the notification.
|
||||
*
|
||||
* @param array<string, mixed> $options The options to set or update
|
||||
* @param array<string, mixed> $options
|
||||
*/
|
||||
public function setOptions(array $options): void;
|
||||
|
||||
/**
|
||||
* Gets a specific option of the notification with a default fallback.
|
||||
*
|
||||
* @param string $name The name of the option
|
||||
* @param mixed $default The default value to return if the option is not set
|
||||
*
|
||||
* @return mixed The option value or the default value
|
||||
*/
|
||||
public function getOption(string $name, mixed $default = null): mixed;
|
||||
|
||||
/**
|
||||
* Sets a specific option for the notification.
|
||||
*
|
||||
* @param string $name The name of the option
|
||||
* @param mixed $value The value of the option
|
||||
*/
|
||||
public function setOption(string $name, mixed $value): void;
|
||||
|
||||
/**
|
||||
* Unsets a specific option of the notification.
|
||||
*
|
||||
* @param string $name The name of the option to unset
|
||||
*/
|
||||
public function unsetOption(string $name): void;
|
||||
|
||||
/**
|
||||
* Converts the notification into an associative array.
|
||||
*
|
||||
* @return array{
|
||||
* title: string,
|
||||
* message: string,
|
||||
* type: string,
|
||||
* options: array<string, mixed>,
|
||||
* } The notification as an array
|
||||
* }
|
||||
*/
|
||||
public function toArray(): array;
|
||||
}
|
||||
|
||||
@@ -5,31 +5,19 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Stamp;
|
||||
|
||||
/**
|
||||
* ContextStamp - Stores additional context data for a notification.
|
||||
*
|
||||
* This stamp provides a way to attach arbitrary context data to a notification.
|
||||
* This context data can be used by presenters, templates, or frontend code to
|
||||
* customize how the notification is rendered or processed.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Value Object: Immutable object representing a specific concept
|
||||
* - Memento: Captures and externalizes an object's internal state
|
||||
* Stores additional context data for a notification.
|
||||
*/
|
||||
final readonly class ContextStamp implements PresentableStampInterface, StampInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new ContextStamp instance.
|
||||
*
|
||||
* @param array<string, mixed> $context The context data to attach
|
||||
* @param array<string, mixed> $context
|
||||
*/
|
||||
public function __construct(private array $context)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the context data.
|
||||
*
|
||||
* @return array<string, mixed> The context data
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getContext(): array
|
||||
{
|
||||
@@ -37,11 +25,7 @@ final readonly class ContextStamp implements PresentableStampInterface, StampInt
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the stamp to an array representation.
|
||||
*
|
||||
* This method implements the serialization logic required by PresentableStampInterface.
|
||||
*
|
||||
* @return array{context: array<string, mixed>} The array representation
|
||||
* @return array{context: array<string, mixed>}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
|
||||
@@ -5,61 +5,25 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Stamp;
|
||||
|
||||
/**
|
||||
* CreatedAtStamp - Records when a notification was created.
|
||||
*
|
||||
* This stamp stores the creation time of a notification, which can be used
|
||||
* for ordering, filtering, or display purposes. It implements OrderableStampInterface
|
||||
* to enable sorting notifications by creation time.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Value Object: Immutable object representing a specific concept
|
||||
* - Temporal Marker: Records a point in time for domain objects
|
||||
* - Comparable: Implements comparison logic for time-based sorting
|
||||
* Records when a notification was created.
|
||||
*/
|
||||
final readonly class CreatedAtStamp implements OrderableStampInterface, PresentableStampInterface, StampInterface
|
||||
{
|
||||
/**
|
||||
* The creation timestamp.
|
||||
*/
|
||||
private \DateTimeImmutable $createdAt;
|
||||
|
||||
/**
|
||||
* The format string for date presentation.
|
||||
*/
|
||||
private string $format;
|
||||
|
||||
/**
|
||||
* Creates a new CreatedAtStamp instance.
|
||||
*
|
||||
* @param \DateTimeImmutable|null $createdAt The datetime object representing the creation time
|
||||
* @param string|null $format The format in which the datetime should be presented
|
||||
*/
|
||||
public function __construct(?\DateTimeImmutable $createdAt = null, ?string $format = null)
|
||||
{
|
||||
$this->createdAt = $createdAt ?: new \DateTimeImmutable();
|
||||
$this->format = $format ?: 'Y-m-d H:i:s';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the creation timestamp.
|
||||
*
|
||||
* @return \DateTimeImmutable The creation timestamp
|
||||
*/
|
||||
public function getCreatedAt(): \DateTimeImmutable
|
||||
{
|
||||
return $this->createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this stamp with another for ordering purposes.
|
||||
*
|
||||
* This method implements the comparison logic required by OrderableStampInterface.
|
||||
* It orders notifications chronologically by creation time.
|
||||
*
|
||||
* @param StampInterface $orderable The stamp to compare with
|
||||
*
|
||||
* @return int Negative if this is older, positive if newer, zero if same time
|
||||
*/
|
||||
public function compare(StampInterface $orderable): int
|
||||
{
|
||||
if (!$orderable instanceof self) {
|
||||
@@ -70,11 +34,7 @@ final readonly class CreatedAtStamp implements OrderableStampInterface, Presenta
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the stamp to an array representation.
|
||||
*
|
||||
* This method implements the serialization logic required by PresentableStampInterface.
|
||||
*
|
||||
* @return array{created_at: string} The array representation with formatted timestamp
|
||||
* @return array{created_at: string}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
|
||||
@@ -5,30 +5,14 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Stamp;
|
||||
|
||||
/**
|
||||
* DelayStamp - Controls notification display delay.
|
||||
*
|
||||
* This stamp specifies how long to wait (in milliseconds) before displaying
|
||||
* a notification. It allows for scheduling notifications to appear after a
|
||||
* certain amount of time has passed.
|
||||
*
|
||||
* Design pattern: Value Object - Immutable object representing a specific concept
|
||||
* Controls notification display delay.
|
||||
*/
|
||||
final readonly class DelayStamp implements StampInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new DelayStamp instance.
|
||||
*
|
||||
* @param int $delay The delay in milliseconds before displaying the notification
|
||||
*/
|
||||
public function __construct(private int $delay)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the delay value.
|
||||
*
|
||||
* @return int The delay in milliseconds
|
||||
*/
|
||||
public function getDelay(): int
|
||||
{
|
||||
return $this->delay;
|
||||
|
||||
@@ -5,32 +5,14 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Stamp;
|
||||
|
||||
/**
|
||||
* HopsStamp - Controls notification persistence across requests.
|
||||
*
|
||||
* This stamp defines how many request cycles ("hops") a notification should persist for.
|
||||
* A value of 1 means the notification will only appear in the current request,
|
||||
* while higher values allow notifications to survive across redirects or page loads.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Value Object: Immutable object representing a specific concept
|
||||
* - Lifecycle Control: Controls the lifecycle of a notification across requests
|
||||
* Controls notification persistence across requests.
|
||||
*/
|
||||
final readonly class HopsStamp implements StampInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new HopsStamp instance.
|
||||
*
|
||||
* @param int $amount The number of request cycles the notification should persist for
|
||||
*/
|
||||
public function __construct(private int $amount)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of hops.
|
||||
*
|
||||
* @return int The number of request cycles
|
||||
*/
|
||||
public function getAmount(): int
|
||||
{
|
||||
return $this->amount;
|
||||
|
||||
@@ -7,42 +7,17 @@ namespace Flasher\Prime\Stamp;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* IdStamp - Provides a unique identifier for notifications.
|
||||
*
|
||||
* This stamp assigns a unique identifier to each notification, which can be
|
||||
* used for referencing, tracking, or manipulating specific notifications. It
|
||||
* also provides utility methods for working with collections of notifications.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Value Object: Immutable object representing a specific concept
|
||||
* - Identity: Provides a unique identifier for domain objects
|
||||
* - Collection Utility: Provides methods for working with notification collections
|
||||
* Provides a unique identifier for notifications.
|
||||
*/
|
||||
final readonly class IdStamp implements PresentableStampInterface, StampInterface
|
||||
{
|
||||
/**
|
||||
* The unique identifier.
|
||||
*/
|
||||
private string $id;
|
||||
|
||||
/**
|
||||
* Creates a new IdStamp instance.
|
||||
*
|
||||
* @param string|null $id The identifier. If not provided, a unique identifier is generated.
|
||||
*/
|
||||
public function __construct(?string $id = null)
|
||||
{
|
||||
$this->id = $id ?? $this->generateUniqueId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique identifier.
|
||||
*
|
||||
* This method attempts to use cryptographically secure random bytes for the ID,
|
||||
* with a fallback to uniqid() if random_bytes() fails.
|
||||
*
|
||||
* @return string The generated unique identifier
|
||||
*/
|
||||
private function generateUniqueId(): string
|
||||
{
|
||||
try {
|
||||
@@ -55,14 +30,9 @@ final readonly class IdStamp implements PresentableStampInterface, StampInterfac
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes an array of envelopes by their ID.
|
||||
* @param Envelope[] $envelopes
|
||||
*
|
||||
* This utility method creates a map of envelopes keyed by their unique IDs,
|
||||
* adding IdStamps to envelopes that don't already have them.
|
||||
*
|
||||
* @param Envelope[] $envelopes An array of envelopes to index
|
||||
*
|
||||
* @return array<string, Envelope> An associative array of envelopes indexed by their ID
|
||||
* @return array<string, Envelope>
|
||||
*/
|
||||
public static function indexById(array $envelopes): array
|
||||
{
|
||||
@@ -83,22 +53,13 @@ final readonly class IdStamp implements PresentableStampInterface, StampInterfac
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the identifier.
|
||||
*
|
||||
* @return string The identifier
|
||||
*/
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the stamp to an array representation.
|
||||
*
|
||||
* This method implements the serialization logic required by PresentableStampInterface.
|
||||
*
|
||||
* @return array{id: string} The array representation
|
||||
* @return array{id: string}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
|
||||
@@ -5,29 +5,9 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Stamp;
|
||||
|
||||
/**
|
||||
* OrderableStampInterface - Contract for stamps that affect notification ordering.
|
||||
*
|
||||
* This interface identifies stamps that provide ordering behavior for notifications.
|
||||
* It defines a comparison method that can be used to sort notifications based on
|
||||
* stamp-specific criteria.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Comparable: Defines an interface for objects that can be compared for ordering
|
||||
* - Strategy: Allows different ordering strategies to be implemented and used interchangeably
|
||||
* Contract for stamps that affect notification ordering.
|
||||
*/
|
||||
interface OrderableStampInterface
|
||||
{
|
||||
/**
|
||||
* Compares this stamp with another for determining ordering.
|
||||
*
|
||||
* This method should return:
|
||||
* - A negative value if this stamp should be ordered before the other
|
||||
* - A positive value if this stamp should be ordered after the other
|
||||
* - Zero if the stamps are equivalent for ordering purposes
|
||||
*
|
||||
* @param StampInterface $orderable The stamp to compare with
|
||||
*
|
||||
* @return int Negative if before, positive if after, zero if equivalent
|
||||
*/
|
||||
public function compare(StampInterface $orderable): int;
|
||||
}
|
||||
|
||||
@@ -5,25 +5,12 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Stamp;
|
||||
|
||||
/**
|
||||
* PresentableStampInterface - Contract for stamps that contribute to presentation.
|
||||
*
|
||||
* This interface identifies stamps that should include their data in the notification's
|
||||
* serialized form when being presented. Stamps implementing this interface will have
|
||||
* their data included in the notification's metadata when rendered.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Marker Interface: Identifies stamps that provide presentation metadata
|
||||
* - Serializable: Defines a standard way to convert objects to serializable data
|
||||
* Contract for stamps that contribute to presentation.
|
||||
*/
|
||||
interface PresentableStampInterface
|
||||
{
|
||||
/**
|
||||
* Converts the stamp to an array representation.
|
||||
*
|
||||
* This method should return an associative array containing the stamp's
|
||||
* data in a form that can be serialized and used in presentation.
|
||||
*
|
||||
* @return array<string, mixed> The array representation
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(): array;
|
||||
}
|
||||
|
||||
@@ -5,43 +5,24 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Stamp;
|
||||
|
||||
/**
|
||||
* PresetStamp - Associates a notification with a predefined template.
|
||||
*
|
||||
* This stamp identifies which preset template should be used for a notification.
|
||||
* Presets allow defining reusable notification templates with predefined types,
|
||||
* titles, messages, and options. The stamp can also include template parameters
|
||||
* for variable substitution.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Template Reference: References a predefined template to use
|
||||
* - Parameter Carrier: Carries parameters for template variable substitution
|
||||
* Associates a notification with a predefined template.
|
||||
*/
|
||||
final readonly class PresetStamp implements StampInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new PresetStamp instance.
|
||||
*
|
||||
* @param string $preset The preset name to use
|
||||
* @param array<string, mixed> $parameters Template parameters for variable substitution
|
||||
* @param array<string, mixed> $parameters
|
||||
*/
|
||||
public function __construct(private string $preset, private array $parameters = [])
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the preset name.
|
||||
*
|
||||
* @return string The preset name
|
||||
*/
|
||||
public function getPreset(): string
|
||||
{
|
||||
return $this->preset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the template parameters.
|
||||
*
|
||||
* @return array<string, mixed> The template parameters
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getParameters(): array
|
||||
{
|
||||
|
||||
@@ -5,50 +5,19 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Stamp;
|
||||
|
||||
/**
|
||||
* PriorityStamp - Controls notification priority for ordering.
|
||||
*
|
||||
* This stamp assigns a priority value to notifications, which affects their
|
||||
* display order. Higher priority notifications are typically displayed before
|
||||
* lower priority ones. This stamp also implements the OrderableStampInterface to
|
||||
* participate in sorting operations and PresentableStampInterface to be included
|
||||
* in the notification's metadata.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Value Object: Immutable object representing a specific concept
|
||||
* - Comparable: Implements comparison logic for sorting
|
||||
* Controls notification priority for ordering.
|
||||
*/
|
||||
final readonly class PriorityStamp implements OrderableStampInterface, PresentableStampInterface, StampInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new PriorityStamp instance.
|
||||
*
|
||||
* @param int $priority The priority value (higher values typically displayed first)
|
||||
*/
|
||||
public function __construct(private int $priority)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the priority value.
|
||||
*
|
||||
* @return int The priority value
|
||||
*/
|
||||
public function getPriority(): int
|
||||
{
|
||||
return $this->priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this stamp with another for ordering purposes.
|
||||
*
|
||||
* This method implements the comparison logic required by OrderableStampInterface.
|
||||
* It returns a positive value if this stamp has higher priority, negative if lower,
|
||||
* or zero if equal.
|
||||
*
|
||||
* @param StampInterface $orderable The stamp to compare with
|
||||
*
|
||||
* @return int Negative if this has lower priority, positive if higher, zero if equal
|
||||
*/
|
||||
public function compare(StampInterface $orderable): int
|
||||
{
|
||||
if (!$orderable instanceof self) {
|
||||
@@ -59,11 +28,7 @@ final readonly class PriorityStamp implements OrderableStampInterface, Presentab
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the stamp to an array representation.
|
||||
*
|
||||
* This method implements the serialization logic required by PresentableStampInterface.
|
||||
*
|
||||
* @return array{priority: int} The array representation
|
||||
* @return array{priority: int}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
|
||||
@@ -5,18 +5,8 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Stamp;
|
||||
|
||||
/**
|
||||
* StampInterface - Marker interface for notification metadata.
|
||||
*
|
||||
* This interface is a base marker for all stamp classes that can be attached
|
||||
* to notification envelopes. Stamps provide metadata and behavior modifiers
|
||||
* for notifications, following the Envelope Pattern where the core notification
|
||||
* is wrapped with various stamps that affect its behavior.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Marker Interface: Identifies classes that can serve as notification stamps
|
||||
* - Envelope Pattern: Part of a system where a core object is wrapped with metadata
|
||||
* Marker interface for notification metadata.
|
||||
*/
|
||||
interface StampInterface
|
||||
{
|
||||
// This is a marker interface with no methods
|
||||
}
|
||||
|
||||
@@ -5,43 +5,25 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Stamp;
|
||||
|
||||
/**
|
||||
* TranslationStamp - Provides translation parameters and locale for a notification.
|
||||
*
|
||||
* This stamp contains translation parameters and an optional locale override
|
||||
* for translating notification content. It allows for customization of how
|
||||
* notification titles and messages are translated.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Value Object: Immutable object representing a specific concept
|
||||
* - Parameter Carrier: Carries parameters for translation processing
|
||||
* Provides translation parameters and locale for a notification.
|
||||
*/
|
||||
final readonly class TranslationStamp implements StampInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new TranslationStamp instance.
|
||||
*
|
||||
* @param array<string, mixed> $parameters Translation parameters for variable substitution
|
||||
* @param string|null $locale Locale override (null uses default locale)
|
||||
* @param array<string, mixed> $parameters
|
||||
*/
|
||||
public function __construct(private array $parameters = [], private ?string $locale = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the translation parameters.
|
||||
*
|
||||
* @return array<string, mixed> The translation parameters
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getParameters(): array
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the locale override.
|
||||
*
|
||||
* @return string|null The locale override, or null to use default locale
|
||||
*/
|
||||
public function getLocale(): ?string
|
||||
{
|
||||
return $this->locale;
|
||||
|
||||
@@ -5,30 +5,14 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Stamp;
|
||||
|
||||
/**
|
||||
* UnlessStamp - Controls conditional suppression of notifications.
|
||||
*
|
||||
* This stamp provides a way to conditionally suppress notifications based on
|
||||
* a boolean condition. If the condition is true, the notification will be
|
||||
* suppressed, otherwise it will be displayed.
|
||||
*
|
||||
* Design pattern: Specification - Encapsulates a business rule as a value object
|
||||
* Controls conditional suppression of notifications.
|
||||
*/
|
||||
final readonly class UnlessStamp implements StampInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new UnlessStamp instance.
|
||||
*
|
||||
* @param bool $condition When true, the notification will be suppressed
|
||||
*/
|
||||
public function __construct(private bool $condition)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the condition value.
|
||||
*
|
||||
* @return bool True if the notification should be suppressed, false otherwise
|
||||
*/
|
||||
public function getCondition(): bool
|
||||
{
|
||||
return $this->condition;
|
||||
|
||||
@@ -5,30 +5,14 @@ declare(strict_types=1);
|
||||
namespace Flasher\Prime\Stamp;
|
||||
|
||||
/**
|
||||
* WhenStamp - Controls conditional display of notifications.
|
||||
*
|
||||
* This stamp provides a way to conditionally display notifications based on
|
||||
* a boolean condition. If the condition is true, the notification will be
|
||||
* displayed, otherwise it will be suppressed.
|
||||
*
|
||||
* Design pattern: Specification - Encapsulates a business rule as a value object
|
||||
* Controls conditional display of notifications.
|
||||
*/
|
||||
final readonly class WhenStamp implements StampInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new WhenStamp instance.
|
||||
*
|
||||
* @param bool $condition When true, the notification will be displayed
|
||||
*/
|
||||
public function __construct(private bool $condition)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the condition value.
|
||||
*
|
||||
* @return bool True if the notification should be displayed, false otherwise
|
||||
*/
|
||||
public function getCondition(): bool
|
||||
{
|
||||
return $this->condition;
|
||||
|
||||
@@ -7,27 +7,17 @@ namespace Flasher\Prime\Storage\Bag;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* ArrayBag - In-memory storage bag for notifications.
|
||||
*
|
||||
* This class provides a simple implementation of the storage bag interface
|
||||
* that stores notification envelopes in a instance-level array. It's suitable
|
||||
* for testing or applications with short-lived processes.
|
||||
*
|
||||
* Design pattern: Value Object - Provides a simple container for notification storage.
|
||||
* In-memory storage bag for notifications.
|
||||
*/
|
||||
final class ArrayBag implements BagInterface
|
||||
{
|
||||
/**
|
||||
* The stored notification envelopes.
|
||||
*
|
||||
* @var Envelope[]
|
||||
*/
|
||||
private array $envelopes = [];
|
||||
|
||||
/**
|
||||
* Retrieves all stored notification envelopes.
|
||||
*
|
||||
* @return Envelope[] Array of all stored notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function get(): array
|
||||
{
|
||||
@@ -35,11 +25,7 @@ final class ArrayBag implements BagInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stored notification envelopes.
|
||||
*
|
||||
* This method replaces all existing envelopes with the provided ones.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to store
|
||||
* @param Envelope[] $envelopes
|
||||
*/
|
||||
public function set(array $envelopes): void
|
||||
{
|
||||
|
||||
@@ -7,30 +7,17 @@ namespace Flasher\Prime\Storage\Bag;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* BagInterface - Contract for notification envelope storage containers.
|
||||
*
|
||||
* This interface defines the essential operations for a storage container
|
||||
* that can hold notification envelopes. Different implementations can use
|
||||
* different storage backends (array, session, etc.).
|
||||
*
|
||||
* Design pattern: Repository - Defines a simple contract for storing and
|
||||
* retrieving notification envelopes.
|
||||
* Contract for notification envelope storage containers.
|
||||
*/
|
||||
interface BagInterface
|
||||
{
|
||||
/**
|
||||
* Retrieves all stored notification envelopes.
|
||||
*
|
||||
* @return Envelope[] Array of all stored notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function get(): array;
|
||||
|
||||
/**
|
||||
* Sets the stored notification envelopes.
|
||||
*
|
||||
* This method should replace all existing envelopes with the provided ones.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to store
|
||||
* @param Envelope[] $envelopes
|
||||
*/
|
||||
public function set(array $envelopes): void;
|
||||
}
|
||||
|
||||
@@ -7,28 +7,17 @@ namespace Flasher\Prime\Storage\Bag;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* StaticBag - Static/global storage bag for notifications.
|
||||
*
|
||||
* This class provides an implementation of the storage bag interface that
|
||||
* stores notification envelopes in a static class-level array. This allows
|
||||
* sharing notifications across multiple instances of the bag class.
|
||||
*
|
||||
* Design pattern: Value Object with Singleton state - Provides a container
|
||||
* for notification storage with globally shared state.
|
||||
* Static/global storage bag for notifications.
|
||||
*/
|
||||
final class StaticBag implements BagInterface
|
||||
{
|
||||
/**
|
||||
* The stored notification envelopes (shared across all instances).
|
||||
*
|
||||
* @var Envelope[]
|
||||
*/
|
||||
private static array $envelopes = [];
|
||||
|
||||
/**
|
||||
* Retrieves all stored notification envelopes.
|
||||
*
|
||||
* @return Envelope[] Array of all stored notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function get(): array
|
||||
{
|
||||
@@ -36,12 +25,7 @@ final class StaticBag implements BagInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stored notification envelopes.
|
||||
*
|
||||
* This method replaces all existing envelopes with the provided ones
|
||||
* in the shared static storage.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to store
|
||||
* @param Envelope[] $envelopes
|
||||
*/
|
||||
public function set(array $envelopes): void
|
||||
{
|
||||
|
||||
@@ -7,26 +7,14 @@ namespace Flasher\Prime\Storage\Filter\Criteria;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* CriteriaInterface - Contract for notification filtering criteria.
|
||||
*
|
||||
* This interface defines the essential operation for filtering notification
|
||||
* envelopes based on specific criteria. Each implementation defines its own
|
||||
* logic for determining which envelopes match the criteria.
|
||||
*
|
||||
* Design pattern: Specification - Defines a clear, boolean-logic based way
|
||||
* to check if an object satisfies some criteria.
|
||||
* Contract for notification filtering criteria.
|
||||
*/
|
||||
interface CriteriaInterface
|
||||
{
|
||||
/**
|
||||
* Applies the criterion to filter notification envelopes.
|
||||
* @param Envelope[] $envelopes
|
||||
*
|
||||
* This method should analyze the provided envelopes and return
|
||||
* only those that match the criterion's conditions.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to filter
|
||||
*
|
||||
* @return Envelope[] The filtered notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function apply(array $envelopes): array;
|
||||
}
|
||||
|
||||
@@ -8,36 +8,18 @@ use Flasher\Prime\Notification\Envelope;
|
||||
use Flasher\Prime\Stamp\DelayStamp;
|
||||
|
||||
/**
|
||||
* DelayCriteria - Filters notifications by delay time.
|
||||
*
|
||||
* This criterion filters notification envelopes based on their delay time,
|
||||
* which determines how long to wait before displaying a notification.
|
||||
* It can filter for delays within a specific range (min to max) or above a minimum.
|
||||
*
|
||||
* Design pattern: Specification - Defines filter logic based on delay ranges.
|
||||
* Filters notifications by delay time.
|
||||
*/
|
||||
final readonly class DelayCriteria implements CriteriaInterface
|
||||
{
|
||||
use RangeExtractor;
|
||||
|
||||
/**
|
||||
* The minimum delay time in milliseconds (inclusive).
|
||||
*/
|
||||
private ?int $minDelay;
|
||||
|
||||
/**
|
||||
* The maximum delay time in milliseconds (inclusive).
|
||||
*/
|
||||
private ?int $maxDelay;
|
||||
|
||||
/**
|
||||
* Creates a new DelayCriteria instance.
|
||||
*
|
||||
* @param mixed $criteria The delay criteria, either:
|
||||
* - An integer (minimum delay threshold)
|
||||
* - An array with 'min' and/or 'max' keys
|
||||
*
|
||||
* @throws \InvalidArgumentException If the criteria format is invalid
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(mixed $criteria)
|
||||
{
|
||||
@@ -48,24 +30,15 @@ final readonly class DelayCriteria implements CriteriaInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters envelopes by delay time.
|
||||
* @param Envelope[] $envelopes
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to filter
|
||||
*
|
||||
* @return Envelope[] Envelopes that match the delay criteria
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function apply(array $envelopes): array
|
||||
{
|
||||
return array_filter($envelopes, fn (Envelope $envelope): bool => $this->match($envelope));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an envelope matches the delay criteria.
|
||||
*
|
||||
* @param Envelope $envelope The envelope to check
|
||||
*
|
||||
* @return bool True if the envelope matches the criteria, false otherwise
|
||||
*/
|
||||
public function match(Envelope $envelope): bool
|
||||
{
|
||||
$stamp = $envelope->get(DelayStamp::class);
|
||||
|
||||
@@ -7,32 +7,17 @@ namespace Flasher\Prime\Storage\Filter\Criteria;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* FilterCriteria - Applies custom closure-based filters to notifications.
|
||||
*
|
||||
* This criterion allows applying custom filtering logic provided as closures.
|
||||
* It's a flexible way to implement complex or specific filtering needs that
|
||||
* aren't covered by the standard criteria.
|
||||
*
|
||||
* Design pattern: Strategy - Encapsulates custom filtering algorithms provided
|
||||
* as closures and applies them to notification collections.
|
||||
* Applies custom closure-based filters to notifications.
|
||||
*/
|
||||
final class FilterCriteria implements CriteriaInterface
|
||||
{
|
||||
/**
|
||||
* The collection of filter callbacks.
|
||||
*
|
||||
* @var \Closure[]
|
||||
*/
|
||||
private array $callbacks;
|
||||
|
||||
/**
|
||||
* Creates a new FilterCriteria instance.
|
||||
*
|
||||
* @param mixed $criteria Either a single closure or an array of closures
|
||||
* Each closure should accept an array of Envelope objects
|
||||
* and return a filtered array of Envelope objects
|
||||
*
|
||||
* @throws \InvalidArgumentException If the criteria is not a closure or array of closures
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(mixed $criteria)
|
||||
{
|
||||
@@ -51,14 +36,9 @@ final class FilterCriteria implements CriteriaInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the filter callbacks to the envelopes.
|
||||
* @param Envelope[] $envelopes
|
||||
*
|
||||
* Each callback is applied in sequence, with the output of one becoming
|
||||
* the input to the next.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to filter
|
||||
*
|
||||
* @return Envelope[] The filtered notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function apply(array $envelopes): array
|
||||
{
|
||||
|
||||
@@ -8,36 +8,18 @@ use Flasher\Prime\Notification\Envelope;
|
||||
use Flasher\Prime\Stamp\HopsStamp;
|
||||
|
||||
/**
|
||||
* HopsCriteria - Filters notifications by hops count.
|
||||
*
|
||||
* This criterion filters notification envelopes based on their hops count,
|
||||
* which determines how many requests/redirects a notification should persist for.
|
||||
* It can filter for hops within a specific range (min to max) or above a minimum.
|
||||
*
|
||||
* Design pattern: Specification - Defines filter logic based on hops ranges.
|
||||
* Filters notifications by hops count.
|
||||
*/
|
||||
final readonly class HopsCriteria implements CriteriaInterface
|
||||
{
|
||||
use RangeExtractor;
|
||||
|
||||
/**
|
||||
* The minimum hops amount (inclusive).
|
||||
*/
|
||||
private readonly ?int $minAmount;
|
||||
|
||||
/**
|
||||
* The maximum hops amount (inclusive).
|
||||
*/
|
||||
private readonly ?int $maxAmount;
|
||||
|
||||
/**
|
||||
* Creates a new HopsCriteria instance.
|
||||
*
|
||||
* @param mixed $criteria The hops criteria, either:
|
||||
* - An integer (minimum hops threshold)
|
||||
* - An array with 'min' and/or 'max' keys
|
||||
*
|
||||
* @throws \InvalidArgumentException If the criteria format is invalid
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(mixed $criteria)
|
||||
{
|
||||
@@ -48,24 +30,15 @@ final readonly class HopsCriteria implements CriteriaInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters envelopes by hops count.
|
||||
* @param Envelope[] $envelopes
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to filter
|
||||
*
|
||||
* @return Envelope[] Envelopes that match the hops criteria
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function apply(array $envelopes): array
|
||||
{
|
||||
return array_filter($envelopes, fn (Envelope $e): bool => $this->match($e));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an envelope matches the hops criteria.
|
||||
*
|
||||
* @param Envelope $envelope The envelope to check
|
||||
*
|
||||
* @return bool True if the envelope matches the criteria, false otherwise
|
||||
*/
|
||||
public function match(Envelope $envelope): bool
|
||||
{
|
||||
$stamp = $envelope->get(HopsStamp::class);
|
||||
|
||||
@@ -7,27 +7,14 @@ namespace Flasher\Prime\Storage\Filter\Criteria;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* LimitCriteria - Limits the number of notifications returned.
|
||||
*
|
||||
* This criterion doesn't filter based on notification content but instead
|
||||
* limits the total number of notifications in the result set. It's useful
|
||||
* for pagination or enforcing display limits.
|
||||
*
|
||||
* Design pattern: Specification - Defines filter logic based on result count.
|
||||
* Limits the number of notifications returned.
|
||||
*/
|
||||
final readonly class LimitCriteria implements CriteriaInterface
|
||||
{
|
||||
/**
|
||||
* The maximum number of notifications to return.
|
||||
*/
|
||||
private int $limit;
|
||||
|
||||
/**
|
||||
* Creates a new LimitCriteria instance.
|
||||
*
|
||||
* @param mixed $criteria The maximum number of notifications to return
|
||||
*
|
||||
* @throws \InvalidArgumentException If the criteria is not an integer
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(mixed $criteria)
|
||||
{
|
||||
@@ -39,11 +26,9 @@ final readonly class LimitCriteria implements CriteriaInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits the number of envelopes in the result set.
|
||||
* @param Envelope[] $envelopes
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to limit
|
||||
*
|
||||
* @return Envelope[] The limited set of notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function apply(array $envelopes): array
|
||||
{
|
||||
|
||||
@@ -20,29 +20,15 @@ use Flasher\Prime\Stamp\UnlessStamp;
|
||||
use Flasher\Prime\Stamp\WhenStamp;
|
||||
|
||||
/**
|
||||
* OrderByCriteria - Sorts notifications based on stamp attributes.
|
||||
*
|
||||
* This criterion doesn't filter notifications but instead sorts them based
|
||||
* on attributes from their stamps. It supports sorting by multiple fields
|
||||
* in either ascending or descending order.
|
||||
*
|
||||
* Design pattern: Sorter - Defines sorting logic for collections.
|
||||
* Sorts notifications based on stamp attributes.
|
||||
*/
|
||||
final class OrderByCriteria implements CriteriaInterface
|
||||
{
|
||||
/**
|
||||
* Constant for ascending sort order.
|
||||
*/
|
||||
public const ASC = 'ASC';
|
||||
|
||||
/**
|
||||
* Constant for descending sort order.
|
||||
*/
|
||||
public const DESC = 'DESC';
|
||||
|
||||
/**
|
||||
* Map of friendly names to stamp class names.
|
||||
*
|
||||
* @var array<string, class-string<StampInterface>>
|
||||
*/
|
||||
private array $aliases = [
|
||||
@@ -60,20 +46,12 @@ final class OrderByCriteria implements CriteriaInterface
|
||||
];
|
||||
|
||||
/**
|
||||
* The sort ordering configuration.
|
||||
*
|
||||
* @var array<class-string<StampInterface>, "ASC"|"DESC">
|
||||
*/
|
||||
private array $orderings = [];
|
||||
|
||||
/**
|
||||
* Creates a new OrderByCriteria instance.
|
||||
*
|
||||
* @param mixed $criteria The sort criteria, either:
|
||||
* - A string with field name (defaults to ASC)
|
||||
* - An array mapping field names to directions
|
||||
*
|
||||
* @throws \InvalidArgumentException If the criteria format is invalid
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(mixed $criteria)
|
||||
{
|
||||
@@ -111,11 +89,9 @@ final class OrderByCriteria implements CriteriaInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the notification envelopes.
|
||||
* @param Envelope[] $envelopes
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to sort
|
||||
*
|
||||
* @return Envelope[] The sorted notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function apply(array $envelopes): array
|
||||
{
|
||||
|
||||
@@ -8,27 +8,14 @@ use Flasher\Prime\Notification\Envelope;
|
||||
use Flasher\Prime\Stamp\PresenterStamp;
|
||||
|
||||
/**
|
||||
* PresenterCriteria - Filters notifications by presenter compatibility.
|
||||
*
|
||||
* This criterion filters envelopes based on whether they are compatible
|
||||
* with a specific presenter format. It uses regular expression patterns
|
||||
* from PresenterStamp to determine compatibility.
|
||||
*
|
||||
* Design pattern: Specification - Defines filter logic based on presenter compatibility.
|
||||
* Filters notifications by presenter compatibility.
|
||||
*/
|
||||
final class PresenterCriteria implements CriteriaInterface
|
||||
{
|
||||
/**
|
||||
* The presenter format to check for compatibility.
|
||||
*/
|
||||
private string $presenter;
|
||||
|
||||
/**
|
||||
* Creates a new PresenterCriteria instance.
|
||||
*
|
||||
* @param mixed $criteria The presenter format name (e.g., 'html', 'json')
|
||||
*
|
||||
* @throws \InvalidArgumentException If the criteria is not a string
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(mixed $criteria)
|
||||
{
|
||||
@@ -40,14 +27,9 @@ final class PresenterCriteria implements CriteriaInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters envelopes by presenter compatibility.
|
||||
* @param Envelope[] $envelopes
|
||||
*
|
||||
* An envelope is compatible if it either has no presenter restrictions
|
||||
* or has a presenter pattern that matches the specified presenter format.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to filter
|
||||
*
|
||||
* @return Envelope[] Envelopes that are compatible with the presenter
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function apply(array $envelopes): array
|
||||
{
|
||||
|
||||
@@ -8,36 +8,18 @@ use Flasher\Prime\Notification\Envelope;
|
||||
use Flasher\Prime\Stamp\PriorityStamp;
|
||||
|
||||
/**
|
||||
* PriorityCriteria - Filters notifications by priority.
|
||||
*
|
||||
* This criterion filters notification envelopes based on their priority level.
|
||||
* It can filter for priorities within a specific range (min to max) or above
|
||||
* a minimum threshold.
|
||||
*
|
||||
* Design pattern: Specification - Defines filter logic based on priority ranges.
|
||||
* Filters notifications by priority.
|
||||
*/
|
||||
final readonly class PriorityCriteria implements CriteriaInterface
|
||||
{
|
||||
use RangeExtractor;
|
||||
|
||||
/**
|
||||
* The minimum priority threshold (inclusive).
|
||||
*/
|
||||
private ?int $minPriority;
|
||||
|
||||
/**
|
||||
* The maximum priority threshold (inclusive).
|
||||
*/
|
||||
private ?int $maxPriority;
|
||||
|
||||
/**
|
||||
* Creates a new PriorityCriteria instance.
|
||||
*
|
||||
* @param mixed $criteria The priority criteria, either:
|
||||
* - An integer (minimum priority threshold)
|
||||
* - An array with 'min' and/or 'max' keys
|
||||
*
|
||||
* @throws \InvalidArgumentException If the criteria format is invalid
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(mixed $criteria)
|
||||
{
|
||||
@@ -48,24 +30,15 @@ final readonly class PriorityCriteria implements CriteriaInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters envelopes by priority.
|
||||
* @param Envelope[] $envelopes
|
||||
*
|
||||
* @param Envelope[] $envelopes The envelopes to filter
|
||||
*
|
||||
* @return Envelope[] Envelopes that match the priority criteria
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function apply(array $envelopes): array
|
||||
{
|
||||
return array_filter($envelopes, fn (Envelope $envelope): bool => $this->match($envelope));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an envelope matches the priority criteria.
|
||||
*
|
||||
* @param Envelope $envelope The envelope to check
|
||||
*
|
||||
* @return bool True if the envelope matches the criteria, false otherwise
|
||||
*/
|
||||
public function match(Envelope $envelope): bool
|
||||
{
|
||||
$stamp = $envelope->get(PriorityStamp::class);
|
||||
|
||||
@@ -7,41 +7,21 @@ namespace Flasher\Prime\Storage\Filter\Criteria;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* StampsCriteria - Filters notifications by the presence of specific stamps.
|
||||
*
|
||||
* This criterion filters envelopes based on whether they have specific stamps.
|
||||
* It supports two filtering strategies:
|
||||
* - AND: Envelope must have all specified stamps
|
||||
* - OR: Envelope must have at least one of the specified stamps
|
||||
*
|
||||
* Design pattern: Specification - Defines filter logic based on stamp presence.
|
||||
* Filters notifications by the presence of specific stamps.
|
||||
*/
|
||||
final class StampsCriteria implements CriteriaInterface
|
||||
{
|
||||
/**
|
||||
* Strategy constant for requiring all stamps (logical AND).
|
||||
*/
|
||||
public const STRATEGY_AND = 'and';
|
||||
|
||||
/**
|
||||
* Strategy constant for requiring at least one stamp (logical OR).
|
||||
*/
|
||||
public const STRATEGY_OR = 'or';
|
||||
|
||||
/**
|
||||
* The stamps to check for.
|
||||
*
|
||||
* @var array<string, mixed>
|
||||
*/
|
||||
private array $stamps = [];
|
||||
|
||||
/**
|
||||
* Creates a new StampsCriteria instance.
|
||||
*
|
||||
* @param mixed $criteria An array of stamp class names to check for
|
||||
* @param string $strategy The matching strategy to use (AND or OR)
|
||||
*
|
||||
* @throws \InvalidArgumentException If the criteria is not an array
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(mixed $criteria, private readonly string $strategy = self::STRATEGY_AND)
|
||||
{
|
||||
@@ -55,24 +35,15 @@ final class StampsCriteria implements CriteriaInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters envelopes based on stamp presence.
|
||||
* @param Envelope[] $envelopes
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to filter
|
||||
*
|
||||
* @return Envelope[] Envelopes that match the stamp criteria
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function apply(array $envelopes): array
|
||||
{
|
||||
return array_filter($envelopes, fn (Envelope $e): bool => $this->match($e));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an envelope matches the stamps criteria.
|
||||
*
|
||||
* @param Envelope $envelope The envelope to check
|
||||
*
|
||||
* @return bool True if the envelope matches the criteria, false otherwise
|
||||
*/
|
||||
public function match(Envelope $envelope): bool
|
||||
{
|
||||
$diff = array_diff($this->stamps, array_keys($envelope->all()));
|
||||
|
||||
@@ -8,32 +8,19 @@ use Flasher\Prime\Notification\Envelope;
|
||||
use Flasher\Prime\Storage\Filter\Criteria\CriteriaInterface;
|
||||
|
||||
/**
|
||||
* Filter - Default implementation of the filter interface.
|
||||
*
|
||||
* This class implements a chain of filtering criteria that are applied in sequence
|
||||
* to notification envelopes. Each criterion refines the set of envelopes further.
|
||||
*
|
||||
* Design pattern: Chain of Responsibility - Each criterion in the chain has a chance
|
||||
* to process the envelopes, potentially filtering some out, before passing to the next.
|
||||
* Default implementation of the filter interface.
|
||||
*/
|
||||
final class Filter implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* The chain of filtering criteria.
|
||||
*
|
||||
* @var CriteriaInterface[]
|
||||
*/
|
||||
private array $criteriaChain = [];
|
||||
|
||||
/**
|
||||
* Applies the filter to an array of notification envelopes.
|
||||
* @param Envelope[] $envelopes
|
||||
*
|
||||
* This method applies each criterion in the chain sequentially,
|
||||
* passing the results from one to the next.
|
||||
*
|
||||
* @param Envelope[] $envelopes The notification envelopes to filter
|
||||
*
|
||||
* @return Envelope[] The filtered notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function apply(array $envelopes): array
|
||||
{
|
||||
@@ -44,13 +31,6 @@ final class Filter implements FilterInterface
|
||||
return $envelopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a criterion to the filter chain.
|
||||
*
|
||||
* Each added criterion will be applied in the order they were added.
|
||||
*
|
||||
* @param CriteriaInterface $criteria The criterion to add
|
||||
*/
|
||||
public function addCriteria(CriteriaInterface $criteria): void
|
||||
{
|
||||
$this->criteriaChain[] = $criteria;
|
||||
|
||||
@@ -16,31 +16,15 @@ use Flasher\Prime\Storage\Filter\Criteria\PriorityCriteria;
|
||||
use Flasher\Prime\Storage\Filter\Criteria\StampsCriteria;
|
||||
|
||||
/**
|
||||
* FilterFactory - Creates and configures filter instances.
|
||||
*
|
||||
* This class is responsible for creating filter instances with the appropriate
|
||||
* criteria based on configuration. It maintains a registry of available criteria
|
||||
* implementations that can be used to build filters.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Factory: Creates and configures filters based on configuration
|
||||
* - Registry: Maintains a collection of available criteria implementations
|
||||
* Creates and configures filter instances.
|
||||
*/
|
||||
final class FilterFactory implements FilterFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Registry of available criteria implementations.
|
||||
*
|
||||
* @var array<string, callable|CriteriaInterface>
|
||||
*/
|
||||
private array $criteria = [];
|
||||
|
||||
/**
|
||||
* Creates a new FilterFactory instance with default criteria.
|
||||
*
|
||||
* This constructor registers all the standard criteria types that can
|
||||
* be used for filtering notifications.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$criteriaClasses = [
|
||||
@@ -60,16 +44,9 @@ final class FilterFactory implements FilterFactoryInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a filter based on the provided configuration.
|
||||
* @param array<string, mixed> $config
|
||||
*
|
||||
* This method creates a new filter and adds criteria to it based on
|
||||
* the provided configuration keys and values.
|
||||
*
|
||||
* @param array<string, mixed> $config Configuration for the filter criteria
|
||||
*
|
||||
* @return Filter The created filter with configured criteria
|
||||
*
|
||||
* @throws CriteriaNotRegisteredException If a requested criterion doesn't exist
|
||||
* @throws CriteriaNotRegisteredException
|
||||
*/
|
||||
public function createFilter(array $config): Filter
|
||||
{
|
||||
@@ -84,33 +61,14 @@ final class FilterFactory implements FilterFactoryInterface
|
||||
return $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new criterion implementation.
|
||||
*
|
||||
* This method allows adding custom criteria to the factory. The criterion
|
||||
* can be provided either as an instance or as a factory callback.
|
||||
*
|
||||
* @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
|
||||
{
|
||||
$this->criteria[$name] = $criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal helper to create a criterion instance.
|
||||
*
|
||||
* This method looks up the requested criterion by name and creates an
|
||||
* instance with the provided value.
|
||||
*
|
||||
* @param string $name The name of the criterion
|
||||
* @param mixed $value The configuration value for the criterion
|
||||
*
|
||||
* @return CriteriaInterface The created criterion instance
|
||||
*
|
||||
* @throws CriteriaNotRegisteredException If the requested criterion doesn't exist
|
||||
* @throws \UnexpectedValueException If the factory doesn't return a CriteriaInterface
|
||||
* @throws CriteriaNotRegisteredException
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
private function createCriteria(string $name, mixed $value): CriteriaInterface
|
||||
{
|
||||
|
||||
@@ -8,65 +8,30 @@ use Flasher\Prime\Notification\Envelope;
|
||||
use Flasher\Prime\Stamp\IdStamp;
|
||||
use Flasher\Prime\Storage\Bag\BagInterface;
|
||||
|
||||
/**
|
||||
* Storage - Default implementation of the storage interface.
|
||||
*
|
||||
* This class provides a standard implementation of StorageInterface that
|
||||
* delegates to a storage bag. It handles identity tracking using IdStamp
|
||||
* to ensure unique envelopes in storage.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Adapter: Adapts the bag interface to the storage interface
|
||||
* - Decorator: Adds identity tracking to the underlying storage bag
|
||||
*/
|
||||
final readonly class Storage implements StorageInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new Storage instance.
|
||||
*
|
||||
* @param BagInterface $bag The underlying storage bag implementation
|
||||
*/
|
||||
public function __construct(private BagInterface $bag)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all stored notification envelopes.
|
||||
*
|
||||
* @return Envelope[] Array of all stored notification envelopes as values
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function all(): array
|
||||
{
|
||||
return array_values($this->bag->get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one or more notification envelopes to the storage.
|
||||
*
|
||||
* @param Envelope ...$envelopes One or more notification envelopes to store
|
||||
*/
|
||||
public function add(Envelope ...$envelopes): void
|
||||
{
|
||||
$this->save(...$envelopes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates one or more notification envelopes in the storage.
|
||||
*
|
||||
* @param Envelope ...$envelopes One or more notification envelopes to update
|
||||
*/
|
||||
public function update(Envelope ...$envelopes): void
|
||||
{
|
||||
$this->save(...$envelopes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes one or more notification envelopes from the storage.
|
||||
*
|
||||
* This method filters out the specified envelopes from storage based on their IDs.
|
||||
*
|
||||
* @param Envelope ...$envelopes One or more notification envelopes to remove
|
||||
*/
|
||||
public function remove(Envelope ...$envelopes): void
|
||||
{
|
||||
$envelopes = IdStamp::indexById($envelopes);
|
||||
@@ -76,22 +41,11 @@ final readonly class Storage implements StorageInterface
|
||||
$this->bag->set(array_values($envelopes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all notification envelopes from the storage.
|
||||
*/
|
||||
public function clear(): void
|
||||
{
|
||||
$this->bag->set([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal helper method to save envelopes.
|
||||
*
|
||||
* This method indexes envelopes by their IDs, merges them with existing envelopes,
|
||||
* and updates the storage bag. New envelopes replace existing ones with the same ID.
|
||||
*
|
||||
* @param Envelope ...$envelopes One or more notification envelopes to save
|
||||
*/
|
||||
private function save(Envelope ...$envelopes): void
|
||||
{
|
||||
$envelopes = IdStamp::indexById($envelopes);
|
||||
|
||||
@@ -6,51 +6,18 @@ namespace Flasher\Prime\Storage;
|
||||
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
|
||||
/**
|
||||
* StorageInterface - Core contract for notification storage implementations.
|
||||
*
|
||||
* This interface defines the essential operations for managing notifications
|
||||
* in a storage system. Implementations can range from simple in-memory arrays
|
||||
* to persistent storage like sessions, databases, or files.
|
||||
*
|
||||
* Design pattern: Repository - Defines a common interface for storing and
|
||||
* retrieving notification envelopes from various storage backends.
|
||||
*/
|
||||
interface StorageInterface
|
||||
{
|
||||
/**
|
||||
* Retrieves all stored notification envelopes.
|
||||
*
|
||||
* @return Envelope[] Array of all stored notification envelopes
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function all(): array;
|
||||
|
||||
/**
|
||||
* Adds one or more notification envelopes to the storage.
|
||||
*
|
||||
* @param Envelope ...$envelopes One or more notification envelopes to store
|
||||
*/
|
||||
public function add(Envelope ...$envelopes): void;
|
||||
|
||||
/**
|
||||
* Updates one or more notification envelopes in the storage.
|
||||
*
|
||||
* This method should replace existing envelopes with the same identifiers,
|
||||
* or add them if they don't exist yet.
|
||||
*
|
||||
* @param Envelope ...$envelopes One or more notification envelopes to update
|
||||
*/
|
||||
public function update(Envelope ...$envelopes): void;
|
||||
|
||||
/**
|
||||
* Removes one or more notification envelopes from the storage.
|
||||
*
|
||||
* @param Envelope ...$envelopes One or more notification envelopes to remove
|
||||
*/
|
||||
public function remove(Envelope ...$envelopes): void;
|
||||
|
||||
/**
|
||||
* Clears all notification envelopes from the storage.
|
||||
*/
|
||||
public function clear(): void;
|
||||
}
|
||||
|
||||
@@ -12,30 +12,13 @@ use Flasher\Prime\EventDispatcher\Event\PostUpdateEvent;
|
||||
use Flasher\Prime\EventDispatcher\Event\RemoveEvent;
|
||||
use Flasher\Prime\EventDispatcher\Event\UpdateEvent;
|
||||
use Flasher\Prime\EventDispatcher\EventDispatcherInterface;
|
||||
use Flasher\Prime\Exception\CriteriaNotRegisteredException;
|
||||
use Flasher\Prime\Notification\Envelope;
|
||||
use Flasher\Prime\Storage\Filter\FilterFactoryInterface;
|
||||
|
||||
/**
|
||||
* StorageManager - Manages notification storage with event dispatch and filtering.
|
||||
*
|
||||
* This class orchestrates the storage of notifications, dispatching events before and
|
||||
* after storage operations, and filtering notifications based on criteria. It acts as
|
||||
* a mediator between the storage implementation and the rest of the system.
|
||||
*
|
||||
* Design patterns:
|
||||
* - Mediator: Coordinates operations between storage, filters, and event dispatcher
|
||||
* - Decorator: Adds event dispatching and filtering capabilities to the core storage
|
||||
*/
|
||||
final readonly class StorageManager implements StorageManagerInterface
|
||||
{
|
||||
/**
|
||||
* Creates a new StorageManager instance.
|
||||
*
|
||||
* @param StorageInterface $storage The underlying storage implementation
|
||||
* @param EventDispatcherInterface $eventDispatcher Event dispatcher for notification lifecycle events
|
||||
* @param FilterFactoryInterface $filterFactory Factory for creating notification filters
|
||||
* @param array<string, mixed> $criteria Default criteria for filtering notifications
|
||||
* @param array<string, mixed> $criteria
|
||||
*/
|
||||
public function __construct(
|
||||
private StorageInterface $storage,
|
||||
@@ -46,8 +29,6 @@ final readonly class StorageManager implements StorageManagerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all stored envelopes.
|
||||
*
|
||||
* @return Envelope[]
|
||||
*/
|
||||
public function all(): array
|
||||
@@ -56,17 +37,9 @@ final readonly class StorageManager implements StorageManagerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters notifications by criteria.
|
||||
*
|
||||
* This method combines default criteria with provided criteria,
|
||||
* creates a filter using the filter factory, and applies it to envelopes.
|
||||
* Before applying the filter, it dispatches a FilterEvent to allow modification.
|
||||
*
|
||||
* @param array<string, mixed> $criteria
|
||||
*
|
||||
* @return Envelope[]
|
||||
*
|
||||
* @throws CriteriaNotRegisteredException
|
||||
*/
|
||||
public function filter(array $criteria = []): array
|
||||
{
|
||||
@@ -79,12 +52,6 @@ final readonly class StorageManager implements StorageManagerInterface
|
||||
return $event->getFilter()->apply($event->getEnvelopes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds notification envelopes to storage.
|
||||
*
|
||||
* Before adding envelopes, it dispatches a PersistEvent to allow modification
|
||||
* of the envelopes. After storage, it dispatches a PostPersistEvent.
|
||||
*/
|
||||
public function add(Envelope ...$envelopes): void
|
||||
{
|
||||
$event = new PersistEvent($envelopes);
|
||||
@@ -96,12 +63,6 @@ final readonly class StorageManager implements StorageManagerInterface
|
||||
$this->eventDispatcher->dispatch($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates notification envelopes in storage.
|
||||
*
|
||||
* Before updating envelopes, it dispatches an UpdateEvent to allow modification
|
||||
* of the envelopes. After update, it dispatches a PostUpdateEvent.
|
||||
*/
|
||||
public function update(Envelope ...$envelopes): void
|
||||
{
|
||||
$event = new UpdateEvent($envelopes);
|
||||
@@ -113,13 +74,6 @@ final readonly class StorageManager implements StorageManagerInterface
|
||||
$this->eventDispatcher->dispatch($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes notification envelopes from storage.
|
||||
*
|
||||
* Before removal, it dispatches a RemoveEvent to allow listeners to modify
|
||||
* which envelopes should be removed or kept. After removal, it dispatches
|
||||
* a PostRemoveEvent.
|
||||
*/
|
||||
public function remove(Envelope ...$envelopes): void
|
||||
{
|
||||
$event = new RemoveEvent($envelopes);
|
||||
@@ -132,9 +86,6 @@ final readonly class StorageManager implements StorageManagerInterface
|
||||
$this->eventDispatcher->dispatch($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all notification envelopes from storage.
|
||||
*/
|
||||
public function clear(): void
|
||||
{
|
||||
$this->storage->clear();
|
||||
|
||||
Reference in New Issue
Block a user