Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions DependencyInjection/Compiler/AliasedPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Overblog\GraphQLBundle\DependencyInjection\Compiler;

use Overblog\GraphQLBundle\Definition\Resolver\AliasedInterface;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

final class AliasedPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
$definitions = $this->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;
}
}
31 changes: 4 additions & 27 deletions DependencyInjection/Compiler/AutoMappingPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand All @@ -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)) {
Expand Down
2 changes: 1 addition & 1 deletion DependencyInjection/Compiler/ConfigTypesPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}
}
}
4 changes: 3 additions & 1 deletion OverblogGraphQLBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
21 changes: 20 additions & 1 deletion Resources/doc/definitions/resolver.md
Original file line number Diff line number Diff line change
Expand Up @@ -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']])'`.
Expand Down