Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ab23d37

Browse filesBrowse files
author
Hugo Hamon
committed
[Form] use new service locator in DependencyInjectionExtension class, so that form types can be made private at some point.
1 parent 3e9b8f3 commit ab23d37
Copy full SHA for ab23d37

File tree

6 files changed

+299
-230
lines changed
Filter options

6 files changed

+299
-230
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml
+3-7Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,9 @@
3030

3131
<!-- DependencyInjectionExtension -->
3232
<service id="form.extension" class="Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension" public="false">
33-
<argument type="service" id="service_container" />
34-
<!-- All services with tag "form.type" are inserted here by FormPass -->
35-
<argument type="collection" />
36-
<!-- All services with tag "form.type_extension" are inserted here by FormPass -->
37-
<argument type="collection" />
38-
<!-- All services with tag "form.type_guesser" are inserted here by FormPass -->
39-
<argument type="collection" />
33+
<argument type="service-locator" /><!-- All services with tag "form.type" are stored in a service locator by FormPass -->
34+
<argument type="collection" /><!-- All services with tag "form.type_extension" are stored here by FormPass -->
35+
<argument type="iterator" /><!-- All services with tag "form.type_guesser" are stored here by FormPass -->
4036
</service>
4137

4238
<!-- ValidatorTypeGuesser -->

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/FormPassTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/FormPassTest.php
+74-77Lines changed: 74 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass;
16+
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
17+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
1618
use Symfony\Component\DependencyInjection\ContainerBuilder;
1719
use Symfony\Component\DependencyInjection\Definition;
1820
use Symfony\Component\DependencyInjection\Reference;
@@ -27,8 +29,7 @@ class FormPassTest extends TestCase
2729
{
2830
public function testDoNothingIfFormExtensionNotLoaded()
2931
{
30-
$container = new ContainerBuilder();
31-
$container->addCompilerPass(new FormPass());
32+
$container = $this->createContainerBuilder();
3233

3334
$container->compile();
3435

@@ -37,47 +38,36 @@ public function testDoNothingIfFormExtensionNotLoaded()
3738

3839
public function testAddTaggedTypes()
3940
{
40-
$container = new ContainerBuilder();
41-
$container->addCompilerPass(new FormPass());
42-
43-
$extDefinition = new Definition('Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension');
44-
$extDefinition->setArguments(array(
45-
new Reference('service_container'),
46-
array(),
47-
array(),
48-
array(),
49-
));
41+
$container = $this->createContainerBuilder();
5042

51-
$container->setDefinition('form.extension', $extDefinition);
43+
$container->setDefinition('form.extension', $this->createExtensionDefinition());
5244
$container->register('my.type1', __CLASS__.'_Type1')->addTag('form.type');
5345
$container->register('my.type2', __CLASS__.'_Type2')->addTag('form.type');
5446

5547
$container->compile();
5648

5749
$extDefinition = $container->getDefinition('form.extension');
58-
59-
$this->assertEquals(array(
60-
__CLASS__.'_Type1' => 'my.type1',
61-
__CLASS__.'_Type2' => 'my.type2',
62-
), $extDefinition->getArgument(1));
50+
$locator = $extDefinition->getArgument(0);
51+
52+
$this->assertEquals(
53+
new ServiceLocatorArgument(array(
54+
__CLASS__.'_Type1' => new Reference('my.type1'),
55+
__CLASS__.'_Type2' => new Reference('my.type2'),
56+
'my.type1' => new Reference('my.type1'),
57+
'my.type2' => new Reference('my.type2'),
58+
)),
59+
$locator
60+
);
6361
}
6462

6563
/**
6664
* @dataProvider addTaggedTypeExtensionsDataProvider
6765
*/
6866
public function testAddTaggedTypeExtensions(array $extensions, array $expectedRegisteredExtensions)
6967
{
70-
$container = new ContainerBuilder();
71-
$container->addCompilerPass(new FormPass());
68+
$container = $this->createContainerBuilder();
7269

73-
$extDefinition = new Definition('Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension', array(
74-
new Reference('service_container'),
75-
array(),
76-
array(),
77-
array(),
78-
));
79-
80-
$container->setDefinition('form.extension', $extDefinition);
70+
$container->setDefinition('form.extension', $this->createExtensionDefinition());
8171

8272
foreach ($extensions as $serviceId => $tag) {
8373
$container->register($serviceId, 'stdClass')->addTag('form.type_extension', $tag);
@@ -86,7 +76,7 @@ public function testAddTaggedTypeExtensions(array $extensions, array $expectedRe
8676
$container->compile();
8777

8878
$extDefinition = $container->getDefinition('form.extension');
89-
$this->assertSame($expectedRegisteredExtensions, $extDefinition->getArgument(2));
79+
$this->assertEquals($expectedRegisteredExtensions, $extDefinition->getArgument(1));
9080
}
9181

9282
/**
@@ -102,8 +92,11 @@ public function addTaggedTypeExtensionsDataProvider()
10292
'my.type_extension3' => array('extended_type' => 'type2'),
10393
),
10494
array(
105-
'type1' => array('my.type_extension1', 'my.type_extension2'),
106-
'type2' => array('my.type_extension3'),
95+
'type1' => new IteratorArgument(array(
96+
new Reference('my.type_extension1'),
97+
new Reference('my.type_extension2'),
98+
)),
99+
'type2' => new IteratorArgument(array(new Reference('my.type_extension3'))),
107100
),
108101
),
109102
array(
@@ -116,8 +109,16 @@ public function addTaggedTypeExtensionsDataProvider()
116109
'my.type_extension6' => array('extended_type' => 'type2', 'priority' => 1),
117110
),
118111
array(
119-
'type1' => array('my.type_extension2', 'my.type_extension1', 'my.type_extension3'),
120-
'type2' => array('my.type_extension4', 'my.type_extension5', 'my.type_extension6'),
112+
'type1' => new IteratorArgument(array(
113+
new Reference('my.type_extension2'),
114+
new Reference('my.type_extension1'),
115+
new Reference('my.type_extension3'),
116+
)),
117+
'type2' => new IteratorArgument(array(
118+
new Reference('my.type_extension4'),
119+
new Reference('my.type_extension5'),
120+
new Reference('my.type_extension6'),
121+
)),
121122
),
122123
),
123124
);
@@ -129,17 +130,9 @@ public function addTaggedTypeExtensionsDataProvider()
129130
*/
130131
public function testAddTaggedFormTypeExtensionWithoutExtendedTypeAttribute()
131132
{
132-
$container = new ContainerBuilder();
133-
$container->addCompilerPass(new FormPass());
133+
$container = $this->createContainerBuilder();
134134

135-
$extDefinition = new Definition('Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension', array(
136-
new Reference('service_container'),
137-
array(),
138-
array(),
139-
array(),
140-
));
141-
142-
$container->setDefinition('form.extension', $extDefinition);
135+
$container->setDefinition('form.extension', $this->createExtensionDefinition());
143136
$container->register('my.type_extension', 'stdClass')
144137
->addTag('form.type_extension');
145138

@@ -148,68 +141,72 @@ public function testAddTaggedFormTypeExtensionWithoutExtendedTypeAttribute()
148141

149142
public function testAddTaggedGuessers()
150143
{
151-
$container = new ContainerBuilder();
152-
$container->addCompilerPass(new FormPass());
153-
154-
$extDefinition = new Definition('Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension');
155-
$extDefinition->setArguments(array(
156-
new Reference('service_container'),
157-
array(),
158-
array(),
159-
array(),
160-
));
144+
$container = $this->createContainerBuilder();
161145

162146
$definition1 = new Definition('stdClass');
163147
$definition1->addTag('form.type_guesser');
164148
$definition2 = new Definition('stdClass');
165149
$definition2->addTag('form.type_guesser');
166150

167-
$container->setDefinition('form.extension', $extDefinition);
151+
$container->setDefinition('form.extension', $this->createExtensionDefinition());
168152
$container->setDefinition('my.guesser1', $definition1);
169153
$container->setDefinition('my.guesser2', $definition2);
170154

171155
$container->compile();
172156

173157
$extDefinition = $container->getDefinition('form.extension');
174-
175-
$this->assertSame(array(
176-
'my.guesser1',
177-
'my.guesser2',
178-
), $extDefinition->getArgument(3));
158+
$iteratorArgument = $extDefinition->getArgument(2);
159+
160+
$this->assertEquals(
161+
new IteratorArgument(array(
162+
new Reference('my.guesser1'),
163+
new Reference('my.guesser2'),
164+
)),
165+
$iteratorArgument
166+
);
179167
}
180168

181169
/**
182170
* @dataProvider privateTaggedServicesProvider
183171
*/
184-
public function testPrivateTaggedServices($id, $tagName, $expectedExceptionMessage)
172+
public function testPrivateTaggedServices($id, $tagName, array $tagAttributes = array())
185173
{
186-
$container = new ContainerBuilder();
187-
$container->addCompilerPass(new FormPass());
174+
$container = $this->createContainerBuilder();
188175

189-
$extDefinition = new Definition('Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension');
190-
$extDefinition->setArguments(array(
191-
new Reference('service_container'),
192-
array(),
193-
array(),
194-
array(),
195-
));
196-
197-
$container->setDefinition('form.extension', $extDefinition);
198-
$container->register($id, 'stdClass')->setPublic(false)->addTag($tagName);
199-
200-
$this->setExpectedException('\InvalidArgumentException', $expectedExceptionMessage);
176+
$container->setDefinition('form.extension', $this->createExtensionDefinition());
177+
$container->register($id, 'stdClass')->setPublic(false)->addTag($tagName, $tagAttributes);
201178

202179
$container->compile();
203180
}
204181

205182
public function privateTaggedServicesProvider()
206183
{
207184
return array(
208-
array('my.type', 'form.type', 'The service "my.type" must be public as form types are lazy-loaded'),
209-
array('my.type_extension', 'form.type_extension', 'The service "my.type_extension" must be public as form type extensions are lazy-loaded'),
210-
array('my.guesser', 'form.type_guesser', 'The service "my.guesser" must be public as form type guessers are lazy-loaded'),
185+
array('my.type', 'form.type'),
186+
array('my.type_extension', 'form.type_extension', array('extended_type' => 'Symfony\Component\Form\Extension\Core\Type\FormType')),
187+
array('my.guesser', 'form.type_guesser'),
211188
);
212189
}
190+
191+
private function createContainerBuilder()
192+
{
193+
$container = new ContainerBuilder();
194+
$container->addCompilerPass(new FormPass());
195+
196+
return $container;
197+
}
198+
199+
private function createExtensionDefinition()
200+
{
201+
$definition = new Definition('Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension');
202+
$definition->setArguments(array(
203+
new ServiceLocatorArgument(array()),
204+
new IteratorArgument(array()),
205+
new IteratorArgument(array()),
206+
));
207+
208+
return $definition;
209+
}
213210
}
214211

215212
class FormPassTest_Type1 extends AbstractType

‎src/Symfony/Component/Form/DependencyInjection/FormPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/DependencyInjection/FormPass.php
+28-21Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@
1111

1212
namespace Symfony\Component\Form\DependencyInjection;
1313

14+
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
15+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
1416
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
1517
use Symfony\Component\DependencyInjection\ContainerBuilder;
1618
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1719
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
20+
use Symfony\Component\DependencyInjection\Reference;
1821

1922
/**
2023
* Adds all services with the tags "form.type" and "form.type_guesser" as
@@ -47,28 +50,25 @@ public function process(ContainerBuilder $container)
4750

4851
$definition = $container->getDefinition($this->formExtensionService);
4952

53+
// Get service locator argument
54+
$servicesMap = array();
55+
$locator = $definition->getArgument(0);
56+
if ($locator instanceof ServiceLocatorArgument) {
57+
$servicesMap = $locator->getValues();
58+
}
59+
5060
// Builds an array with fully-qualified type class names as keys and service IDs as values
51-
$types = array();
5261
foreach ($container->findTaggedServiceIds($this->formTypeTag) as $serviceId => $tag) {
5362
$serviceDefinition = $container->getDefinition($serviceId);
54-
if (!$serviceDefinition->isPublic()) {
55-
throw new InvalidArgumentException(sprintf('The service "%s" must be public as form types are lazy-loaded.', $serviceId));
56-
}
57-
58-
// Support type access by FQCN
59-
$types[$serviceDefinition->getClass()] = $serviceId;
63+
// Add form type service to the service locator
64+
$servicesMap[$serviceId] = new Reference($serviceId);
65+
$servicesMap[$serviceDefinition->getClass()] = new Reference($serviceId);
6066
}
6167

62-
$definition->replaceArgument(1, $types);
63-
6468
$typeExtensions = array();
65-
6669
foreach ($this->findAndSortTaggedServices($this->formTypeExtensionTag, $container) as $reference) {
6770
$serviceId = (string) $reference;
6871
$serviceDefinition = $container->getDefinition($serviceId);
69-
if (!$serviceDefinition->isPublic()) {
70-
throw new InvalidArgumentException(sprintf('The service "%s" must be public as form type extensions are lazy-loaded.', $serviceId));
71-
}
7272

7373
$tag = $serviceDefinition->getTag($this->formTypeExtensionTag);
7474
if (isset($tag[0]['extended_type'])) {
@@ -80,16 +80,23 @@ public function process(ContainerBuilder $container)
8080
$typeExtensions[$extendedType][] = $serviceId;
8181
}
8282

83-
$definition->replaceArgument(2, $typeExtensions);
83+
$allExtensions = array();
84+
foreach ($typeExtensions as $extendedType => $extensions) {
85+
$allExtensions[$extendedType] = new IteratorArgument(array_map(
86+
function ($extensionId) {
87+
return new Reference($extensionId);
88+
},
89+
$extensions
90+
));
91+
}
8492

85-
$guessers = array_keys($container->findTaggedServiceIds($this->formTypeGuesserTag));
86-
foreach ($guessers as $serviceId) {
87-
$serviceDefinition = $container->getDefinition($serviceId);
88-
if (!$serviceDefinition->isPublic()) {
89-
throw new InvalidArgumentException(sprintf('The service "%s" must be public as form type guessers are lazy-loaded.', $serviceId));
90-
}
93+
$guessers = array();
94+
foreach (array_keys($container->findTaggedServiceIds($this->formTypeGuesserTag)) as $serviceId) {
95+
$guessers[] = new Reference($serviceId);
9196
}
9297

93-
$definition->replaceArgument(3, $guessers);
98+
$definition->replaceArgument(0, new ServiceLocatorArgument($servicesMap));
99+
$definition->replaceArgument(1, $allExtensions);
100+
$definition->replaceArgument(2, new IteratorArgument($guessers));
94101
}
95102
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.