From 0263c7d91bd59855b546d828b7fe1ef3ac3c95ab Mon Sep 17 00:00:00 2001 From: Jeremiah VALERIE Date: Mon, 11 Dec 2017 21:18:12 +0100 Subject: [PATCH] Move Aliased to dedicated compiler pass --- DependencyInjection/Compiler/AliasedPass.php | 67 +++++++++++++++++++ .../Compiler/AutoMappingPass.php | 31 ++------- .../Compiler/ConfigTypesPass.php | 2 +- OverblogGraphQLBundle.php | 4 +- Resources/doc/definitions/resolver.md | 21 +++++- 5 files changed, 95 insertions(+), 30 deletions(-) create mode 100644 DependencyInjection/Compiler/AliasedPass.php diff --git a/DependencyInjection/Compiler/AliasedPass.php b/DependencyInjection/Compiler/AliasedPass.php new file mode 100644 index 000000000..7be3aca45 --- /dev/null +++ b/DependencyInjection/Compiler/AliasedPass.php @@ -0,0 +1,67 @@ +filterDefinitions($container->getDefinitions()); + foreach ($definitions as $definition) { + $this->addDefinitionTagsFromAliases($definition); + } + } + + /** + * @param Definition[] $definitions + * + * @return Definition[] + */ + private function filterDefinitions($definitions) + { + return array_filter($definitions, function (Definition $definition) { + foreach (AutoMappingPass::SERVICE_SUBCLASS_TAG_MAPPING as $tagName) { + if ($definition->hasTag($tagName)) { + return is_subclass_of($definition->getClass(), AliasedInterface::class); + } + } + + return false; + }); + } + + /** + * @param Definition $definition + */ + private function addDefinitionTagsFromAliases(Definition $definition) + { + $aliases = call_user_func([$definition->getClass(), 'getAliases']); + $tagName = $this->guessTagName($definition); + $withMethod = TypeTaggedServiceMappingPass::TAG_NAME !== $tagName; + + foreach ($aliases as $key => $alias) { + $definition->addTag($tagName, $withMethod ? ['alias' => $alias, 'method' => $key] : ['alias' => $alias]); + } + } + + private function guessTagName(Definition $definition) + { + $tagName = null; + foreach (AutoMappingPass::SERVICE_SUBCLASS_TAG_MAPPING as $refClassName => $tag) { + if (is_subclass_of($definition->getClass(), $refClassName)) { + $tagName = $tag; + break; + } + } + + return $tagName; + } +} diff --git a/DependencyInjection/Compiler/AutoMappingPass.php b/DependencyInjection/Compiler/AutoMappingPass.php index fc8f5a014..7a1e3ca62 100644 --- a/DependencyInjection/Compiler/AutoMappingPass.php +++ b/DependencyInjection/Compiler/AutoMappingPass.php @@ -17,10 +17,10 @@ class AutoMappingPass implements CompilerPassInterface { - private static $serviceSubclassTagMapping = [ + const SERVICE_SUBCLASS_TAG_MAPPING = [ MutationInterface::class => 'overblog_graphql.mutation', ResolverInterface::class => 'overblog_graphql.resolver', - Type::class => 'overblog_graphql.type', + Type::class => TypeTaggedServiceMappingPass::TAG_NAME, ]; public function process(ContainerBuilder $container) @@ -88,9 +88,7 @@ private function addServiceDefinition(ContainerBuilder $container, \ReflectionCl private function addDefinitionTags(Definition $definition, \ReflectionClass $reflectionClass) { - $className = $definition->getClass(); - - foreach (self::$serviceSubclassTagMapping as $subclass => $tagName) { + foreach (self::SERVICE_SUBCLASS_TAG_MAPPING as $subclass => $tagName) { if (!$reflectionClass->isSubclassOf($subclass)) { continue; } @@ -104,36 +102,15 @@ private function addDefinitionTags(Definition $definition, \ReflectionClass $ref } $definition->addTag($tagName, ['method' => $publicReflectionMethod->name]); } - if ($isAliased) { - $this->addDefinitionTagsFromAliasesMethod($definition, $className, $tagName, true); - } } else { $definition->addTag($tagName); - $this->addDefinitionTagsFromAliasesMethod($definition, $className, $tagName, false); } } } - /** - * @param string|null $className - * @param bool $withMethod - */ - private function addDefinitionTagsFromAliasesMethod(Definition $definition, $className, $tagName, $withMethod) - { - // from getAliases - if (!is_callable([$className, 'getAliases'])) { - return; - } - $aliases = call_user_func([$className, 'getAliases']); - - foreach ($aliases as $key => $alias) { - $definition->addTag($tagName, $withMethod ? ['alias' => $alias, 'method' => $key] : ['alias' => $alias]); - } - } - private function subclass($class) { - $interfaces = array_keys(self::$serviceSubclassTagMapping); + $interfaces = array_keys(self::SERVICE_SUBCLASS_TAG_MAPPING); foreach ($interfaces as $interface) { if (is_a($class, $interface, true)) { diff --git a/DependencyInjection/Compiler/ConfigTypesPass.php b/DependencyInjection/Compiler/ConfigTypesPass.php index 60c04c8d0..d4c1697ce 100644 --- a/DependencyInjection/Compiler/ConfigTypesPass.php +++ b/DependencyInjection/Compiler/ConfigTypesPass.php @@ -27,7 +27,7 @@ private function setTypeServiceDefinition(ContainerBuilder $container, $class, a $definition->setPublic(false); $definition->setArguments([new Reference('service_container')]); foreach ($aliases as $alias) { - $definition->addTag('overblog_graphql.type', ['alias' => $alias, 'generated' => true]); + $definition->addTag(TypeTaggedServiceMappingPass::TAG_NAME, ['alias' => $alias, 'generated' => true]); } } } diff --git a/OverblogGraphQLBundle.php b/OverblogGraphQLBundle.php index 395df8bfa..307a9b9e2 100644 --- a/OverblogGraphQLBundle.php +++ b/OverblogGraphQLBundle.php @@ -2,6 +2,7 @@ namespace Overblog\GraphQLBundle; +use Overblog\GraphQLBundle\DependencyInjection\Compiler\AliasedPass; use Overblog\GraphQLBundle\DependencyInjection\Compiler\AutoMappingPass; use Overblog\GraphQLBundle\DependencyInjection\Compiler\AutowiringTypesPass; use Overblog\GraphQLBundle\DependencyInjection\Compiler\ConfigTypesPass; @@ -26,7 +27,8 @@ public function build(ContainerBuilder $container) //ConfigTypesPass and AutoMappingPass must be before TypeTaggedServiceMappingPass $container->addCompilerPass(new AutoMappingPass()); - $container->addCompilerPass(new ConfigTypesPass()); + $container->addCompilerPass(new ConfigTypesPass(), PassConfig::TYPE_BEFORE_REMOVING); + $container->addCompilerPass(new AliasedPass()); $container->addCompilerPass(new AutowiringTypesPass()); $container->addCompilerPass(new TypeTaggedServiceMappingPass(), PassConfig::TYPE_BEFORE_REMOVING); diff --git a/Resources/doc/definitions/resolver.md b/Resources/doc/definitions/resolver.md index 042d30bb9..1f4e1c9bf 100644 --- a/Resources/doc/definitions/resolver.md +++ b/Resources/doc/definitions/resolver.md @@ -109,13 +109,32 @@ Resolvers can be define 2 different ways - "%kernel.root_dir%/src/*Bundle/CustomDir" - "%kernel.root_dir%/src/AppBundle/{foo,bar}" ``` - To disable auto mapping: + + If using Symfony 3.3+ disabling auto mapping can be a solution to leave place to native + DI `autoconfigure`: + ```yaml overblog_graphql: definitions: auto_mapping: false ``` + Here an example of how this can be done with DI `autoconfigure`: + + ```yaml + App\Mutation\: + resource: '../src/Mutation' + tags: ['overblog_graphql.mutation'] + + App\Resolver\: + resource: '../src/Resolver' + tags: ['overblog_graphql.resolver'] + + App\Type\: + resource: '../src/Type' + tags: ['overblog_graphql.type'] + ``` + **Note:** * When using FQCN in yaml definition, backslash must be correctly quotes, here an example `'@=resolver("App\\GraphQL\\Resolver\\Greetings", [args['name']])'`.