Skip to content

Commit ab7d571

Browse files
authored
Merge 91b6f1c into 4720e0c
2 parents 4720e0c + 91b6f1c commit ab7d571

File tree

12 files changed

+212
-119
lines changed

12 files changed

+212
-119
lines changed

Command/DebugCommand.php

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -74,38 +74,35 @@ protected function execute(InputInterface $input, OutputInterface $output)
7474

7575
/** @var FluentResolverInterface $resolver */
7676
$resolver = $this->{$category.'Resolver'};
77-
78-
$solutions = $this->retrieveSolutions($resolver);
79-
$this->renderTable($tableHeaders, $solutions, $io);
77+
$this->renderTable($resolver, $tableHeaders, $io);
8078
}
8179
}
8280

83-
private function renderTable(array $tableHeaders, array $solutions, SymfonyStyle $io)
81+
private function renderTable(FluentResolverInterface $resolver, array $tableHeaders, SymfonyStyle $io)
8482
{
8583
$tableRows = [];
86-
foreach ($solutions as $id => &$options) {
87-
ksort($options['aliases']);
88-
$tableRows[] = [$id, implode("\n", $options['aliases'])];
89-
}
90-
$io->table($tableHeaders, $tableRows);
91-
$io->write("\n\n");
92-
}
93-
94-
private function retrieveSolutions(FluentResolverInterface $resolver)
95-
{
96-
$data = [];
97-
foreach ($resolver->getSolutions() as $alias => $solution) {
98-
$options = $resolver->getSolutionOptions($alias);
99-
84+
$solutions = $resolver->getSolutions();
85+
ksort($solutions);
86+
foreach ($solutions as $solutionID => $solution) {
87+
$aliases = $resolver->getSolutionAliases($solutionID);
88+
$aliases[] = $solutionID;
89+
ksort($aliases);
90+
91+
$options = $resolver->getSolutionOptions($solutionID);
10092
$id = $options['id'];
101-
if (!isset($data[$id]['aliases'])) {
102-
$data[$id]['aliases'] = [];
103-
}
104-
$data[$id]['aliases'][] = $options['alias'].(isset($options['method']) ? ' (method: '.$options['method'].')' : '');
93+
$aliases = array_map(function ($alias) use ($options) {
94+
return $alias.(isset($options['method']) ? ' (method: '.$options['method'].')' : '');
95+
}, $aliases);
96+
97+
$tableRows[$id] = [
98+
$id,
99+
implode("\n", $aliases),
100+
];
105101
}
106-
ksort($data);
102+
ksort($tableRows);
107103

108-
return $data;
104+
$io->table($tableHeaders, $tableRows);
105+
$io->write("\n\n");
109106
}
110107

111108
public static function getCategories()

Config/Processor/NamedConfigProcessor.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ public static function process(array $configs)
1111
{
1212
foreach ($configs as $name => &$config) {
1313
$config['config'] = isset($config['config']) && is_array($config['config']) ? $config['config'] : [];
14-
$config['config']['name'] = $name;
14+
if (empty($config['config']['name'])) {
15+
$config['config']['name'] = $name;
16+
}
1517
}
1618

1719
return $configs;

Config/TypeDefinition.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ protected function nameSection()
3737
->ifTrue(function ($name) {
3838
return !preg_match('/^[_a-z][_0-9a-z]*$/i', $name);
3939
})
40-
->thenInvalid('Invalid type name "%s". (see https://facebook.github.io/graphql/#Name)')
40+
->thenInvalid('Invalid type name "%s". (see http://facebook.github.io/graphql/October2016/#Name)')
4141
->end();
4242

4343
return $node;

DependencyInjection/Compiler/ConfigTypesPass.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,16 @@ public function process(ContainerBuilder $container)
1818
->compile(TypeGenerator::MODE_MAPPING_ONLY);
1919

2020
foreach ($generatedClasses as $class => $file) {
21-
$aliases = [preg_replace('/Type$/', '', substr(strrchr($class, '\\'), 1))];
22-
$this->setTypeServiceDefinition($container, $class, $aliases);
21+
$alias = preg_replace('/Type$/', '', substr(strrchr($class, '\\'), 1));
22+
$this->setTypeServiceDefinition($container, $class, $alias);
2323
}
2424
}
2525

26-
private function setTypeServiceDefinition(ContainerBuilder $container, $class, array $aliases)
26+
private function setTypeServiceDefinition(ContainerBuilder $container, $class, $alias)
2727
{
2828
$definition = $container->setDefinition($class, new Definition($class));
2929
$definition->setPublic(false);
3030
$definition->setArguments([new Reference(ConfigProcessor::class), new Reference(GlobalVariables::class)]);
31-
foreach ($aliases as $alias) {
32-
$definition->addTag(TypeTaggedServiceMappingPass::TAG_NAME, ['alias' => $alias, 'generated' => true]);
33-
}
31+
$definition->addTag(TypeTaggedServiceMappingPass::TAG_NAME, ['alias' => $alias, 'generated' => true]);
3432
}
3533
}

DependencyInjection/Compiler/TaggedServiceMappingPass.php

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
66
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
77
use Symfony\Component\DependencyInjection\ContainerBuilder;
8+
use Symfony\Component\DependencyInjection\Definition;
89
use Symfony\Component\DependencyInjection\Reference;
910

1011
abstract class TaggedServiceMappingPass implements CompilerPassInterface
@@ -18,23 +19,26 @@ private function getTaggedServiceMapping(ContainerBuilder $container, $tagName)
1819

1920
foreach ($taggedServices as $id => $tags) {
2021
$className = $container->findDefinition($id)->getClass();
21-
foreach ($tags as $tag) {
22-
$this->checkRequirements($id, $tag);
23-
$tag = array_merge($tag, ['id' => $id]);
22+
foreach ($tags as $attributes) {
23+
$this->checkRequirements($id, $attributes);
24+
$attributes = array_merge($attributes, ['id' => $id, 'aliases' => []]);
25+
2426
if (!$isType) {
25-
$tag['method'] = isset($tag['method']) ? $tag['method'] : '__invoke';
27+
$attributes['method'] = isset($attributes['method']) ? $attributes['method'] : '__invoke';
28+
}
29+
if ($isType || '__invoke' === $attributes['method']) {
30+
$solutionID = $className;
31+
} else {
32+
$solutionID = sprintf('%s::%s', $className, $attributes['method']);
2633
}
27-
if (isset($tag['alias'])) {
28-
$serviceMapping[$tag['alias']] = $tag;
34+
35+
if (!isset($serviceMapping[$solutionID])) {
36+
$serviceMapping[$solutionID] = $attributes;
2937
}
3038

31-
// add FQCN alias
32-
$alias = $className;
33-
if (!$isType && '__invoke' !== $tag['method']) {
34-
$alias .= '::'.$tag['method'];
39+
if (isset($attributes['alias']) && $solutionID !== $attributes['alias']) {
40+
$serviceMapping[$solutionID]['aliases'][] = $attributes['alias'];
3541
}
36-
$tag['alias'] = $alias;
37-
$serviceMapping[$tag['alias']] = $tag;
3842
}
3943
}
4044

@@ -46,35 +50,19 @@ public function process(ContainerBuilder $container)
4650
$mapping = $this->getTaggedServiceMapping($container, $this->getTagName());
4751
$resolverDefinition = $container->findDefinition($this->getResolverServiceID());
4852

49-
foreach ($mapping as $name => $options) {
50-
$cleanOptions = $options;
51-
$solutionID = $options['id'];
53+
foreach ($mapping as $solutionID => $attributes) {
54+
$attributes['aliases'] = array_unique($attributes['aliases']);
55+
$aliases = $attributes['aliases'];
56+
$serviceID = $attributes['id'];
5257

53-
$solutionDefinition = $container->findDefinition($solutionID);
58+
$solutionDefinition = $container->findDefinition($serviceID);
5459
// make solution service public to improve lazy loading
5560
$solutionDefinition->setPublic(true);
56-
57-
$methods = array_map(
58-
function ($methodCall) {
59-
return $methodCall[0];
60-
},
61-
$solutionDefinition->getMethodCalls()
62-
);
63-
if (
64-
empty($options['generated']) // false is consider as empty
65-
&& is_subclass_of($solutionDefinition->getClass(), ContainerAwareInterface::class)
66-
&& !in_array('setContainer', $methods)
67-
) {
68-
@trigger_error(
69-
'Autowire custom tagged (type, resolver or mutation) services is deprecated as of 0.9 and will be removed in 1.0. Use AutoMapping or set it manually instead.',
70-
E_USER_DEPRECATED
71-
);
72-
$solutionDefinition->addMethodCall('setContainer', [new Reference('service_container')]);
73-
}
61+
$this->autowireSolutionImplementingContainerAwareInterface($solutionDefinition, empty($attributes['generated']));
7462

7563
$resolverDefinition->addMethodCall(
7664
'addSolution',
77-
[$name, [new Reference('service_container'), 'get'], [$solutionID], $cleanOptions]
65+
[$solutionID, [[new Reference('service_container'), 'get'], [$serviceID]], $aliases, $attributes]
7866
);
7967
}
8068
}
@@ -88,6 +76,30 @@ protected function checkRequirements($id, array $tag)
8876
}
8977
}
9078

79+
private function autowireSolutionImplementingContainerAwareInterface(Definition $solutionDefinition, $isGenerated)
80+
{
81+
$methods = array_map(
82+
function ($methodCall) {
83+
return $methodCall[0];
84+
},
85+
$solutionDefinition->getMethodCalls()
86+
);
87+
if (
88+
$isGenerated
89+
&& is_subclass_of($solutionDefinition->getClass(), ContainerAwareInterface::class)
90+
&& !in_array('setContainer', $methods)
91+
) {
92+
@trigger_error(
93+
sprintf(
94+
'Autowire method "%s::setContainer" for custom tagged (type, resolver or mutation) services is deprecated as of 0.9 and will be removed in 1.0.',
95+
ContainerAwareInterface::class
96+
),
97+
E_USER_DEPRECATED
98+
);
99+
$solutionDefinition->addMethodCall('setContainer', [new Reference('service_container')]);
100+
}
101+
}
102+
91103
abstract protected function getTagName();
92104

93105
/**

Resolver/AbstractResolver.php

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,50 @@ abstract class AbstractResolver implements FluentResolverInterface
77
/** @var array */
88
private $solutions = [];
99

10+
private $aliases = [];
11+
1012
/** @var array */
1113
private $solutionOptions = [];
1214

1315
/** @var array */
1416
private $fullyLoadedSolutions = [];
1517

16-
public function addSolution($name, callable $solutionFunc, array $solutionFuncArgs = [], array $options = [])
18+
public function addSolution($id, $solutionOrFactory, array $aliases = [], array $options = [])
1719
{
18-
$this->fullyLoadedSolutions[$name] = false;
19-
$this->solutions[$name] = function () use ($name, $solutionFunc, $solutionFuncArgs) {
20-
$solution = call_user_func_array($solutionFunc, $solutionFuncArgs);
21-
$this->checkSolution($name, $solution);
20+
$this->fullyLoadedSolutions[$id] = false;
21+
$this->addAliases($id, $aliases);
22+
23+
$this->solutions[$id] = function () use ($id, $solutionOrFactory) {
24+
if (is_array($solutionOrFactory) && isset($solutionOrFactory[0]) && is_callable($solutionOrFactory[0])) {
25+
$solutionOrFactory[1] = isset($solutionOrFactory[1]) ? $solutionOrFactory[1] : [];
26+
$solution = call_user_func_array(...$solutionOrFactory);
27+
} else {
28+
$solution = $solutionOrFactory;
29+
}
30+
$this->checkSolution($id, $solution);
2231

2332
return $solution;
2433
};
25-
$this->solutionOptions[$name] = $options;
34+
$this->solutionOptions[$id] = $options;
2635

2736
return $this;
2837
}
2938

30-
public function hasSolution($name)
39+
public function hasSolution($id)
3140
{
32-
return isset($this->solutions[$name]);
41+
$id = $this->resolveAlias($id);
42+
43+
return isset($this->solutions[$id]);
3344
}
3445

3546
/**
36-
* @param $name
47+
* @param $id
3748
*
3849
* @return mixed
3950
*/
40-
public function getSolution($name)
51+
public function getSolution($id)
4152
{
42-
return $this->loadSolution($name);
53+
return $this->loadSolution($id);
4354
}
4455

4556
/**
@@ -50,38 +61,58 @@ public function getSolutions()
5061
return $this->loadSolutions();
5162
}
5263

64+
public function getSolutionAliases($id)
65+
{
66+
return array_keys($this->aliases, $id);
67+
}
68+
5369
/**
54-
* @param $name
70+
* @param $id
5571
*
5672
* @return mixed
5773
*/
58-
public function getSolutionOptions($name)
74+
public function getSolutionOptions($id)
5975
{
60-
return isset($this->solutionOptions[$name]) ? $this->solutionOptions[$name] : [];
76+
$id = $this->resolveAlias($id);
77+
78+
return isset($this->solutionOptions[$id]) ? $this->solutionOptions[$id] : [];
6179
}
6280

6381
/**
64-
* @param string $name
82+
* @param string $id
6583
*
6684
* @return mixed
6785
*/
68-
private function loadSolution($name)
86+
private function loadSolution($id)
6987
{
70-
if (!$this->hasSolution($name)) {
88+
$id = $this->resolveAlias($id);
89+
if (!$this->hasSolution($id)) {
7190
return null;
7291
}
7392

74-
if ($this->fullyLoadedSolutions[$name]) {
75-
return $this->solutions[$name];
93+
if ($this->fullyLoadedSolutions[$id]) {
94+
return $this->solutions[$id];
7695
} else {
77-
$loader = $this->solutions[$name];
78-
$this->solutions[$name] = $loader();
79-
$this->fullyLoadedSolutions[$name] = true;
96+
$loader = $this->solutions[$id];
97+
$this->solutions[$id] = $loader();
98+
$this->fullyLoadedSolutions[$id] = true;
8099

81-
return $this->solutions[$name];
100+
return $this->solutions[$id];
82101
}
83102
}
84103

104+
private function addAliases($id, $aliases)
105+
{
106+
foreach ($aliases as $alias) {
107+
$this->aliases[$alias] = $id;
108+
}
109+
}
110+
111+
private function resolveAlias($alias)
112+
{
113+
return isset($this->aliases[$alias]) ? $this->aliases[$alias] : $alias;
114+
}
115+
85116
/**
86117
* @return mixed[]
87118
*/
@@ -106,11 +137,11 @@ protected function supportsSolution($solution)
106137
return null === $supportedClass || $solution instanceof $supportedClass;
107138
}
108139

109-
protected function checkSolution($name, $solution)
140+
protected function checkSolution($id, $solution)
110141
{
111142
if (!$this->supportsSolution($solution)) {
112143
throw new UnsupportedResolverException(
113-
sprintf('Resolver "%s" must be "%s" "%s" given.', $name, $this->supportedSolutionClass(), get_class($solution))
144+
sprintf('Resolver "%s" must be "%s" "%s" given.', $id, $this->supportedSolutionClass(), get_class($solution))
114145
);
115146
}
116147
}
@@ -122,6 +153,6 @@ protected function checkSolution($name, $solution)
122153
*/
123154
protected function supportedSolutionClass()
124155
{
125-
return;
156+
return null;
126157
}
127158
}

0 commit comments

Comments
 (0)