Files
php-flasher/src/Laravel/FlasherServiceProvider.php
T
Younes ENNAJI d7234c64a2 Simplify verbose PHPDoc class descriptions across 76 files
Remove descriptive class/interface-level documentation that duplicates
what the class/interface names already convey, while keeping all
type annotations (@param, @return, @var, @throws, @phpstan-, @mixin,
@template, @internal).

Files modified:
- Symfony integration (18 files): Attribute, Translation, Template,
  Component, Storage, Support, Http, Profiler, Command, Twig,
  EventListener, FlasherSymfonyBundle
- Laravel integration (13 files): ServiceProvider, Storage, Middleware,
  Http, Facade, Template, Translation, Command, Component, EventListener
- Prime/EventDispatcher (17 files): Events and EventListeners
- Prime/Storage (11 files): Filter/Criteria and Bag interfaces
- Prime/Stamp (4 files): Interface and stamp classes
- Prime/Factory (5 files): Factory interfaces and implementations
- Prime/Notification (2 files): Envelope and Notification
- Prime/Support/Traits (1 file): ForwardsCalls
2026-01-16 01:46:44 +01:00

321 lines
11 KiB
PHP

<?php
declare(strict_types=1);
namespace Flasher\Laravel;
use Flasher\Laravel\Command\InstallCommand;
use Flasher\Laravel\Component\FlasherComponent;
use Flasher\Laravel\EventListener\LivewireListener;
use Flasher\Laravel\EventListener\OctaneListener;
use Flasher\Laravel\Middleware\FlasherMiddleware;
use Flasher\Laravel\Middleware\SessionMiddleware;
use Flasher\Laravel\Storage\SessionBag;
use Flasher\Laravel\Support\PluginServiceProvider;
use Flasher\Laravel\Template\BladeTemplateEngine;
use Flasher\Laravel\Translation\Translator;
use Flasher\Prime\Asset\AssetManager;
use Flasher\Prime\Container\FlasherContainer;
use Flasher\Prime\EventDispatcher\EventDispatcher;
use Flasher\Prime\EventDispatcher\EventListener\ApplyPresetListener;
use Flasher\Prime\EventDispatcher\EventListener\NotificationLoggerListener;
use Flasher\Prime\EventDispatcher\EventListener\TranslationListener;
use Flasher\Prime\Factory\NotificationFactoryLocator;
use Flasher\Prime\Flasher;
use Flasher\Prime\FlasherInterface;
use Flasher\Prime\Http\Csp\ContentSecurityPolicyHandler;
use Flasher\Prime\Http\Csp\NonceGenerator;
use Flasher\Prime\Http\RequestExtension;
use Flasher\Prime\Http\ResponseExtension;
use Flasher\Prime\Plugin\FlasherPlugin;
use Flasher\Prime\Response\Resource\ResourceManager;
use Flasher\Prime\Response\ResponseManager;
use Flasher\Prime\Storage\Filter\FilterFactory;
use Flasher\Prime\Storage\Storage;
use Flasher\Prime\Storage\StorageManager;
use Illuminate\Container\Container;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Http\Kernel as HttpKernel;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Console\AboutCommand;
use Illuminate\View\Compilers\BladeCompiler;
use Laravel\Octane\Events\RequestReceived;
use Livewire\LivewireManager;
final class FlasherServiceProvider extends PluginServiceProvider
{
public function register(): void
{
$this->plugin = $this->createPlugin();
$this->registerConfiguration();
$this->registerFlasher();
$this->registerFactoryLocator();
$this->registerResponseManager();
$this->registerTemplateEngine();
$this->registerResourceManager();
$this->registerStorageManager();
$this->registerEventDispatcher();
$this->registerCspHandler();
$this->registerAssetManager();
}
public function boot(): void
{
FlasherContainer::from(static fn () => Container::getInstance());
$this->registerCommands();
$this->loadTranslationsFrom(__DIR__.'/Translation/lang', 'flasher');
$this->registerMiddlewares();
$this->callAfterResolving('blade.compiler', $this->registerBladeDirectives(...));
$this->registerLivewire();
}
public function createPlugin(): FlasherPlugin
{
return new FlasherPlugin();
}
private function registerFlasher(): void
{
$this->app->singleton('flasher', static function (Application $app) {
$config = $app->make('config');
$default = $config->get('flasher.default');
$factoryLocator = $app->make('flasher.factory_locator');
$responseManager = $app->make('flasher.response_manager');
$storageManager = $app->make('flasher.storage_manager');
return new Flasher($default, $factoryLocator, $responseManager, $storageManager);
});
$this->app->alias('flasher', Flasher::class);
$this->app->bind(FlasherInterface::class, 'flasher');
}
private function registerFactoryLocator(): void
{
$this->app->singleton('flasher.factory_locator', static function () {
return new NotificationFactoryLocator();
});
}
private function registerResponseManager(): void
{
$this->app->singleton('flasher.response_manager', static function (Application $app) {
$resourceManager = $app->make('flasher.resource_manager');
$storageManager = $app->make('flasher.storage_manager');
$eventDispatcher = $app->make('flasher.event_dispatcher');
return new ResponseManager($resourceManager, $storageManager, $eventDispatcher);
});
}
private function registerTemplateEngine(): void
{
$this->app->singleton('flasher.template_engine', static function (Application $app) {
$viewFactory = $app->make('view');
return new BladeTemplateEngine($viewFactory);
});
}
private function registerResourceManager(): void
{
$this->app->singleton('flasher.resource_manager', static function (Application $app) {
$config = $app->make('config');
$templateEngine = $app->make('flasher.template_engine');
$assetManager = $app->make('flasher.asset_manager');
$mainScript = $config->get('flasher.main_script');
$resources = [];
foreach ($config->get('flasher.plugins') as $name => $options) {
$resources[$name] = $options;
}
foreach ($config->get('flasher.themes') as $name => $options) {
$resources['theme.'.$name] = $options;
}
return new ResourceManager($templateEngine, $assetManager, $mainScript, $resources);
});
}
private function registerStorageManager(): void
{
$this->app->singleton('flasher.storage_manager', static function (Application $app) {
$config = $app->make('config');
$storageBag = new Storage(new SessionBag($app->make('session')));
$eventDispatcher = $app->make('flasher.event_dispatcher');
$filterFactory = new FilterFactory();
$criteria = $config->get('flasher.filter');
return new StorageManager($storageBag, $eventDispatcher, $filterFactory, $criteria);
});
}
private function registerEventDispatcher(): void
{
$this->app->singleton('flasher.notification_logger_listener', fn () => new NotificationLoggerListener());
$this->app->singleton('flasher.event_dispatcher', static function (Application $app) {
$config = $app->make('config');
$eventDispatcher = new EventDispatcher();
$translatorListener = new TranslationListener(new Translator($app->make('translator')));
$eventDispatcher->addListener($translatorListener);
$presetListener = new ApplyPresetListener($config->get('flasher.presets'));
$eventDispatcher->addListener($presetListener);
$eventDispatcher->addListener($app->make('flasher.notification_logger_listener'));
return $eventDispatcher;
});
$this->callAfterResolving(Dispatcher::class, function (Dispatcher $dispatcher) {
$dispatcher->listen(RequestReceived::class, OctaneListener::class);
});
}
private function registerCommands(): void
{
if (!$this->app->runningInConsole()) {
return;
}
$this->registerAboutCommand();
$this->app->singleton(InstallCommand::class, static function (Application $app) {
$assetManager = $app->make('flasher.asset_manager');
return new InstallCommand($assetManager);
});
$this->commands(InstallCommand::class);
}
private function registerAboutCommand(): void
{
if (!class_exists(AboutCommand::class)) {
return;
}
$pluginServiceProviders = array_filter(array_keys($this->app->getLoadedProviders()), function ($provider) {
return is_a($provider, PluginServiceProvider::class, true);
});
$factories = array_map(function ($providerClass) {
/** @var PluginServiceProvider $provider */
$provider = $this->app->getProvider($providerClass);
$plugin = $provider->createPlugin();
return $plugin->getAlias();
}, $pluginServiceProviders);
AboutCommand::add('PHPFlasher', [
'Version' => Flasher::VERSION,
'Factories' => implode(' <fg=gray;options=bold>/</> ', array_map(fn ($factory) => \sprintf('<fg=yellow;options=bold>%s</>', $factory), $factories)),
]);
}
private function registerMiddlewares(): void
{
$this->registerSessionMiddleware();
$this->registerFlasherMiddleware();
}
private function registerFlasherMiddleware(): void
{
if (!$this->getConfig('inject_assets')) {
return;
}
$this->app->singleton(FlasherMiddleware::class, static function (Application $app) {
$config = $app->make('config');
$flasher = $app->make('flasher');
$cspHandler = $app->make('flasher.csp_handler');
$excludedPaths = $config->get('flasher.excluded_paths', []) ?: [];
return new FlasherMiddleware(new ResponseExtension($flasher, $cspHandler, $excludedPaths));
});
$this->pushMiddlewareToGroup(FlasherMiddleware::class);
}
private function registerSessionMiddleware(): void
{
if (!$this->getConfig('flash_bag')) {
return;
}
$this->app->singleton(SessionMiddleware::class, static function (Application $app) {
$config = $app->make('config');
$flasher = $app->make('flasher');
$mapping = $config->get('flasher.flash_bag', []) ?: [];
return new SessionMiddleware(new RequestExtension($flasher, $mapping));
});
$this->pushMiddlewareToGroup(SessionMiddleware::class);
}
private function pushMiddlewareToGroup(string $middleware): void
{
$this->callAfterResolving(HttpKernel::class, function (HttpKernel $kernel) use ($middleware) {
$kernel->appendMiddlewareToGroup('web', $middleware);
});
}
private function registerCspHandler(): void
{
$this->app->singleton('flasher.csp_handler', static function () {
return new ContentSecurityPolicyHandler(new NonceGenerator());
});
}
private function registerAssetManager(): void
{
$this->app->singleton('flasher.asset_manager', static function () {
$publicDir = public_path('/');
$manifestPath = public_path('vendor'.\DIRECTORY_SEPARATOR.'flasher'.\DIRECTORY_SEPARATOR.'manifest.json');
return new AssetManager($publicDir, $manifestPath);
});
}
private function registerBladeDirectives(BladeCompiler $blade): void
{
$blade->directive('flasher_render', function (string $expression = '') {
if (!empty($expression) && str_starts_with($expression, '(') && str_ends_with($expression, ')')) {
$expression = substr($expression, 1, -1);
}
return "<?php app('flasher')->render('html', $expression); ?>";
});
$blade->component(FlasherComponent::class, 'flasher');
}
private function registerLivewire(): void
{
if (class_exists(LivewireManager::class) && !$this->app->bound('livewire')) {
return;
}
$this->callAfterResolving('livewire', function (LivewireManager $livewire, Application $app) {
$flasher = $app->make('flasher');
$cspHandler = $app->make('flasher.csp_handler');
$request = fn () => $app->make('request');
$livewire->listen('dehydrate', new LivewireListener($livewire, $flasher, $cspHandler, $request));
});
}
}