From dd69b8875dc2477a12edc18f1baaf0113c8331b3 Mon Sep 17 00:00:00 2001 From: Julien Falque Date: Mon, 7 Nov 2016 20:38:43 +0100 Subject: [PATCH 01/81] Fix bundle commands are not available via find() --- .../FrameworkBundle/Console/Application.php | 10 ++++ .../Tests/Console/ApplicationTest.php | 46 +++++++++++-------- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Application.php b/src/Symfony/Bundle/FrameworkBundle/Console/Application.php index 221a00425069b..6e6aca6043c67 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Application.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Application.php @@ -90,6 +90,16 @@ public function doRun(InputInterface $input, OutputInterface $output) return parent::doRun($input, $output); } + /** + * {@inheritdoc} + */ + public function find($name) + { + $this->registerCommands(); + + return parent::find($name); + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php index fc0e7654db2ca..a944da863f6d0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php @@ -32,8 +32,7 @@ public function testBundleInterfaceImplementation() public function testBundleCommandsAreRegistered() { - $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle'); - $bundle->expects($this->once())->method('registerCommands'); + $bundle = $this->createBundleMock(array()); $kernel = $this->getKernel(array($bundle), true); @@ -46,8 +45,7 @@ public function testBundleCommandsAreRegistered() public function testBundleCommandsAreRetrievable() { - $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle'); - $bundle->expects($this->once())->method('registerCommands'); + $bundle = $this->createBundleMock(array()); $kernel = $this->getKernel(array($bundle)); @@ -60,47 +58,41 @@ public function testBundleCommandsAreRetrievable() public function testBundleSingleCommandIsRetrievable() { - $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle'); - $bundle->expects($this->once())->method('registerCommands'); + $command = new Command('example'); + + $bundle = $this->createBundleMock(array($command)); $kernel = $this->getKernel(array($bundle)); $application = new Application($kernel); - $command = new Command('example'); - $application->add($command); - $this->assertSame($command, $application->get('example')); } public function testBundleCommandCanBeFound() { - $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle'); - $bundle->expects($this->once())->method('registerCommands'); + $command = new Command('example'); + + $bundle = $this->createBundleMock(array($command)); $kernel = $this->getKernel(array($bundle)); $application = new Application($kernel); - $command = new Command('example'); - $application->add($command); - $this->assertSame($command, $application->find('example')); } public function testBundleCommandCanBeFoundByAlias() { - $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle'); - $bundle->expects($this->once())->method('registerCommands'); + $command = new Command('example'); + $command->setAliases(array('alias')); + + $bundle = $this->createBundleMock(array($command)); $kernel = $this->getKernel(array($bundle)); $application = new Application($kernel); - $command = new Command('example'); - $command->setAliases(array('alias')); - $application->add($command); - $this->assertSame($command, $application->find('alias')); } @@ -167,4 +159,18 @@ private function getKernel(array $bundles, $useDispatcher = false) return $kernel; } + + private function createBundleMock(array $commands) + { + $bundle = $this->getMock('Symfony\Component\HttpKernel\Bundle\Bundle'); + $bundle + ->expects($this->once()) + ->method('registerCommands') + ->will($this->returnCallback(function (Application $application) use ($commands) { + $application->addCommands($commands); + })) + ; + + return $bundle; + } } From bb3ee76d566ad61982b9f3dee0dc2fdee4a9439c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 15 Nov 2016 22:27:40 +0100 Subject: [PATCH 02/81] [Serializer] Optimize max depth checking --- .../Normalizer/AbstractObjectNormalizer.php | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index 9ff231e7a426c..577edc1a7067f 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -17,6 +17,7 @@ use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; use Symfony\Component\PropertyInfo\Type; +use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; use Symfony\Component\Serializer\NameConverter\NameConverterInterface; @@ -67,9 +68,10 @@ public function normalize($object, $format = null, array $context = array()) $stack = array(); $attributes = $this->getAttributes($object, $format, $context); $class = get_class($object); + $attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null; foreach ($attributes as $attribute) { - if ($this->isMaxDepthReached($class, $attribute, $context)) { + if (null !== $attributesMetadata && $this->isMaxDepthReached($attributesMetadata, $class, $attribute, $context)) { continue; } @@ -303,42 +305,35 @@ private function updateData(array $data, $attribute, $attributeValue) /** * Is the max depth reached for the given attribute? * - * @param string $class - * @param string $attribute - * @param array $context + * @param AttributeMetadataInterface[] $attributesMetadata + * @param string $class + * @param string $attribute + * @param array $context * * @return bool */ - private function isMaxDepthReached($class, $attribute, array &$context) + private function isMaxDepthReached(array $attributesMetadata, $class, $attribute, array &$context) { - if (!$this->classMetadataFactory || !isset($context[static::ENABLE_MAX_DEPTH])) { + if ( + !isset($context[static::ENABLE_MAX_DEPTH]) || + !isset($attributesMetadata[$attribute]) || + null === $maxDepth = $attributesMetadata[$attribute]->getMaxDepth() + ) { return false; } - $classMetadata = $this->classMetadataFactory->getMetadataFor($class); - $attributesMetadata = $classMetadata->getAttributesMetadata(); - - if (!isset($attributesMetadata[$attribute])) { - return false; - } + $key = sprintf(static::DEPTH_KEY_PATTERN, $class, $attribute); + if (!isset($context[$key])) { + $context[$key] = 1; - $maxDepth = $attributesMetadata[$attribute]->getMaxDepth(); - if (null === $maxDepth) { return false; } - $key = sprintf(static::DEPTH_KEY_PATTERN, $class, $attribute); - $keyExist = isset($context[$key]); - - if ($keyExist && $context[$key] === $maxDepth) { + if ($context[$key] === $maxDepth) { return true; } - if ($keyExist) { - ++$context[$key]; - } else { - $context[$key] = 1; - } + ++$context[$key]; return false; } From 2acaf5f5112ea353e04879e91e116904d9ebf8e7 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 2 Nov 2016 09:57:00 +0100 Subject: [PATCH 03/81] [github] Tweak PR template --- .github/PULL_REQUEST_TEMPLATE.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 99ba8e00213af..216a2ba4e5625 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,11 +1,19 @@ | Q | A | ------------- | --- -| Branch? | "master" for new features / 2.7, 2.8 or 3.1 for fixes +| Branch? | master / 2.7, 2.8, 3.1 or 3.2 | Bug fix? | yes/no | New feature? | yes/no | BC breaks? | yes/no | Deprecations? | yes/no | Tests pass? | yes/no -| Fixed tickets | comma-separated list of tickets fixed by the PR, if any +| Fixed tickets | #... | License | MIT -| Doc PR | reference to the documentation PR, if any +| Doc PR | symfony/symfony-docs#... + + From 70c42f2676eb82ba2d6137919ddf50b41eaa73ee Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Wed, 16 Nov 2016 18:59:59 +0100 Subject: [PATCH 04/81] Cast result to int before adding to it This fixes the occasional warning about non-numeric values when using PHP 7.1 --- .../Loader/XmlFileLoader.php | 23 ++++++++++--------- .../xml/with_key_outside_collection.xml | 9 ++++++++ .../Tests/Loader/XmlFileLoaderTest.php | 9 ++++++++ 3 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/with_key_outside_collection.xml diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index e60c2f7df76c1..b3e4ef4d3e7c1 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -346,21 +346,22 @@ private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true) $arg->setAttribute('key', $arg->getAttribute('name')); } - if (!$arg->hasAttribute('key')) { - $key = !$arguments ? 0 : max(array_keys($arguments)) + 1; - } else { - $key = $arg->getAttribute('key'); - } - - // parameter keys are case insensitive - if ('parameter' == $name && $lowercase) { - $key = strtolower($key); - } - // this is used by DefinitionDecorator to overwrite a specific // argument of the parent definition if ($arg->hasAttribute('index')) { $key = 'index_'.$arg->getAttribute('index'); + } elseif (!$arg->hasAttribute('key')) { + // Append an empty argument, then fetch its key to overwrite it later + $arguments[] = null; + $keys = array_keys($arguments); + $key = array_pop($keys); + } else { + $key = $arg->getAttribute('key'); + + // parameter keys are case insensitive + if ('parameter' == $name && $lowercase) { + $key = strtolower($key); + } } switch ($arg->getAttribute('type')) { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/with_key_outside_collection.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/with_key_outside_collection.xml new file mode 100644 index 0000000000000..5f3a2843612df --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/with_key_outside_collection.xml @@ -0,0 +1,9 @@ + + + + + foo + bar + + + diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index 2de5915f4ef41..fd4517228430c 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -542,4 +542,13 @@ public function testLoadInlinedServices() $this->assertSame('Baz', $barConfigurator[0]->getClass()); $this->assertSame('configureBar', $barConfigurator[1]); } + + public function testArgumentWithKeyOutsideCollection() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('with_key_outside_collection.xml'); + + $this->assertSame(array('type' => 'foo', 'bar'), $container->getDefinition('foo')->getArguments()); + } } From 7e8490715c29e02270cee788f09a2b0e43496a5e Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Sun, 6 Nov 2016 15:11:25 +0100 Subject: [PATCH 05/81] [Form] fixed "empty_value" option deprecation --- .../Component/Form/Extension/Core/Type/ChoiceType.php | 9 +++++++-- .../Component/Form/Extension/Core/Type/DateType.php | 4 ++-- .../Component/Form/Extension/Core/Type/TimeType.php | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php index 49bea1aceca09..d376109828718 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php @@ -39,6 +39,11 @@ class ChoiceType extends AbstractType { + /** + * @internal To be removed in 3.0 + */ + const DEPRECATED_EMPTY_VALUE = '__deprecated_empty_value__'; + /** * Caches created choice lists. * @@ -336,7 +341,7 @@ public function configureOptions(OptionsResolver $resolver) }; $placeholderNormalizer = function (Options $options, $placeholder) use ($that) { - if (!is_object($options['empty_value']) || !$options['empty_value'] instanceof \Exception) { + if ($that::DEPRECATED_EMPTY_VALUE !== $options['empty_value']) { @trigger_error(sprintf('The form option "empty_value" of the "%s" form type (%s) is deprecated since version 2.6 and will be removed in 3.0. Use "placeholder" instead.', $that->getName(), __CLASS__), E_USER_DEPRECATED); if (null === $placeholder || '' === $placeholder) { @@ -388,7 +393,7 @@ public function configureOptions(OptionsResolver $resolver) 'preferred_choices' => array(), 'group_by' => null, 'empty_data' => $emptyData, - 'empty_value' => new \Exception(), // deprecated + 'empty_value' => self::DEPRECATED_EMPTY_VALUE, 'placeholder' => $placeholder, 'error_bubbling' => false, 'compound' => $compound, diff --git a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php index ae4c6bacf2066..8af7a96f13cd6 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/DateType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/DateType.php @@ -183,7 +183,7 @@ public function configureOptions(OptionsResolver $resolver) }; $placeholderNormalizer = function (Options $options, $placeholder) use ($placeholderDefault) { - if (!is_object($options['empty_value']) || !$options['empty_value'] instanceof \Exception) { + if (ChoiceType::DEPRECATED_EMPTY_VALUE !== $options['empty_value']) { @trigger_error('The form option "empty_value" is deprecated since version 2.6 and will be removed in 3.0. Use "placeholder" instead.', E_USER_DEPRECATED); $placeholder = $options['empty_value']; @@ -218,7 +218,7 @@ public function configureOptions(OptionsResolver $resolver) 'format' => $format, 'model_timezone' => null, 'view_timezone' => null, - 'empty_value' => new \Exception(), // deprecated + 'empty_value' => ChoiceType::DEPRECATED_EMPTY_VALUE, 'placeholder' => $placeholder, 'html5' => true, // Don't modify \DateTime classes by reference, we treat diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php index 8232170278502..dab0572927be8 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimeType.php @@ -171,7 +171,7 @@ public function configureOptions(OptionsResolver $resolver) }; $placeholderNormalizer = function (Options $options, $placeholder) use ($placeholderDefault) { - if (!is_object($options['empty_value']) || !$options['empty_value'] instanceof \Exception) { + if (ChoiceType::DEPRECATED_EMPTY_VALUE !== $options['empty_value']) { @trigger_error('The form option "empty_value" is deprecated since version 2.6 and will be removed in 3.0. Use "placeholder" instead.', E_USER_DEPRECATED); $placeholder = $options['empty_value']; @@ -203,7 +203,7 @@ public function configureOptions(OptionsResolver $resolver) 'with_seconds' => false, 'model_timezone' => null, 'view_timezone' => null, - 'empty_value' => new \Exception(), // deprecated + 'empty_value' => ChoiceType::DEPRECATED_EMPTY_VALUE, 'placeholder' => $placeholder, 'html5' => true, // Don't modify \DateTime classes by reference, we treat From de7b326c7ce13f74eadcb0fbe7dd773a0cbe269b Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sat, 26 Nov 2016 16:44:35 +0100 Subject: [PATCH 06/81] Maintain the selected panel when redirecting to another profile --- .../WebProfilerBundle/Resources/views/Profiler/layout.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig index 146718ac30c7f..804b03a95ef27 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig @@ -39,7 +39,7 @@ {%- else -%} {{ redirect_route }} {%- endif %} - ({{ redirect.token }}) + ({{ redirect.token }}) {%- endif %} From 595a9781e2482e2cd0929a888eb99b8d90696b2c Mon Sep 17 00:00:00 2001 From: Antanas Arvasevicius Date: Sat, 10 Sep 2016 20:39:00 +0300 Subject: [PATCH 07/81] [DependencyInjection] PhpDumper.php: hasReference() should not search references in lazy service arguments. --- .../Compiler/CheckCircularReferencesPass.php | 17 ++++--- .../DependencyInjection/Dumper/PhpDumper.php | 7 +++ .../Tests/Dumper/PhpDumperTest.php | 51 +++++++++++++++++++ .../Tests/Fixtures/includes/classes.php | 30 +++++++++++ 4 files changed, 99 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php index d7570ddc2c4d1..b6a898736f653 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php @@ -60,14 +60,19 @@ private function checkOutEdges(array $edges) $id = $node->getId(); if (empty($this->checkedNodes[$id])) { - $searchKey = array_search($id, $this->currentPath); - $this->currentPath[] = $id; - if (false !== $searchKey) { - throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey)); - } + // * don't check circular dependencies in lazy services. + $isLazy = $node->getValue() && $node->getValue()->isLazy(); + if (!$isLazy) { + $searchKey = array_search($id, $this->currentPath); + $this->currentPath[] = $id; + + if (false !== $searchKey) { + throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey)); + } - $this->checkOutEdges($node->getOutEdges()); + $this->checkOutEdges($node->getOutEdges()); + } $this->checkedNodes[$id] = true; array_pop($this->currentPath); diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 2f7a01bc081d4..bf5956b394d43 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1293,6 +1293,13 @@ private function hasReference($id, array $arguments, $deep = false, array &$visi $visited[$argumentId] = true; $service = $this->container->getDefinition($argumentId); + + // if exists proxy dumper (proxy-manager) don't search references in lazy services. + // As these services will be instantiated lazily and don't have direct related references. + if ($service->isLazy() && !($this->getProxyDumper() instanceof NullDumper)) { + continue; + } + $arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties()); if ($this->hasReference($id, $arguments, $deep, $visited)) { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 72215e8c486a5..ab9d5926106a5 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\DependencyInjection\Tests\Dumper; +use DummyProxyDumper; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Dumper\PhpDumper; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; @@ -19,6 +20,8 @@ use Symfony\Component\DependencyInjection\Variable; use Symfony\Component\ExpressionLanguage\Expression; +require_once __DIR__.'/../Fixtures/includes/classes.php'; + class PhpDumperTest extends \PHPUnit_Framework_TestCase { protected static $fixturesPath; @@ -286,4 +289,52 @@ public function testInitializePropertiesBeforeMethodCalls() $container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls(); $this->assertTrue($container->get('bar')->callPassed(), '->dump() initializes properties before method calls'); } + + public function testCircularReferenceAllowanceForLazyServices() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->addArgument(new Reference('bar')); + $container->register('bar', 'stdClass')->setLazy(true)->addArgument(new Reference('foo')); + $container->compile(); + + $dumper = new PhpDumper($container); + $dumper->dump(); + } + + public function testCircularReferenceAllowanceForInlinedDefinitionsForLazyServices() + { + /* + * test graph: + * [connection] -> [event_manager] --> [entity_manager](lazy) + * | + * --(call)- addEventListener ("@lazy_service") + * + * [lazy_service](lazy) -> [entity_manager](lazy) + * + */ + + $container = new ContainerBuilder(); + + $eventManagerDefinition = new Definition('stdClass'); + + $connectionDefinition = $container->register('connection', 'stdClass'); + $connectionDefinition->addArgument($eventManagerDefinition); + + $container->register('entity_manager', 'stdClass') + ->setLazy(true) + ->addArgument(new Reference('connection')); + + $lazyServiceDefinition = $container->register('lazy_service', 'stdClass'); + $lazyServiceDefinition->setLazy(true); + $lazyServiceDefinition->addArgument(new Reference('entity_manager')); + + $eventManagerDefinition->addMethodCall('addEventListener', array(new Reference('lazy_service'))); + + $container->compile(); + + $dumper = new PhpDumper($container); + + $dumper->setProxyDumper(new DummyProxyDumper()); + $dumper->dump(); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php index 48b687c1f4e53..cdc89e42ab3a8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php @@ -1,5 +1,8 @@ configure(); @@ -76,3 +79,30 @@ public function callPassed() return $this->callPassed; } } + +class DummyProxyDumper implements ProxyDumper +{ + /** + * {@inheritdoc} + */ + public function isProxyCandidate(Definition $definition) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function getProxyFactoryCode(Definition $definition, $id) + { + return ''; + } + + /** + * {@inheritdoc} + */ + public function getProxyCode(Definition $definition) + { + return ''; + } +} From 4514c1b0c487c061a0fd2d18afe0f2c6a7e2388b Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Tue, 29 Nov 2016 21:18:47 +0100 Subject: [PATCH 08/81] [Serializer] Add deprecation missing from UPGRADE files --- UPGRADE-3.2.md | 5 +++++ UPGRADE-4.0.md | 2 ++ 2 files changed, 7 insertions(+) diff --git a/UPGRADE-3.2.md b/UPGRADE-3.2.md index f4b043c754c66..5862071d94093 100644 --- a/UPGRADE-3.2.md +++ b/UPGRADE-3.2.md @@ -116,6 +116,11 @@ HttpFoundation - `isInvalid`/`isSuccessful`/`isRedirection`/`isClientError`/`isServerError` - `isOk`/`isForbidden`/`isNotFound`/`isRedirect`/`isEmpty` +Serializer +---------- + + * Method `AbstractNormalizer::instantiateObject()` will have a 6th `$format = null` argument in Symfony 4.0. Not defining it when overriding the method is deprecated. + TwigBridge ---------- diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index 483b7e6ed1447..227e9b93f36e8 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -170,6 +170,8 @@ Serializer * The ability to pass a Doctrine `Cache` instance to the `ClassMetadataFactory` class has been removed. You should use the `CacheClassMetadataFactory` class instead. + + * Not defining the 6th argument `$format = null` of the `AbstractNormalizer::instantiateObject()` method when overriding it is not supported anymore. Translation ----------- From 597bbdc41845a65e04f7deab7cd0d261791d4ce6 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 30 Nov 2016 09:00:20 +0100 Subject: [PATCH 09/81] Lines length should be 80 or less characters --- UPGRADE-3.2.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/UPGRADE-3.2.md b/UPGRADE-3.2.md index 5862071d94093..97a8aeba029c0 100644 --- a/UPGRADE-3.2.md +++ b/UPGRADE-3.2.md @@ -119,7 +119,9 @@ HttpFoundation Serializer ---------- - * Method `AbstractNormalizer::instantiateObject()` will have a 6th `$format = null` argument in Symfony 4.0. Not defining it when overriding the method is deprecated. + * Method `AbstractNormalizer::instantiateObject()` will have a 6th + `$format = null` argument in Symfony 4.0. Not defining it when overriding + the method is deprecated. TwigBridge ---------- From d681c1abc4c2e3e8c616edc7a9aa8ff2582a724f Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 30 Nov 2016 09:01:12 +0100 Subject: [PATCH 10/81] Lines length should be 80 or less characters --- UPGRADE-4.0.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index 227e9b93f36e8..2cd22e1a1236c 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -171,7 +171,9 @@ Serializer class has been removed. You should use the `CacheClassMetadataFactory` class instead. - * Not defining the 6th argument `$format = null` of the `AbstractNormalizer::instantiateObject()` method when overriding it is not supported anymore. + * Not defining the 6th argument `$format = null` of the + `AbstractNormalizer::instantiateObject()` method when overriding it is not + supported anymore. Translation ----------- From b5520e92c9ecc5d11741dbcdb1542e17d6cc996e Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 30 Nov 2016 10:16:00 +0100 Subject: [PATCH 11/81] bumped Symfony version to 3.2.1 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index b76db82d81b7d..eefd76b16d8f7 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '3.2.0'; - const VERSION_ID = 30200; + const VERSION = '3.2.1-DEV'; + const VERSION_ID = 30201; const MAJOR_VERSION = 3; const MINOR_VERSION = 2; - const RELEASE_VERSION = 0; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 1; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '07/2017'; const END_OF_LIFE = '01/2018'; From 07cdfd533d5ff9c710600d552f0bb5b2f48c8ee3 Mon Sep 17 00:00:00 2001 From: Maxime STEINHAUSSER Date: Wed, 30 Nov 2016 15:40:17 +0100 Subject: [PATCH 12/81] [WebProfiler][Translator] Fix TranslationDataCollector should use cloneVar --- .../Resources/views/Collector/translation.html.twig | 3 +-- .../DataCollector/TranslationDataCollector.php | 4 ++-- .../Tests/DataCollector/TranslationDataCollectorTest.php | 9 ++++++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig index 0be04e76117d8..f5ff17680a236 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig @@ -183,8 +183,7 @@ {% endif %} diff --git a/src/Symfony/Component/Translation/DataCollector/TranslationDataCollector.php b/src/Symfony/Component/Translation/DataCollector/TranslationDataCollector.php index cb59d0a7e70e4..6b5e165aad9a7 100644 --- a/src/Symfony/Component/Translation/DataCollector/TranslationDataCollector.php +++ b/src/Symfony/Component/Translation/DataCollector/TranslationDataCollector.php @@ -101,12 +101,12 @@ private function sanitizeCollectedMessages($messages) if (!isset($result[$messageId])) { $message['count'] = 1; - $message['parameters'] = !empty($message['parameters']) ? array($message['parameters']) : array(); + $message['parameters'] = !empty($message['parameters']) ? array($this->cloneVar($message['parameters'])) : array(); $messages[$key]['translation'] = $this->sanitizeString($message['translation']); $result[$messageId] = $message; } else { if (!empty($message['parameters'])) { - $result[$messageId]['parameters'][] = $message['parameters']; + $result[$messageId]['parameters'][] = $this->cloneVar($message['parameters']); } ++$result[$messageId]['count']; diff --git a/src/Symfony/Component/Translation/Tests/DataCollector/TranslationDataCollectorTest.php b/src/Symfony/Component/Translation/Tests/DataCollector/TranslationDataCollectorTest.php index 3d1e86e22cbed..ba9df0751b389 100644 --- a/src/Symfony/Component/Translation/Tests/DataCollector/TranslationDataCollectorTest.php +++ b/src/Symfony/Component/Translation/Tests/DataCollector/TranslationDataCollectorTest.php @@ -13,6 +13,7 @@ use Symfony\Component\Translation\DataCollectorTranslator; use Symfony\Component\Translation\DataCollector\TranslationDataCollector; +use Symfony\Component\VarDumper\Cloner\VarCloner; class TranslationDataCollectorTest extends \PHPUnit_Framework_TestCase { @@ -39,6 +40,8 @@ public function testCollectEmptyMessages() public function testCollect() { + $cloner = new VarCloner(); + $collectedMessages = array( array( 'id' => 'foo', @@ -115,9 +118,9 @@ public function testCollect() 'state' => DataCollectorTranslator::MESSAGE_MISSING, 'count' => 3, 'parameters' => array( - array('%count%' => 3), - array('%count%' => 3), - array('%count%' => 4, '%foo%' => 'bar'), + $cloner->cloneVar(array('%count%' => 3)), + $cloner->cloneVar(array('%count%' => 3)), + $cloner->cloneVar(array('%count%' => 4, '%foo%' => 'bar')), ), 'transChoiceNumber' => 3, ), From 695d10071b92725a57f5ae74b03c938bcd535708 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 29 Nov 2016 18:32:01 +0100 Subject: [PATCH 13/81] [FrameworkBundle] Resolve env params in debug:config command --- .../Command/ConfigDebugCommand.php | 2 +- .../Command/ContainerDebugCommand.php | 7 ++++- .../Console/Descriptor/Descriptor.php | 2 +- .../DependencyInjection/ContainerBuilder.php | 31 +++++++++++++------ .../Tests/ContainerBuilderTest.php | 2 +- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php index 22811c6558894..17571fb48ad25 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php @@ -80,7 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->validateConfiguration($extension, $configuration); - $configs = $container->getParameterBag()->resolveValue($configs); + $configs = $container->resolveEnvPlaceholders($container->getParameterBag()->resolveValue($configs)); $processor = new Processor(); $config = $processor->processConfiguration($configuration, $configs); diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php index 981df241cd3a1..c9d0e419e290e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php @@ -19,6 +19,7 @@ use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\Config\FileLocator; /** @@ -96,7 +97,11 @@ protected function execute(InputInterface $input, OutputInterface $output) $object = $this->getContainerBuilder(); if ($input->getOption('parameters')) { - $object = $object->getParameterBag(); + $parameters = array(); + foreach ($object->getParameterBag()->all() as $k => $v) { + $parameters[$k] = $object->resolveEnvPlaceholders($v); + } + $object = new ParameterBag($parameters); $options = array(); } elseif ($parameter = $input->getOption('parameter')) { $options = array('parameter' => $parameter); diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php index da809aea8df63..95c9324662490 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/Descriptor.php @@ -57,7 +57,7 @@ public function describe(OutputInterface $output, $object, array $options = arra $this->describeContainerService($this->resolveServiceDefinition($object, $options['id']), $options); break; case $object instanceof ContainerBuilder && isset($options['parameter']): - $this->describeContainerParameter($object->getParameter($options['parameter']), $options); + $this->describeContainerParameter($object->resolveEnvPlaceholders($object->getParameter($options['parameter'])), $options); break; case $object instanceof ContainerBuilder: $this->describeContainerServices($object, $options); diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 58a38048f7530..45c6f2cf677b0 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -1026,34 +1026,47 @@ public function getExpressionLanguageProviders() } /** - * Resolves env parameter placeholders in a string. + * Resolves env parameter placeholders in a string or an array. * - * @param string $string The string to resolve + * @param mixed $value The value to resolve * @param string|null $format A sprintf() format to use as replacement for env placeholders or null to use the default parameter format * @param array &$usedEnvs Env vars found while resolving are added to this array * * @return string The string with env parameters resolved */ - public function resolveEnvPlaceholders($string, $format = null, array &$usedEnvs = null) + public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null) { - $bag = $this->getParameterBag(); - $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders; - if (null === $format) { $format = '%%env(%s)%%'; } + if (is_array($value)) { + $result = array(); + foreach ($value as $k => $v) { + $result[$this->resolveEnvPlaceholders($k, $format, $usedEnvs)] = $this->resolveEnvPlaceholders($v, $format, $usedEnvs); + } + + return $result; + } + + if (!is_string($value)) { + return $value; + } + + $bag = $this->getParameterBag(); + $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders; + foreach ($envPlaceholders as $env => $placeholders) { foreach ($placeholders as $placeholder) { - if (false !== stripos($string, $placeholder)) { - $string = str_ireplace($placeholder, sprintf($format, $env), $string); + if (false !== stripos($value, $placeholder)) { + $value = str_ireplace($placeholder, sprintf($format, $env), $value); $usedEnvs[$env] = $env; $this->envCounters[$env] = isset($this->envCounters[$env]) ? 1 + $this->envCounters[$env] : 1; } } } - return $string; + return $value; } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 155da75fb7958..9ba5a36c4d55d 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -495,7 +495,7 @@ public function testMerge() $bag = new EnvPlaceholderParameterBag(); $bag->get('env(Foo)'); $config = new ContainerBuilder($bag); - $config->resolveEnvPlaceholders($bag->get('env(Bar)')); + $this->assertSame(array('%env(Bar)%'), $config->resolveEnvPlaceholders(array($bag->get('env(Bar)')))); $container->merge($config); $this->assertEquals(array('Foo' => 0, 'Bar' => 1), $container->getEnvCounters()); } From 44a0ef169c74df3bc90cae604ae26b434b7fce1b Mon Sep 17 00:00:00 2001 From: Maxime STEINHAUSSER Date: Wed, 30 Nov 2016 16:30:36 +0100 Subject: [PATCH 14/81] [WebProfilerBundle] Fix vertical alignment for profiler open action --- .../Resources/views/Profiler/open.css.twig | 6 ++++-- .../Resources/views/Profiler/open.html.twig | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig index 9e290b22e6432..144e86f062bb1 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig @@ -31,21 +31,23 @@ body { background-color: #222; position: fixed; top: 0; + display: flex; width: 100%; } .header h1 { - float: left; color: #FFF; font-weight: normal; font-size: 21px; margin: 0; padding: 10px 10px 8px; + word-break: break-all; } a.doc { - float: right; color: #FFF; text-decoration: none; + margin: auto; + margin-right: 10px; } a.doc:hover { diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.html.twig index 438146b633ecb..9b482f1f0aa96 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.html.twig @@ -8,8 +8,8 @@ {% block body %}
- Open in your IDE?

{{ file }} line {{ line }}

+ Open in your IDE?
{{ filename|file_excerpt(line, -1) }} From 18fc6b54da0108cb0393142066affa005c99e88b Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Wed, 30 Nov 2016 19:19:43 +0100 Subject: [PATCH 15/81] [Console] Fix wrong handling of multiline arg/opt descriptions --- .../Console/Descriptor/TextDescriptor.php | 16 ++++++++-------- .../Console/Tests/Fixtures/input_argument_4.txt | 2 +- .../Console/Tests/Fixtures/input_option_5.txt | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Console/Descriptor/TextDescriptor.php b/src/Symfony/Component/Console/Descriptor/TextDescriptor.php index 0d722ed5aaeae..eb02c89dfa372 100644 --- a/src/Symfony/Component/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Component/Console/Descriptor/TextDescriptor.php @@ -38,13 +38,13 @@ protected function describeInputArgument(InputArgument $argument, array $options } $totalWidth = isset($options['total_width']) ? $options['total_width'] : strlen($argument->getName()); - $spacingWidth = $totalWidth - strlen($argument->getName()) + 2; + $spacingWidth = $totalWidth - strlen($argument->getName()); - $this->writeText(sprintf(' %s%s%s%s', + $this->writeText(sprintf(' %s %s%s%s', $argument->getName(), str_repeat(' ', $spacingWidth), - // + 17 = 2 spaces + + + 2 spaces - preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 17), $argument->getDescription()), + // + 4 = 2 spaces before , 2 spaces after + preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $argument->getDescription()), $default ), $options); } @@ -75,13 +75,13 @@ protected function describeInputOption(InputOption $option, array $options = arr sprintf('--%s%s', $option->getName(), $value) ); - $spacingWidth = $totalWidth - strlen($synopsis) + 2; + $spacingWidth = $totalWidth - strlen($synopsis); - $this->writeText(sprintf(' %s%s%s%s%s', + $this->writeText(sprintf(' %s %s%s%s%s', $synopsis, str_repeat(' ', $spacingWidth), - // + 17 = 2 spaces + + + 2 spaces - preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 17), $option->getDescription()), + // + 4 = 2 spaces before , 2 spaces after + preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $option->getDescription()), $default, $option->isArray() ? ' (multiple values allowed)' : '' ), $options); diff --git a/src/Symfony/Component/Console/Tests/Fixtures/input_argument_4.txt b/src/Symfony/Component/Console/Tests/Fixtures/input_argument_4.txt index aa74e8ceb2507..fc7d669a112ec 100644 --- a/src/Symfony/Component/Console/Tests/Fixtures/input_argument_4.txt +++ b/src/Symfony/Component/Console/Tests/Fixtures/input_argument_4.txt @@ -1,2 +1,2 @@ argument_name multiline - argument description + argument description diff --git a/src/Symfony/Component/Console/Tests/Fixtures/input_option_5.txt b/src/Symfony/Component/Console/Tests/Fixtures/input_option_5.txt index 4368883cc7217..9563b4cab142c 100644 --- a/src/Symfony/Component/Console/Tests/Fixtures/input_option_5.txt +++ b/src/Symfony/Component/Console/Tests/Fixtures/input_option_5.txt @@ -1,2 +1,2 @@ -o, --option_name=OPTION_NAME multiline - option description + option description From 26f588a7b584b3e39f6223d06bbb305e00e6453c Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Thu, 1 Dec 2016 15:23:59 +0100 Subject: [PATCH 16/81] Fix unresolved parameters from default bundle configs in debug:config --- .../Bundle/FrameworkBundle/Command/ConfigDebugCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php index 9059905e04f54..22a98d8023a4e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php @@ -90,7 +90,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln(sprintf('# Current configuration for "%s"', $name)); } - $output->writeln(Yaml::dump(array($extension->getAlias() => $config), 10)); + $output->writeln(Yaml::dump(array($extension->getAlias() => $container->getParameterBag()->resolveValue($config)), 10)); } private function compileContainer() From 997beb21bf942c1f54ae225c8da61a13255ef396 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Thu, 1 Dec 2016 20:26:29 +0100 Subject: [PATCH 17/81] [WebProfilerBundle] Fix dump block is unfairly restrained --- .../Resources/views/Profiler/toolbar.css.twig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig index d87e81399d412..14dd2d4b591ce 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig @@ -356,11 +356,13 @@ border-color: #777; border-radius: 0; margin: 6px 0 12px 0; - width: 200px; } .sf-toolbar-block-dump pre.sf-dump:last-child { margin-bottom: 0; } +.sf-toolbar-block-dump .sf-toolbar-info-piece { + display: block; +} .sf-toolbar-block-dump .sf-toolbar-info-piece .sf-toolbar-file-line { color: #AAA; margin-left: 4px; From b0a8f8e376fabed0890c7ff32578acbfabb3785d Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Thu, 1 Dec 2016 11:14:27 -0500 Subject: [PATCH 18/81] Fixed max width from ajax request url element (td) --- .../WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig index d87e81399d412..12dd8a3d45302 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig @@ -315,7 +315,7 @@ padding: 4px; } .sf-ajax-request-url { - max-width: 300px; + max-width: 250px; line-height: 9px; overflow: hidden; text-overflow: ellipsis; From 22e56680564523010a1a8b603f76f6e603f762fb Mon Sep 17 00:00:00 2001 From: Nicolas Dewez Date: Thu, 1 Dec 2016 22:26:29 +0100 Subject: [PATCH 19/81] Fix hide button in toolbar --- .../Resources/views/Profiler/toolbar_js.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_js.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_js.html.twig index 1dfeb1a29c8eb..ea038277c4bec 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_js.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_js.html.twig @@ -66,7 +66,7 @@ } }; } - Sfjs.addEventListener(document.getElementById('sfToolbarHideButton-{{ token }}'), 'click', function () { + Sfjs.addEventListener(document.getElementById('sfToolbarHideButton-{{ token }}'), 'click', function (event) { event.preventDefault(); var p = this.parentNode; From 070800359e6901af225055c5c7b960ab38d0ff5d Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Wed, 30 Nov 2016 20:06:05 +0100 Subject: [PATCH 20/81] [Form] Remove unused var cloner property --- .../Form/Extension/DataCollector/FormDataCollector.php | 2 ++ .../Form/Extension/DataCollector/FormDataExtractor.php | 5 ----- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php index b72a5739f843d..624632f3b2ce8 100644 --- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php +++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php @@ -17,8 +17,10 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\DataCollector\DataCollector; use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter; +use Symfony\Component\Validator\ConstraintViolationInterface; use Symfony\Component\VarDumper\Caster\Caster; use Symfony\Component\VarDumper\Caster\ClassStub; +use Symfony\Component\VarDumper\Cloner\ClonerInterface; use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Component\VarDumper\Cloner\Stub; use Symfony\Component\VarDumper\Cloner\VarCloner; diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php index a09b87fa1c330..de6fac41231de 100644 --- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php +++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php @@ -23,11 +23,6 @@ */ class FormDataExtractor implements FormDataExtractorInterface { - /** - * @var VarCloner - */ - private $cloner; - /** * Constructs a new data extractor. */ From 2c818193c1ead4748a8f31d687418f0baff91898 Mon Sep 17 00:00:00 2001 From: Maxime STEINHAUSSER Date: Thu, 1 Dec 2016 11:14:14 +0100 Subject: [PATCH 21/81] [TwigBundle] Fix twig loader registered twice --- .../TwigBundle/DependencyInjection/Compiler/ExtensionPass.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php index 87469984688ab..d09de2d615c0a 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\TwigBundle\DependencyInjection\Compiler; +use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -73,7 +74,7 @@ public function process(ContainerBuilder $container) $loader->addTag('twig.loader'); $loader->setMethodCalls($container->getDefinition('twig.loader.filesystem')->getMethodCalls()); - $container->setDefinition('twig.loader.filesystem', $loader); + $container->setAlias('twig.loader.filesystem', new Alias('twig.loader.native_filesystem', false)); } if ($container->has('assets.packages')) { From b8e77792bc0c838650e3d9a3dec20fbc0fe86684 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Wed, 30 Nov 2016 17:57:42 -0500 Subject: [PATCH 22/81] Grouping FrameworkBundle upgrade notes --- UPGRADE-3.2.md | 74 ++++++++++++++++++++++++-------------------------- UPGRADE-4.0.md | 72 ++++++++++++++++++++++++------------------------ 2 files changed, 71 insertions(+), 75 deletions(-) diff --git a/UPGRADE-3.2.md b/UPGRADE-3.2.md index f4b043c754c66..a26ed257739ab 100644 --- a/UPGRADE-3.2.md +++ b/UPGRADE-3.2.md @@ -6,28 +6,6 @@ BrowserKit * Client HTTP user agent has been changed to 'Symfony BrowserKit' (was 'Symfony2 BrowserKit' before). -FrameworkBundle ---------------- - - * The `doctrine/annotations` dependency has been removed; require it via `composer - require doctrine/annotations` if you are using annotations in your project - * The `symfony/security-core` and `symfony/security-csrf` dependencies have - been removed; require them via `composer require symfony/security-core - symfony/security-csrf` if you depend on them and don't already depend on - `symfony/symfony` - * The `symfony/templating` dependency has been removed; require it via `composer - require symfony/templating` if you depend on it and don't already depend on - `symfony/symfony` - * The `symfony/translation` dependency has been removed; require it via `composer - require symfony/translation` if you depend on it and don't already depend on - `symfony/symfony` - * The `symfony/asset` dependency has been removed; require it via `composer - require symfony/asset` if you depend on it and don't already depend on - `symfony/symfony` - * The `Resources/public/images/*` files have been removed. - * The `Resources/public/css/*.css` files have been removed (they are now inlined - in TwigBundle). - Console ------- @@ -72,25 +50,26 @@ Form FrameworkBundle --------------- + * The `doctrine/annotations` dependency has been removed; require it via `composer + require doctrine/annotations` if you are using annotations in your project + * The `symfony/security-core` and `symfony/security-csrf` dependencies have + been removed; require them via `composer require symfony/security-core + symfony/security-csrf` if you depend on them and don't already depend on + `symfony/symfony` + * The `symfony/templating` dependency has been removed; require it via `composer + require symfony/templating` if you depend on it and don't already depend on + `symfony/symfony` + * The `symfony/translation` dependency has been removed; require it via `composer + require symfony/translation` if you depend on it and don't already depend on + `symfony/symfony` + * The `symfony/asset` dependency has been removed; require it via `composer + require symfony/asset` if you depend on it and don't already depend on + `symfony/symfony` + * The `Resources/public/images/*` files have been removed. + * The `Resources/public/css/*.css` files have been removed (they are now inlined + in TwigBundle). * The service `serializer.mapping.cache.doctrine.apc` is deprecated. APCu should now be automatically used when available. - -HttpKernel ----------- - - * `DataCollector::varToString()` is deprecated and will be removed in Symfony - 4.0. Use the `cloneVar()` method instead. - - * Surrogate name in a `Surrogate-Capability` HTTP request header has been changed to 'symfony'. - - Before: - ``` - Surrogate-Capability: symfony2="ESI/1.0" - ``` - - After: - ``` - Surrogate-Capability: symfony="ESI/1.0" ``` HttpFoundation @@ -116,6 +95,23 @@ HttpFoundation - `isInvalid`/`isSuccessful`/`isRedirection`/`isClientError`/`isServerError` - `isOk`/`isForbidden`/`isNotFound`/`isRedirect`/`isEmpty` +HttpKernel +---------- + + * `DataCollector::varToString()` is deprecated and will be removed in Symfony + 4.0. Use the `cloneVar()` method instead. + + * Surrogate name in a `Surrogate-Capability` HTTP request header has been changed to 'symfony'. + + Before: + ``` + Surrogate-Capability: symfony2="ESI/1.0" + ``` + + After: + ``` + Surrogate-Capability: symfony="ESI/1.0" + TwigBridge ---------- diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index 483b7e6ed1447..d018136932b56 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -182,6 +182,42 @@ TwigBridge * The possibility to inject the Form Twig Renderer into the form extension has been removed. Inject it into the `TwigRendererEngine` instead. +Validator +--------- + + * The `DateTimeValidator::PATTERN` constant was removed. + + * `Tests\Constraints\AbstractConstraintValidatorTest` has been removed in + favor of `Test\ConstraintValidatorTestCase`. + + Before: + + ```php + // ... + use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest; + + class MyCustomValidatorTest extends AbstractConstraintValidatorTest + { + // ... + } + ``` + + After: + + ```php + // ... + use Symfony\Component\Validator\Test\ConstraintValidatorTestCase; + + class MyCustomValidatorTest extends ConstraintValidatorTestCase + { + // ... + } + ``` + + * The default value of the strict option of the `Choice` Constraint has been + changed to `true` as of 4.0. If you need the the previous behaviour ensure to + set the option to `false`. + Yaml ---- @@ -273,39 +309,3 @@ Yaml the `!php/object` tag. * Duplicate mapping keys lead to a `ParseException`. - -Validator ---------- - - * The `DateTimeValidator::PATTERN` constant was removed. - - * `Tests\Constraints\AbstractConstraintValidatorTest` has been removed in - favor of `Test\ConstraintValidatorTestCase`. - - Before: - - ```php - // ... - use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest; - - class MyCustomValidatorTest extends AbstractConstraintValidatorTest - { - // ... - } - ``` - - After: - - ```php - // ... - use Symfony\Component\Validator\Test\ConstraintValidatorTestCase; - - class MyCustomValidatorTest extends ConstraintValidatorTestCase - { - // ... - } - ``` - - * The default value of the strict option of the `Choice` Constraint has been - changed to `true` as of 4.0. If you need the the previous behaviour ensure to - set the option to `false`. From 27de65aa144c089935ba6f318550237ae1508b9c Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Tue, 29 Nov 2016 20:46:44 +0100 Subject: [PATCH 23/81] [Serializer] Fix argument object denormalization --- .../Normalizer/AbstractNormalizer.php | 6 ++- .../DenormalizerDecoratorSerializer.php | 43 ------------------- .../Tests/Normalizer/ObjectNormalizerTest.php | 5 +-- .../Serializer/Tests/SerializerTest.php | 29 +++++++++++++ 4 files changed, 36 insertions(+), 47 deletions(-) delete mode 100644 src/Symfony/Component/Serializer/Tests/Fixtures/DenormalizerDecoratorSerializer.php diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index 82f6e1e2a8f39..cd46b5b97d20c 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -13,6 +13,7 @@ use Symfony\Component\Serializer\Exception\CircularReferenceException; use Symfony\Component\Serializer\Exception\InvalidArgumentException; +use Symfony\Component\Serializer\Exception\LogicException; use Symfony\Component\Serializer\Exception\RuntimeException; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface; @@ -336,8 +337,11 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref $parameterData = $data[$key]; try { if (null !== $constructorParameter->getClass()) { + if (!$this->serializer instanceof DenormalizerInterface) { + throw new LogicException(sprintf('Cannot create an instance of %s from serialized data because the serializer inject in "%s" is not a denormalizer', $constructorParameter->getClass(), static::class)); + } $parameterClass = $constructorParameter->getClass()->getName(); - $parameterData = $this->serializer->deserialize($parameterData, $parameterClass, $format, $context); + $parameterData = $this->serializer->denormalize($parameterData, $parameterClass, $format, $context); } } catch (\ReflectionException $e) { throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $key), 0, $e); diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/DenormalizerDecoratorSerializer.php b/src/Symfony/Component/Serializer/Tests/Fixtures/DenormalizerDecoratorSerializer.php deleted file mode 100644 index 06d36c4bd85ca..0000000000000 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/DenormalizerDecoratorSerializer.php +++ /dev/null @@ -1,43 +0,0 @@ - - */ -class DenormalizerDecoratorSerializer implements SerializerInterface -{ - private $normalizer; - - /** - * @param NormalizerInterface|DenormalizerInterface $normalizer - */ - public function __construct($normalizer) - { - if (false === $normalizer instanceof NormalizerInterface && false === $normalizer instanceof DenormalizerInterface) { - throw new \InvalidArgumentException(); - } - - $this->normalizer = $normalizer; - } - - /** - * {@inheritdoc} - */ - public function serialize($data, $format, array $context = array()) - { - return $this->normalizer->normalize($data, $format, $context); - } - - /** - * {@inheritdoc} - */ - public function deserialize($data, $type, $format, array $context = array()) - { - return $this->normalizer->denormalize($data, $type, $format, $context); - } -} diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php index 161145bd97497..e1d3a905ecf73 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -23,7 +23,6 @@ use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy; -use Symfony\Component\Serializer\Tests\Fixtures\DenormalizerDecoratorSerializer; use Symfony\Component\Serializer\Tests\Fixtures\MaxDepthDummy; use Symfony\Component\Serializer\Tests\Fixtures\SiblingHolder; use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; @@ -171,7 +170,7 @@ public function testConstructorWithObjectTypeHintDenormalize() ); $normalizer = new ObjectNormalizer(); - $serializer = new DenormalizerDecoratorSerializer($normalizer); + $serializer = new Serializer(array($normalizer)); $normalizer->setSerializer($serializer); $obj = $normalizer->denormalize($data, DummyWithConstructorObject::class); @@ -197,7 +196,7 @@ public function testConstructorWithUnknownObjectTypeHintDenormalize() ); $normalizer = new ObjectNormalizer(); - $serializer = new DenormalizerDecoratorSerializer($normalizer); + $serializer = new Serializer(array($normalizer)); $normalizer->setSerializer($serializer); $normalizer->denormalize($data, DummyWithConstructorInexistingObject::class); diff --git a/src/Symfony/Component/Serializer/Tests/SerializerTest.php b/src/Symfony/Component/Serializer/Tests/SerializerTest.php index 362357864c463..ff7820c0d07e4 100644 --- a/src/Symfony/Component/Serializer/Tests/SerializerTest.php +++ b/src/Symfony/Component/Serializer/Tests/SerializerTest.php @@ -336,6 +336,15 @@ public function testDenormalizerAware() new Serializer(array($denormalizerAware)); } + + public function testDeserializeObjectConstructorWithObjectTypeHint() + { + $jsonData = '{"bar":{"value":"baz"}}'; + + $serializer = new Serializer(array(new ObjectNormalizer()), array('json' => new JsonEncoder())); + + $this->assertEquals(new Foo(new Bar('baz')), $serializer->deserialize($jsonData, Foo::class, 'json')); + } } class Model @@ -381,3 +390,23 @@ public function toArray() return array('title' => $this->title, 'numbers' => $this->numbers); } } + +class Foo +{ + private $bar; + + public function __construct(Bar $bar) + { + $this->bar = $bar; + } +} + +class Bar +{ + private $value; + + public function __construct($value) + { + $this->value = $value; + } +} From dcf9fbb18c3fb73667fae79f9f678a17dcd57cc3 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 2 Dec 2016 15:52:29 +0100 Subject: [PATCH 24/81] [HttpKernel] Fix annotation cache warmer with failing or missing classes --- .../CacheWarmer/AnnotationsCacheWarmer.php | 16 +++++++++++++--- .../AddClassesToCachePass.php | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php index 6d044676eb012..2c0a435617d4a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php +++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/AnnotationsCacheWarmer.php @@ -66,9 +66,19 @@ public function warmUp($cacheDir) $arrayPool = new ArrayAdapter(0, false); $reader = new CachedReader($this->annotationReader, new DoctrineProvider($arrayPool)); - - foreach ($annotatedClasses as $class) { - $this->readAllComponents($reader, $class); + $throwingAutoloader = function ($class) { throw new \ReflectionException(sprintf('Class %s does not exist', $class)); }; + spl_autoload_register($throwingAutoloader); + + try { + foreach ($annotatedClasses as $class) { + try { + $this->readAllComponents($reader, $class); + } catch (\ReflectionException $e) { + // ignore failing reflection + } + } + } finally { + spl_autoload_unregister($throwingAutoloader); } $values = $arrayPool->getValues(); diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/AddClassesToCachePass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/AddClassesToCachePass.php index 0cc8d99864391..e9d012033d6d4 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/AddClassesToCachePass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/AddClassesToCachePass.php @@ -101,7 +101,7 @@ private function getClassesInComposerClassMaps() } if (is_array($function) && $function[0] instanceof ClassLoader) { - $classes += $function[0]->getClassMap(); + $classes += array_filter($function[0]->getClassMap()); } } From 9b9d33959cf8402ed16a988f0ff1dd27d386f712 Mon Sep 17 00:00:00 2001 From: vlakoff Date: Sat, 3 Dec 2016 05:32:18 +0100 Subject: [PATCH 25/81] [Finder] Refine phpdoc about argument for NumberComparator --- src/Symfony/Component/Finder/Comparator/NumberComparator.php | 2 +- src/Symfony/Component/Finder/Finder.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Finder/Comparator/NumberComparator.php b/src/Symfony/Component/Finder/Comparator/NumberComparator.php index 4b5b5ba8380ce..16f91285a6d8c 100644 --- a/src/Symfony/Component/Finder/Comparator/NumberComparator.php +++ b/src/Symfony/Component/Finder/Comparator/NumberComparator.php @@ -37,7 +37,7 @@ class NumberComparator extends Comparator /** * Constructor. * - * @param string $test A comparison string + * @param string|int $test A comparison string or an integer * * @throws \InvalidArgumentException If the test is not understood */ diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php index 90dcd20958118..c9d14809dc28a 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -200,7 +200,7 @@ public function files() * $finder->depth('> 1') // the Finder will start matching at level 1. * $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point. * - * @param int $level The depth level expression + * @param string|int $level The depth level expression * * @return Finder|SplFileInfo[] The current Finder instance * @@ -372,7 +372,7 @@ public function notPath($pattern) * $finder->size('<= 1Ki'); * $finder->size(4); * - * @param string $size A size range string + * @param string|int $size A size range string or an integer * * @return Finder|SplFileInfo[] The current Finder instance * From 526979644827c848eca55b022129d8cc54a0495d Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 3 Dec 2016 10:52:31 +0100 Subject: [PATCH 26/81] fix the inline level for dumped multi-line strings --- src/Symfony/Component/Yaml/Dumper.php | 2 +- src/Symfony/Component/Yaml/Tests/DumperTest.php | 2 +- .../Yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 10ffe82b010aa..98d82434c2388 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -88,7 +88,7 @@ public function dump($input, $inline = 0, $indent = 0, $flags = 0) $isAHash = Inline::isHash($input); foreach ($input as $key => $value) { - if ($inline > 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && is_string($value) && false !== strpos($value, "\n")) { + if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && is_string($value) && false !== strpos($value, "\n")) { $output .= sprintf("%s%s%s |\n", $prefix, $isAHash ? Inline::dump($key, $flags).':' : '-', ''); foreach (preg_split('/\n|\r\n/', $value) as $row) { diff --git a/src/Symfony/Component/Yaml/Tests/DumperTest.php b/src/Symfony/Component/Yaml/Tests/DumperTest.php index afc491209516b..06e9d3f5c38a9 100644 --- a/src/Symfony/Component/Yaml/Tests/DumperTest.php +++ b/src/Symfony/Component/Yaml/Tests/DumperTest.php @@ -342,7 +342,7 @@ public function testDumpMultiLineStringAsScalarBlock() ), ); - $this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block.yml'), $this->dumper->dump($data, 3, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); + $this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block.yml'), $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); } /** diff --git a/src/Symfony/Component/Yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml b/src/Symfony/Component/Yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml index 5994f323062e3..b4903d30a11c0 100644 --- a/src/Symfony/Component/Yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml +++ b/src/Symfony/Component/Yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml @@ -10,5 +10,4 @@ data: empty line: baz - nested_inlined_multi_line_string: - inlined_multi_line: "foo\nbar\r\nempty line:\n\nbaz" + nested_inlined_multi_line_string: { inlined_multi_line: "foo\nbar\r\nempty line:\n\nbaz" } From 5f62f0194304fd5e22caa290e625d01c735bf848 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 3 Dec 2016 11:50:08 +0100 Subject: [PATCH 27/81] fixed CS --- .../Compiler/CheckCircularReferencesPass.php | 5 ++--- .../Component/DependencyInjection/Dumper/PhpDumper.php | 6 +++--- .../Tests/Fixtures/includes/classes.php | 9 --------- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php index b6a898736f653..11856b6cbc053 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php @@ -61,9 +61,8 @@ private function checkOutEdges(array $edges) if (empty($this->checkedNodes[$id])) { - // * don't check circular dependencies in lazy services. - $isLazy = $node->getValue() && $node->getValue()->isLazy(); - if (!$isLazy) { + // don't check circular dependencies for lazy services + if (!$node->getValue() && $node->getValue()->isLazy()) { $searchKey = array_search($id, $this->currentPath); $this->currentPath[] = $id; diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index bf5956b394d43..c4bfa93d2a950 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1294,9 +1294,9 @@ private function hasReference($id, array $arguments, $deep = false, array &$visi $service = $this->container->getDefinition($argumentId); - // if exists proxy dumper (proxy-manager) don't search references in lazy services. - // As these services will be instantiated lazily and don't have direct related references. - if ($service->isLazy() && !($this->getProxyDumper() instanceof NullDumper)) { + // if the proxy manager is enabled, disable searching for references in lazy services, + // as these services will be instantiated lazily and don't have direct related references. + if ($service->isLazy() && !$this->getProxyDumper() instanceof NullDumper) { continue; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php index cdc89e42ab3a8..0ecdea3fbfb89 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php @@ -82,25 +82,16 @@ public function callPassed() class DummyProxyDumper implements ProxyDumper { - /** - * {@inheritdoc} - */ public function isProxyCandidate(Definition $definition) { return false; } - /** - * {@inheritdoc} - */ public function getProxyFactoryCode(Definition $definition, $id) { return ''; } - /** - * {@inheritdoc} - */ public function getProxyCode(Definition $definition) { return ''; From 36b7ba64f4a27c742be010f855d0fb27bfccfb76 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Wed, 2 Nov 2016 11:44:02 -0400 Subject: [PATCH 28/81] [Form][DX] FileType "multiple" fixes --- .../Form/Extension/Core/Type/FileType.php | 41 ++++++++++++++++--- .../Extension/Core/Type/FileTypeTest.php | 27 ++++++++++++ 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index bc24899de5cb0..914c9402fc8e4 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -12,12 +12,37 @@ namespace Symfony\Component\Form\Extension\Core\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; +use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; class FileType extends AbstractType { + /** + * {@inheritdoc} + */ + public function buildForm(FormBuilderInterface $builder, array $options) + { + if ($options['multiple']) { + $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { + $form = $event->getForm(); + $data = $event->getData(); + + // submitted data for an input file (not required) without choosing any file + if (array(null) === $data) { + $emptyData = $form->getConfig()->getEmptyData(); + + $data = is_callable($emptyData) ? call_user_func($emptyData, $form, $data) : $emptyData; + $event->setData($data); + } + }); + } + } + /** * {@inheritdoc} */ @@ -39,9 +64,7 @@ public function buildView(FormView $view, FormInterface $form, array $options) */ public function finishView(FormView $view, FormInterface $form, array $options) { - $view - ->vars['multipart'] = true - ; + $view->vars['multipart'] = true; } /** @@ -49,10 +72,18 @@ public function finishView(FormView $view, FormInterface $form, array $options) */ public function configureOptions(OptionsResolver $resolver) { + $dataClass = function (Options $options) { + return $options['multiple'] ? null : 'Symfony\Component\HttpFoundation\File\File'; + }; + + $emptyData = function (Options $options) { + return $options['multiple'] ? array() : null; + }; + $resolver->setDefaults(array( 'compound' => false, - 'data_class' => 'Symfony\Component\HttpFoundation\File\File', - 'empty_data' => null, + 'data_class' => $dataClass, + 'empty_data' => $emptyData, 'multiple' => false, )); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php index 55555efecb7bf..c6a61af8b7159 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php @@ -44,6 +44,33 @@ public function testSubmitEmpty() $this->assertNull($form->getData()); } + public function testSubmitEmptyMultiple() + { + $form = $this->factory->createBuilder('file', null, array( + 'multiple' => true, + ))->getForm(); + + // submitted data when an input file is uploaded without choosing any file + $form->submit(array(null)); + + $this->assertSame(array(), $form->getData()); + } + + public function testSetDataMultiple() + { + $form = $this->factory->createBuilder('file', null, array( + 'multiple' => true, + ))->getForm(); + + $data = array( + $this->createUploadedFileMock('abcdef', 'first.jpg', true), + $this->createUploadedFileMock('zyxwvu', 'second.jpg', true), + ); + + $form->setData($data); + $this->assertSame($data, $form->getData()); + } + public function testSubmitMultiple() { $form = $this->factory->createBuilder('file', null, array( From aea04784513aff2e9e56cfe692746597ccb2392e Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 3 Dec 2016 14:48:59 +0100 Subject: [PATCH 29/81] fix a test checking for a value --- .../Compiler/CheckCircularReferencesPass.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php index 11856b6cbc053..156bcc0c3ab7b 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php @@ -62,7 +62,7 @@ private function checkOutEdges(array $edges) if (empty($this->checkedNodes[$id])) { // don't check circular dependencies for lazy services - if (!$node->getValue() && $node->getValue()->isLazy()) { + if (!$node->getValue() || !$node->getValue()->isLazy()) { $searchKey = array_search($id, $this->currentPath); $this->currentPath[] = $id; From d1a7164626f06f5bcaeab20ff964318ef474b88b Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Mon, 5 Dec 2016 08:37:16 +0100 Subject: [PATCH 30/81] Regression test for missing controller arguments --- .../HttpKernel/Controller/ControllerResolver.php | 10 +++++++++- .../Tests/Controller/ControllerResolverTest.php | 13 +++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php index c76b57bb6a7db..a1cff53535dc1 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php @@ -36,6 +36,13 @@ class ControllerResolver implements ControllerResolverInterface */ private $supportsVariadic; + /** + * If scalar types exists. + * + * @var bool + */ + private $supportsScalarTypes; + /** * Constructor. * @@ -46,6 +53,7 @@ public function __construct(LoggerInterface $logger = null) $this->logger = $logger; $this->supportsVariadic = method_exists('ReflectionParameter', 'isVariadic'); + $this->supportsScalarTypes = method_exists('ReflectionParameter', 'getType'); } /** @@ -132,7 +140,7 @@ protected function doGetArguments(Request $request, $controller, array $paramete $arguments[] = $request; } elseif ($param->isDefaultValueAvailable()) { $arguments[] = $param->getDefaultValue(); - } elseif ($param->allowsNull()) { + } elseif ($this->supportsScalarTypes && $param->hasType() && $param->allowsNull()) { $arguments[] = null; } else { if (is_array($controller)) { diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php index 9aa7e20a9a910..f3b0ac025d6bf 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php @@ -223,6 +223,19 @@ public function testCreateControllerCanReturnAnyCallable() $mock->getController($request); } + /** + * @expectedException \RuntimeException + */ + public function testIfExceptionIsThrownWhenMissingAnArgument() + { + $resolver = new ControllerResolver(); + $request = Request::create('/'); + + $controller = array($this, 'controllerMethod1'); + + $resolver->getArguments($request, $controller); + } + /** * @requires PHP 7.1 */ From 9e588b8d96906886d8e6132d82e2e42ce764107e Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Mon, 5 Dec 2016 09:10:32 +0100 Subject: [PATCH 31/81] Regression test for missing controller arguments (3.1) --- .../ArgumentResolver/DefaultValueResolver.php | 2 +- .../Tests/Controller/ArgumentResolverTest.php | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DefaultValueResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DefaultValueResolver.php index 1af03651c3799..e58fd3ab2bed7 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DefaultValueResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/DefaultValueResolver.php @@ -27,7 +27,7 @@ final class DefaultValueResolver implements ArgumentValueResolverInterface */ public function supports(Request $request, ArgumentMetadata $argument) { - return $argument->hasDefaultValue() || ($argument->isNullable() && !$argument->isVariadic()); + return $argument->hasDefaultValue() || (null !== $argument->getType() && $argument->isNullable() && !$argument->isVariadic()); } /** diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverTest.php index 964d83236278e..d89ba605b7646 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverTest.php @@ -203,6 +203,17 @@ public function testGetArgumentWithoutArray() $resolver->getArguments($request, $controller); } + /** + * @expectedException \RuntimeException + */ + public function testIfExceptionIsThrownWhenMissingAnArgument() + { + $request = Request::create('/'); + $controller = array($this, 'controllerWithFoo'); + + self::$resolver->getArguments($request, $controller); + } + /** * @requires PHP 7.1 */ From 10947739995b315ab17c7db670ff0089a747f7ac Mon Sep 17 00:00:00 2001 From: Arthur de Moulins Date: Fri, 2 Dec 2016 16:57:47 +0100 Subject: [PATCH 32/81] inject project root path into twig filesystem loader --- .../DependencyInjection/Compiler/ExtensionPass.php | 6 +++++- .../Bundle/TwigBundle/Loader/FilesystemLoader.php | 9 +++++---- src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml | 5 +++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php index 603cbe8e22ef1..dbad1b653c1dd 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php @@ -64,9 +64,13 @@ public function process(ContainerBuilder $container) $container->getDefinition('twig.extension.debug')->addTag('twig.extension'); } + $composerRootDir = $this->getComposerRootDir($container->getParameter('kernel.root_dir')); + $loader = $container->getDefinition('twig.loader.filesystem'); + $loader->replaceArgument(2, $composerRootDir); + if (!$container->has('templating')) { $loader = $container->getDefinition('twig.loader.native_filesystem'); - $loader->replaceArgument(1, $this->getComposerRootDir($container->getParameter('kernel.root_dir'))); + $loader->replaceArgument(1, $composerRootDir); $loader->addTag('twig.loader'); $loader->setMethodCalls($container->getDefinition('twig.loader.filesystem')->getMethodCalls()); diff --git a/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php b/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php index 53fe300e29a62..0a9ac7a3ca19a 100644 --- a/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php +++ b/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php @@ -29,12 +29,13 @@ class FilesystemLoader extends \Twig_Loader_Filesystem /** * Constructor. * - * @param FileLocatorInterface $locator A FileLocatorInterface instance - * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance + * @param FileLocatorInterface $locator A FileLocatorInterface instance + * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance + * @param string|null $rootPath The root path common to all relative paths (null for getcwd()) */ - public function __construct(FileLocatorInterface $locator, TemplateNameParserInterface $parser) + public function __construct(FileLocatorInterface $locator, TemplateNameParserInterface $parser, $rootPath = null) { - parent::__construct(array()); + parent::__construct(array(), $rootPath); $this->locator = $locator; $this->parser = $parser; diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml index c82cbafbeb953..06af08d15ba7a 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -46,12 +46,13 @@ - + + @@ -87,7 +88,7 @@ - + %kernel.root_dir% %kernel.charset% From 899fa7936bccb786d0d661c504e06489660101d3 Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Sat, 3 Dec 2016 12:12:21 +0100 Subject: [PATCH 33/81] [Console] fixed PHP7 Errors when not using Dispatcher --- src/Symfony/Component/Console/Application.php | 8 +++++++- .../Console/Tests/ApplicationTest.php | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index b11268ade33bf..2aff1b635ba1c 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -843,7 +843,13 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI } if (null === $this->dispatcher) { - return $command->run($input, $output); + try { + return $command->run($input, $output); + } catch (\Exception $e) { + throw $e; + } catch (\Throwable $e) { + throw new FatalThrowableError($e); + } } $event = new ConsoleCommandEvent($command, $input, $output); diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 9d375f6b7b264..2612be9e9eaaa 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -951,6 +951,24 @@ public function testRunDispatchesAllEventsWithException() $this->assertContains('before.foo.caught.after.', $tester->getDisplay()); } + public function testRunWithError() + { + $this->setExpectedException('Exception', 'dymerr'); + + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('dym.'); + + throw new \Error('dymerr'); + }); + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'dym')); + } + /** * @expectedException \LogicException * @expectedExceptionMessage caught From adc4a26971749d31d23f8a5f2ec80243231cb421 Mon Sep 17 00:00:00 2001 From: Gabriel Moreira Date: Sun, 4 Dec 2016 10:01:09 +0100 Subject: [PATCH 34/81] [HttpKernel] Fixed RequestDataCollector handling of null header values. --- .../Component/HttpKernel/DataCollector/RequestDataCollector.php | 2 +- .../HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index deafe10745732..0f2dc9b6c6084 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -125,7 +125,7 @@ public function collect(Request $request, Response $response, \Exception $except continue; } if ('request_headers' === $key || 'response_headers' === $key) { - $value = array_map(function ($v) { return isset($v[1]) ? $v : $v[0]; }, $value); + $value = array_map(function ($v) { return isset($v[0]) && !isset($v[1]) ? $v[0] : $v; }, $value); } if ('request_server' !== $key && 'request_cookies' !== $key) { $this->data[$key] = array_map(array($this, 'cloneVar'), $value); diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php index 0e4cfe0d6ba91..a8b4e1ce2e7c9 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php @@ -234,6 +234,7 @@ protected function createResponse() $response = new Response(); $response->setStatusCode(200); $response->headers->set('Content-Type', 'application/json'); + $response->headers->set('X-Foo-Bar', null); $response->headers->setCookie(new Cookie('foo', 'bar', 1, '/foo', 'localhost', true, true)); $response->headers->setCookie(new Cookie('bar', 'foo', new \DateTime('@946684800'))); $response->headers->setCookie(new Cookie('bazz', 'foo', '2000-12-12')); From 0cd2c589eb8aa70e94fcb32b31d4e0907b2d3b6f Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 30 Nov 2016 09:21:31 -0600 Subject: [PATCH 35/81] Ignore missing 'debug.file_link_formatter' service in Debug and Twig bundles --- src/Symfony/Bundle/DebugBundle/Resources/config/services.xml | 2 +- src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml b/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml index aada03eff87cf..655d0ae5c7e89 100644 --- a/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml +++ b/src/Symfony/Bundle/DebugBundle/Resources/config/services.xml @@ -14,7 +14,7 @@ - + %kernel.charset% null diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml index 06af08d15ba7a..c2477cef6e2cb 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -88,7 +88,7 @@ - + %kernel.root_dir% %kernel.charset% From 164a20c8523bf390118e654ef08081c65ab3619d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 5 Dec 2016 15:31:21 +0100 Subject: [PATCH 36/81] [Form] Fix FormDataCollector --- .../DataCollector/FormDataCollector.php | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php index 624632f3b2ce8..a0f5a7835ad31 100644 --- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php +++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php @@ -209,9 +209,7 @@ public function collectViewVariables(FormView $view) */ public function buildPreliminaryFormTree(FormInterface $form) { - $this->data['forms'][$form->getName()] = array(); - - $this->recursiveBuildPreliminaryFormTree($form, $this->data['forms'][$form->getName()], $this->data['forms_by_hash']); + $this->data['forms'][$form->getName()] = &$this->recursiveBuildPreliminaryFormTree($form, $this->data['forms_by_hash']); } /** @@ -219,9 +217,7 @@ public function buildPreliminaryFormTree(FormInterface $form) */ public function buildFinalFormTree(FormInterface $form, FormView $view) { - $this->data['forms'][$form->getName()] = array(); - - $this->recursiveBuildFinalFormTree($form, $view, $this->data['forms'][$form->getName()], $this->data['forms_by_hash']); + $this->data['forms'][$form->getName()] = &$this->recursiveBuildFinalFormTree($form, $view, $this->data['forms_by_hash']); } /** @@ -354,26 +350,25 @@ protected function cloneVar($var, $isClass = false) return $cache = $this->cloner->cloneVar($var); } - private function recursiveBuildPreliminaryFormTree(FormInterface $form, &$output, array &$outputByHash) + private function &recursiveBuildPreliminaryFormTree(FormInterface $form, array &$outputByHash) { $hash = spl_object_hash($form); + $output = &$outputByHash[$hash]; $output = isset($this->dataByForm[$hash]) ? $this->dataByForm[$hash] : array(); - $outputByHash[$hash] = &$output; - $output['children'] = array(); foreach ($form as $name => $child) { - $output['children'][$name] = array(); - - $this->recursiveBuildPreliminaryFormTree($child, $output['children'][$name], $outputByHash); + $output['children'][$name] = &$this->recursiveBuildPreliminaryFormTree($child, $outputByHash); } + + return $output; } - private function recursiveBuildFinalFormTree(FormInterface $form = null, FormView $view, &$output, array &$outputByHash) + private function &recursiveBuildFinalFormTree(FormInterface $form = null, FormView $view, array &$outputByHash) { $viewHash = spl_object_hash($view); $formHash = null; @@ -386,6 +381,9 @@ private function recursiveBuildFinalFormTree(FormInterface $form = null, FormVie // corresponding FormInterface instance for its view in a different way $formHash = $this->formsByView[$viewHash]; } + if (null !== $formHash) { + $output = &$outputByHash[$formHash]; + } $output = isset($this->dataByView[$viewHash]) ? $this->dataByView[$viewHash] @@ -398,8 +396,6 @@ private function recursiveBuildFinalFormTree(FormInterface $form = null, FormVie ? $this->dataByForm[$formHash] : array() ); - - $outputByHash[$formHash] = &$output; } $output['children'] = array(); @@ -411,9 +407,9 @@ private function recursiveBuildFinalFormTree(FormInterface $form = null, FormVie ? $form->get($name) : null; - $output['children'][$name] = array(); - - $this->recursiveBuildFinalFormTree($childForm, $childView, $output['children'][$name], $outputByHash); + $output['children'][$name] = &$this->recursiveBuildFinalFormTree($childForm, $childView, $outputByHash); } + + return $output; } } From bfe149fdc68b411e76aca2610e2358cde50b6ac4 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 5 Dec 2016 18:10:19 +0100 Subject: [PATCH 37/81] [Cache] Fix dumping SplDoublyLinkedList iter mode --- .../Component/VarDumper/Caster/SplCaster.php | 2 +- .../VarDumper/Tests/Caster/SplCasterTest.php | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php diff --git a/src/Symfony/Component/VarDumper/Caster/SplCaster.php b/src/Symfony/Component/VarDumper/Caster/SplCaster.php index 79e8bb80b9afc..b0b57e3cda598 100644 --- a/src/Symfony/Component/VarDumper/Caster/SplCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/SplCaster.php @@ -64,7 +64,7 @@ public static function castDoublyLinkedList(\SplDoublyLinkedList $c, array $a, S $c->setIteratorMode(\SplDoublyLinkedList::IT_MODE_KEEP | $mode & ~\SplDoublyLinkedList::IT_MODE_DELETE); $a += array( - $prefix.'mode' => new ConstStub((($mode & \SplDoublyLinkedList::IT_MODE_LIFO) ? 'IT_MODE_LIFO' : 'IT_MODE_FIFO').' | '.(($mode & \SplDoublyLinkedList::IT_MODE_KEEP) ? 'IT_MODE_KEEP' : 'IT_MODE_DELETE'), $mode), + $prefix.'mode' => new ConstStub((($mode & \SplDoublyLinkedList::IT_MODE_LIFO) ? 'IT_MODE_LIFO' : 'IT_MODE_FIFO').' | '.(($mode & \SplDoublyLinkedList::IT_MODE_DELETE) ? 'IT_MODE_DELETE' : 'IT_MODE_KEEP'), $mode), $prefix.'dllist' => iterator_to_array($c), ); $c->setIteratorMode($mode); diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php new file mode 100644 index 0000000000000..96e0307385fb6 --- /dev/null +++ b/src/Symfony/Component/VarDumper/Tests/Caster/SplCasterTest.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use Symfony\Component\VarDumper\Test\VarDumperTestCase; + +class SplCasterTest extends VarDumperTestCase +{ + /** + * @dataProvider provideCastSplDoublyLinkedList + */ + public function testCastSplDoublyLinkedList($modeValue, $modeDump) + { + $var = new \SplDoublyLinkedList(); + $var->setIteratorMode($modeValue); + $dump = <<assertDumpMatchesFormat($dump, $var); + } + + public function provideCastSplDoublyLinkedList() + { + return array( + array(\SplDoublyLinkedList::IT_MODE_FIFO, 'IT_MODE_FIFO | IT_MODE_KEEP'), + array(\SplDoublyLinkedList::IT_MODE_LIFO, 'IT_MODE_LIFO | IT_MODE_KEEP'), + array(\SplDoublyLinkedList::IT_MODE_FIFO | \SplDoublyLinkedList::IT_MODE_DELETE, 'IT_MODE_FIFO | IT_MODE_DELETE'), + array(\SplDoublyLinkedList::IT_MODE_LIFO | \SplDoublyLinkedList::IT_MODE_DELETE, 'IT_MODE_LIFO | IT_MODE_DELETE'), + ); + } +} From 50400c45eedfd748a953dd39e6ce782fd9f22422 Mon Sep 17 00:00:00 2001 From: Adam Prager Date: Mon, 5 Dec 2016 18:24:28 +0100 Subject: [PATCH 38/81] [Form] Add failing test for data collector bug --- .../DataCollector/FormDataCollector.php | 2 +- .../DataCollector/FormDataCollectorTest.php | 108 ++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php index a0f5a7835ad31..a4b4dcfcc866d 100644 --- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php +++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php @@ -254,7 +254,7 @@ public function serialize() case 'resolved_options': case 'default_data': case 'submitted_data': - if ($v) { + if ($v && is_array($v)) { $form[$k] = array_map($cloneVar, $v); } break; diff --git a/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php b/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php index 0fddf14dc57bc..ff75cff20a726 100644 --- a/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php @@ -342,6 +342,114 @@ public function testBuildFinalFormTree() ), $this->dataCollector->getData()); } + public function testSerializeWithFormAddedMultipleTimes() + { + $form1 = $this->createForm('form1'); + $form2 = $this->createForm('form2'); + $child1 = $this->createForm('child1'); + + $form1View = new FormView(); + $form2View = new FormView(); + $child1View = new FormView(); + $child1View->vars['is_selected'] = function ($choice, array $values) { + return in_array($choice, $values, true); + }; + + $form1->add($child1); + $form2->add($child1); + + $form1View->children['child1'] = $child1View; + $form2View->children['child1'] = $child1View; + + $this->dataExtractor->expects($this->at(0)) + ->method('extractConfiguration') + ->with($form1) + ->will($this->returnValue(array('config' => 'foo'))); + $this->dataExtractor->expects($this->at(1)) + ->method('extractConfiguration') + ->with($child1) + ->will($this->returnValue(array('config' => 'bar'))); + + $this->dataExtractor->expects($this->at(2)) + ->method('extractDefaultData') + ->with($form1) + ->will($this->returnValue(array('default_data' => 'foo'))); + $this->dataExtractor->expects($this->at(3)) + ->method('extractDefaultData') + ->with($child1) + ->will($this->returnValue(array('default_data' => 'bar'))); + + $this->dataExtractor->expects($this->at(4)) + ->method('extractSubmittedData') + ->with($form1) + ->will($this->returnValue(array('submitted_data' => 'foo'))); + $this->dataExtractor->expects($this->at(5)) + ->method('extractSubmittedData') + ->with($child1) + ->will($this->returnValue(array('submitted_data' => 'bar'))); + + $this->dataExtractor->expects($this->at(6)) + ->method('extractViewVariables') + ->with($form1View) + ->will($this->returnValue(array('view_vars' => 'foo'))); + + $this->dataExtractor->expects($this->at(7)) + ->method('extractViewVariables') + ->with($child1View) + ->will($this->returnValue(array('view_vars' => $child1View->vars))); + + $this->dataExtractor->expects($this->at(8)) + ->method('extractConfiguration') + ->with($form2) + ->will($this->returnValue(array('config' => 'foo'))); + $this->dataExtractor->expects($this->at(9)) + ->method('extractConfiguration') + ->with($child1) + ->will($this->returnValue(array('config' => 'bar'))); + + $this->dataExtractor->expects($this->at(10)) + ->method('extractDefaultData') + ->with($form2) + ->will($this->returnValue(array('default_data' => 'foo'))); + $this->dataExtractor->expects($this->at(11)) + ->method('extractDefaultData') + ->with($child1) + ->will($this->returnValue(array('default_data' => 'bar'))); + + $this->dataExtractor->expects($this->at(12)) + ->method('extractSubmittedData') + ->with($form2) + ->will($this->returnValue(array('submitted_data' => 'foo'))); + $this->dataExtractor->expects($this->at(13)) + ->method('extractSubmittedData') + ->with($child1) + ->will($this->returnValue(array('submitted_data' => 'bar'))); + + $this->dataExtractor->expects($this->at(14)) + ->method('extractViewVariables') + ->with($form2View) + ->will($this->returnValue(array('view_vars' => 'foo'))); + + $this->dataExtractor->expects($this->at(15)) + ->method('extractViewVariables') + ->with($child1View) + ->will($this->returnValue(array('view_vars' => $child1View->vars))); + + $this->dataCollector->collectConfiguration($form1); + $this->dataCollector->collectDefaultData($form1); + $this->dataCollector->collectSubmittedData($form1); + $this->dataCollector->collectViewVariables($form1View); + $this->dataCollector->buildFinalFormTree($form1, $form1View); + + $this->dataCollector->collectConfiguration($form2); + $this->dataCollector->collectDefaultData($form2); + $this->dataCollector->collectSubmittedData($form2); + $this->dataCollector->collectViewVariables($form2View); + $this->dataCollector->buildFinalFormTree($form2, $form2View); + + $this->dataCollector->serialize(); + } + public function testFinalFormReliesOnFormViewStructure() { $this->form->add($child1 = $this->createForm('first')); From d99234a93020535f8acddb28a891f8016ae83943 Mon Sep 17 00:00:00 2001 From: Edwin Hageman Date: Mon, 5 Dec 2016 17:26:24 +0100 Subject: [PATCH 39/81] FIXED NON EXISTING TYPE DECLARATION --- src/Symfony/Component/Validator/ConstraintValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/ConstraintValidator.php b/src/Symfony/Component/Validator/ConstraintValidator.php index 965a888af0981..ece4400065c6a 100644 --- a/src/Symfony/Component/Validator/ConstraintValidator.php +++ b/src/Symfony/Component/Validator/ConstraintValidator.php @@ -36,7 +36,7 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface const OBJECT_TO_STRING = 2; /** - * @var ExecutionContextInterface2Dot5 + * @var ExecutionContextInterface */ protected $context; From 182f90638d9b5f2f35a177471a5afe5af29cfec7 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 6 Dec 2016 15:06:08 +0100 Subject: [PATCH 40/81] Fix merge --- .../Component/Form/Tests/Extension/Core/Type/FileTypeTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php index cbeeb468c1c22..fe7a6b1d727ec 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FileTypeTest.php @@ -56,7 +56,7 @@ public function testSubmitEmpty() public function testSubmitEmptyMultiple() { - $form = $this->factory->createBuilder('file', null, array( + $form = $this->factory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FileType', null, array( 'multiple' => true, ))->getForm(); @@ -68,7 +68,7 @@ public function testSubmitEmptyMultiple() public function testSetDataMultiple() { - $form = $this->factory->createBuilder('file', null, array( + $form = $this->factory->createBuilder('Symfony\Component\Form\Extension\Core\Type\FileType', null, array( 'multiple' => true, ))->getForm(); From 488ebbfe5d8acfad8baf8710fcdcf390962f5394 Mon Sep 17 00:00:00 2001 From: ShinDarth Date: Tue, 6 Dec 2016 16:01:27 +0100 Subject: [PATCH 41/81] [VarDumper] fix tests when xdebug is enabled --- src/Symfony/Component/VarDumper/Tests/VarClonerTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php b/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php index 1184f2c76a255..9f60032e0c62b 100644 --- a/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php +++ b/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php @@ -137,6 +137,10 @@ public function testClone() public function testJsonCast() { + if (ini_get('xdebug.overload_var_dump') == 2) { + $this->markTestSkipped('xdebug is active'); + } + $data = (array) json_decode('{"1":{}}'); $cloner = new VarCloner(); From a77761833f478cbf99ad3fdad03f247e0d5de94d Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 6 Dec 2016 17:18:42 +0100 Subject: [PATCH 42/81] Don't use the "app" global variable in the profiler --- .../WebProfilerBundle/Resources/views/Profiler/layout.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig index e6da0d4e5812d..447162c9b5b62 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig @@ -39,7 +39,7 @@ {%- else -%} {{ redirect_route }} {%- endif %} - ({{ redirect.token }}) + ({{ redirect.token }}) {%- endif %} From 8fe144e86aa44884f05dd6b3c670c1b4b36a25cf Mon Sep 17 00:00:00 2001 From: Adam Prager Date: Tue, 6 Dec 2016 14:57:19 +0100 Subject: [PATCH 43/81] [Workflow] Added missing docblock --- src/Symfony/Component/Workflow/DefinitionBuilder.php | 3 +++ src/Symfony/Component/Workflow/Registry.php | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/Symfony/Component/Workflow/DefinitionBuilder.php b/src/Symfony/Component/Workflow/DefinitionBuilder.php index 447d67337d09f..34d27aa5e9d0d 100644 --- a/src/Symfony/Component/Workflow/DefinitionBuilder.php +++ b/src/Symfony/Component/Workflow/DefinitionBuilder.php @@ -79,6 +79,9 @@ public function addPlaces(array $places) } } + /** + * @param Transition[] $transitions + */ public function addTransitions(array $transitions) { foreach ($transitions as $transition) { diff --git a/src/Symfony/Component/Workflow/Registry.php b/src/Symfony/Component/Workflow/Registry.php index 619ed5f66a5b1..53e06fbb5e8e4 100644 --- a/src/Symfony/Component/Workflow/Registry.php +++ b/src/Symfony/Component/Workflow/Registry.php @@ -30,6 +30,12 @@ public function add(Workflow $workflow, $className) $this->workflows[] = array($workflow, $className); } + /** + * @param object $subject + * @param string|null $workflowName + * + * @return Workflow + */ public function get($subject, $workflowName = null) { $matched = null; From 6f1c59c7ef6456c8357e4f3512d4b8e4db98cfd9 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 5 Dec 2016 18:36:31 +0100 Subject: [PATCH 44/81] [Bridge\Twig] Trigger deprecation when using FormExtension::$renderer --- .../Bridge/Twig/Extension/FormExtension.php | 70 ++++++++++++++++++- .../TwigBundle/Resources/config/twig.xml | 7 +- src/Symfony/Bundle/TwigBundle/composer.json | 2 +- 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Extension/FormExtension.php b/src/Symfony/Bridge/Twig/Extension/FormExtension.php index 016e6a9586c97..d5c08038ecc46 100644 --- a/src/Symfony/Bridge/Twig/Extension/FormExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/FormExtension.php @@ -13,6 +13,7 @@ use Symfony\Bridge\Twig\TokenParser\FormThemeTokenParser; use Symfony\Bridge\Twig\Form\TwigRendererInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Form\ChoiceList\View\ChoiceView; /** @@ -23,12 +24,17 @@ */ class FormExtension extends \Twig_Extension implements \Twig_Extension_InitRuntimeInterface { + /** + * @deprecated since version 3.2, to be removed in 4.0 alongside with magic methods below + */ private $renderer; - public function __construct(TwigRendererInterface $renderer = null) + public function __construct($renderer = null) { - if (null !== $this->renderer) { + if ($this->renderer instanceof TwigRendererInterface) { @trigger_error(sprintf('Passing a Twig Form Renderer to the "%s" constructor is deprecated since version 3.2 and won\'t be possible in 4.0. Pass the Twig_Environment to the TwigRendererEngine constructor instead.', static::class), E_USER_DEPRECATED); + } elseif (null !== $renderer && !(is_array($renderer) && isset($renderer[0], $renderer[1]) && $renderer[0] instanceof ContainerInterface)) { + throw new \InvalidArgumentException(sprintf('Passing any arguments the constructor of %s is reserved for internal use.', __CLASS__)); } $this->renderer = $renderer; } @@ -40,8 +46,10 @@ public function __construct(TwigRendererInterface $renderer = null) */ public function initRuntime(\Twig_Environment $environment) { - if (null !== $this->renderer) { + if ($this->renderer instanceof TwigRendererInterface) { $this->renderer->setEnvironment($environment); + } elseif (null !== $this->renderer) { + $this->renderer[2] = $environment; } } @@ -94,6 +102,62 @@ public function getTests() ); } + /** + * @internal + */ + public function __get($name) + { + if ('renderer' === $name) { + @trigger_error(sprintf('Using the "%s::$renderer" property is deprecated since version 3.2 as it will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED); + + if (is_array($this->renderer)) { + $renderer = $this->renderer[0]->get($this->renderer[1]); + if (isset($this->renderer[2])) { + $renderer->setEnvironment($this->renderer[2]); + } + $this->renderer = $renderer; + } + } + + return $this->$name; + } + + /** + * @internal + */ + public function __set($name, $value) + { + if ('renderer' === $name) { + @trigger_error(sprintf('Using the "%s::$renderer" property is deprecated since version 3.2 as it will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED); + } + + $this->$name = $value; + } + + /** + * @internal + */ + public function __isset($name) + { + if ('renderer' === $name) { + @trigger_error(sprintf('Using the "%s::$renderer" property is deprecated since version 3.2 as it will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED); + } + + return isset($this->$name); + } + + /** + * @internal + */ + public function __unset($name) + { + if ('renderer' === $name) { + @trigger_error(sprintf('Using the "%s::$renderer" property is deprecated since version 3.2 as it will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED); + } + + unset($this->$name); + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml index 06af08d15ba7a..f584cd75e3968 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -118,7 +118,12 @@ - + + + + twig.form.renderer + + diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index fbb5f9bf8afd5..ecb5ed5917a17 100644 --- a/src/Symfony/Bundle/TwigBundle/composer.json +++ b/src/Symfony/Bundle/TwigBundle/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=5.5.9", - "symfony/twig-bridge": "~3.2", + "symfony/twig-bridge": "^3.2.1", "symfony/http-foundation": "~2.8|~3.0", "symfony/http-kernel": "~2.8|~3.0", "twig/twig": "~1.28|~2.0" From 4e563aee0232e81667a74884978a123f24e75704 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 6 Dec 2016 21:51:50 +0100 Subject: [PATCH 45/81] fix the docblock in regard to the role argument --- .../Security/Core/Authentication/Token/AbstractToken.php | 2 +- .../Core/Authentication/Token/PreAuthenticatedToken.php | 2 +- .../Core/Authentication/Token/UsernamePasswordToken.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php index 7538648b1329f..2e9c0f34b4b5d 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php @@ -33,7 +33,7 @@ abstract class AbstractToken implements TokenInterface /** * Constructor. * - * @param RoleInterface[]|string[] $roles An array of roles + * @param (RoleInterface|string)[] $roles An array of roles * * @throws \InvalidArgumentException */ diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php index b4b5e70b188fb..a5460f50839ee 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php @@ -29,7 +29,7 @@ class PreAuthenticatedToken extends AbstractToken * @param string|object $user The user can be a UserInterface instance, or an object implementing a __toString method or the username as a regular string * @param mixed $credentials The user credentials * @param string $providerKey The provider key - * @param RoleInterface[]|string[] $roles An array of roles + * @param (RoleInterface|string)[] $roles An array of roles */ public function __construct($user, $credentials, $providerKey, array $roles = array()) { diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php index 33b00f01f82ae..71d19adc14f2b 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php @@ -29,7 +29,7 @@ class UsernamePasswordToken extends AbstractToken * @param string|object $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method * @param string $credentials This usually is the password of the user * @param string $providerKey The provider key - * @param RoleInterface[]|string[] $roles An array of roles + * @param (RoleInterface|string)[] $roles An array of roles * * @throws \InvalidArgumentException */ From ad477e705e5f95e7869d3b0aa50fb5e540bf1727 Mon Sep 17 00:00:00 2001 From: Victor Bocharsky Date: Wed, 7 Dec 2016 13:56:23 +0200 Subject: [PATCH 46/81] Fix email address --- .../Security/Guard/Token/PostAuthenticationGuardToken.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php b/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php index 36c40cab9579d..5b353d97a6dd6 100644 --- a/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php +++ b/src/Symfony/Component/Security/Guard/Token/PostAuthenticationGuardToken.php @@ -21,7 +21,7 @@ * If you're using Guard authentication, you *must* use a class that implements * GuardTokenInterface as your authenticated token (like this class). * - * @author Ryan Weaver n@gmail.com> + * @author Ryan Weaver */ class PostAuthenticationGuardToken extends AbstractToken implements GuardTokenInterface { From 8e1dac5507fd1b613a2245271ae1c4cb6e01c080 Mon Sep 17 00:00:00 2001 From: Sander Toonen Date: Wed, 7 Dec 2016 14:49:15 +0100 Subject: [PATCH 47/81] [FrameworkBundle] Removed the kernel.debug parameter from the cache pool namespace seed --- .../DependencyInjection/Compiler/CachePoolPass.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php index 1748862219ddf..93adf546b7c7b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php @@ -30,7 +30,7 @@ public function process(ContainerBuilder $container) { $namespaceSuffix = ''; - foreach (array('name', 'root_dir', 'environment', 'debug') as $key) { + foreach (array('name', 'root_dir', 'environment') as $key) { if ($container->hasParameter('kernel.'.$key)) { $namespaceSuffix .= '.'.$container->getParameter('kernel.'.$key); } From 3f94abde00df6fd1038a8beede3f101e79352b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz?= Date: Thu, 8 Dec 2016 08:04:49 +0100 Subject: [PATCH 48/81] Fixed typo --- .../Resources/views/Collector/exception.css.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig index 197cc010d2e40..0d057b98a4334 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/exception.css.twig @@ -9,7 +9,7 @@ padding-bottom: 2px; } .sf-reset .traces li { - ccolor: #222; + color: #222; font-size: 14px; padding: 5px 0; list-style-type: decimal; From 685a9b9d9adff18befeafffdc525e87c5034e29b Mon Sep 17 00:00:00 2001 From: Maxime STEINHAUSSER Date: Thu, 8 Dec 2016 11:30:28 +0100 Subject: [PATCH 49/81] [Config] Fix YamlReferenceDumper extra space --- .../Component/Config/Definition/Dumper/YamlReferenceDumper.php | 2 +- .../Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php | 1 + .../Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php | 1 + .../Tests/Fixtures/Configuration/ExampleConfiguration.php | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php b/src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php index f9da698e0924e..12ababe39435b 100644 --- a/src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php +++ b/src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php @@ -120,7 +120,7 @@ private function writeNode(NodeInterface $node, $depth = 0) $default = (string) $default != '' ? ' '.$default : ''; $comments = count($comments) ? '# '.implode(', ', $comments) : ''; - $text = rtrim(sprintf('%-20s %s %s', $node->getName().':', $default, $comments), ' '); + $text = rtrim(sprintf('%-21s%s %s', $node->getName().':', $default, $comments), ' '); if ($info = $node->getInfo()) { $this->writeLine(''); diff --git a/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php b/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php index 42207b0399e37..2c0551d062ef0 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php @@ -49,6 +49,7 @@ private function getConfigurationAsString() scalar-array-empty="" scalar-array-defaults="elem1,elem2" scalar-required="" + node-with-a-looong-name="" enum-with-default="this" enum="" > diff --git a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php index 131ca072fe6f6..ad1daddd7e07c 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php @@ -43,6 +43,7 @@ private function getConfigurationAsString() - elem1 - elem2 scalar_required: ~ # Required + node_with_a_looong_name: ~ enum_with_default: this # One of "this"; "that" enum: ~ # One of "this"; "that" diff --git a/src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php b/src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php index 68aa0c059399c..1573177f440ce 100644 --- a/src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php +++ b/src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php @@ -34,6 +34,7 @@ public function getConfigTreeBuilder() ->scalarNode('scalar_array_empty')->defaultValue(array())->end() ->scalarNode('scalar_array_defaults')->defaultValue(array('elem1', 'elem2'))->end() ->scalarNode('scalar_required')->isRequired()->end() + ->scalarNode('node_with_a_looong_name')->end() ->enumNode('enum_with_default')->values(array('this', 'that'))->defaultValue('this')->end() ->enumNode('enum')->values(array('this', 'that'))->end() ->arrayNode('array') From 1ed9335e88ed543e8ab9104c3c2f4a5370d716a2 Mon Sep 17 00:00:00 2001 From: Maxime STEINHAUSSER Date: Thu, 8 Dec 2016 11:59:24 +0100 Subject: [PATCH 50/81] [Config] Do not skip YamlReferenceDumperTest entirely --- .../Tests/Definition/Dumper/YamlReferenceDumperTest.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php index 131ca072fe6f6..21cce575e3732 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php @@ -22,8 +22,8 @@ public function testDumper() $dumper = new YamlReferenceDumper(); + $this->assertContains($this->getConfigurationAsString(), $dumper->dump($configuration)); $this->markTestIncomplete('The Yaml Dumper currently does not support prototyped arrays'); - $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration)); } private function getConfigurationAsString() @@ -32,7 +32,7 @@ private function getConfigurationAsString() acme_root: boolean: true scalar_empty: ~ - scalar_null: ~ + scalar_null: null scalar_true: true scalar_false: false scalar_default: default @@ -59,10 +59,6 @@ enum: ~ # One of "this"; "that" # Prototype name: ~ - connections: - # Prototype - - { user: ~, pass: ~ } - EOL; } } From 073a1dae1318519066ca9fb0d2dc53392ac5fbca Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 8 Dec 2016 13:07:24 +0100 Subject: [PATCH 51/81] [Validator] Fix init of YamlFileLoader::$classes for empty files --- .../Validator/Mapping/Loader/YamlFileLoader.php | 12 +++--------- .../Tests/Mapping/Loader/YamlFileLoaderTest.php | 4 ++++ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php index cf6dd92dcad9b..16212833dc169 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php @@ -46,13 +46,7 @@ public function loadClassMetadata(ClassMetadata $metadata) $this->yamlParser = new YamlParser(); } - // This method may throw an exception. Do not modify the class' - // state before it completes - if (false === ($classes = $this->parseFile($this->file))) { - return false; - } - - $this->classes = $classes; + $this->classes = $this->parseFile($this->file); if (isset($this->classes['namespaces'])) { foreach ($this->classes['namespaces'] as $alias => $namespace) { @@ -111,7 +105,7 @@ protected function parseNodes(array $nodes) * * @param string $path The path of the YAML file * - * @return array|null The class descriptions or null, if the file was empty + * @return array The class descriptions * * @throws \InvalidArgumentException If the file could not be loaded or did * not contain a YAML array @@ -126,7 +120,7 @@ private function parseFile($path) // empty file if (null === $classes) { - return; + return array(); } // not an array diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php index 2ca64122aafae..15f02139ae318 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php @@ -31,6 +31,10 @@ public function testLoadClassMetadataReturnsFalseIfEmpty() $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity'); $this->assertFalse($loader->loadClassMetadata($metadata)); + + $r = new \ReflectionProperty($loader, 'classes'); + $r->setAccessible(true); + $this->assertSame(array(), $r->getValue($loader)); } /** From 53234e907af8ea2d0a3dee46dca0dc0d49d37d8b Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 8 Dec 2016 13:36:55 +0100 Subject: [PATCH 52/81] [FrameworkBundle] Fix validation cache warmer with failing or missing classes --- .../CacheWarmer/ValidatorCacheWarmer.php | 19 +++++++++++++++---- .../Tests/Fixtures/Validation/Article.php | 8 ++++++++ .../Fixtures/Validation/Resources/person.xml | 4 ++-- 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php index ce5104dc41cc5..d450cc1f85237 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php +++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php @@ -66,12 +66,23 @@ public function warmUp($cacheDir) $loaders = $this->validatorBuilder->getLoaders(); $metadataFactory = new LazyLoadingMetadataFactory(new LoaderChain($loaders), new Psr6Cache($arrayPool)); - foreach ($this->extractSupportedLoaders($loaders) as $loader) { - foreach ($loader->getMappedClasses() as $mappedClass) { - if ($metadataFactory->hasMetadataFor($mappedClass)) { - $metadataFactory->getMetadataFor($mappedClass); + $throwingAutoloader = function ($class) { throw new \ReflectionException(sprintf('Class %s does not exist', $class)); }; + spl_autoload_register($throwingAutoloader); + + try { + foreach ($this->extractSupportedLoaders($loaders) as $loader) { + foreach ($loader->getMappedClasses() as $mappedClass) { + try { + if ($metadataFactory->hasMetadataFor($mappedClass)) { + $metadataFactory->getMetadataFor($mappedClass); + } + } catch (\ReflectionException $e) { + // ignore failing reflection + } } } + } finally { + spl_autoload_unregister($throwingAutoloader); } $values = $arrayPool->getValues(); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php new file mode 100644 index 0000000000000..a1ecee6d0b375 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Article.php @@ -0,0 +1,8 @@ + - - + +