diff --git a/src/FrameworkBridge/Symfony/Config/services.php b/src/FrameworkBridge/Symfony/Config/services.php index 7568201..4176d14 100644 --- a/src/FrameworkBridge/Symfony/Config/services.php +++ b/src/FrameworkBridge/Symfony/Config/services.php @@ -67,7 +67,7 @@ $services->set(ServiceProxySubscriber::class) ->public() ->args([ - tagged_iterator('openclassrooms.service_proxy'), + tagged_iterator('openclassrooms.service_proxy.proxy_method_instance'), tagged_iterator('openclassrooms.service_proxy.start_up_interceptor'), ]) ->tag('kernel.event_subscriber'); diff --git a/src/FrameworkBridge/Symfony/DependencyInjection/Compiler/ServiceProxyPass.php b/src/FrameworkBridge/Symfony/DependencyInjection/Compiler/ServiceProxyPass.php index 4c066c3..917022c 100644 --- a/src/FrameworkBridge/Symfony/DependencyInjection/Compiler/ServiceProxyPass.php +++ b/src/FrameworkBridge/Symfony/DependencyInjection/Compiler/ServiceProxyPass.php @@ -4,7 +4,11 @@ namespace OpenClassrooms\ServiceProxy\FrameworkBridge\Symfony\DependencyInjection\Compiler; +use OC\Common\Util\Chrono; +use OpenClassrooms\ServiceProxy\Model\Request\Instance; +use OpenClassrooms\ServiceProxy\Model\Request\Method; use OpenClassrooms\ServiceProxy\ProxyFactory; +use ProxyManager\Proxy\ValueHolderInterface; use Symfony\Component\DependencyInjection\Compiler\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -40,6 +44,7 @@ private function buildServiceProxies(): void private function buildServiceProxyFactoryDefinition(string $taggedServiceName): void { + Chrono::start(); $definition = $this->container->findDefinition($taggedServiceName); $factoryDefinition = new Definition($definition->getClass()); $factoryDefinition->setFactory([new Reference(ProxyFactory::class), 'createProxy']); @@ -48,5 +53,20 @@ private function buildServiceProxyFactoryDefinition(string $taggedServiceName): $factoryDefinition->setPublic($definition->isPublic()); $factoryDefinition->setLazy($definition->isLazy()); $factoryDefinition->setTags($definition->getTags()); + + $proxyRef = new \ReflectionClass($definition->getClass()); + $proxyMethodsRef = $proxyRef->getMethods(\ReflectionMethod::IS_PUBLIC); + foreach ($proxyMethodsRef as $proxyMethodRef) { + $instance = new Definition(Instance::class); + $instance->setFactory([new Reference(Instance::class), 'createFromProxy']); + $instance->setArguments([ + new Reference($taggedServiceName), + $proxyMethodRef->getName(), + ]); + $instance->setTags(['openclassrooms.service_proxy.proxy_method_instance']); + dump($taggedServiceName.'_'.$proxyMethodRef->getName().'_instance'); + $this->container->setDefinition($taggedServiceName.'_'.$proxyMethodRef->getName().'_instance', $instance); + } + Chrono::end(); } } diff --git a/src/FrameworkBridge/Symfony/Subscriber/ServiceProxySubscriber.php b/src/FrameworkBridge/Symfony/Subscriber/ServiceProxySubscriber.php index 9fdf2dd..c95234b 100644 --- a/src/FrameworkBridge/Symfony/Subscriber/ServiceProxySubscriber.php +++ b/src/FrameworkBridge/Symfony/Subscriber/ServiceProxySubscriber.php @@ -6,9 +6,6 @@ use Doctrine\Common\Annotations\AnnotationReader; use OpenClassrooms\ServiceProxy\Interceptor\Contract\StartUpInterceptor; -use OpenClassrooms\ServiceProxy\Model\Request\Instance; -use OpenClassrooms\ServiceProxy\Model\Request\Method; -use ProxyManager\Proxy\ValueHolderInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\RequestEvent; @@ -28,7 +25,7 @@ final class ServiceProxySubscriber implements EventSubscriberInterface * @throws \Doctrine\Common\Annotations\AnnotationException */ public function __construct( - private readonly iterable $proxies, + private readonly iterable $proxyMethodInstances, iterable $startUpInterceptors, ) { if (!\is_array($startUpInterceptors)) { @@ -56,42 +53,12 @@ public function startUp(RequestEvent $event): void StartUpInterceptor $b ) => $a->getStartUpPriority() <=> $b->getStartUpPriority() ); - foreach ($this->getInstances() as $instance) { + foreach ($this->proxyMethodInstances as $proxyMethodInstance) { foreach ($this->startUpInterceptors as $interceptor) { - if ($interceptor->supportsStartUp($instance)) { - $interceptor->startUp($instance); + if ($interceptor->supportsStartUp($proxyMethodInstance)) { + $interceptor->startUp($proxyMethodInstance); } } } } - - /** - * @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; - } - } - } } diff --git a/src/Model/Request/Instance.php b/src/Model/Request/Instance.php index 8a44678..21f595c 100644 --- a/src/Model/Request/Instance.php +++ b/src/Model/Request/Instance.php @@ -6,6 +6,7 @@ use Doctrine\Common\Annotations\AnnotationException; use Doctrine\Common\Annotations\AnnotationReader; +use ProxyManager\Proxy\ValueHolderInterface; final class Instance { @@ -64,6 +65,24 @@ public static function create( return $self; } + public static function createFromProxy( + object $proxy, + string $methodName + ): self { + $object = $proxy; + if ($proxy instanceof ValueHolderInterface) { + $object = $proxy->getWrappedValueHolderValue(); + if ($object === null) { + throw new \Exception('The proxy is not initialized.'); + } + } + return Instance::create( + $proxy, + new \ReflectionObject($object), + Method::create(new \ReflectionMethod($proxy, $methodName)) + ); + } + /** * @param array $parameters */ diff --git a/src/Model/Request/Method.php b/src/Model/Request/Method.php index 63cad01..7ddb751 100644 --- a/src/Model/Request/Method.php +++ b/src/Model/Request/Method.php @@ -35,7 +35,7 @@ private function __construct() /** * @param array $annotations */ - public static function create(\ReflectionMethod $reflection, array $annotations): self + public static function create(\ReflectionMethod $reflection, array $annotations = []): self { $self = new self(); $self->reflection = $reflection;