From c4429c342401703188f0d949b5302e8011691b38 Mon Sep 17 00:00:00 2001 From: Stanislau Komar <stanislau_komar@epam.com> Date: Fri, 25 Nov 2022 20:55:46 +0400 Subject: [PATCH] v1.1 release --- composer.json | 6 +- src/Business/Factory/EventEmitterFactory.php | 33 ++++++++++ .../Locator/EventListenerClassLocator.php | 32 ++++++++++ .../EventListenerClassLocatorFactory.php | 27 ++++++++ ...ntListenerClassLocatorFactoryInterface.php | 11 ++++ .../EventListenerClassLocatorInterface.php | 13 ++++ .../Provider/ApplicationListenerProvider.php | 61 +++++++++++++++++++ src/Business/Provider/ProviderFactory.php | 48 +++++++++++++++ .../Provider/ProviderFactoryInterface.php | 13 ++++ src/EventEmitterPlugin.php | 57 +++++++++++++++-- 10 files changed, 294 insertions(+), 7 deletions(-) create mode 100644 src/Business/Factory/EventEmitterFactory.php create mode 100644 src/Business/Locator/EventListenerClassLocator.php create mode 100644 src/Business/Locator/EventListenerClassLocatorFactory.php create mode 100644 src/Business/Locator/EventListenerClassLocatorFactoryInterface.php create mode 100644 src/Business/Locator/EventListenerClassLocatorInterface.php create mode 100644 src/Business/Provider/ApplicationListenerProvider.php create mode 100644 src/Business/Provider/ProviderFactory.php create mode 100644 src/Business/Provider/ProviderFactoryInterface.php diff --git a/composer.json b/composer.json index b876be0..ee3e380 100755 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "Micro Framework: Application plugin to provide an event emitter", "type": "library", "license": "MIT", - "version": "1.0", + "version": "1.1", "autoload": { "psr-4": { "Micro\\Plugin\\EventEmitter\\": "src/" @@ -17,6 +17,8 @@ ], "require": { "micro/event-emitter": "^1", - "micro/kernel": "^1" + "micro/plugin-locator": "^1", + "micro/kernel": "^1", + "micro/autowire": "^1" } } diff --git a/src/Business/Factory/EventEmitterFactory.php b/src/Business/Factory/EventEmitterFactory.php new file mode 100644 index 0000000..2d310e2 --- /dev/null +++ b/src/Business/Factory/EventEmitterFactory.php @@ -0,0 +1,33 @@ +<?php + +namespace Micro\Plugin\EventEmitter\Business\Factory; + +use Micro\Component\EventEmitter\EventEmitterInterface; +use Micro\Component\EventEmitter\EventEmitterFactory as BaseEventEmitterFactory; +use Micro\Plugin\EventEmitter\Business\Provider\ProviderFactoryInterface; + +class EventEmitterFactory extends BaseEventEmitterFactory +{ + /** + * @param ProviderFactoryInterface $providerFactoryInterface + */ + public function __construct( + private readonly ProviderFactoryInterface $providerFactoryInterface + ) + { + } + + /** + * {@inheritDoc} + */ + public function create(): EventEmitterInterface + { + $emitter = parent::create(); + + $emitter->addListenerProvider( + $this->providerFactoryInterface->create() + ); + + return $emitter; + } +} \ No newline at end of file diff --git a/src/Business/Locator/EventListenerClassLocator.php b/src/Business/Locator/EventListenerClassLocator.php new file mode 100644 index 0000000..8569e5d --- /dev/null +++ b/src/Business/Locator/EventListenerClassLocator.php @@ -0,0 +1,32 @@ +<?php + +namespace Micro\Plugin\EventEmitter\Business\Locator; + +use Micro\Component\EventEmitter\EventListenerInterface; +use Micro\Plugin\Locator\Facade\LocatorFacadeInterface; + +class EventListenerClassLocator implements EventListenerClassLocatorInterface +{ + /** + * @param LocatorFacadeInterface $locatorFacade + */ + public function __construct( + private readonly LocatorFacadeInterface $locatorFacade + ) + { + } + + /** + * {@inheritDoc} + */ + public function lookupListenerClasses(): iterable + { + $listenerClassCollection = []; + + foreach ($this->locatorFacade->lookup(EventListenerInterface::class) as $listenerClass) { + $listenerClassCollection[] = $listenerClass; + } + + return $listenerClassCollection; + } +} \ No newline at end of file diff --git a/src/Business/Locator/EventListenerClassLocatorFactory.php b/src/Business/Locator/EventListenerClassLocatorFactory.php new file mode 100644 index 0000000..b1a5db3 --- /dev/null +++ b/src/Business/Locator/EventListenerClassLocatorFactory.php @@ -0,0 +1,27 @@ +<?php + +namespace Micro\Plugin\EventEmitter\Business\Locator; + +use Micro\Plugin\Locator\Facade\LocatorFacadeInterface; + +class EventListenerClassLocatorFactory implements EventListenerClassLocatorFactoryInterface +{ + /** + * @param LocatorFacadeInterface $locatorFacade + */ + public function __construct( + private readonly LocatorFacadeInterface $locatorFacade + ) + { + } + + /** + * {@inheritDoc} + */ + public function create(): EventListenerClassLocatorInterface + { + return new EventListenerClassLocator( + $this->locatorFacade, + ); + } +} \ No newline at end of file diff --git a/src/Business/Locator/EventListenerClassLocatorFactoryInterface.php b/src/Business/Locator/EventListenerClassLocatorFactoryInterface.php new file mode 100644 index 0000000..bd3346a --- /dev/null +++ b/src/Business/Locator/EventListenerClassLocatorFactoryInterface.php @@ -0,0 +1,11 @@ +<?php + +namespace Micro\Plugin\EventEmitter\Business\Locator; + +interface EventListenerClassLocatorFactoryInterface +{ + /** + * @return EventListenerClassLocatorInterface + */ + public function create(): EventListenerClassLocatorInterface; +} \ No newline at end of file diff --git a/src/Business/Locator/EventListenerClassLocatorInterface.php b/src/Business/Locator/EventListenerClassLocatorInterface.php new file mode 100644 index 0000000..50983c5 --- /dev/null +++ b/src/Business/Locator/EventListenerClassLocatorInterface.php @@ -0,0 +1,13 @@ +<?php + +namespace Micro\Plugin\EventEmitter\Business\Locator; + +use Micro\Component\EventEmitter\EventListenerInterface; + +interface EventListenerClassLocatorInterface +{ + /** + * @return iterable<class-string<EventListenerInterface>> + */ + public function lookupListenerClasses(): iterable; +} \ No newline at end of file diff --git a/src/Business/Provider/ApplicationListenerProvider.php b/src/Business/Provider/ApplicationListenerProvider.php new file mode 100644 index 0000000..af31d18 --- /dev/null +++ b/src/Business/Provider/ApplicationListenerProvider.php @@ -0,0 +1,61 @@ +<?php + +namespace Micro\Plugin\EventEmitter\Business\Provider; + +use Micro\Component\DependencyInjection\Autowire\AutowireHelperInterface; +use Micro\Component\EventEmitter\EventInterface; +use Micro\Component\EventEmitter\ListenerProviderInterface; + +class ApplicationListenerProvider implements ListenerProviderInterface +{ + /** + * @param AutowireHelperInterface $autowireHelper + * @param iterable $eventListenersClasses + */ + public function __construct( + private readonly AutowireHelperInterface $autowireHelper, + private readonly iterable $eventListenersClasses, + ) + { + } + + /** + * {@inheritDoc} + */ + public function getListenersForEvent(EventInterface $event): iterable + { + foreach ($this->getEventListeners() as $listenerClass) { + if(!$listenerClass::supports($event)) { + continue; + } + + $callback = $this->autowireHelper->autowire($listenerClass); + + yield $callback(); + } + } + + /** + * {@inheritDoc} + */ + public function __toString(): string + { + return $this->getName() ?? get_class($this); + } + + /** + * {@inheritDoc} + */ + public function getName(): string + { + return 'events.listener_provider.default'; + } + + /** + * {@inheritDoc} + */ + public function getEventListeners(): iterable + { + return $this->eventListenersClasses; + } +} \ No newline at end of file diff --git a/src/Business/Provider/ProviderFactory.php b/src/Business/Provider/ProviderFactory.php new file mode 100644 index 0000000..d4de22b --- /dev/null +++ b/src/Business/Provider/ProviderFactory.php @@ -0,0 +1,48 @@ +<?php + +namespace Micro\Plugin\EventEmitter\Business\Provider; + +use Micro\Component\DependencyInjection\Autowire\AutowireHelperFactoryInterface; +use Micro\Component\DependencyInjection\Autowire\AutowireHelperInterface; +use Micro\Component\EventEmitter\EventListenerInterface; +use Micro\Component\EventEmitter\ListenerProviderInterface; +use Micro\Plugin\EventEmitter\Business\Locator\EventListenerClassLocatorFactoryInterface; + +class ProviderFactory implements ProviderFactoryInterface +{ + /** + * @param AutowireHelperInterface $autowireHelper + * @param EventListenerClassLocatorFactoryInterface $eventListenerClassLocatorFactory + */ + public function __construct( + private readonly AutowireHelperInterface $autowireHelper, + private readonly EventListenerClassLocatorFactoryInterface $eventListenerClassLocatorFactory + ) + { + } + + /** + *{@inheritDoc} + */ + public function create(): ListenerProviderInterface + { + $listeners = $this->eventListenerClassLocatorFactory + ->create() + ->lookupListenerClasses(); + + return $this->createProvider($listeners); + } + + /** + * @param iterable<class-string<EventListenerInterface>> $listeners + * + * @return ListenerProviderInterface + */ + protected function createProvider(iterable $listeners): ListenerProviderInterface + { + return new ApplicationListenerProvider( + $this->autowireHelper, + $listeners + ); + } +} \ No newline at end of file diff --git a/src/Business/Provider/ProviderFactoryInterface.php b/src/Business/Provider/ProviderFactoryInterface.php new file mode 100644 index 0000000..aad8b51 --- /dev/null +++ b/src/Business/Provider/ProviderFactoryInterface.php @@ -0,0 +1,13 @@ +<?php + +namespace Micro\Plugin\EventEmitter\Business\Provider; + +use Micro\Component\EventEmitter\ListenerProviderInterface; + +interface ProviderFactoryInterface +{ + /** + * @return ListenerProviderInterface + */ + public function create(): ListenerProviderInterface; +} \ No newline at end of file diff --git a/src/EventEmitterPlugin.php b/src/EventEmitterPlugin.php index 43099d5..f0105ee 100755 --- a/src/EventEmitterPlugin.php +++ b/src/EventEmitterPlugin.php @@ -2,20 +2,44 @@ namespace Micro\Plugin\EventEmitter; +use Micro\Component\DependencyInjection\Autowire\AutowireHelperFactory; +use Micro\Component\DependencyInjection\Autowire\AutowireHelperFactoryInterface; +use Micro\Component\DependencyInjection\Autowire\AutowireHelperInterface; use Micro\Component\DependencyInjection\Container; -use Micro\Component\EventEmitter\EventEmitterFactory; use Micro\Component\EventEmitter\EventEmitterFactoryInterface; -use Micro\Framework\Kernel\Plugin\AbstractPlugin; +use Micro\Framework\Kernel\Plugin\DependencyProviderInterface; use Micro\Plugin\EventEmitter\Business\Facade\EventsFacade; +use Micro\Plugin\EventEmitter\Business\Factory\EventEmitterFactory; +use Micro\Plugin\EventEmitter\Business\Locator\EventListenerClassLocatorFactory; +use Micro\Plugin\EventEmitter\Business\Locator\EventListenerClassLocatorFactoryInterface; +use Micro\Plugin\EventEmitter\Business\Provider\ProviderFactory; +use Micro\Plugin\EventEmitter\Business\Provider\ProviderFactoryInterface; +use Micro\Plugin\Locator\Facade\LocatorFacadeInterface; -class EventEmitterPlugin extends AbstractPlugin +class EventEmitterPlugin implements DependencyProviderInterface { + /** + * @var LocatorFacadeInterface + */ + private readonly LocatorFacadeInterface $locatorFacade; + + /** + * @var AutowireHelperInterface $autowireHelper + */ + private readonly AutowireHelperInterface $autowireHelper; + /** * {@inheritDoc} */ public function provideDependencies(Container $container): void { - $container->register(EventsFacadeInterface::class, function (Container $container) { + $container->register(EventsFacadeInterface::class, function ( + AutowireHelperInterface $autowireHelper, + LocatorFacadeInterface $locatorFacade, + ) { + $this->locatorFacade = $locatorFacade; + $this->autowireHelper = $autowireHelper; + return $this->createFacade(); }); } @@ -33,6 +57,29 @@ protected function createFacade(): EventsFacadeInterface */ protected function createEventEmitterFactory(): EventEmitterFactoryInterface { - return new EventEmitterFactory(); + return new EventEmitterFactory( + $this->createProviderFactory() + ); + } + + /** + * @return ProviderFactoryInterface + */ + protected function createProviderFactory(): ProviderFactoryInterface + { + return new ProviderFactory( + $this->autowireHelper, + $this->createEventListenerClassLocatorFactory(), + ); + } + + /** + * @return EventListenerClassLocatorFactoryInterface + */ + protected function createEventListenerClassLocatorFactory(): EventListenerClassLocatorFactoryInterface + { + return new EventListenerClassLocatorFactory( + $this->locatorFacade + ); } }