diff --git a/src/FrameworkBridge/Symfony/Config/services.php b/src/FrameworkBridge/Symfony/Config/services.php index 338854d..3954ad7 100644 --- a/src/FrameworkBridge/Symfony/Config/services.php +++ b/src/FrameworkBridge/Symfony/Config/services.php @@ -3,7 +3,6 @@ declare(strict_types=1); use OpenClassrooms\ServiceProxy\FrameworkBridge\Symfony\Messenger\Transport\Serialization\MessageSerializer; -use OpenClassrooms\ServiceProxy\FrameworkBridge\Symfony\Subscriber\ServiceProxySubscriber; use OpenClassrooms\ServiceProxy\Handler\Impl\Cache\SymfonyCacheHandler; use OpenClassrooms\ServiceProxy\Invoker\Impl\AggregateMethodInvoker; use OpenClassrooms\ServiceProxy\ProxyFactory; @@ -65,13 +64,4 @@ ->autowire() ->autoconfigure() ; - - $services->set(ServiceProxySubscriber::class) - ->public() - ->args([ - tagged_iterator('openclassrooms.service_proxy'), - tagged_iterator('openclassrooms.service_proxy.start_up_interceptor'), - service('annotation_reader')->nullOnInvalid(), - ]) - ->tag('kernel.event_subscriber'); }; diff --git a/src/FrameworkBridge/Symfony/DependencyInjection/Compiler/ServiceProxyPass.php b/src/FrameworkBridge/Symfony/DependencyInjection/Compiler/ServiceProxyPass.php index 4c066c3..2c18302 100644 --- a/src/FrameworkBridge/Symfony/DependencyInjection/Compiler/ServiceProxyPass.php +++ b/src/FrameworkBridge/Symfony/DependencyInjection/Compiler/ServiceProxyPass.php @@ -4,6 +4,10 @@ namespace OpenClassrooms\ServiceProxy\FrameworkBridge\Symfony\DependencyInjection\Compiler; +use Doctrine\Common\Annotations\AnnotationException; +use Doctrine\Common\Annotations\AnnotationReader; +use OpenClassrooms\ServiceProxy\Attribute\Event\Listen; +use OpenClassrooms\ServiceProxy\Model\Request\Method; use OpenClassrooms\ServiceProxy\ProxyFactory; use Symfony\Component\DependencyInjection\Compiler\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; @@ -23,6 +27,7 @@ public function process(ContainerBuilder $container): void $this->compiler = $container->getCompiler(); $this->buildServiceProxies(); + $this->addStartupListeners(); } private function buildServiceProxies(): void @@ -49,4 +54,57 @@ private function buildServiceProxyFactoryDefinition(string $taggedServiceName): $factoryDefinition->setLazy($definition->isLazy()); $factoryDefinition->setTags($definition->getTags()); } + + private function addStartupListeners(): void + { + if (!$this->container->findDefinition('event_dispatcher')) { + return; + } + + $eventDispatcherDefinition = $this->container->findDefinition('event_dispatcher'); + $proxies = $this->container->findTaggedServiceIds('openclassrooms.service_proxy'); + + foreach (\array_keys($proxies) as $proxy) { + $definition = $this->container->findDefinition($proxy); + $class = $definition->getClass(); + $instanceRef = new \ReflectionClass($class); + $methods = $instanceRef->getMethods(\ReflectionMethod::IS_PUBLIC); + foreach ($methods as $methodRef) { + + try { + $methodAnnotations = (new AnnotationReader())->getMethodAnnotations($methodRef); + } catch (AnnotationException) { + continue; + } + + $method = Method::create( + $methodRef, + $methodAnnotations, + ); + + if ($method->hasAttribute(Listen::class)) { + $attributes = $method->getAttributesInstances(Listen::class); + + foreach ($attributes as $attribute) { + /** + * @var Listen $attribute + */ + $name = $attribute->name; + $transport = $attribute->transport; + + if ($transport !== null) { + $name .= '.' . $transport->value; + } + + $eventDispatcherDefinition->addMethodCall('addListener', [ + $name, + [new Reference($proxy), $method->getName()], + $attribute->priority + ]); + } + + } + } + } + } } diff --git a/src/FrameworkBridge/Symfony/Subscriber/ServiceProxySubscriber.php b/src/FrameworkBridge/Symfony/Subscriber/ServiceProxySubscriber.php deleted file mode 100644 index 1129550..0000000 --- a/src/FrameworkBridge/Symfony/Subscriber/ServiceProxySubscriber.php +++ /dev/null @@ -1,104 +0,0 @@ - - */ - private array $startUpInterceptors; - - private Reader $annotationReader; - - /** - * @param iterable $startUpInterceptors - * @param iterable $proxies - * - * @throws \Doctrine\Common\Annotations\AnnotationException - */ - public function __construct( - private readonly iterable $proxies, - iterable $startUpInterceptors, - Reader|null $annotationReader = null, - ) { - if (!\is_array($startUpInterceptors)) { - $this->startUpInterceptors = iterator_to_array($startUpInterceptors); - } - - $this->annotationReader = $annotationReader ?? new AnnotationReader(); - } - - /** - * @return array - */ - public static function getSubscribedEvents(): array - { - return [ - 'kernel.request' => 'startUp', - ]; - } - - public function startUp(RequestEvent $event): void - { - if (\count($this->startUpInterceptors) === 0) { - return; - } - - usort( - $this->startUpInterceptors, - static fn ( - StartUpInterceptor $a, - StartUpInterceptor $b - ) => $a->getStartUpPriority() <=> $b->getStartUpPriority() - ); - foreach ($this->getInstances() as $instance) { - foreach ($this->startUpInterceptors as $interceptor) { - if ($interceptor->supportsStartUp($instance)) { - $interceptor->startUp($instance); - } - } - } - } - - /** - * @return iterable - */ - public function getInstances(): iterable - { - foreach ($this->proxies as $proxy) { - $object = $proxy; - if ($proxy instanceof ValueHolderInterface) { - $object = $proxy->getWrappedValueHolderValue(); - if ($object === null) { - continue; - } - } - $instanceRef = new \ReflectionObject($object); - $methods = $instanceRef->getMethods(\ReflectionMethod::IS_PUBLIC); - foreach ($methods as $methodRef) { - $methodAnnotations = $this->annotationReader->getMethodAnnotations($methodRef); - $instance = Instance::create( - $proxy, - $instanceRef, - Method::create( - $methodRef, - $methodAnnotations, - ) - ); - yield $instance; - } - } - } -}