8000 [Form] use new service locator in DependencyInjectionExtension class,… · symfony/symfony@2ca9847 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2ca9847

Browse 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 61d5353 commit 2ca9847

File tree

6 files changed

+244
-201
lines changed

6 files changed

+244
-201
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
<!-- DependencyInjectionExtension -->
3232
<service id="form.extension" class="Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension" public="false">
33-
<argument type="service" id="service_container" />
33+
<argument type="service-locator" />
3434
<!-- All services with tag "form.type" are inserted here by FormPass -->
3535
<argument type="collection" />
3636
<!-- All services with tag "form.type_extension" are inserted here by FormPass -->
@@ -61,10 +61,10 @@
6161

6262
<service id="form.choice_list_factory" alias="form.choice_list_factory.cached" public="false"/>
6363

64-
<service id="form.type.form" class="Symfony\Component\Form\Extension\Core\Type\FormType">
64+
<!--<service id="form.type.form" class="Symfony\Component\Form\Extension\Core\Type\FormType">
6565
<argument type="service" id="form.property_accessor" />
6666
<tag name="form.type" />
67-
</service>
67+
</service>-->
6868
<service id="form.type.birthday" class="Symfony\Component\Form\Extension\Core\Type\BirthdayType">
6969
<deprecated>The "%service_id%" service is deprecated since Symfony 3.1 and will be removed in 4.0.</deprecated>
7070
</service>

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

Lines changed: 52 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass;
16+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
1617
use Symfony\Component\DependencyInjection\ContainerBuilder;
1718
use Symfony\Component\DependencyInjection\Definition;
18-
use Symfony\Component\DependencyInjection\Reference;
1919
use Symfony\Component\Form\AbstractType;
2020

2121
/**
@@ -27,8 +27,7 @@ class FormPassTest extends TestCase
2727
{
2828
public function testDoNothingIfFormExtensionNotLoaded()
2929
{
30-
$container = new ContainerBuilder();
31-
$container->addCompilerPass(new FormPass());
30+
$container = $this->createContainerBuilder();
3231

3332
$container->compile();
3433

@@ -37,47 +36,33 @@ public function testDoNothingIfFormExtensionNotLoaded()
3736

3837
public function testAddTaggedTypes()
3938
{
40-
$container = new ContainerBuilder();
41-
$container->addCompilerPass(new FormPass());
39+
$container = $this->createContainerBuilder();
4240

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-
));
50-
51-
$container->setDefinition('form.extension', $extDefinition);
41+
$container->setDefinition('form.extension', $this->createExtensionDefinition());
5242
$container->register('my.type1', __CLASS__.'_Type1')->addTag('form.type');
5343
$container->register('my.type2', __CLASS__.'_Type2')->addTag('form.type');
5444

5545
$container->compile();
5646

5747
$extDefinition = $container->getDefinition('form.extension');
5848

59-
$this->assertEquals(array(
60-
__CLASS__.'_Type1' => 'my.type1',
61-
__CLASS__.'_Type2' => 'my.type2',
62-
), $extDefinition->getArgument(1));
49+
$this->assertSame(
50+
array(
51+
__CLASS__.'_Type1' => 'my.type1',
52+
__CLASS__.'_Type2' => 'my.type2',
53+
),
54+
$extDefinition->getArgument(1)
55+
);
6356
}
6457

6558
/**
6659
* @dataProvider addTaggedTypeExtensionsDataProvider
6760
*/
6861
public function testAddTaggedTypeExtensions(array $extensions, array $expectedRegisteredExtensions)
6962
{
70-
$container = new ContainerBuilder();
71-
$container->addCompilerPass(new FormPass());
63+
$container = $this->createContainerBuilder();
7264

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);
65+
$container->setDefinition('form.extension', $this->createExtensionDefinition());
8166

8267
foreach ($extensions as $serviceId => $tag) {
8368
$container->register($serviceId, 'stdClass')->addTag('form.type_extension', $tag);
@@ -129,17 +114,9 @@ public function addTaggedTypeExtensionsDataProvider()
129114
*/
130115
public function testAddTaggedFormTypeExtensionWithoutExtendedTypeAttribute()
131116
{
132-
$container = new ContainerBuilder();
133-
$container->addCompilerPass(new FormPass());
134-
135-
$extDefinition = new Definition('Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension', array(
136-
new Reference('service_container'),
137-
array(),
138-
array(),
139-
array(),
140-
));
117+
$container = $this->createContainerBuilder();
141118

142-
$container->setDefinition('form.extension', $extDefinition);
119+
$container->setDefinition('form.extension', $this->createExtensionDefinition());
143120
$container->register('my.type_extension', 'stdClass')
144121
->addTag('form.type_extension');
145122

@@ -148,68 +125,72 @@ public function testAddTaggedFormTypeExtensionWithoutExtendedTypeAttribute()
148125

149126
public function testAddTaggedGuessers()
150127
{
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-
));
128+
$container = $this->createContainerBuilder();
161129

162130
$definition1 = new Definition('stdClass');
163131
$definition1->addTag('form.type_guesser');
164132
$definition2 = new Definition('stdClass');
165133
$definition2->addTag('form.type_guesser');
166134

167-
$container->setDefinition('form.extension', $extDefinition);
135+
$container->setDefinition('form.extension', $this->createExtensionDefinition());
168136
$container->setDefinition('my.guesser1', $definition1);
169137
$container->setDefinition('my.guesser2', $definition2);
170138

171139
$container->compile();
172140

173141
$extDefinition = $container->getDefinition('form.extension');
174142

175-
$this->assertSame(array(
176-
'my.guesser1',
177-
'my.guesser2',
178-
), $extDefinition->getArgument(3));
143+
$this->assertSame(
144+
array(
145+
'my.guesser1',
146+
'my.guesser2',
147+
),
148+
$extDefinition->getArgument(3)
149+
);
179150
}
180151

181152
/**
182153
* @dataProvider privateTaggedServicesProvider
183154
*/
184-
public function testPrivateTaggedServices($id, $tagName, $expectedExceptionMessage)
155+
public function testPrivateTaggedServices($id, $tagName, array $tagAttributes = array())
185156
{
186-
$container = new ContainerBuilder();
187-
$container->addCompilerPass(new FormPass());
188-
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);
157+
$container = $this->createContainerBuilder();
199158

200-
$this->setExpectedException('\InvalidArgumentException', $expectedExceptionMessage);
159+
$container->setDefinition('form.extension', $this->createExtensionDefinition());
160+
$container->register($id, 'stdClass')->setPublic(false)->addTag($tagName, $tagAttributes);
201161

202162
$container->compile();
203163
}
204164

205165
public function privateTaggedServicesProvider()
206166
{
207167
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'),
168+
array('my.type', 'form.type'),
169+
array('my.type_extension', 'form.type_extension', array('extended_type' => 'Symfony\Component\Form\Extension\Core\Type\FormType')),
170+
array('my.guesser', 'form.type_guesser'),
211171
);
212172
}
173+
174+
private function createContainerBuilder()
175+
{
176+
$container = new ContainerBuilder();
177+
$container->addCompilerPass(new FormPass());
178+
179+
return $container;
180+
}
181+
182+
private function createExtensionDefinition()
183+
{
184+
$definition = new Definition('Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension');
185+
$definition->setArguments(array(
186+
new ServiceLocatorArgument(array()),
187+
array(),
188+
array(),
189+
array(),
190+
));
191+
192+
return $definition;
193+
}
213194
}
214195

215196
class FormPassTest_Type1 extends AbstractType

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

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111

1212
namespace Symfony\Component\Form\DependencyInjection;
1313

14+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
1415
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
1516
use Symfony\Component\DependencyInjection\ContainerBuilder;
1617
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1718
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
19+
use Symfony\Component\DependencyInjection\Reference;
1820

1921
/**
2022
* Adds all services with the tags "form.type" and "form.type_guesser" as
@@ -47,16 +49,24 @@ public function process(ContainerBuilder $container)
4749

4850
$definition = $container->getDefinition($this->formExtensionService);
4951

52+
// Get service locator argument
53+
$servicesMap = array();
54+
$locator = $definition->getArgument(0);
55+
if ($locator instanceof ServiceLocatorArgument) {
56+
$servicesMap = $locator->getValues();
57+
}
58+
5059
// Builds an array with fully-qualified type class names as keys and service IDs as values
5160
$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-
}
5763

5864
// Support type access by FQCN
5965
$types[$serviceDefinition->getClass()] = $serviceId;
66+
67+
// Add form type service to the service locator
68+
$servicesMap[$serviceId] = new Reference($serviceId);
69+
$servicesMap[$serviceDefinition->getClass()] = new Reference($serviceId);
6070
}
6171

6272
$definition->replaceArgument(1, $types);
@@ -66,9 +76,6 @@ public function process(ContainerBuilder $container)
6676
foreach ($this->findAndSortTaggedServices($this->formTypeExtensionTag, $container) as $reference) {
6777
$serviceId = (string) $reference;
6878
$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-
}
7279

7380
$tag = $serviceDefinition->getTag($this->formTypeExtensionTag);
7481
if (isset($tag[0]['extended_type'])) {
@@ -78,18 +85,20 @@ public function process(ContainerBuilder $container)
7885
}
7986

8087
$typeExtensions[$extendedType][] = $serviceId;
88+
89+
// Add form type extension service to the service locator
90+
$servicesMap[$serviceId] = new Reference($serviceId);
8191
}
8292

8393
$definition->replaceArgument(2, $typeExtensions);
8494

8595
$guessers = array_keys($container->findTaggedServiceIds($this->formTypeGuesserTag));
8696
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-
}
97+
// Add form type guesser service to the service locator
98+
$servicesMap[$serviceId] = new Reference($serviceId);
9199
}
92100

101+
$definition->replaceArgument(0, new ServiceLocatorArgument($servicesMap));
93102
$definition->replaceArgument(3, $guessers);
94103
}
95104
}

0 commit comments

Comments
 (0)
0