8000 Fix IDs in ServiceLocator · symfony/symfony@aadc68d · GitHub
[go: up one dir, main page]

Skip to content

Commit aadc68d

Browse files
committed
Fix IDs in ServiceLocator
1 parent d38ef67 commit aadc68d

File tree

2 files changed

+57
-17
lines changed

2 files changed

+57
-17
lines changed

src/Symfony/Component/DependencyInjection/Compiler/ServiceLocatorTagPass.php

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ protected function processValue($value, bool $isRoot = false)
3737
$value->setValues($this->findAndSortTaggedServices($value->getTaggedIteratorArgument(), $this->container));
3838
}
3939

40-
return self::register($this->container, $value->getValues());
40+
return self::register($this->container, $this->processLocatorKeys($value->getValues()));
4141
}
4242

4343
if ($value instanceof Definition) {
@@ -62,7 +62,7 @@ protected function processValue($value, bool $isRoot = false)
6262
throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set.', $this->currentId));
6363
}
6464

65-
$i = 0;
65+
$services = $this->processLocatorKeys($services);
6666

6767
foreach ($services as $k => $v) {
6868
if ($v instanceof ServiceClosureArgument) {
@@ -72,17 +72,8 @@ protected function processValue($value, bool $isRoot = false)
7272
throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set, "%s" found for key "%s".', $this->currentId, get_debug_type($v), $k));
7373
}
7474

75-
if ($i === $k) {
76-
unset($services[$k]);
77-
78-
$k = (string) $v;
79-
++$i;
80-
} elseif (\is_int($k)) {
81-
$i = null;
82-
}
8375
$services[$k] = new ServiceClosureArgument($v);
8476
}
85-
ksort($services);
8677

8778
$value->setArgument(0, $services);
8879

@@ -101,6 +92,31 @@ protected function processValue($value, bool $isRoot = false)
10192
return new Reference($id);
10293
}
10394

95+
/**
96+
* @param array<array-key, mixed> $services
97+
*
98+
* @return array<string, mixed>
99+
*/
100+
private function processLocatorKeys(array $services): array
101+
{
102+
$i = 0;
103+
foreach ($services as $k => $v) {
104+
if ($i === $k && $v instanceof Reference) {
105+
unset($services[$k]);
106+
$k = (string) $v;
107+
++$i;
108+
} elseif (\is_int($k)) {
109+
$i = null;
110+
}
111+
112+
$services[$k] = $v;
113+
}
114+
115+
ksort($services);
116+
117+
return $services;
118+
}
119+
104120
/**
105121
* @param Reference[] $refMap
106122
*/

src/Symfony/Component/DependencyInjection/Tests/Compiler/ServiceLocatorTagPassTest.php

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
2222
use Symfony\Component\DependencyInjection\Reference;
2323
use Symfony\Component\DependencyInjection\ServiceLocator;
24-
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
2524
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1;
2625
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition2;
2726

27+
require_once __DIR__.'/../Fixtures/includes/autowiring_classes.php';
2828
require_once __DIR__.'/../Fixtures/includes/classes.php';
2929

3030
class ServiceLocatorTagPassTest extends TestCase
@@ -62,8 +62,8 @@ public function testProcessValue()
6262
{
6363
$container = new ContainerBuilder();
6464

65-
$container->register('bar', CustomDefinition::class);
66-
$container->register('baz', CustomDefinition::class);
65+
$container->register('bar', TestDefinition1::class);
66+
$container->register('baz', TestDefinition2::class);
6767

6868
$container->register('foo', ServiceLocator::class)
6969
->setArguments([[
@@ -79,9 +79,33 @@ public function testProcessValue()
7979
/** @var ServiceLocator $locator */
8080
$locator = $container->get('foo');
8181

82-
$this->assertSa 2364 me(CustomDefinition::class, \get_class($locator('bar')));
83-
$this->assertSame(CustomDefinition::class, \get_class($locator('baz')));
84-
$this->assertSame(CustomDefinition::class, \get_class($locator('some.service')));
82+
$this->assertSame(TestDefinition1::class, \get_class($locator('bar')));
83+
$this->assertSame(TestDefinition2::class, \get_class($locator('baz')));
84+
$this->assertSame(TestDefinition1::class, \get_class($locator('some.service')));
85+
}
86+
87+
public function testProcessLocatorArgumentValue()
88+
{
89+
$container = new ContainerBuilder();
90+
91+
$container->register('bar', TestDefinition1::class);
92+
$container->register('baz', TestDefinition2::class);
93+
94+
$container->register('foo', Locator::class)
95+
->addArgument(new ServiceLocatorArgument([
96+
new Reference('bar'),
97+
'some.service' => new Reference('bar'),
98+
new Reference('baz'),
99+
]));
100+
101+
(new ServiceLocatorTagPass())->process($container);
102+
103+
/** @var ServiceLocator $locator */
104+
$locator = $container->get('foo')->locator;
105+
106+
$this->assertSame(TestDefinition1::class, \get_debug_type($locator('bar')));
107+
$this->assertSame(TestDefinition1::class, \get_debug_type($locator('some.service')));
108+
$this->assertSame(TestDefinition2::class, \get_debug_type($locator('baz')));
85109
}
86110

87111
public function testServiceWithKeyOverwritesPreviousInheritedKey()

0 commit comments

Comments
 (0)
0