Skip to content

Commit 8c1f174

Browse files
committed
Merge branch '2.7'
* 2.7: (55 commits) CS: fix some license headers CS: Ensure there is no code on the same line as the PHP open tag and it is followed by a blankline Improve triggering of the deprecation error [SecurityBundle] Fix typos in LogoutUrlHelper [VarDumper] add caster for MongoCursor objects make it possible to dump inlined services to XML [VarDumper] Fixed notice when Exchange is mocked [Translation] keep old array structure of resourcesFiles to avoid BC. removed deprecated notices that make the tests fail use visited lookup with reference to gain performance [VarDumper] with-er interface for Cloner\Data Replace GET parameters when changed tweaked phpdocs [Process] Fix outdated Process->start() docblock prevent inlining service configurators Improve entropy of generated salt Complete the removal of API versions in the validator component [Validator] deprecated API version Removed 2.5 bc layer [SecurityBundle] UserPasswordEncoderCommand: fix help arguments order. ... Conflicts: CHANGELOG-2.3.md CHANGELOG-2.6.md src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperDivLayoutTest.php src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTableLayoutTest.php src/Symfony/Bundle/FrameworkBundle/composer.json src/Symfony/Bundle/SecurityBundle/composer.json src/Symfony/Component/Console/Helper/DialogHelper.php src/Symfony/Component/Console/Tests/Helper/LegacyTableHelperTest.php src/Symfony/Component/Form/ResolvedFormType.php src/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php
2 parents 3d6dd29 + a028faa commit 8c1f174

35 files changed

+377
-301
lines changed

Client.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class Client extends BaseClient
2929
{
3030
private $hasPerformedRequest = false;
3131
private $profiler = false;
32+
private $reboot = true;
3233

3334
/**
3435
* {@inheritdoc}
@@ -84,6 +85,25 @@ public function enableProfiler()
8485
}
8586
}
8687

88+
/**
89+
* Disables kernel reboot between requests.
90+
*
91+
* By default, the Client reboots the Kernel for each request. This method
92+
* allows to keep the same kernel across requests.
93+
*/
94+
public function disableReboot()
95+
{
96+
$this->reboot = false;
97+
}
98+
99+
/**
100+
* Enables kernel reboot between requests.
101+
*/
102+
public function enableReboot()
103+
{
104+
$this->reboot = true;
105+
}
106+
87107
/**
88108
* {@inheritdoc}
89109
*
@@ -95,7 +115,7 @@ protected function doRequest($request)
95115
{
96116
// avoid shutting down the Kernel if no request has been performed yet
97117
// WebTestCase::createClient() boots the Kernel but do not handle a request
98-
if ($this->hasPerformedRequest) {
118+
if ($this->hasPerformedRequest && $this->reboot) {
99119
$this->kernel->shutdown();
100120
} else {
101121
$this->hasPerformedRequest = true;

Command/AbstractConfigCommand.php

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
use Symfony\Component\Config\Definition\ConfigurationInterface;
1515
use Symfony\Component\Console\Output\OutputInterface;
1616
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
17-
use Symfony\Component\DependencyInjection\ContainerBuilder;
18-
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
1917

2018
/**
2119
* A console command for dumping available configuration reference.
@@ -43,37 +41,24 @@ protected function listBundles(OutputInterface $output)
4341
protected function findExtension($name)
4442
{
4543
$extension = null;
44+
$bundles = $this->initializeBundles();
45+
foreach ($bundles as $bundle) {
46+
$extension = $bundle->getContainerExtension();
4647

47-
$bundles = $this->getContainer()->get('kernel')->getBundles();
48-
49-
if (preg_match('/Bundle$/', $name)) {
50-
// input is bundle name
51-
52-
if (isset($bundles[$name])) {
53-
$extension = $bundles[$name]->getContainerExtension();
54-
}
55-
56-
if (!$extension) {
57-
throw new \LogicException(sprintf('No extensions with configuration available for "%s"', $name));
48+
if ($extension && ($name === $extension->getAlias() || $name === $bundle->getName())) {
49+
break;
5850
}
59-
} else {
60-
foreach ($bundles as $bundle) {
61-
$extension = $bundle->getContainerExtension();
62-
63-
if ($extension && $name === $extension->getAlias()) {
64-
break;
65-
}
51+
}
6652

67-
$extension = null;
53+
if (!$extension) {
54+
$message = sprintf('No extension with alias "%s" is enabled', $name);
55+
if (preg_match('/Bundle$/', $name)) {
56+
$message = sprintf('No extensions with configuration available for "%s"', $name);
6857
}
6958

70-
if (!$extension) {
71-
throw new \LogicException(sprintf('No extension with alias "%s" is enabled', $name));
72-
}
59+
throw new \LogicException($message);
7360
}
7461

75-
$this->initializeExtensions($bundles);
76-
7762
return $extension;
7863
}
7964

@@ -88,21 +73,22 @@ public function validateConfiguration(ExtensionInterface $extension, $configurat
8873
}
8974
}
9075

91-
private function initializeExtensions($bundles)
76+
private function initializeBundles()
9277
{
9378
// Re-build bundle manually to initialize DI extensions that can be extended by other bundles in their build() method
9479
// as this method is not called when the container is loaded from the cache.
95-
$parameters = $this->getContainer()->getParameterBag()->all();
96-
$container = new ContainerBuilder(new ParameterBag($parameters));
80+
$container = $this->getContainerBuilder();
81+
$bundles = $this->getContainer()->get('kernel')->registerBundles();
9782
foreach ($bundles as $bundle) {
9883
if ($extension = $bundle->getContainerExtension()) {
9984
$container->registerExtension($extension);
10085
}
10186
}
10287

10388
foreach ($bundles as $bundle) {
104-
$bundle = clone $bundle;
10589
$bundle->build($container);
10690
}
91+
92+
return $bundles;
10793
}
10894
}

Command/ConfigDebugCommand.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
7070
}
7171

7272
$extension = $this->findExtension($name);
73-
74-
$kernel = $this->getContainer()->get('kernel');
75-
$method = new \ReflectionMethod($kernel, 'buildContainer');
76-
$method->setAccessible(true);
77-
$container = $method->invoke($kernel);
73+
$container = $this->compileContainer();
7874

7975
$configs = $container->getExtensionConfig($extension->getAlias());
8076
$configuration = $extension->getConfiguration($configs, $container);
@@ -94,4 +90,17 @@ protected function execute(InputInterface $input, OutputInterface $output)
9490

9591
$output->writeln(Yaml::dump(array($extension->getAlias() => $config), 3));
9692
}
93+
94+
private function compileContainer()
95+
{
96+
$kernel = clone $this->getContainer()->get('kernel');
97+
$kernel->boot();
98+
99+
$method = new \ReflectionMethod($kernel, 'buildContainer');
100+
$method->setAccessible(true);
101+
$container = $method->invoke($kernel);
102+
$container->getCompiler()->compile($container);
103+
104+
return $container;
105+
}
97106
}

Command/ContainerDebugCommand.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ protected function validateInput(InputInterface $input)
166166
*/
167167
protected function getContainerBuilder()
168168
{
169+
if ($this->containerBuilder) {
170+
return $this->containerBuilder;
171+
}
172+
169173
if (!$this->getApplication()->getKernel()->isDebug()) {
170174
throw new \LogicException(sprintf('Debug information about the container is only available in debug mode.'));
171175
}
@@ -179,7 +183,7 @@ protected function getContainerBuilder()
179183
$loader = new XmlFileLoader($container, new FileLocator());
180184
$loader->load($cachedFile);
181185

182-
return $container;
186+
return $this->containerBuilder = $container;
183187
}
184188

185189
private function findProperServiceName(InputInterface $input, OutputInterface $output, ContainerBuilder $builder, $name)

DependencyInjection/Configuration.php

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ private function addValidationSection(ArrayNodeDefinition $rootNode)
471471
->scalarNode('translation_domain')->defaultValue('validators')->end()
472472
->booleanNode('strict_email')->defaultFalse()->end()
473473
->enumNode('api')
474+
->info('Deprecated since version 2.7, to be removed in 3.0')
474475
->values(array('2.4', '2.5', '2.5-bc', 'auto'))
475476
->beforeNormalization()
476477
// XML/YAML parse as numbers, not as strings
@@ -481,19 +482,6 @@ private function addValidationSection(ArrayNodeDefinition $rootNode)
481482
->end()
482483
->end()
483484
->end()
484-
->validate()
485-
->ifTrue(function ($v) { return !isset($v['validation']['api']) || 'auto' === $v['validation']['api']; })
486-
->then(function ($v) {
487-
// This condition is duplicated in ValidatorBuilder. This
488-
// duplication is necessary in order to know the desired
489-
// API version already during container configuration
490-
// (to adjust service classes etc.)
491-
// See https://github.com/symfony/symfony/issues/11580
492-
$v['validation']['api'] = '2.5-bc';
493-
494-
return $v;
495-
})
496-
->end()
497485
;
498486
}
499487

@@ -521,6 +509,10 @@ private function addSerializerSection(ArrayNodeDefinition $rootNode)
521509
->arrayNode('serializer')
522510
->info('serializer configuration')
523511
->canBeEnabled()
512+
->children()
513+
->booleanNode('enable_annotations')->defaultFalse()->end()
514+
->scalarNode('cache')->end()
515+
->end()
524516
->end()
525517
->end()
526518
;

DependencyInjection/FrameworkExtension.php

Lines changed: 88 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\DependencyInjection\ContainerBuilder;
1515
use Symfony\Component\DependencyInjection\ContainerInterface;
16+
use Symfony\Component\DependencyInjection\Definition;
1617
use Symfony\Component\DependencyInjection\DefinitionDecorator;
1718
use Symfony\Component\DependencyInjection\Exception\LogicException;
1819
use Symfony\Component\DependencyInjection\Reference;
@@ -29,6 +30,7 @@
2930
*
3031
* @author Fabien Potencier <fabien@symfony.com>
3132
* @author Jeremy Mikola <jmikola@gmail.com>
33+
* @author Kévin Dunglas <dunglas@gmail.com>
3234
*/
3335
class FrameworkExtension extends Extension
3436
{
@@ -122,11 +124,10 @@ public function load(array $configs, ContainerBuilder $container)
122124
}
123125

124126
$this->registerAnnotationsConfiguration($config['annotations'], $container, $loader);
125-
126127
$this->registerPropertyAccessConfiguration($config['property_access'], $container);
127128

128-
if (isset($config['serializer']) && $config['serializer']['enabled']) {
129-
$loader->load('serializer.xml');
129+
if (isset($config['serializer'])) {
130+
$this->registerSerializerConfiguration($config['serializer'], $container, $loader);
130131
}
131132

132133
$loader->load('debug_prod.xml');
@@ -699,11 +700,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
699700

700701
foreach ($finder as $file) {
701702
list($domain, $locale, $format) = explode('.', $file->getBasename(), 3);
702-
if (!isset($files[$locale])) {
703-
$files[$locale] = array();
704-
}
705-
706-
$files[$locale][] = (string) $file;
703+
$files[] = (string) $file;
707704
}
708705

709706
$translator->replaceArgument(4, $files);
@@ -760,20 +757,11 @@ private function registerValidationConfiguration(array $config, ContainerBuilder
760757
$validatorBuilder->addMethodCall('setMetadataCache', array(new Reference($config['cache'])));
761758
}
762759

763-
if ('2.5' === $config['api']) {
764-
$api = Validation::API_VERSION_2_5;
765-
} else {
766-
// 2.4 is now the same as 2.5 BC
767-
$api = Validation::API_VERSION_2_5_BC;
768-
// the validation class needs to be changed for BC
769-
$container->setParameter('validator.class', 'Symfony\Component\Validator\ValidatorInterface');
770-
}
771-
772-
$validatorBuilder->addMethodCall('setApiVersion', array($api));
773-
774760
// You can use this parameter to check the API version in your own
775761
// bundle extension classes
776-
$container->setParameter('validator.api', $api);
762+
// This is set to 2.5-bc for compatibility with Symfony 2.5 and 2.6.
763+
// @deprecated since version 2.7, to be removed in 3.0
764+
$container->setParameter('validator.api', '2.5-bc');
777765
}
778766

779767
private function getValidatorMappingFiles(ContainerBuilder $container)
@@ -874,6 +862,86 @@ private function registerSecurityCsrfConfiguration(array $config, ContainerBuild
874862
$loader->load('security_csrf.xml');
875863
}
876864

865+
/**
866+
* Loads the serializer configuration.
867+
*
868+
* @param array $config A serializer configuration array
869+
* @param ContainerBuilder $container A ContainerBuilder instance
870+
* @param XmlFileLoader $loader An XmlFileLoader instance
871+
*/
872+
private function registerSerializerConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
873+
{
874+
if (!$config['enabled']) {
875+
return;
876+
}
877+
878+
$loader->load('serializer.xml');
879+
$chainLoader = $container->getDefinition('serializer.mapping.chain_loader');
880+
881+
$serializerLoaders = array();
882+
if (isset($config['enable_annotations']) && $config['enable_annotations']) {
883+
$annotationLoader = new Definition(
884+
'Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader',
885+
array(new Reference('annotation_reader'))
886+
);
887+
$annotationLoader->setPublic(false);
888+
889+
$serializerLoaders[] = $annotationLoader;
890+
}
891+
892+
$bundles = $container->getParameter('kernel.bundles');
893+
foreach ($bundles as $bundle) {
894+
$reflection = new \ReflectionClass($bundle);
895+
$dirname = dirname($reflection->getFilename());
896+
897+
if (is_file($file = $dirname.'/Resources/config/serialization.xml')) {
898+
$definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array(realpath($file)));
899+
$definition->setPublic(false);
900+
901+
$serializerLoaders[] = $definition;
902+
$container->addResource(new FileResource($file));
903+
}
904+
905+
if (is_file($file = $dirname.'/Resources/config/serialization.yml')) {
906+
$definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader', array(realpath($file)));
907+
$definition->setPublic(false);
908+
909+
$serializerLoaders[] = $definition;
910+
$container->addResource(new FileResource($file));
911+
}
912+
913+
if (is_dir($dir = $dirname.'/Resources/config/serialization')) {
914+
foreach (Finder::create()->files()->in($dir)->name('*.xml') as $file) {
915+
$definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader', array($file->getRealpath()));
916+
$definition->setPublic(false);
917+
918+
$serializerLoaders[] = $definition;
919+
}
920+
foreach (Finder::create()->files()->in($dir)->name('*.yml') as $file) {
921+
$definition = new Definition('Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader', array($file->getRealpath()));
922+
$definition->setPublic(false);
923+
924+
$serializerLoaders[] = $definition;
925+
}
926+
927+
$container->addResource(new DirectoryResource($dir));
928+
}
929+
}
930+
931+
$chainLoader->replaceArgument(0, $serializerLoaders);
932+
933+
if (isset($config['cache']) && $config['cache']) {
934+
$container->setParameter(
935+
'serializer.mapping.cache.prefix',
936+
'serializer_'.hash('sha256', $container->getParameter('kernel.root_dir'))
937+
);
938+
939+
$container->getDefinition('serializer.mapping.class_metadata_factory')->replaceArgument(
940+
1, new Reference($config['cache'])
941+
);
942+
}
943+
}
944+
877945
/**
878946
* Returns the base path for the XSD files.
879947
*

Resources/config/schema/symfony-1.0.xsd

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
<xsd:element name="validation" type="validation" minOccurs="0" maxOccurs="1" />
3333
<xsd:element name="annotations" type="annotations" minOccurs="0" maxOccurs="1" />
3434
<xsd:element name="property-access" type="property_access" minOccurs="0" maxOccurs="1" />
35+
<xsd:element name="serializer" type="serializer" minOccurs="0" maxOccurs="1" />
3536
</xsd:all>
3637

3738
<xsd:attribute name="http-method-override" type="xsd:boolean" />
@@ -196,4 +197,10 @@
196197
<xsd:attribute name="magic-call" type="xsd:boolean" />
197198
<xsd:attribute name="throw-exception-on-invalid-index" type="xsd:boolean" />
198199
</xsd:complexType>
200+
201+
<xsd:complexType name="serializer">
202+
<xsd:attribute name="enabled" type="xsd:boolean" />
203+
<xsd:attribute name="cache" type="xsd:string" />
204+
<xsd:attribute name="enable-annotations" type="xsd:boolean" />
205+
</xsd:complexType>
199206
</xsd:schema>

0 commit comments

Comments
 (0)