From a1b14843764ab2168448e54f491c727fab96bed6 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 11 Jan 2018 08:05:20 +0100 Subject: [PATCH 001/166] always call the parent class' constructor --- .../DependencyInjection/Dumper/PhpDumper.php | 23 ++++++-- .../Tests/Dumper/PhpDumperTest.php | 40 +++++++++++++ ...tructorWithMandatoryArgumentsContainer.php | 10 ++++ ...structorWithOptionalArgumentsContainer.php | 10 ++++ .../ConstructorWithoutArgumentsContainer.php | 10 ++++ .../Container/NoConstructorContainer.php | 7 +++ ...er_class_constructor_without_arguments.php | 57 +++++++++++++++++++ ...s_with_mandatory_constructor_arguments.php | 55 ++++++++++++++++++ ...ss_with_optional_constructor_arguments.php | 57 +++++++++++++++++++ ...om_container_class_without_constructor.php | 55 ++++++++++++++++++ 10 files changed, 320 insertions(+), 4 deletions(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/Container/ConstructorWithMandatoryArgumentsContainer.php create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/Container/ConstructorWithOptionalArgumentsContainer.php create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/Container/ConstructorWithoutArgumentsContainer.php create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/Container/NoConstructorContainer.php create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_constructor_without_arguments.php create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_mandatory_constructor_arguments.php create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_optional_constructor_arguments.php create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_without_constructor.php diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 4ff85f51b374b..2fd3c72fd11e1 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -128,6 +128,11 @@ public function dump(array $options = array()) if (0 !== strpos($baseClass = $options['base_class'], '\\') && 'Container' !== $baseClass) { $baseClass = sprintf('%s\%s', $options['namespace'] ? '\\'.$options['namespace'] : '', $baseClass); + $baseClassWithNamespace = $baseClass; + } elseif ('Container' === $baseClass) { + $baseClassWithNamespace = Container::class; + } else { + $baseClassWithNamespace = $baseClass; } $this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass); @@ -169,7 +174,7 @@ public function dump(array $options = array()) } $code = - $this->startClass($options['class'], $baseClass). + $this->startClass($options['class'], $baseClass, $baseClassWithNamespace). $this->addServices(). $this->addDefaultParametersMethod(). $this->endClass() @@ -917,12 +922,13 @@ private function addNewInstance(Definition $definition, $return, $instantiation, /** * Adds the class headers. * - * @param string $class Class name - * @param string $baseClass The name of the base class + * @param string $class Class name + * @param string $baseClass The name of the base class + * @param string $baseClassWithNamespace Fully qualified base class name * * @return string */ - private function startClass($class, $baseClass) + private function startClass($class, $baseClass, $baseClassWithNamespace) { $bagClass = $this->container->isCompiled() ? 'use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;' : 'use Symfony\Component\DependencyInjection\ParameterBag\\ParameterBag;'; $namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : ''; @@ -970,9 +976,18 @@ public function __construct() } if ($this->container->isCompiled()) { + if (Container::class !== $baseClassWithNamespace) { + $r = $this->container->getReflectionClass($baseClassWithNamespace, false); + + if (null !== $r && (null !== $constructor = $r->getConstructor()) && 0 === $constructor->getNumberOfRequiredParameters()) { + $code .= " parent::__construct();\n\n"; + } + } + if ($this->container->getParameterBag()->all()) { $code .= " \$this->parameters = \$this->getDefaultParameters();\n\n"; } + $code .= " \$this->services = array();\n"; } else { $arguments = $this->container->getParameterBag()->all() ? 'new ParameterBag($this->getDefaultParameters())' : null; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 4a882828a3f30..f12fc608c9608 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -107,6 +107,46 @@ public function testDumpRelativeDir() $this->assertStringEqualsFile(self::$fixturesPath.'/php/services12.php', $dumper->dump(array('file' => __FILE__)), '->dump() dumps __DIR__ relative strings'); } + public function testDumpCustomContainerClassWithoutConstructor() + { + $container = new ContainerBuilder(); + $container->compile(); + + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_without_constructor.php', $dumper->dump(array('base_class' => 'NoConstructorContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container'))); + } + + public function testDumpCustomContainerClassConstructorWithoutArguments() + { + $container = new ContainerBuilder(); + $container->compile(); + + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_constructor_without_arguments.php', $dumper->dump(array('base_class' => 'ConstructorWithoutArgumentsContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container'))); + } + + public function testDumpCustomContainerClassWithOptionalArgumentLessConstructor() + { + $container = new ContainerBuilder(); + $container->compile(); + + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_with_optional_constructor_arguments.php', $dumper->dump(array('base_class' => 'ConstructorWithOptionalArgumentsContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container'))); + } + + public function testDumpCustomContainerClassWithMandatoryArgumentLessConstructor() + { + $container = new ContainerBuilder(); + $container->compile(); + + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_with_mandatory_constructor_arguments.php', $dumper->dump(array('base_class' => 'ConstructorWithMandatoryArgumentsContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container'))); + } + /** * @dataProvider provideInvalidParameters * @expectedException \InvalidArgumentException diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Container/ConstructorWithMandatoryArgumentsContainer.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Container/ConstructorWithMandatoryArgumentsContainer.php new file mode 100644 index 0000000000000..ba55fb75d8e20 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Container/ConstructorWithMandatoryArgumentsContainer.php @@ -0,0 +1,10 @@ +services = array(); + + $this->aliases = array(); + } + + public function getRemovedIds() + { + return array( + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ); + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } +} diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_mandatory_constructor_arguments.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_mandatory_constructor_arguments.php new file mode 100644 index 0000000000000..dd9ed9cbb3141 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_mandatory_constructor_arguments.php @@ -0,0 +1,55 @@ +services = array(); + + $this->aliases = array(); + } + + public function getRemovedIds() + { + return array( + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ); + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } +} diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_optional_constructor_arguments.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_optional_constructor_arguments.php new file mode 100644 index 0000000000000..d65ac7dfbcac9 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_optional_constructor_arguments.php @@ -0,0 +1,57 @@ +services = array(); + + $this->aliases = array(); + } + + public function getRemovedIds() + { + return array( + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ); + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } +} diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_without_constructor.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_without_constructor.php new file mode 100644 index 0000000000000..4cf1ae40b44df --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_without_constructor.php @@ -0,0 +1,55 @@ +services = array(); + + $this->aliases = array(); + } + + public function getRemovedIds() + { + return array( + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ); + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } +} From 041c42db6a1247007eb1ef412a54357a2a21522f Mon Sep 17 00:00:00 2001 From: Mathieu Lechat Date: Wed, 10 Jan 2018 13:22:09 +0100 Subject: [PATCH 002/166] Allow trans filter to be safe --- .../Twig/Resources/views/Form/form_div_layout.html.twig | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig index 7df55bc4d3879..a5b72c17622c1 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig @@ -219,7 +219,13 @@ {% set label = name|humanize %} {%- endif -%} {%- endif -%} - {{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }} + + {%- if translation_domain is same as(false) -%} + {{- label -}} + {%- else -%} + {{- label|trans({}, translation_domain) -}} + {%- endif -%} + {%- endif -%} {%- endblock form_label -%} From 58cdbd03e14fe82651380d01e4997831054ad52b Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 24 Jan 2018 14:33:28 +0100 Subject: [PATCH 003/166] collect extension information as late as possible --- src/Symfony/Component/HttpKernel/Kernel.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 06f58ee48bfaa..d192a89281cb2 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -700,7 +700,6 @@ protected function prepareContainer(ContainerBuilder $container) foreach ($this->bundles as $bundle) { if ($extension = $bundle->getContainerExtension()) { $container->registerExtension($extension); - $extensions[] = $extension->getAlias(); } if ($this->debug) { @@ -714,6 +713,10 @@ protected function prepareContainer(ContainerBuilder $container) $this->build($container); + foreach ($container->getExtensions() as $extension) { + $extensions[] = $extension->getAlias(); + } + // ensure these extensions are implicitly loaded $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions)); } From 317da3bdf83c5834dde2fc850509d39da8435472 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 26 Jan 2018 17:21:59 +0100 Subject: [PATCH 004/166] keep the context when validating forms --- .../Form/Extension/Validator/Constraints/FormValidator.php | 2 ++ .../Tests/Extension/Validator/Constraints/FormValidatorTest.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php index bddb8a09e8603..4183e1a726593 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php +++ b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php @@ -124,6 +124,7 @@ public function validate($form, Constraint $constraint) : gettype($form->getViewData()); if ($this->context instanceof ExecutionContextInterface) { + $this->context->setConstraint($constraint); $this->context->buildViolation($config->getOption('invalid_message')) ->setParameters(array_replace(array('{{ value }}' => $clientDataAsString), $config->getOption('invalid_message_parameters'))) ->setInvalidValue($form->getViewData()) @@ -144,6 +145,7 @@ public function validate($form, Constraint $constraint) // Mark the form with an error if it contains extra fields if (!$config->getOption('allow_extra_fields') && count($form->getExtraData()) > 0) { if ($this->context instanceof ExecutionContextInterface) { + $this->context->setConstraint($constraint); $this->context->buildViolation($config->getOption('extra_fields_message')) ->setParameter('{{ extra_fields }}', implode('", "', array_keys($form->getExtraData()))) ->setInvalidValue($form->getExtraData()) diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php index 78015b504940b..4bb360a99fe0a 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php @@ -51,6 +51,8 @@ protected function setUp() $this->serverParams = $this->getMockBuilder('Symfony\Component\Form\Extension\Validator\Util\ServerParams')->setMethods(array('getNormalizedIniPostMaxSize', 'getContentLength'))->getMock(); parent::setUp(); + + $this->constraint = new Form(); } protected function getApiVersion() From 3d6c3ba836e6755100915846c797fde572e976b2 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 25 Jan 2018 20:21:40 +0100 Subject: [PATCH 005/166] Don't stop PSR-4 service discovery if a parent class is missing. --- .../DependencyInjection/Loader/FileLoader.php | 25 ++++++++++++++++--- .../Prototype/BadClasses/MissingParent.php | 7 ++++++ .../Tests/Fixtures/config/prototype.php | 2 +- .../Tests/Fixtures/xml/services_prototype.xml | 2 +- .../Fixtures/yaml/services_prototype.yml | 2 +- .../Tests/Loader/FileLoaderTest.php | 21 ++++++++++++++++ 6 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/BadClasses/MissingParent.php diff --git a/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php index c61acdf065183..fa8c636edcd1f 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php @@ -60,11 +60,16 @@ public function registerClasses(Definition $prototype, $namespace, $resource, $e $interfaces = array(); $singlyImplemented = array(); - foreach ($classes as $class) { + foreach ($classes as $class => $errorMessage) { if (interface_exists($class, false)) { $interfaces[] = $class; } else { - $this->setDefinition($class, unserialize($serializedPrototype)); + $this->setDefinition($class, $definition = unserialize($serializedPrototype)); + if (null !== $errorMessage) { + $definition->addError($errorMessage); + + continue; + } foreach (class_implements($class, false) as $interface) { $singlyImplemented[$interface] = isset($singlyImplemented[$interface]) ? false : $class; } @@ -139,13 +144,25 @@ private function findClasses($namespace, $pattern, $excludePattern) if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+$/', $class)) { continue; } + + try { + $r = $this->container->getReflectionClass($class); + } catch (\ReflectionException $e) { + $classes[$class] = sprintf( + 'While discovering services from namespace "%s", an error was thrown when processing the class "%s": "%s".', + $namespace, + $class, + $e->getMessage() + ); + continue; + } // check to make sure the expected class exists - if (!$r = $this->container->getReflectionClass($class)) { + if (!$r) { throw new InvalidArgumentException(sprintf('Expected to find class "%s" in file "%s" while importing services from resource "%s", but it was not found! Check the namespace prefix used with the resource.', $class, $path, $pattern)); } if ($r->isInstantiable() || $r->isInterface()) { - $classes[] = $class; + $classes[$class] = null; } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/BadClasses/MissingParent.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/BadClasses/MissingParent.php new file mode 100644 index 0000000000000..53c97249cf3f2 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/BadClasses/MissingParent.php @@ -0,0 +1,7 @@ +tag('baz'); $di->load(Prototype::class.'\\', '../Prototype') ->autoconfigure() - ->exclude('../Prototype/{OtherDir}') + ->exclude('../Prototype/{OtherDir,BadClasses}') ->factory('f') ->deprecate('%service_id%') ->args(array(0)) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_prototype.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_prototype.xml index 333e71ce57d5a..381f95dd00fa5 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_prototype.xml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_prototype.xml @@ -1,6 +1,6 @@ - + diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_prototype.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_prototype.yml index fb47bcb7e7a52..8c0b202aab2b7 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_prototype.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_prototype.yml @@ -1,4 +1,4 @@ services: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\: resource: ../Prototype - exclude: '../Prototype/{OtherDir}' + exclude: '../Prototype/{OtherDir,BadClasses}' diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php index 4cba7443e8ce9..8a271a818a475 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php @@ -25,6 +25,7 @@ use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\MissingParent; use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\AnotherSub\DeeperBaz; use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\Baz; use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo; @@ -163,6 +164,26 @@ public function testNestedRegisterClasses() $this->assertFalse($alias->isPrivate()); } + public function testMissingParentClass() + { + $container = new ContainerBuilder(); + $container->setParameter('bad_classes_dir', 'BadClasses'); + $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures')); + + $loader->registerClasses( + (new Definition())->setPublic(false), + 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\\', + 'Prototype/%bad_classes_dir%/*' + ); + + $this->assertTrue($container->has(MissingParent::class)); + + $this->assertSame( + array('While discovering services from namespace "Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\", an error was thrown when processing the class "Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\MissingParent": "Class Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\MissingClass not found".'), + $container->getDefinition(MissingParent::class)->getErrors() + ); + } + /** * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException * @expectedExceptionMessageRegExp /Expected to find class "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\Prototype\\Bar" in file ".+" while importing services from resource "Prototype\/Sub\/\*", but it was not found\! Check the namespace prefix used with the resource/ From 9722c063fb18e850d591711fd7113369aafcf272 Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Thu, 25 Jan 2018 23:08:02 +0100 Subject: [PATCH 006/166] [Form] Fixed empty data on expanded ChoiceType and FileType --- .../Form/Extension/Core/Type/ChoiceType.php | 9 +- .../Form/Extension/Core/Type/FileType.php | 15 ++-- .../Extension/Core/Type/ChoiceTypeTest.php | 90 +++++++++++++++++++ 3 files changed, 100 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php index 46a57190cf5a5..601583b7839f8 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php @@ -33,7 +33,6 @@ use Symfony\Component\Form\Extension\Core\EventListener\MergeCollectionListener; use Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToValueTransformer; use Symfony\Component\Form\Extension\Core\DataTransformer\ChoicesToValuesTransformer; -use Symfony\Component\Form\Util\FormUtil; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -91,12 +90,12 @@ public function buildForm(FormBuilderInterface $builder, array $options) $form = $event->getForm(); $data = $event->getData(); + // Since the type always use mapper an empty array will not be + // considered as empty in Form::submit(), we need to evaluate + // empty data here so its value is submitted to sub forms if (null === $data) { $emptyData = $form->getConfig()->getEmptyData(); - - if (false === FormUtil::isEmpty($emptyData) && array() !== $emptyData) { - $data = is_callable($emptyData) ? call_user_func($emptyData, $form, $data) : $emptyData; - } + $data = $emptyData instanceof \Closure ? $emptyData($form, $data) : $emptyData; } // Convert the submitted data to a string, if scalar, before diff --git a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php index 7d84512d9b3c7..321cbc03690e5 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/FileType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/FileType.php @@ -27,10 +27,10 @@ class FileType extends AbstractType */ public function buildForm(FormBuilderInterface $builder, array $options) { + // Ensure that submitted data is always an uploaded file or an array of some $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) { $form = $event->getForm(); $requestHandler = $form->getConfig()->getRequestHandler(); - $data = null; if ($options['multiple']) { $data = array(); @@ -46,19 +46,16 @@ public function buildForm(FormBuilderInterface $builder, array $options) } } - // submitted data for an input file (not required) without choosing any file - if (array(null) === $data || array() === $data) { + // Since the array is never considered empty in the view data format + // on submission, we need to evaluate the configured empty data here + if (array() === $data) { $emptyData = $form->getConfig()->getEmptyData(); - - $data = is_callable($emptyData) ? call_user_func($emptyData, $form, $data) : $emptyData; + $data = $emptyData instanceof \Closure ? $emptyData($form, $data) : $emptyData; } $event->setData($data); } elseif (!$requestHandler->isFileUpload($event->getData())) { - $emptyData = $form->getConfig()->getEmptyData(); - - $data = is_callable($emptyData) ? call_user_func($emptyData, $form, $data) : $emptyData; - $event->setData($data); + $event->setData(null); } }); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php index 9b0983eac5937..842136e14c677 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -690,6 +690,21 @@ public function testSubmitSingleChoiceWithEmptyData() $this->assertSame('test', $form->getData()); } + public function testSubmitSingleChoiceWithEmptyDataAndInitialData() + { + $form = $this->factory->create(static::TESTED_TYPE, 'initial', array( + 'multiple' => false, + 'expanded' => false, + 'choices' => array('initial', 'test'), + 'choices_as_values' => true, + 'empty_data' => 'test', + )); + + $form->submit(null); + + $this->assertSame('test', $form->getData()); + } + public function testSubmitMultipleChoiceWithEmptyData() { $form = $this->factory->create(static::TESTED_TYPE, null, array( @@ -705,6 +720,36 @@ public function testSubmitMultipleChoiceWithEmptyData() $this->assertSame(array('test'), $form->getData()); } + public function testSubmitMultipleChoiceWithEmptyDataAndInitialEmptyArray() + { + $form = $this->factory->create(static::TESTED_TYPE, array(), array( + 'multiple' => true, + 'expanded' => false, + 'choices' => array('test'), + 'choices_as_values' => true, + 'empty_data' => array('test'), + )); + + $form->submit(null); + + $this->assertSame(array('test'), $form->getData()); + } + + public function testSubmitMultipleChoiceWithEmptyDataAndInitialData() + { + $form = $this->factory->create(static::TESTED_TYPE, array('initial'), array( + 'multiple' => true, + 'expanded' => false, + 'choices' => array('initial', 'test'), + 'choices_as_values' => true, + 'empty_data' => array('test'), + )); + + $form->submit(null); + + $this->assertSame(array('test'), $form->getData()); + } + public function testSubmitSingleChoiceExpandedWithEmptyData() { $form = $this->factory->create(static::TESTED_TYPE, null, array( @@ -720,6 +765,21 @@ public function testSubmitSingleChoiceExpandedWithEmptyData() $this->assertSame('test', $form->getData()); } + public function testSubmitSingleChoiceExpandedWithEmptyDataAndInitialData() + { + $form = $this->factory->create(static::TESTED_TYPE, 'initial', array( + 'multiple' => false, + 'expanded' => true, + 'choices' => array('initial', 'test'), + 'choices_as_values' => true, + 'empty_data' => 'test', + )); + + $form->submit(null); + + $this->assertSame('test', $form->getData()); + } + public function testSubmitMultipleChoiceExpandedWithEmptyData() { $form = $this->factory->create(static::TESTED_TYPE, null, array( @@ -735,6 +795,36 @@ public function testSubmitMultipleChoiceExpandedWithEmptyData() $this->assertSame(array('test'), $form->getData()); } + public function testSubmitMultipleChoiceExpandedWithEmptyDataAndInitialEmptyArray() + { + $form = $this->factory->create(static::TESTED_TYPE, array(), array( + 'multiple' => true, + 'expanded' => true, + 'choices' => array('test'), + 'choices_as_values' => true, + 'empty_data' => array('test'), + )); + + $form->submit(null); + + $this->assertSame(array('test'), $form->getData()); + } + + public function testSubmitMultipleChoiceExpandedWithEmptyDataAndInitialData() + { + $form = $this->factory->create(static::TESTED_TYPE, array('init'), array( + 'multiple' => true, + 'expanded' => true, + 'choices' => array('init', 'test'), + 'choices_as_values' => true, + 'empty_data' => array('test'), + )); + + $form->submit(null); + + $this->assertSame(array('test'), $form->getData()); + } + /** * @group legacy */ From b18f9e76a5b32a853d9ca183913cf58c4b41959e Mon Sep 17 00:00:00 2001 From: Dariusz Date: Sun, 21 Jan 2018 19:35:11 +0100 Subject: [PATCH 007/166] [HttpFoundation] Added "null" type on Request::create docblock --- .../Component/HttpFoundation/Request.php | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index 297f036a2f099..fe7080ab86321 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -130,7 +130,7 @@ class Request public $headers; /** - * @var string|resource + * @var string|resource|false|null */ protected $content; @@ -207,13 +207,13 @@ class Request protected static $requestFactory; /** - * @param array $query The GET parameters - * @param array $request The POST parameters - * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...) - * @param array $cookies The COOKIE parameters - * @param array $files The FILES parameters - * @param array $server The SERVER parameters - * @param string|resource $content The raw body data + * @param array $query The GET parameters + * @param array $request The POST parameters + * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...) + * @param array $cookies The COOKIE parameters + * @param array $files The FILES parameters + * @param array $server The SERVER parameters + * @param string|resource|null $content The raw body data */ public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) { @@ -225,13 +225,13 @@ public function __construct(array $query = array(), array $request = array(), ar * * This method also re-initializes all properties. * - * @param array $query The GET parameters - * @param array $request The POST parameters - * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...) - * @param array $cookies The COOKIE parameters - * @param array $files The FILES parameters - * @param array $server The SERVER parameters - * @param string|resource $content The raw body data + * @param array $query The GET parameters + * @param array $request The POST parameters + * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...) + * @param array $cookies The COOKIE parameters + * @param array $files The FILES parameters + * @param array $server The SERVER parameters + * @param string|resource|null $content The raw body data */ public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null) { @@ -294,13 +294,13 @@ public static function createFromGlobals() * The information contained in the URI always take precedence * over the other information (server and parameters). * - * @param string $uri The URI - * @param string $method The HTTP method - * @param array $parameters The query (GET) or request (POST) parameters - * @param array $cookies The request cookies ($_COOKIE) - * @param array $files The request files ($_FILES) - * @param array $server The server parameters ($_SERVER) - * @param string|resource $content The raw body data + * @param string $uri The URI + * @param string $method The HTTP method + * @param array $parameters The query (GET) or request (POST) parameters + * @param array $cookies The request cookies ($_COOKIE) + * @param array $files The request files ($_FILES) + * @param array $server The server parameters ($_SERVER) + * @param string|resource|null $content The raw body data * * @return static */ From 6d59c13e7184cead29f8c2c6010154e902a8541e Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 29 Jan 2018 11:08:21 +0100 Subject: [PATCH 008/166] updated CHANGELOG for 2.7.41 --- CHANGELOG-2.7.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md index 16c5342500901..3b9be1a043a02 100644 --- a/CHANGELOG-2.7.md +++ b/CHANGELOG-2.7.md @@ -7,6 +7,34 @@ in 2.7 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.7.0...v2.7.1 +* 2.7.41 (2018-01-29) + + * bug #25922 [HttpFoundation] Use the correct syntax for session gc based on Pdo driver (tanasecosminromeo) + * bug #25933 Disable CSP header on exception pages only in debug (ostrolucky) + * bug #25926 [Form] Fixed Button::setParent() when already submitted (HeahDude) + * bug #25927 [Form] Fixed submitting disabled buttons (HeahDude) + * bug #25891 [DependencyInjection] allow null values for root nodes in YAML configs (xabbuh) + * bug #25848 [Validator] add missing parent isset and add test (Simperfit) + * bug #25861 do not conflict with egulias/email-validator 2.0+ (xabbuh) + * bug #25851 [Validator] Conflict with egulias/email-validator 2.0 (emodric) + * bug #25837 [SecurityBundle] Don't register in memory users as services (chalasr) + * bug #25835 [HttpKernel] DebugHandlersListener should always replace the existing exception handler (nicolas-grekas) + * bug #25829 [Debug] Always decorate existing exception handlers to deal with fatal errors (nicolas-grekas) + * bug #25824 Fixing a bug where the dump() function depended on bundle ordering (weaverryan) + * bug #25789 Enableable ArrayNodeDefinition is disabled for empty configuration (kejwmen) + * bug #25816 Problem in phar see mergerequest #25579 (betzholz) + * bug #25781 [Form] Disallow transform dates beyond the year 9999 (curry684) + * bug #25812 Copied NO language files to the new NB locale (derrabus) + * bug #25801 [Router] Skip anonymous classes when loading annotated routes (pierredup) + * bug #25657 [Security] Fix fatal error on non string username (chalasr) + * bug #25799 Fixed Request::__toString ignoring cookies (Toflar) + * bug #25755 [Debug] prevent infinite loop with faulty exception handlers (nicolas-grekas) + * bug #25771 [Validator] 19 digits VISA card numbers are valid (xabbuh) + * bug #25751 [FrameworkBundle] Add the missing `enabled` session attribute (sroze) + * bug #25750 [HttpKernel] Turn bad hosts into 400 instead of 500 (nicolas-grekas) + * bug #25490 [Serializer] Fixed throwing exception with option JSON_PARTIAL_OUTPUT_ON_ERROR (diversantvlz) + * feature #25669 [Security] Fail gracefully if the security token cannot be unserialized from the session (thewilkybarkid) + * 2.7.40 (2018-01-05) * bug #25532 [HttpKernel] Disable CSP header on exception pages (ostrolucky) From 50931d83f50a0069479a802b2e3b9b6f6b088f39 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 29 Jan 2018 11:08:31 +0100 Subject: [PATCH 009/166] update CONTRIBUTORS for 2.7.41 --- CONTRIBUTORS.md | 56 ++++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 85b3003b2abc6..96a8a8f23cc19 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -16,8 +16,8 @@ Symfony is the result of the work of many people who made the code better - Kévin Dunglas (dunglas) - Jakub Zalas (jakubzalas) - Kris Wallsmith (kriswallsmith) - - Ryan Weaver (weaverryan) - Robin Chalas (chalas_r) + - Ryan Weaver (weaverryan) - Javier Eguiluz (javier.eguiluz) - Maxime Steinhausser (ogizanagi) - Hugo Hamon (hhamon) @@ -58,21 +58,21 @@ Symfony is the result of the work of many people who made the code better - Diego Saint Esteben (dii3g0) - Dany Maillard (maidmaid) - Konstantin Kudryashov (everzet) + - Amrouche Hamza (simperfit) - Kevin Bond (kbond) - - Bilal Amarni (bamarni) - Pierre du Plessis (pierredup) + - Bilal Amarni (bamarni) - Florin Patan (florinpatan) - Jérémy DERUSSÉ (jderusse) - - Amrouche Hamza (simperfit) + - Samuel ROZE (sroze) - Gábor Egyed (1ed) + - Alexander M. Turek (derrabus) - Michel Weimerskirch (mweimerskirch) - Andrej Hudec (pulzarraider) - - Alexander M. Turek (derrabus) - Eric Clemmons (ericclemmons) - Jáchym Toušek (enumag) - Charles Sarrazin (csarrazi) - Titouan Galopin (tgalopin) - - Samuel ROZE (sroze) - Konstantin Myakshin (koc) - Christian Raue - Arnout Boks (aboks) @@ -100,9 +100,9 @@ Symfony is the result of the work of many people who made the code better - Maxime STEINHAUSSER - Michal Piotrowski (eventhorizon) - Tim Nagel (merk) + - David Maicher (dmaicher) - Vladimir Reznichenko (kalessil) - Brice BERNARD (brikou) - - David Maicher (dmaicher) - Baptiste Clavié (talus) - marc.weistroff - lenar @@ -112,17 +112,17 @@ Symfony is the result of the work of many people who made the code better - Florian Voutzinos (florianv) - Colin Frei - Adrien Brault (adrienbrault) + - Tomáš Votruba (tomas_votruba) - Joshua Thijssen - Peter Kokot (maastermedia) - David Buchmann (dbu) - excelwebzone - - Tomáš Votruba (tomas_votruba) + - Grégoire Paris (greg0ire) - Fabien Pennequin (fabienpennequin) - Gordon Franke (gimler) - Eric GELOEN (gelo) - Daniel Wehner (dawehner) - Tugdual Saunier (tucksaun) - - Grégoire Paris (greg0ire) - Théo FIDRY (theofidry) - Robert Schönthal (digitalkaoz) - Florian Lonqueu-Brochard (florianlb) @@ -135,11 +135,11 @@ Symfony is the result of the work of many people who made the code better - Sebastian Hörl (blogsh) - Daniel Gomes (danielcsgomes) - Hidenori Goto (hidenorigoto) + - Alex Pott - Guilherme Blanco (guilhermeblanco) - Pablo Godel (pgodel) - Jérémie Augustin (jaugustin) - Andréia Bohner (andreia) - - Alex Pott - Julien Falque (julienfalque) - Rafael Dohms (rdohms) - Arnaud Kleinpeter (nanocom) @@ -147,6 +147,7 @@ Symfony is the result of the work of many people who made the code better - Mikael Pajunen - Joel Wurtz (brouznouf) - Jérôme Vasseur (jvasseur) + - Chris Wilkinson (thewilkybarkid) - Oleg Voronkovich - Philipp Wahala (hifi) - Vyacheslav Pavlov @@ -169,7 +170,6 @@ Symfony is the result of the work of many people who made the code better - GDIBass - jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent) - James Halsall (jaitsu) - - Chris Wilkinson (thewilkybarkid) - Warnar Boekkooi (boekkooi) - Dmitrii Chekaliuk (lazyhammer) - Clément JOBEILI (dator) @@ -213,8 +213,10 @@ Symfony is the result of the work of many people who made the code better - Tom Van Looy (tvlooy) - Sven Paulus (subsven) - Rui Marinho (ruimarinho) + - Niels Keurentjes (curry684) - Eugene Wissner - Julien Brochet (mewt) + - Gabriel Ostrolucký - Tristan Darricau (nicofuma) - Michaël Perrin (michael.perrin) - Marcel Beerta (mazen) @@ -247,13 +249,11 @@ Symfony is the result of the work of many people who made the code better - Alessandro Chitolina - Kristen Gilden (kgilden) - Pierre-Yves LEBECQ (pylebecq) - - Niels Keurentjes (curry684) - Jordan Samouh (jordansamouh) - Jakub Kucharovic (jkucharovic) - Uwe Jäger (uwej711) - Eugene Leonovich (rybakit) - Filippo Tessarotto - - Gabriel Ostrolucký - Joseph Rouff (rouffj) - Félix Labrecque (woodspire) - GordonsLondon @@ -285,6 +285,7 @@ Symfony is the result of the work of many people who made the code better - Robert Kiss (kepten) - Roumen Damianoff (roumen) - Antonio J. García Lagar (ajgarlag) + - Benoît Burnichon (bburnichon) - Kim Hemsø Rasmussen (kimhemsoe) - Wouter Van Hecke - Jérôme Parmentier (lctrs) @@ -293,6 +294,9 @@ Symfony is the result of the work of many people who made the code better - Michael Holm (hollo) - Marc Weistroff (futurecat) - Christian Schmidt + - Yanick Witschi (toflar) + - Edi Modrić (emodric) + - Thomas Calvet (fancyweb) - Chad Sikorra (chadsikorra) - Chris Smith (cs278) - Florian Klein (docteurklein) @@ -309,6 +313,7 @@ Symfony is the result of the work of many people who made the code better - Wouter J - Ismael Ambrosi (iambrosi) - Baptiste Lafontaine + - François Pluchino (francoispluchino) - Aurelijus Valeiša (aurelijus) - Victor Bocharsky (bocharsky_bw) - Jan Decavele (jandc) @@ -347,11 +352,9 @@ Symfony is the result of the work of many people who made the code better - Damien Alexandre (damienalexandre) - Felix Labrecque - Yaroslav Kiliba + - Maxime Veber (nek-) - Terje Bråten - - Yanick Witschi (toflar) - Robbert Klarenbeek (robbertkl) - - Edi Modrić (emodric) - - Thomas Calvet (fancyweb) - JhonnyL - David Badura (davidbadura) - hossein zolfi (ocean) @@ -364,7 +367,6 @@ Symfony is the result of the work of many people who made the code better - Philipp Kräutli (pkraeutli) - Kirill chEbba Chebunin (chebba) - Greg Thornton (xdissent) - - Benoît Burnichon (bburnichon) - Costin Bereveanu (schniper) - Loïc Chardonnet (gnusat) - Marek Kalnik (marekkalnik) @@ -372,7 +374,6 @@ Symfony is the result of the work of many people who made the code better - Hassan Amouhzi - Tamas Szijarto - Pavel Volokitin (pvolok) - - François Pluchino (francoispluchino) - Arthur de Moulins (4rthem) - Nicolas Dewez (nicolas_dewez) - Endre Fejes @@ -452,7 +453,6 @@ Symfony is the result of the work of many people who made the code better - Zander Baldwin - Adam Harvey - Anton Bakai - - Maxime Veber (nek-) - Alex Bakhturin - Alexander Obuhovich (aik099) - boombatower @@ -575,6 +575,7 @@ Symfony is the result of the work of many people who made the code better - Hany el-Kerdany - Wang Jingyu - Åsmund Garfors + - Gunnstein Lye (glye) - Maxime Douailin - Jean Pasdeloup (pasdeloup) - Benjamin Cremer (bcremer) @@ -587,6 +588,7 @@ Symfony is the result of the work of many people who made the code better - Sebastian Marek (proofek) - Erkhembayar Gantulga (erheme318) - Michal Trojanowski + - Mateusz Sip - David Fuhr - Kamil Kokot (pamil) - Aurimas Niekis (gcds) @@ -648,6 +650,8 @@ Symfony is the result of the work of many people who made the code better - Richard van den Brand (ricbra) - develop - VJ + - Delf Tonder (leberknecht) + - Sullivan SENECHAL (soullivaneuh) - Mark Sonnabaum - Richard Quadling - jochenvdv @@ -801,6 +805,7 @@ Symfony is the result of the work of many people who made the code better - Jacques Moati - Balazs Csaba (balazscsaba2006) - Douglas Reith (douglas_reith) + - Forfarle (forfarle) - Harry Walter (haswalt) - Johnson Page (jwpage) - Ruben Gonzalez (rubenruateltek) @@ -930,6 +935,7 @@ Symfony is the result of the work of many people who made the code better - benatespina (benatespina) - Denis Kop - jfcixmedia + - Nikita Konstantinov - Martijn Evers - Benjamin Paap (benjaminpaap) - Christian @@ -975,6 +981,7 @@ Symfony is the result of the work of many people who made the code better - Jeremy Bush - wizhippo - Viacheslav Sychov + - Matt Brunt - Carlos Ortega Huetos - rpg600 - Péter Buri (burci) @@ -1026,6 +1033,7 @@ Symfony is the result of the work of many people who made the code better - Felicitus - Krzysztof Przybyszewski - Paul Matthews + - Vacheslav Silyutin - Juan Traverso - Alain Flaus (halundra) - Tarjei Huse (tarjei) @@ -1070,7 +1078,6 @@ Symfony is the result of the work of many people who made the code better - Sebastian Göttschkes (sgoettschkes) - Tatsuya Tsuruoka - Ross Tuck - - Gunnstein Lye (glye) - Kévin Gomez (kevin) - azine - Dawid Sajdak @@ -1126,6 +1133,7 @@ Symfony is the result of the work of many people who made the code better - Kim Laï Trinh - Jason Desrosiers - m.chwedziak + - Andreas Frömer - Philip Frank - Lance McNearney - Gonzalo Vilaseca (gonzalovilaseca) @@ -1144,7 +1152,6 @@ Symfony is the result of the work of many people who made the code better - WedgeSama - Felds Liscia - Chihiro Adachi (chihiro-adachi) - - Sullivan SENECHAL - Tadcka - Beth Binkovitz - Gonzalo Míguez @@ -1202,6 +1209,7 @@ Symfony is the result of the work of many people who made the code better - Simon Neidhold - Xavier HAUSHERR - Valentin VALCIU + - Jeremiah VALERIE - Kevin Dew - James Cowgill - 1ma (jautenim) @@ -1251,6 +1259,7 @@ Symfony is the result of the work of many people who made the code better - natechicago - Jonathan Poston - Adrian Olek (adrianolek) + - Jody Mickey (jwmickey) - Przemysław Piechota (kibao) - Leonid Terentyev (li0n) - ryunosuke @@ -1260,6 +1269,7 @@ Symfony is the result of the work of many people who made the code better - Iwan van Staveren (istaveren) - Povilas S. (povilas) - pborreli + - Boris Betzholz - Eric Caron - 2manypeople - Wing @@ -1409,6 +1419,7 @@ Symfony is the result of the work of many people who made the code better - vlakoff - bertillon - Bertalan Attila + - AmsTaFF (amstaff) - Yannick Bensacq (cibou) - Frédéric G. Marand (fgm) - Freek Van der Herten (freekmurze) @@ -1514,6 +1525,7 @@ Symfony is the result of the work of many people who made the code better - Javier Núñez Berrocoso (javiernuber) - Jelle Bekker (jbekker) - Ian Jenkins (jenkoian) + - Giovanni Albero (johntree) - Jorge Martin (jorgemartind) - Joeri Verdeyen (jverdeyen) - Dmitrii Poddubnyi (karser) @@ -1560,6 +1572,7 @@ Symfony is the result of the work of many people who made the code better - Ismail Asci (ismailasci) - Simon CONSTANS (kosssi) - Kristof Van Cauwenbergh (kristofvc) + - Dennis Langen (nijusan) - Paulius Jarmalavičius (pjarmalavicius) - Ramon Henrique Ornelas (ramonornela) - Ricardo de Vries (ricknox) @@ -1598,6 +1611,7 @@ Symfony is the result of the work of many people who made the code better - lol768 - jamogon - Vyacheslav Slinko + - Jakub Chábek - Johannes - Jörg Rühl - wesleyh @@ -1606,6 +1620,7 @@ Symfony is the result of the work of many people who made the code better - Michael Genereux - patrick-mcdougle - Dariusz Czech + - Jack Wright - Anonymous User - Paweł Tomulik - Eric J. Duran @@ -1728,7 +1743,6 @@ Symfony is the result of the work of many people who made the code better - Fabien D. (fabd) - Carsten Eilers (fnc) - Sorin Gitlan (forapathy) - - Forfarle (forfarle) - Yohan Giarelli (frequence-web) - Gerry Vandermaesen (gerryvdm) - Ghazy Ben Ahmed (ghazy) From 87580b1fd2620f50b92da9e17f201c8988496360 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 29 Jan 2018 11:08:39 +0100 Subject: [PATCH 010/166] updated VERSION for 2.7.41 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index afbd8159996f3..82bd5ea5d88c5 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 = '2.7.41-DEV'; + const VERSION = '2.7.41'; const VERSION_ID = 20741; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; const RELEASE_VERSION = 41; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From 1ee3950b7310ab892531e4fc43961b448cf2bd28 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 29 Jan 2018 11:46:38 +0100 Subject: [PATCH 011/166] bumped Symfony version to 2.7.42 --- 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 82bd5ea5d88c5..159bde4d1bccc 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 = '2.7.41'; - const VERSION_ID = 20741; + const VERSION = '2.7.42-DEV'; + const VERSION_ID = 20742; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; - const RELEASE_VERSION = 41; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 42; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From 58b93ddc57969b959fd2617daa95856d3e540896 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 29 Jan 2018 11:48:06 +0100 Subject: [PATCH 012/166] updated CHANGELOG for 2.8.34 --- CHANGELOG-2.8.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CHANGELOG-2.8.md b/CHANGELOG-2.8.md index ac8f7b3768625..c4b5466e54e3c 100644 --- a/CHANGELOG-2.8.md +++ b/CHANGELOG-2.8.md @@ -7,6 +7,35 @@ in 2.8 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.8.0...v2.8.1 +* 2.8.34 (2018-01-29) + + * bug #25922 [HttpFoundation] Use the correct syntax for session gc based on Pdo driver (tanasecosminromeo) + * bug #25933 Disable CSP header on exception pages only in debug (ostrolucky) + * bug #25926 [Form] Fixed Button::setParent() when already submitted (HeahDude) + * bug #25927 [Form] Fixed submitting disabled buttons (HeahDude) + * bug #25891 [DependencyInjection] allow null values for root nodes in YAML configs (xabbuh) + * bug #25848 [Validator] add missing parent isset and add test (Simperfit) + * bug #25861 do not conflict with egulias/email-validator 2.0+ (xabbuh) + * bug #25851 [Validator] Conflict with egulias/email-validator 2.0 (emodric) + * bug #25837 [SecurityBundle] Don't register in memory users as services (chalasr) + * bug #25835 [HttpKernel] DebugHandlersListener should always replace the existing exception handler (nicolas-grekas) + * bug #25829 [Debug] Always decorate existing exception handlers to deal with fatal errors (nicolas-grekas) + * bug #25824 Fixing a bug where the dump() function depended on bundle ordering (weaverryan) + * bug #25789 Enableable ArrayNodeDefinition is disabled for empty configuration (kejwmen) + * bug #25816 Problem in phar see mergerequest #25579 (betzholz) + * bug #25781 [Form] Disallow transform dates beyond the year 9999 (curry684) + * bug #25812 Copied NO language files to the new NB locale (derrabus) + * bug #25801 [Router] Skip anonymous classes when loading annotated routes (pierredup) + * bug #25657 [Security] Fix fatal error on non string username (chalasr) + * bug #25799 Fixed Request::__toString ignoring cookies (Toflar) + * bug #25755 [Debug] prevent infinite loop with faulty exception handlers (nicolas-grekas) + * bug #25771 [Validator] 19 digits VISA card numbers are valid (xabbuh) + * bug #25751 [FrameworkBundle] Add the missing `enabled` session attribute (sroze) + * bug #25750 [HttpKernel] Turn bad hosts into 400 instead of 500 (nicolas-grekas) + * bug #25490 [Serializer] Fixed throwing exception with option JSON_PARTIAL_OUTPUT_ON_ERROR (diversantvlz) + * bug #25709 Tweaked some styles in the profiler tables (javiereguiluz) + * feature #25669 [Security] Fail gracefully if the security token cannot be unserialized from the session (thewilkybarkid) + * 2.8.33 (2018-01-05) * bug #25532 [HttpKernel] Disable CSP header on exception pages (ostrolucky) From 854819419692b2d1a838239073f17e5476528f36 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 29 Jan 2018 11:48:12 +0100 Subject: [PATCH 013/166] updated VERSION for 2.8.34 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index b721249e046c9..f2db06634cca4 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.8.34-DEV'; + const VERSION = '2.8.34'; const VERSION_ID = 20834; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; const RELEASE_VERSION = 34; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From d5375d01dd3328b3946b729b744d498674f96c20 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 29 Jan 2018 12:40:56 +0100 Subject: [PATCH 014/166] bumped Symfony version to 2.8.35 --- 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 f2db06634cca4..7f61bdc645e80 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.8.34'; - const VERSION_ID = 20834; + const VERSION = '2.8.35-DEV'; + const VERSION_ID = 20835; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; - const RELEASE_VERSION = 34; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 35; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From cf38c49752dd3ed52e74062e45b3e7b707bf223f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 29 Jan 2018 13:29:35 +0100 Subject: [PATCH 015/166] updated CHANGELOG for 3.4.4 --- CHANGELOG-3.4.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index 38a2d7c9a7a33..39bdf7acc9a6f 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -7,6 +7,57 @@ in 3.4 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.4.0...v3.4.1 +* 3.4.4 (2018-01-29) + + * bug #25932 Don't stop PSR-4 service discovery if a parent class is missing (derrabus) + * bug #25922 [HttpFoundation] Use the correct syntax for session gc based on Pdo driver (tanasecosminromeo) + * bug #25933 Disable CSP header on exception pages only in debug (ostrolucky) + * bug #25926 [Form] Fixed Button::setParent() when already submitted (HeahDude) + * bug #25927 [Form] Fixed submitting disabled buttons (HeahDude) + * bug #25397 [Console] Provide a DX where an array could be passed (Simperfit) + * bug #25858 [DI] Fix initialization of legacy containers by delaying include_once (nicolas-grekas) + * bug #25891 [DependencyInjection] allow null values for root nodes in YAML configs (xabbuh) + * bug #24864 Have weak_vendors ignore deprecations from outside (greg0ire) + * bug #25848 [Validator] add missing parent isset and add test (Simperfit) + * bug #25869 [Process] Skip environment variables with false value in Process (francoispluchino) + * bug #25864 [Yaml] don't split lines on carriage returns when dumping (xabbuh) + * bug #25861 do not conflict with egulias/email-validator 2.0+ (xabbuh) + * bug #25851 [Validator] Conflict with egulias/email-validator 2.0 (emodric) + * bug #25837 [SecurityBundle] Don't register in memory users as services (chalasr) + * bug #25835 [HttpKernel] DebugHandlersListener should always replace the existing exception handler (nicolas-grekas) + * bug #25829 [Debug] Always decorate existing exception handlers to deal with fatal errors (nicolas-grekas) + * bug #25823 [Security] Notify that symfony/expression-language is not installed if ExpressionLanguage is used (giovannialbero1992) + * bug #25824 Fixing a bug where the dump() function depended on bundle ordering (weaverryan) + * bug #25763 [OptionsResolver] Fix options resolver with array allowed types (mcg-web) + * bug #25789 Enableable ArrayNodeDefinition is disabled for empty configuration (kejwmen) + * bug #25822 [Cache] Fix handling of apcu_fetch() edgy behavior (nicolas-grekas) + * bug #25816 Problem in phar see mergerequest #25579 (betzholz) + * bug #25781 [Form] Disallow transform dates beyond the year 9999 (curry684) + * bug #25287 [Serializer] DateTimeNormalizer handling of null and empty values (returning it instead of new object) (Simperfit) + * bug #25249 [Form] Avoid button label translation when it's set to false (TeLiXj) + * bug #25127 [TwigBridge] Pass the form-check-inline in parent (Simperfit) + * bug #25812 Copied NO language files to the new NB locale (derrabus) + * bug #25753 [Console] Fix restoring exception handler (nicolas-grekas, fancyweb) + * bug #25801 [Router] Skip anonymous classes when loading annotated routes (pierredup) + * bug #25508 [FrameworkBundle] Auto-enable CSRF if the component *+ session* are loaded (nicolas-grekas) + * bug #25657 [Security] Fix fatal error on non string username (chalasr) + * bug #25791 [Routing] Make sure we only build routes once (sroze) + * bug #25799 Fixed Request::__toString ignoring cookies (Toflar) + * bug #25755 [Debug] prevent infinite loop with faulty exception handlers (nicolas-grekas) + * bug #25771 [Validator] 19 digits VISA card numbers are valid (xabbuh) + * bug #25751 [FrameworkBundle] Add the missing `enabled` session attribute (sroze) + * bug #25750 [HttpKernel] Turn bad hosts into 400 instead of 500 (nicolas-grekas) + * bug #25699 [HttpKernel] Fix session handling: decouple "save" from setting response "private" (nicolas-grekas) + * bug #25490 [Serializer] Fixed throwing exception with option JSON_PARTIAL_OUTPUT_ON_ERROR (diversantvlz) + * bug #25737 [TwigBridge] swap filter/function and package names (xabbuh) + * bug #25731 [HttpFoundation] Always call proxied handler::destroy() in StrictSessionHandler (nicolas-grekas) + * bug #25733 [HttpKernel] Fix compile error when a legacy container is fresh again (nicolas-grekas) + * bug #25709 Tweaked some styles in the profiler tables (javiereguiluz) + * bug #25719 [HttpKernel] Uses cookies to track the requests redirection (sroze) + * bug #25696 [FrameworkBundle] Fix using "annotations.cached_reader" in after-removing passes (nicolas-grekas) + * feature #25669 [Security] Fail gracefully if the security token cannot be unserialized from the session (thewilkybarkid) + * bug #25700 Run simple-phpunit with --no-suggest option (ro0NL) + * 3.4.3 (2018-01-05) * bug #25685 Use triggering file to determine weak vendors if when the test is run in a separate process (alexpott) From ba2eb73c3b7ff8f3984cec9fc78cbab1a3f1f4ac Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 29 Jan 2018 13:29:46 +0100 Subject: [PATCH 016/166] updated VERSION for 3.4.4 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index b92a5b05e0d0d..eb2364e469ea7 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,12 +67,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.4-DEV'; + const VERSION = '3.4.4'; const VERSION_ID = 30404; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; const RELEASE_VERSION = 4; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From 0023f4e84d525d2d95a672597e1219dd0954c0fd Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 29 Jan 2018 14:25:55 +0100 Subject: [PATCH 017/166] bumped Symfony version to 3.4.5 --- 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 eb2364e469ea7..56dbc1f5f659a 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -67,12 +67,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '3.4.4'; - const VERSION_ID = 30404; + const VERSION = '3.4.5-DEV'; + const VERSION_ID = 30405; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; - const RELEASE_VERSION = 4; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 5; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From c9cf0aaae519333d8097f0db79e6b4f5d012a7e1 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 29 Jan 2018 14:36:59 +0100 Subject: [PATCH 018/166] bumped Symfony version to 4.0.5 --- 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 14d4d269e27dd..9fc493921b0b5 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -63,12 +63,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private $requestStackSize = 0; private $resetServices = false; - const VERSION = '4.0.4'; - const VERSION_ID = 40004; + const VERSION = '4.0.5-DEV'; + const VERSION_ID = 40005; const MAJOR_VERSION = 4; const MINOR_VERSION = 0; - const RELEASE_VERSION = 4; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 5; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '07/2018'; const END_OF_LIFE = '01/2019'; From 35f98e208962d2d40f91ada5c3c994d2edc79b83 Mon Sep 17 00:00:00 2001 From: Greg Anderson Date: Fri, 19 Jan 2018 15:19:59 -0800 Subject: [PATCH 019/166] Follow-on to #25825: Fix edge case in getParameterOption. Add one test to demonstrate getParameterOption fix. Add several tests to demonstrate current limitations in hasParameterOption. --- .../Component/Console/Input/ArgvInput.php | 19 +++++++---- .../Console/Input/InputInterface.php | 4 +++ .../Console/Tests/Input/ArgvInputTest.php | 32 +++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Console/Input/ArgvInput.php b/src/Symfony/Component/Console/Input/ArgvInput.php index c2f533eb36798..da064598d0741 100644 --- a/src/Symfony/Component/Console/Input/ArgvInput.php +++ b/src/Symfony/Component/Console/Input/ArgvInput.php @@ -279,7 +279,11 @@ public function hasParameterOption($values) foreach ($this->tokens as $token) { foreach ($values as $value) { - if ($token === $value || 0 === strpos($token, $value.'=')) { + // Options with values: + // For long options, test for '--option=' at beginning + // For short options, test for '-o' at beginning + $leading = 0 === strpos($value, '--') ? $value.'=' : $value; + if ($token === $value || 0 === strpos($token, $leading)) { return true; } } @@ -300,13 +304,16 @@ public function getParameterOption($values, $default = false) $token = array_shift($tokens); foreach ($values as $value) { - if ($token === $value || 0 === strpos($token, $value.'=')) { - if (false !== $pos = strpos($token, '=')) { - return substr($token, $pos + 1); - } - + if ($token === $value) { return array_shift($tokens); } + // Options with values: + // For long options, test for '--option=' at beginning + // For short options, test for '-o' at beginning + $leading = 0 === strpos($value, '--') ? $value.'=' : $value; + if (0 === strpos($token, $leading)) { + return substr($token, strlen($leading)); + } } } diff --git a/src/Symfony/Component/Console/Input/InputInterface.php b/src/Symfony/Component/Console/Input/InputInterface.php index 9de6e3a409830..ac14de7d6f85f 100644 --- a/src/Symfony/Component/Console/Input/InputInterface.php +++ b/src/Symfony/Component/Console/Input/InputInterface.php @@ -30,6 +30,8 @@ public function getFirstArgument(); * * This method is to be used to introspect the input parameters * before they have been validated. It must be used carefully. + * Does not necessarily return the correct result for short options + * when multiple flags are combined in the same option. * * @param string|array $values The values to look for in the raw parameters (can be an array) * @@ -42,6 +44,8 @@ public function hasParameterOption($values); * * This method is to be used to introspect the input parameters * before they have been validated. It must be used carefully. + * Does not necessarily return the correct result for short options + * when multiple flags are combined in the same option. * * @param string|array $values The value(s) to look for in the raw parameters (can be an array) * @param mixed $default The default value to return if no result is found diff --git a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php index 1fe21d0f6c1a8..04f5ce3157c44 100644 --- a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php +++ b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php @@ -296,6 +296,10 @@ public function testHasParameterOption() $input = new ArgvInput(array('cli.php', '-f', 'foo')); $this->assertTrue($input->hasParameterOption('-f'), '->hasParameterOption() returns true if the given short option is in the raw input'); + $input = new ArgvInput(array('cli.php', '-etest')); + $this->assertTrue($input->hasParameterOption('-e'), '->hasParameterOption() returns true if the given short option is in the raw input'); + $this->assertFalse($input->hasParameterOption('-s'), '->hasParameterOption() returns true if the given short option is in the raw input'); + $input = new ArgvInput(array('cli.php', '--foo', 'foo')); $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given short option is in the raw input'); @@ -306,6 +310,33 @@ public function testHasParameterOption() $this->assertTrue($input->hasParameterOption('--foo'), '->hasParameterOption() returns true if the given option with provided value is in the raw input'); } + public function testHasParameterOptionEdgeCasesAndLimitations() + { + $input = new ArgvInput(array('cli.php', '-fh')); + // hasParameterOption does not know if the previous short option, -f, + // takes a value or not. If -f takes a value, then -fh does NOT include + // -h; Otherwise it does. Since we do not know which short options take + // values, hasParameterOption does not support this use-case. + $this->assertFalse($input->hasParameterOption('-h'), '->hasParameterOption() returns true if the given short option is in the raw input'); + // hasParameterOption does detect that `-fh` contains `-f`, since + // `-f` is the first short option in the set. + $this->assertTrue($input->hasParameterOption('-f'), '->hasParameterOption() returns true if the given short option is in the raw input'); + // The test below happens to pass, although it might make more sense + // to disallow it, and require the use of + // $input->hasParameterOption('-f') && $input->hasParameterOption('-h') + // instead. + $this->assertTrue($input->hasParameterOption('-fh'), '->hasParameterOption() returns true if the given short option is in the raw input'); + // In theory, if -fh is supported, then -hf should also work. + // However, this is not supported. + $this->assertFalse($input->hasParameterOption('-hf'), '->hasParameterOption() returns true if the given short option is in the raw input'); + + $input = new ArgvInput(array('cli.php', '-f', '-h')); + // If hasParameterOption('-fh') is supported for 'cli.php -fh', then + // one might also expect that it should also be supported for + // 'cli.php -f -h'. However, this is not supported. + $this->assertFalse($input->hasParameterOption('-fh'), '->hasParameterOption() returns true if the given short option is in the raw input'); + } + public function testToString() { $input = new ArgvInput(array('cli.php', '-f', 'foo')); @@ -327,6 +358,7 @@ public function testGetParameterOptionEqualSign($argv, $key, $expected) public function provideGetParameterOptionValues() { return array( + array(array('app/console', 'foo:bar', '-edev'), '-e', 'dev'), array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', 'dev'), array(array('app/console', 'foo:bar', '--env=dev'), '--env', 'dev'), array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'dev'), From 926b1bee1828f6a01d93a3926b756e096c5042d2 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 30 Jan 2018 16:11:54 +0100 Subject: [PATCH 020/166] [Debug] Fix bad registration of exception handler, leading to mem leak --- src/Symfony/Component/Debug/ErrorHandler.php | 13 ++++++++++++- .../Component/Debug/Tests/ErrorHandlerTest.php | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index 6a15f7b368307..8875e03e8442b 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -149,9 +149,20 @@ public static function register($handler = null, $replace = true) } if (!$replace && $prev) { restore_error_handler(); + $handlerIsRegistered = is_array($prev) && $handler === $prev[0]; + } else { + $handlerIsRegistered = true; } - if (is_array($prev = set_exception_handler(array($handler, 'handleException'))) && $prev[0] === $handler) { + if (is_array($prev = set_exception_handler(array($handler, 'handleException'))) && $prev[0] instanceof self) { restore_exception_handler(); + if (!$handlerIsRegistered) { + $handler = $prev[0]; + } elseif ($handler !== $prev[0] && $replace) { + set_exception_handler(array($handler, 'handleException')); + $p = $prev[0]->setExceptionHandler(null); + $handler->setExceptionHandler($p); + $prev[0]->setExceptionHandler($p); + } } else { $handler->setExceptionHandler($prev); } diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php index 264dc701e7e2e..f2d0fc8b0bc85 100644 --- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php +++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php @@ -34,7 +34,7 @@ public function testRegister() $newHandler = new ErrorHandler(); - $this->assertSame($newHandler, ErrorHandler::register($newHandler, false)); + $this->assertSame($handler, ErrorHandler::register($newHandler, false)); $h = set_error_handler('var_dump'); restore_error_handler(); $this->assertSame(array($handler, 'handleError'), $h); From 5bbb77b866fc0fb50ef762e572f9344267eaebf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=9D=A6=E7=B1=B3?= Date: Tue, 30 Jan 2018 23:53:25 +0800 Subject: [PATCH 021/166] support sapi_windows_vt100_support for php 7.2+ --- src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php | 3 ++- src/Symfony/Component/Console/Output/StreamOutput.php | 3 ++- src/Symfony/Component/VarDumper/Dumper/CliDumper.php | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index dae4759134c2f..f73690db00553 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -161,7 +161,8 @@ private static function hasColorSupport() { if ('\\' === DIRECTORY_SEPARATOR) { return - '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD + defined('STDOUT') && function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support(STDOUT) + || '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD || false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM'); diff --git a/src/Symfony/Component/Console/Output/StreamOutput.php b/src/Symfony/Component/Console/Output/StreamOutput.php index e547c3a6c0b9f..d32b1cfb54cae 100644 --- a/src/Symfony/Component/Console/Output/StreamOutput.php +++ b/src/Symfony/Component/Console/Output/StreamOutput.php @@ -90,7 +90,8 @@ protected function hasColorSupport() { if (DIRECTORY_SEPARATOR === '\\') { return - '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD + function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support($this->stream) + || '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD || false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM'); diff --git a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php index 107a2a438d35e..689ada77c2460 100644 --- a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php @@ -450,7 +450,8 @@ protected function supportsColors() if ('\\' === DIRECTORY_SEPARATOR) { static::$defaultColors = @( - '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD + function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support($this->outputStream) + || '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD || false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM') From 3288fb0d1778039351cfd5fbed00907adc46c834 Mon Sep 17 00:00:00 2001 From: Joachim Krempel Date: Tue, 30 Jan 2018 12:45:31 +0100 Subject: [PATCH 022/166] [WebProfilerBundle] Increase retry delays between toolbarAction ajax calls --- .../Resources/views/Profiler/base_js.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig index a1b9c4ffd992b..cde7a4c685832 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig @@ -32,7 +32,7 @@ setTimeout(function(){ options.maxTries--; request(url, onSuccess, onError, payload, options); - }, 500); + }, 1000); return null; } From 21bbad93f0a1561d7bd4c2788547c9a567cc0b3a Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 30 Jan 2018 16:03:04 +0100 Subject: [PATCH 023/166] update test for Twig performance optimizations --- src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php b/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php index 4b356b2a8d655..2d4b13f0daecb 100644 --- a/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Node/TransNodeTest.php @@ -57,6 +57,10 @@ protected function getVariableGetterWithoutStrictCheck($name) protected function getVariableGetterWithStrictCheck($name) { + if (Environment::VERSION_ID > 20404) { + return sprintf('(isset($context["%s"]) || array_key_exists("%1$s", $context) ? $context["%1$s"] : (function () { throw new Twig_Error_Runtime(\'Variable "%1$s" does not exist.\', 0, $this->source); })())', $name); + } + if (Environment::MAJOR_VERSION >= 2) { return sprintf('(isset($context["%s"]) || array_key_exists("%1$s", $context) ? $context["%1$s"] : (function () { throw new Twig_Error_Runtime(\'Variable "%1$s" does not exist.\', 0, $this->getSourceContext()); })())', $name); } From b173b81f46cae887be1255be60ec687222b1af72 Mon Sep 17 00:00:00 2001 From: Lars Strojny Date: Tue, 30 Jan 2018 22:52:03 +0100 Subject: [PATCH 024/166] Proxy class names should be deterministic and independent of spl_object_hash() which is somewhat random --- .../Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index 1ec900b84bddf..2b827324fa7b6 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -108,7 +108,7 @@ public function getProxyCode(Definition $definition) */ private function getProxyClassName(Definition $definition) { - return preg_replace('/^.*\\\\/', '', $definition->getClass()).'_'.substr(hash('sha256', spl_object_hash($definition).$this->salt), -7); + return preg_replace('/^.*\\\\/', '', $definition->getClass()).'_'.substr(hash('sha256', $definition->getClass().$this->salt), -7); } /** From 4f18e4b0dcbdb94bfa3ffb3fc009d17fca858b21 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 31 Jan 2018 09:22:50 +0100 Subject: [PATCH 025/166] [DI] Fix tracking of source class changes for lazy-proxies --- .../Component/DependencyInjection/Dumper/PhpDumper.php | 10 ++++++---- src/Symfony/Component/HttpKernel/Kernel.php | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 26a98b581a5dd..563ba785face2 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -398,6 +398,8 @@ private function generateProxyClasses() if (!$proxyDumper->isProxyCandidate($definition)) { continue; } + // register class' reflector for resource tracking + $this->container->getReflectionClass($definition->getClass()); $proxyCode = "\n".$proxyDumper->getProxyCode($definition); if ($strip) { $proxyCode = "setProxyDumper(new ProxyDumper(substr(hash('sha256', $cache->getPath()), 0, 7))); + $dumper->setProxyDumper(new ProxyDumper()); } $content = $dumper->dump(array( From ad593aef2fd616289049e93b909de8d4c1a842ae Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 30 Jan 2018 08:44:00 +0100 Subject: [PATCH 026/166] [Routing] Fix trailing slash redirection for non-safe verbs --- .../Matcher/Dumper/PhpMatcherDumper.php | 10 +- .../Tests/Fixtures/dumper/url_matcher1.php | 2 +- .../Tests/Fixtures/dumper/url_matcher2.php | 23 +++- .../Tests/Fixtures/dumper/url_matcher3.php | 2 +- .../DumpedRedirectableUrlMatcherTest.php | 43 +++++++ .../Tests/Matcher/DumpedUrlMatcherTest.php | 39 ++++++ .../Matcher/RedirectableUrlMatcherTest.php | 34 ++++-- .../Routing/Tests/Matcher/UrlMatcherTest.php | 111 +++++++++++------- 8 files changed, 203 insertions(+), 61 deletions(-) create mode 100644 src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php create mode 100644 src/Symfony/Component/Routing/Tests/Matcher/DumpedUrlMatcherTest.php diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php index 016021e259c5f..28ab3679f9fa8 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -101,7 +101,7 @@ public function match(\$rawPathinfo) \$allow = array(); \$pathinfo = rawurldecode(\$rawPathinfo); \$context = \$this->context; - \$request = \$this->request; + \$request = \$this->request ?: \$this->createRequest(\$pathinfo); $code @@ -283,7 +283,11 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren if ($hasTrailingSlash) { $code .= <<context->getMethod(), array('HEAD', 'GET'))) { + goto $gotoname; + } else { return \$this->redirect(\$rawPathinfo.'/', '$name'); } @@ -329,7 +333,7 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren } $code .= " }\n"; - if ($methods) { + if ($methods || $hasTrailingSlash) { $code .= " $gotoname:\n"; } diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php index 6451192d1877e..a87f063af57ac 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php @@ -20,7 +20,7 @@ public function match($rawPathinfo) $allow = array(); $pathinfo = rawurldecode($rawPathinfo); $context = $this->context; - $request = $this->request; + $request = $this->request ?: $this->createRequest($pathinfo); // foo if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?Pbaz|symfony)$#s', $pathinfo, $matches)) { diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php index 9b44eb920deab..7ec89b8e2f457 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php @@ -20,7 +20,7 @@ public function match($rawPathinfo) $allow = array(); $pathinfo = rawurldecode($rawPathinfo); $context = $this->context; - $request = $this->request; + $request = $this->request ?: $this->createRequest($pathinfo); // foo if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?Pbaz|symfony)$#s', $pathinfo, $matches)) { @@ -66,23 +66,33 @@ public function match($rawPathinfo) // baz3 if ('/test/baz3' === rtrim($pathinfo, '/')) { - if (substr($pathinfo, -1) !== '/') { + if ('/' === substr($pathinfo, -1)) { + // no-op + } elseif (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) { + goto not_baz3; + } else { return $this->redirect($rawPathinfo.'/', 'baz3'); } return array('_route' => 'baz3'); } + not_baz3: } // baz4 if (preg_match('#^/test/(?P[^/]++)/?$#s', $pathinfo, $matches)) { - if (substr($pathinfo, -1) !== '/') { + if ('/' === substr($pathinfo, -1)) { + // no-op + } elseif (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) { + goto not_baz4; + } else { return $this->redirect($rawPathinfo.'/', 'baz4'); } return $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ()); } + not_baz4: // baz5 if (preg_match('#^/test/(?P[^/]++)/$#s', $pathinfo, $matches)) { @@ -170,12 +180,17 @@ public function match($rawPathinfo) // hey if ('/multi/hey' === rtrim($pathinfo, '/')) { - if (substr($pathinfo, -1) !== '/') { + if ('/' === substr($pathinfo, -1)) { + // no-op + } elseif (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) { + goto not_hey; + } else { return $this->redirect($rawPathinfo.'/', 'hey'); } return array('_route' => 'hey'); } + not_hey: } diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher3.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher3.php index 04043273df740..f5234dd43bbec 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher3.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher3.php @@ -20,7 +20,7 @@ public function match($rawPathinfo) $allow = array(); $pathinfo = rawurldecode($rawPathinfo); $context = $this->context; - $request = $this->request; + $request = $this->request ?: $this->createRequest($pathinfo); if (0 === strpos($pathinfo, '/rootprefix')) { // static diff --git a/src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php new file mode 100644 index 0000000000000..28f65aeeb5aa7 --- /dev/null +++ b/src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.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\Routing\Tests\Matcher; + +use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; +use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface; +use Symfony\Component\Routing\Matcher\UrlMatcher; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RequestContext; + +class DumpedRedirectableUrlMatcherTest extends RedirectableUrlMatcherTest +{ + protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null) + { + static $i = 0; + + $class = 'DumpedRedirectableUrlMatcher'.++$i; + $dumper = new PhpMatcherDumper($routes); + $dumpedRoutes = eval('?>'.$dumper->dump(array('class' => $class, 'base_class' => 'Symfony\Component\Routing\Tests\Matcher\TestDumpedRedirectableUrlMatcher'))); + + return $this->getMockBuilder($class) + ->setConstructorArgs(array($context ?: new RequestContext())) + ->setMethods(array('redirect')) + ->getMock(); + } +} + +class TestDumpedRedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface +{ + public function redirect($path, $route, $scheme = null) + { + return array(); + } +} diff --git a/src/Symfony/Component/Routing/Tests/Matcher/DumpedUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/DumpedUrlMatcherTest.php new file mode 100644 index 0000000000000..cc7eb8e2d7307 --- /dev/null +++ b/src/Symfony/Component/Routing/Tests/Matcher/DumpedUrlMatcherTest.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Tests\Matcher; + +use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RequestContext; + +class DumpedUrlMatcherTest extends UrlMatcherTest +{ + /** + * @expectedException \LogicException + * @expectedExceptionMessage The "schemes" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface. + */ + public function testSchemeRequirement() + { + parent::testSchemeRequirement(); + } + + protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null) + { + static $i = 0; + + $class = 'DumpedUrlMatcher'.++$i; + $dumper = new PhpMatcherDumper($routes); + $dumpedRoutes = eval('?>'.$dumper->dump(array('class' => $class))); + + return new $class($context ?: new RequestContext()); + } +} diff --git a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php index 0b5bb0dc78cac..fc7683903fc6b 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php @@ -11,20 +11,19 @@ namespace Symfony\Component\Routing\Tests\Matcher; -use PHPUnit\Framework\TestCase; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RequestContext; -class RedirectableUrlMatcherTest extends TestCase +class RedirectableUrlMatcherTest extends UrlMatcherTest { public function testRedirectWhenNoSlash() { $coll = new RouteCollection(); $coll->add('foo', new Route('/foo/')); - $matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext())); - $matcher->expects($this->once())->method('redirect'); + $matcher = $this->getUrlMatcher($coll); + $matcher->expects($this->once())->method('redirect')->will($this->returnValue(array())); $matcher->match('/foo'); } @@ -38,7 +37,7 @@ public function testRedirectWhenNoSlashForNonSafeMethod() $context = new RequestContext(); $context->setMethod('POST'); - $matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, $context)); + $matcher = $this->getUrlMatcher($coll, $context); $matcher->match('/foo'); } @@ -47,7 +46,7 @@ public function testSchemeRedirectRedirectsToFirstScheme() $coll = new RouteCollection(); $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('FTP', 'HTTPS'))); - $matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext())); + $matcher = $this->getUrlMatcher($coll); $matcher ->expects($this->once()) ->method('redirect') @@ -62,11 +61,10 @@ public function testNoSchemaRedirectIfOnOfMultipleSchemesMatches() $coll = new RouteCollection(); $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https', 'http'))); - $matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext())); + $matcher = $this->getUrlMatcher($coll); $matcher ->expects($this->never()) - ->method('redirect') - ; + ->method('redirect'); $matcher->match('/foo'); } @@ -75,8 +73,22 @@ public function testRedirectPreservesUrlEncoding() $coll = new RouteCollection(); $coll->add('foo', new Route('/foo:bar/')); - $matcher = $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($coll, new RequestContext())); - $matcher->expects($this->once())->method('redirect')->with('/foo%3Abar/'); + $matcher = $this->getUrlMatcher($coll); + $matcher->expects($this->once())->method('redirect')->with('/foo%3Abar/')->willReturn(array()); $matcher->match('/foo%3Abar'); } + + public function testSchemeRequirement() + { + $coll = new RouteCollection(); + $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https'))); + $matcher = $this->getUrlMatcher($coll, new RequestContext()); + $matcher->expects($this->once())->method('redirect')->with('/foo', 'foo', 'https')->willReturn(array('_route' => 'foo')); + $this->assertSame(array('_route' => 'foo'), $matcher->match('/foo')); + } + + protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null) + { + return $this->getMockForAbstractClass('Symfony\Component\Routing\Matcher\RedirectableUrlMatcher', array($routes, $context ?: new RequestContext())); + } } diff --git a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php index 9fd53e9814496..de79a073eaf0c 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php @@ -26,7 +26,7 @@ public function testNoMethodSoAllowed() $coll = new RouteCollection(); $coll->add('foo', new Route('/foo')); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $this->assertInternalType('array', $matcher->match('/foo')); } @@ -35,7 +35,7 @@ public function testMethodNotAllowed() $coll = new RouteCollection(); $coll->add('foo', new Route('/foo', array(), array(), array(), '', array(), array('post'))); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); try { $matcher->match('/foo'); @@ -50,7 +50,7 @@ public function testHeadAllowedWhenRequirementContainsGet() $coll = new RouteCollection(); $coll->add('foo', new Route('/foo', array(), array(), array(), '', array(), array('get'))); - $matcher = new UrlMatcher($coll, new RequestContext('', 'head')); + $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'head')); $this->assertInternalType('array', $matcher->match('/foo')); } @@ -60,7 +60,7 @@ public function testMethodNotAllowedAggregatesAllowedMethods() $coll->add('foo1', new Route('/foo', array(), array(), array(), '', array(), array('post'))); $coll->add('foo2', new Route('/foo', array(), array(), array(), '', array(), array('put', 'delete'))); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); try { $matcher->match('/foo'); @@ -75,7 +75,7 @@ public function testMatch() // test the patterns are matched and parameters are returned $collection = new RouteCollection(); $collection->add('foo', new Route('/foo/{bar}')); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); try { $matcher->match('/no-match'); $this->fail(); @@ -86,17 +86,17 @@ public function testMatch() // test that defaults are merged $collection = new RouteCollection(); $collection->add('foo', new Route('/foo/{bar}', array('def' => 'test'))); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); $this->assertEquals(array('_route' => 'foo', 'bar' => 'baz', 'def' => 'test'), $matcher->match('/foo/baz')); // test that route "method" is ignored if no method is given in the context $collection = new RouteCollection(); $collection->add('foo', new Route('/foo', array(), array(), array(), '', array(), array('get', 'head'))); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); $this->assertInternalType('array', $matcher->match('/foo')); // route does not match with POST method context - $matcher = new UrlMatcher($collection, new RequestContext('', 'post')); + $matcher = $this->getUrlMatcher($collection, new RequestContext('', 'post')); try { $matcher->match('/foo'); $this->fail(); @@ -104,28 +104,28 @@ public function testMatch() } // route does match with GET or HEAD method context - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); $this->assertInternalType('array', $matcher->match('/foo')); - $matcher = new UrlMatcher($collection, new RequestContext('', 'head')); + $matcher = $this->getUrlMatcher($collection, new RequestContext('', 'head')); $this->assertInternalType('array', $matcher->match('/foo')); // route with an optional variable as the first segment $collection = new RouteCollection(); $collection->add('bar', new Route('/{bar}/foo', array('bar' => 'bar'), array('bar' => 'foo|bar'))); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); $this->assertEquals(array('_route' => 'bar', 'bar' => 'bar'), $matcher->match('/bar/foo')); $this->assertEquals(array('_route' => 'bar', 'bar' => 'foo'), $matcher->match('/foo/foo')); $collection = new RouteCollection(); $collection->add('bar', new Route('/{bar}', array('bar' => 'bar'), array('bar' => 'foo|bar'))); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); $this->assertEquals(array('_route' => 'bar', 'bar' => 'foo'), $matcher->match('/foo')); $this->assertEquals(array('_route' => 'bar', 'bar' => 'bar'), $matcher->match('/')); // route with only optional variables $collection = new RouteCollection(); $collection->add('bar', new Route('/{foo}/{bar}', array('foo' => 'foo', 'bar' => 'bar'), array())); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); $this->assertEquals(array('_route' => 'bar', 'foo' => 'foo', 'bar' => 'bar'), $matcher->match('/')); $this->assertEquals(array('_route' => 'bar', 'foo' => 'a', 'bar' => 'bar'), $matcher->match('/a')); $this->assertEquals(array('_route' => 'bar', 'foo' => 'a', 'bar' => 'b'), $matcher->match('/a/b')); @@ -138,7 +138,7 @@ public function testMatchWithPrefixes() $collection->addPrefix('/b'); $collection->addPrefix('/a'); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); $this->assertEquals(array('_route' => 'foo', 'foo' => 'foo'), $matcher->match('/a/b/foo')); } @@ -149,7 +149,7 @@ public function testMatchWithDynamicPrefix() $collection->addPrefix('/b'); $collection->addPrefix('/{_locale}'); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); $this->assertEquals(array('_locale' => 'fr', '_route' => 'foo', 'foo' => 'foo'), $matcher->match('/fr/b/foo')); } @@ -158,7 +158,7 @@ public function testMatchSpecialRouteName() $collection = new RouteCollection(); $collection->add('$péß^a|', new Route('/bar')); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); $this->assertEquals(array('_route' => '$péß^a|'), $matcher->match('/bar')); } @@ -166,9 +166,9 @@ public function testMatchNonAlpha() { $collection = new RouteCollection(); $chars = '!"$%éà &\'()*+,./:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\[]^_`abcdefghijklmnopqrstuvwxyz{|}~-'; - $collection->add('foo', new Route('/{foo}/bar', array(), array('foo' => '['.preg_quote($chars).']+'))); + $collection->add('foo', new Route('/{foo}/bar', array(), array('foo' => '['.preg_quote($chars).']+'), array('utf8' => true))); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); $this->assertEquals(array('_route' => 'foo', 'foo' => $chars), $matcher->match('/'.rawurlencode($chars).'/bar')); $this->assertEquals(array('_route' => 'foo', 'foo' => $chars), $matcher->match('/'.strtr($chars, array('%' => '%25')).'/bar')); } @@ -178,7 +178,7 @@ public function testMatchWithDotMetacharacterInRequirements() $collection = new RouteCollection(); $collection->add('foo', new Route('/{foo}/bar', array(), array('foo' => '.+'))); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); $this->assertEquals(array('_route' => 'foo', 'foo' => "\n"), $matcher->match('/'.urlencode("\n").'/bar'), 'linefeed character is matched'); } @@ -192,7 +192,7 @@ public function testMatchOverriddenRoute() $collection->addCollection($collection1); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); $this->assertEquals(array('_route' => 'foo'), $matcher->match('/foo1')); $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('Symfony\Component\Routing\Exception\ResourceNotFoundException'); @@ -205,12 +205,12 @@ public function testMatchRegression() $coll->add('foo', new Route('/foo/{foo}')); $coll->add('bar', new Route('/foo/bar/{foo}')); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $this->assertEquals(array('foo' => 'bar', '_route' => 'bar'), $matcher->match('/foo/bar/bar')); $collection = new RouteCollection(); $collection->add('foo', new Route('/{bar}')); - $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher = $this->getUrlMatcher($collection); try { $matcher->match('/'); $this->fail(); @@ -223,7 +223,7 @@ public function testDefaultRequirementForOptionalVariables() $coll = new RouteCollection(); $coll->add('test', new Route('/{page}.{_format}', array('page' => 'index', '_format' => 'html'))); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $this->assertEquals(array('page' => 'my-page', '_format' => 'xml', '_route' => 'test'), $matcher->match('/my-page.xml')); } @@ -232,7 +232,7 @@ public function testMatchingIsEager() $coll = new RouteCollection(); $coll->add('test', new Route('/{foo}-{bar}-', array(), array('foo' => '.+', 'bar' => '.+'))); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $this->assertEquals(array('foo' => 'text1-text2-text3', 'bar' => 'text4', '_route' => 'test'), $matcher->match('/text1-text2-text3-text4-')); } @@ -241,7 +241,7 @@ public function testAdjacentVariables() $coll = new RouteCollection(); $coll->add('test', new Route('/{w}{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => 'y|Y'))); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); // 'w' eagerly matches as much as possible and the other variables match the remaining chars. // This also shows that the variables w-z must all exclude the separating char (the dot '.' in this case) by default requirement. // Otherwise they would also consume '.xml' and _format would never match as it's an optional variable. @@ -260,7 +260,7 @@ public function testOptionalVariableWithNoRealSeparator() { $coll = new RouteCollection(); $coll->add('test', new Route('/get{what}', array('what' => 'All'))); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $this->assertEquals(array('what' => 'All', '_route' => 'test'), $matcher->match('/get')); $this->assertEquals(array('what' => 'Sites', '_route' => 'test'), $matcher->match('/getSites')); @@ -275,7 +275,7 @@ public function testRequiredVariableWithNoRealSeparator() { $coll = new RouteCollection(); $coll->add('test', new Route('/get{what}Suffix')); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $this->assertEquals(array('what' => 'Sites', '_route' => 'test'), $matcher->match('/getSitesSuffix')); } @@ -284,7 +284,7 @@ public function testDefaultRequirementOfVariable() { $coll = new RouteCollection(); $coll->add('test', new Route('/{page}.{_format}')); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $this->assertEquals(array('page' => 'index', '_format' => 'mobile.html', '_route' => 'test'), $matcher->match('/index.mobile.html')); } @@ -296,7 +296,7 @@ public function testDefaultRequirementOfVariableDisallowsSlash() { $coll = new RouteCollection(); $coll->add('test', new Route('/{page}.{_format}')); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $matcher->match('/index.sl/ash'); } @@ -308,7 +308,7 @@ public function testDefaultRequirementOfVariableDisallowsNextSeparator() { $coll = new RouteCollection(); $coll->add('test', new Route('/{page}.{_format}', array(), array('_format' => 'html|xml'))); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $matcher->match('/do.t.html'); } @@ -320,7 +320,7 @@ public function testSchemeRequirement() { $coll = new RouteCollection(); $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https'))); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $matcher->match('/foo'); } @@ -333,7 +333,7 @@ public function testCondition() $route = new Route('/foo'); $route->setCondition('context.getMethod() == "POST"'); $coll->add('foo', $route); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $matcher->match('/foo'); } @@ -343,7 +343,7 @@ public function testRequestCondition() $route = new Route('/foo/{bar}'); $route->setCondition('request.getBaseUrl() == "/sub/front.php" and request.getPathInfo() == "/foo/bar"'); $coll->add('foo', $route); - $matcher = new UrlMatcher($coll, new RequestContext('/sub/front.php')); + $matcher = $this->getUrlMatcher($coll, new RequestContext('/sub/front.php')); $this->assertEquals(array('bar' => 'bar', '_route' => 'foo'), $matcher->match('/foo/bar')); } @@ -352,7 +352,7 @@ public function testDecodeOnce() $coll = new RouteCollection(); $coll->add('foo', new Route('/foo/{foo}')); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $this->assertEquals(array('foo' => 'bar%23', '_route' => 'foo'), $matcher->match('/foo/bar%2523')); } @@ -368,7 +368,7 @@ public function testCannotRelyOnPrefix() $coll->addCollection($subColl); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $this->assertEquals(array('_route' => 'bar'), $matcher->match('/new')); } @@ -377,7 +377,7 @@ public function testWithHost() $coll = new RouteCollection(); $coll->add('foo', new Route('/foo/{foo}', array(), array(), array(), '{locale}.example.com')); - $matcher = new UrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com')); + $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com')); $this->assertEquals(array('foo' => 'bar', '_route' => 'foo', 'locale' => 'en'), $matcher->match('/foo/bar')); } @@ -388,10 +388,10 @@ public function testWithHostOnRouteCollection() $coll->add('bar', new Route('/bar/{foo}', array(), array(), array(), '{locale}.example.net')); $coll->setHost('{locale}.example.com'); - $matcher = new UrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com')); + $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com')); $this->assertEquals(array('foo' => 'bar', '_route' => 'foo', 'locale' => 'en'), $matcher->match('/foo/bar')); - $matcher = new UrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com')); + $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com')); $this->assertEquals(array('foo' => 'bar', '_route' => 'bar', 'locale' => 'en'), $matcher->match('/bar/bar')); } @@ -403,7 +403,7 @@ public function testWithOutHostHostDoesNotMatch() $coll = new RouteCollection(); $coll->add('foo', new Route('/foo/{foo}', array(), array(), array(), '{locale}.example.com')); - $matcher = new UrlMatcher($coll, new RequestContext('', 'GET', 'example.com')); + $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'example.com')); $matcher->match('/foo/bar'); } @@ -415,7 +415,7 @@ public function testPathIsCaseSensitive() $coll = new RouteCollection(); $coll->add('foo', new Route('/locale', array(), array('locale' => 'EN|FR|DE'))); - $matcher = new UrlMatcher($coll, new RequestContext()); + $matcher = $this->getUrlMatcher($coll); $matcher->match('/en'); } @@ -424,7 +424,36 @@ public function testHostIsCaseInsensitive() $coll = new RouteCollection(); $coll->add('foo', new Route('/', array(), array('locale' => 'EN|FR|DE'), array(), '{locale}.example.com')); - $matcher = new UrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com')); + $matcher = $this->getUrlMatcher($coll, new RequestContext('', 'GET', 'en.example.com')); $this->assertEquals(array('_route' => 'foo', 'locale' => 'en'), $matcher->match('/')); } + + public function testNestedCollections() + { + $coll = new RouteCollection(); + + $subColl = new RouteCollection(); + $subColl->add('a', new Route('/a')); + $subColl->add('b', new Route('/b')); + $subColl->add('c', new Route('/c')); + $subColl->addPrefix('/p'); + $coll->addCollection($subColl); + + $coll->add('baz', new Route('/{baz}')); + + $subColl = new RouteCollection(); + $subColl->add('buz', new Route('/buz')); + $subColl->addPrefix('/prefix'); + $coll->addCollection($subColl); + + $matcher = $this->getUrlMatcher($coll); + $this->assertEquals(array('_route' => 'a'), $matcher->match('/p/a')); + $this->assertEquals(array('_route' => 'baz', 'baz' => 'p'), $matcher->match('/p')); + $this->assertEquals(array('_route' => 'buz'), $matcher->match('/prefix/buz')); + } + + protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null) + { + return new UrlMatcher($routes, $context ?: new RequestContext()); + } } From 67e821b94f304a9f33ad91f492b0a6ebf2424843 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 30 Jan 2018 22:38:46 +0100 Subject: [PATCH 027/166] [Config] Handle Service/EventSubscriberInterface in ReflectionClassResource --- .../Resource/ReflectionClassResource.php | 17 ++++++- .../Resource/ReflectionClassResourceTest.php | 46 +++++++++++++++++++ src/Symfony/Component/Config/composer.json | 3 +- .../RegisterServiceSubscribersPass.php | 12 ++--- .../RegisterListenersPass.php | 16 +++---- 5 files changed, 77 insertions(+), 17 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php index a8e1f9611b99a..735784ad64111 100644 --- a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php +++ b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php @@ -11,6 +11,9 @@ namespace Symfony\Component\Config\Resource; +use Symfony\Component\DependencyInjection\ServiceSubscriberInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + /** * @author Nicolas Grekas */ @@ -114,7 +117,9 @@ private function computeHash() private function generateSignature(\ReflectionClass $class) { - yield $class->getDocComment().$class->getModifiers(); + yield $class->getDocComment(); + yield (int) $class->isFinal(); + yield (int) $class->isAbstract(); if ($class->isTrait()) { yield print_r(class_uses($class->name), true); @@ -149,6 +154,16 @@ private function generateSignature(\ReflectionClass $class) yield print_r($defaults, true); } } + + if ($class->isSubclassOf(EventSubscriberInterface::class)) { + yield EventSubscriberInterface::class; + yield print_r(\call_user_func(array($class->name, 'getSubscribedEvents')), true); + } + + if ($class->isSubclassOf(ServiceSubscriberInterface::class)) { + yield ServiceSubscriberInterface::class; + yield print_r(\call_user_func(array($class->name, 'getSubscribedServices')), true); + } } } diff --git a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php index 4eca3d50e4a8b..3f13096f0ac11 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php @@ -13,6 +13,8 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Resource\ReflectionClassResource; +use Symfony\Component\DependencyInjection\ServiceSubscriberInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ReflectionClassResourceTest extends TestCase { @@ -136,8 +138,52 @@ public function provideHashedSignature() yield array(0, 14, '/** priv docblock */'); yield array(0, 15, ''); } + + public function testEventSubscriber() + { + $res = new ReflectionClassResource(new \ReflectionClass(TestEventSubscriber::class)); + $this->assertTrue($res->isFresh(0)); + + TestEventSubscriber::$subscribedEvents = array(123); + $this->assertFalse($res->isFresh(0)); + + $res = new ReflectionClassResource(new \ReflectionClass(TestEventSubscriber::class)); + $this->assertTrue($res->isFresh(0)); + } + + public function testServiceSubscriber() + { + $res = new ReflectionClassResource(new \ReflectionClass(TestServiceSubscriber::class)); + $this->assertTrue($res->isFresh(0)); + + TestServiceSubscriber::$subscribedServices = array(123); + $this->assertFalse($res->isFresh(0)); + + $res = new ReflectionClassResource(new \ReflectionClass(TestServiceSubscriber::class)); + $this->assertTrue($res->isFresh(0)); + } } interface DummyInterface { } + +class TestEventSubscriber implements EventSubscriberInterface +{ + public static $subscribedEvents = array(); + + public static function getSubscribedEvents() + { + return self::$subscribedEvents; + } +} + +class TestServiceSubscriber implements ServiceSubscriberInterface +{ + public static $subscribedServices = array(); + + public static function getSubscribedServices() + { + return self::$subscribedServices; + } +} diff --git a/src/Symfony/Component/Config/composer.json b/src/Symfony/Component/Config/composer.json index 6f759720e6b09..ab26402819a28 100644 --- a/src/Symfony/Component/Config/composer.json +++ b/src/Symfony/Component/Config/composer.json @@ -22,7 +22,8 @@ "require-dev": { "symfony/finder": "~3.3|~4.0", "symfony/yaml": "~3.0|~4.0", - "symfony/dependency-injection": "~3.3|~4.0" + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/event-dispatcher": "~3.3|~4.0" }, "conflict": { "symfony/finder": "<3.3", diff --git a/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php b/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php index 4ed990ac08d2b..572eabb7d99e7 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/RegisterServiceSubscribersPass.php @@ -56,14 +56,14 @@ protected function processValue($value, $isRoot = false) } $class = $value->getClass(); - if (!is_subclass_of($class, ServiceSubscriberInterface::class)) { - if (!class_exists($class, false)) { - throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId)); - } - + if (!$r = $this->container->getReflectionClass($class)) { + throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId)); + } + if (!$r->isSubclassOf(ServiceSubscriberInterface::class)) { throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $this->currentId, ServiceSubscriberInterface::class)); } - $this->container->addObjectResource($class); + $class = $r->name; + $subscriberMap = array(); $declaringClass = (new \ReflectionMethod($class, 'getSubscribedServices'))->class; diff --git a/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php b/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php index 9f9c09c528035..ff636d6180bfe 100644 --- a/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php +++ b/src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php @@ -89,17 +89,15 @@ public function process(ContainerBuilder $container) $def = $container->getDefinition($id); // We must assume that the class value has been correctly filled, even if the service is created by a factory - $class = $container->getParameterBag()->resolveValue($def->getClass()); - $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; + $class = $def->getClass(); - if (!is_subclass_of($class, $interface)) { - if (!class_exists($class, false)) { - throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); - } - - throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); + if (!$r = $container->getReflectionClass($class)) { + throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + } + if (!$r->isSubclassOf(EventSubscriberInterface::class)) { + throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, EventSubscriberInterface::class)); } - $container->addObjectResource($class); + $class = $r->name; ExtractingEventDispatcher::$subscriber = $class; $extractingDispatcher->addSubscriber($extractingDispatcher); From ad98c1fa906ab10bc9ce0cc5dc304f9a6028bd40 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 31 Jan 2018 16:05:11 +0100 Subject: [PATCH 028/166] [DI][Routing] Fix tracking of globbed resources --- .../Resources/config/routing.xml | 2 +- .../Bundle/FrameworkBundle/composer.json | 2 +- .../Loader/GlobFileLoader.php | 40 ++++++++++++++++ src/Symfony/Component/HttpKernel/Kernel.php | 4 +- .../Component/HttpKernel/composer.json | 4 +- .../Routing/Loader/GlobFileLoader.php | 47 +++++++++++++++++++ 6 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 src/Symfony/Component/DependencyInjection/Loader/GlobFileLoader.php create mode 100644 src/Symfony/Component/Routing/Loader/GlobFileLoader.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml index 74643a9d208f7..1ad1a752a6a39 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml @@ -38,7 +38,7 @@ - + diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 1f0f233feb0db..9bb59cf8e8db7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -28,7 +28,7 @@ "symfony/polyfill-mbstring": "~1.0", "symfony/filesystem": "~2.8|~3.0|~4.0", "symfony/finder": "~2.8|~3.0|~4.0", - "symfony/routing": "~3.4|~4.0" + "symfony/routing": "^3.4.5|^4.0.5" }, "require-dev": { "doctrine/cache": "~1.0", diff --git a/src/Symfony/Component/DependencyInjection/Loader/GlobFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/GlobFileLoader.php new file mode 100644 index 0000000000000..4b25610efe48e --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Loader/GlobFileLoader.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +/** + * GlobFileLoader loads files from a glob pattern. + * + * @author Nicolas Grekas + */ +class GlobFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + foreach ($this->glob($resource, false, $globResource) as $path => $info) { + $this->import($path); + } + + $this->container->addResource($globResource); + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + return 'glob' === $type; + } +} diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 56dbc1f5f659a..a5f5e3c77017a 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -22,6 +22,7 @@ use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\Loader\IniFileLoader; use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\DependencyInjection\Loader\GlobFileLoader; use Symfony\Component\DependencyInjection\Loader\DirectoryLoader; use Symfony\Component\DependencyInjection\Loader\ClosureLoader; use Symfony\Component\Filesystem\Filesystem; @@ -32,7 +33,6 @@ use Symfony\Component\HttpKernel\Config\FileLocator; use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; use Symfony\Component\HttpKernel\DependencyInjection\AddAnnotatedClassesToCachePass; -use Symfony\Component\Config\Loader\GlobFileLoader; use Symfony\Component\Config\Loader\LoaderResolver; use Symfony\Component\Config\Loader\DelegatingLoader; use Symfony\Component\Config\ConfigCache; @@ -880,7 +880,7 @@ protected function getContainerLoader(ContainerInterface $container) new YamlFileLoader($container, $locator), new IniFileLoader($container, $locator), new PhpFileLoader($container, $locator), - new GlobFileLoader($locator), + new GlobFileLoader($container, $locator), new DirectoryLoader($container, $locator), new ClosureLoader($container), )); diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index b33675763f6e5..26b782bb383b7 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -28,7 +28,7 @@ "symfony/config": "~2.8|~3.0|~4.0", "symfony/console": "~2.8|~3.0|~4.0", "symfony/css-selector": "~2.8|~3.0|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", + "symfony/dependency-injection": "^3.4.5|^4.0.5", "symfony/dom-crawler": "~2.8|~3.0|~4.0", "symfony/expression-language": "~2.8|~3.0|~4.0", "symfony/finder": "~2.8|~3.0|~4.0", @@ -45,7 +45,7 @@ }, "conflict": { "symfony/config": "<2.8", - "symfony/dependency-injection": "<3.4", + "symfony/dependency-injection": "<3.4.5|<4.0.5,>=4", "symfony/var-dumper": "<3.3", "twig/twig": "<1.34|<2.4,>=2" }, diff --git a/src/Symfony/Component/Routing/Loader/GlobFileLoader.php b/src/Symfony/Component/Routing/Loader/GlobFileLoader.php new file mode 100644 index 0000000000000..03ee341b98250 --- /dev/null +++ b/src/Symfony/Component/Routing/Loader/GlobFileLoader.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Config\Loader\FileLoader; +use Symfony\Component\Routing\RouteCollection; + +/** + * GlobFileLoader loads files from a glob pattern. + * + * @author Nicolas Grekas + */ +class GlobFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + $collection = new RouteCollection(); + + foreach ($this->glob($resource, false, $globResource) as $path => $info) { + $collection->addCollection($this->import($path)); + } + + $collection->addResource($globResource); + + return $collection; + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + return 'glob' === $type; + } +} From 31f43e52261c6a3310fdd803f83b87e98b689bf5 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Wed, 31 Jan 2018 18:08:05 +0100 Subject: [PATCH 029/166] Don't show wanna-be-private services as public in debug:container --- .../FrameworkBundle/Console/Descriptor/JsonDescriptor.php | 8 ++++---- .../Console/Descriptor/MarkdownDescriptor.php | 8 ++++---- .../FrameworkBundle/Console/Descriptor/TextDescriptor.php | 6 +++--- .../FrameworkBundle/Console/Descriptor/XmlDescriptor.php | 6 +++--- .../Tests/Fixtures/Descriptor/builder_1_arguments.json | 4 ++-- .../Tests/Fixtures/Descriptor/builder_1_arguments.xml | 4 ++-- .../Tests/Fixtures/Descriptor/definition_arguments_1.json | 4 ++-- .../Tests/Fixtures/Descriptor/definition_arguments_1.xml | 4 ++-- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php index 7b1a70e694134..fde8e9280f5f2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php @@ -113,11 +113,11 @@ protected function describeContainerServices(ContainerBuilder $builder, array $o $service = $this->resolveServiceDefinition($builder, $serviceId); if ($service instanceof Alias) { - if ($showPrivate || $service->isPublic()) { + if ($showPrivate || ($service->isPublic() && !$service->isPrivate())) { $data['aliases'][$serviceId] = $this->getContainerAliasData($service); } } elseif ($service instanceof Definition) { - if (($showPrivate || $service->isPublic())) { + if (($showPrivate || ($service->isPublic() && !$service->isPrivate()))) { $data['definitions'][$serviceId] = $this->getContainerDefinitionData($service, $omitTags, $showArguments); } } else { @@ -217,7 +217,7 @@ private function getContainerDefinitionData(Definition $definition, $omitTags = { $data = array( 'class' => (string) $definition->getClass(), - 'public' => $definition->isPublic(), + 'public' => $definition->isPublic() && !$definition->isPrivate(), 'synthetic' => $definition->isSynthetic(), 'lazy' => $definition->isLazy(), 'shared' => $definition->isShared(), @@ -281,7 +281,7 @@ private function getContainerAliasData(Alias $alias) { return array( 'service' => (string) $alias, - 'public' => $alias->isPublic(), + 'public' => $alias->isPublic() && !$alias->isPrivate(), ); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php index a110dc7eac372..9644a440df4f2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php @@ -139,11 +139,11 @@ protected function describeContainerServices(ContainerBuilder $builder, array $o $service = $this->resolveServiceDefinition($builder, $serviceId); if ($service instanceof Alias) { - if ($showPrivate || $service->isPublic()) { + if ($showPrivate || ($service->isPublic() && !$service->isPrivate())) { $services['aliases'][$serviceId] = $service; } } elseif ($service instanceof Definition) { - if (($showPrivate || $service->isPublic())) { + if (($showPrivate || ($service->isPublic() && !$service->isPrivate()))) { $services['definitions'][$serviceId] = $service; } } else { @@ -182,7 +182,7 @@ protected function describeContainerServices(ContainerBuilder $builder, array $o protected function describeContainerDefinition(Definition $definition, array $options = array()) { $output = '- Class: `'.$definition->getClass().'`' - ."\n".'- Public: '.($definition->isPublic() ? 'yes' : 'no') + ."\n".'- Public: '.($definition->isPublic() && !$definition->isPrivate() ? 'yes' : 'no') ."\n".'- Synthetic: '.($definition->isSynthetic() ? 'yes' : 'no') ."\n".'- Lazy: '.($definition->isLazy() ? 'yes' : 'no') ."\n".'- Shared: '.($definition->isShared() ? 'yes' : 'no') @@ -246,7 +246,7 @@ protected function describeContainerDefinition(Definition $definition, array $op protected function describeContainerAlias(Alias $alias, array $options = array(), ContainerBuilder $builder = null) { $output = '- Service: `'.$alias.'`' - ."\n".'- Public: '.($alias->isPublic() ? 'yes' : 'no'); + ."\n".'- Public: '.($alias->isPublic() && !$alias->isPrivate() ? 'yes' : 'no'); if (!isset($options['id'])) { return $this->write($output); diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php index 3e14b5c2c18e7..ab04ff47f794e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php @@ -194,7 +194,7 @@ protected function describeContainerServices(ContainerBuilder $builder, array $o $definition = $this->resolveServiceDefinition($builder, $serviceId); if ($definition instanceof Definition) { // filter out private services unless shown explicitly - if (!$showPrivate && !$definition->isPublic()) { + if (!$showPrivate && (!$definition->isPublic() || $definition->isPrivate())) { unset($serviceIds[$key]); continue; } @@ -212,7 +212,7 @@ protected function describeContainerServices(ContainerBuilder $builder, array $o } } } elseif ($definition instanceof Alias) { - if (!$showPrivate && !$definition->isPublic()) { + if (!$showPrivate && (!$definition->isPublic() || $definition->isPrivate())) { unset($serviceIds[$key]); continue; } @@ -302,7 +302,7 @@ protected function describeContainerDefinition(Definition $definition, array $op $tableRows[] = array('Calls', implode(', ', $callInformation)); } - $tableRows[] = array('Public', $definition->isPublic() ? 'yes' : 'no'); + $tableRows[] = array('Public', $definition->isPublic() && !$definition->isPrivate() ? 'yes' : 'no'); $tableRows[] = array('Synthetic', $definition->isSynthetic() ? 'yes' : 'no'); $tableRows[] = array('Lazy', $definition->isLazy() ? 'yes' : 'no'); $tableRows[] = array('Shared', $definition->isShared() ? 'yes' : 'no'); diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php index da878b1ee6d53..cadd2ff6059ee 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php @@ -318,7 +318,7 @@ private function getContainerServicesDocument(ContainerBuilder $builder, $tag = foreach ($this->sortServiceIds($serviceIds) as $serviceId) { $service = $this->resolveServiceDefinition($builder, $serviceId); - if (($service instanceof Definition || $service instanceof Alias) && !($showPrivate || $service->isPublic())) { + if (($service instanceof Definition || $service instanceof Alias) && !($showPrivate || ($service->isPublic() && !$service->isPrivate()))) { continue; } @@ -364,7 +364,7 @@ private function getContainerDefinitionDocument(Definition $definition, $id = nu } } - $serviceXML->setAttribute('public', $definition->isPublic() ? 'true' : 'false'); + $serviceXML->setAttribute('public', $definition->isPublic() && !$definition->isPrivate() ? 'true' : 'false'); $serviceXML->setAttribute('synthetic', $definition->isSynthetic() ? 'true' : 'false'); $serviceXML->setAttribute('lazy', $definition->isLazy() ? 'true' : 'false'); $serviceXML->setAttribute('shared', $definition->isShared() ? 'true' : 'false'); @@ -469,7 +469,7 @@ private function getContainerAliasDocument(Alias $alias, $id = null) } $aliasXML->setAttribute('service', (string) $alias); - $aliasXML->setAttribute('public', $alias->isPublic() ? 'true' : 'false'); + $aliasXML->setAttribute('public', $alias->isPublic() && !$alias->isPrivate() ? 'true' : 'false'); return $dom; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.json index e2ab628937760..df76274db6417 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.json +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.json @@ -17,7 +17,7 @@ "%parameter%", { "class": "inline_service", - "public": true, + "public": false, "synthetic": false, "lazy": false, "shared": true, @@ -39,7 +39,7 @@ }, { "class": "inline_service", - "public": true, + "public": false, "synthetic": false, "lazy": false, "shared": true, diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.xml index b016ae382a908..59811b00d37b9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.xml @@ -6,7 +6,7 @@ %parameter% - + arg1 arg2 @@ -15,7 +15,7 @@ foo - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.json index 5074d4fba6170..2568b87dec458 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.json +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.json @@ -15,7 +15,7 @@ "%parameter%", { "class": "inline_service", - "public": true, + "public": false, "synthetic": false, "lazy": false, "shared": true, @@ -37,7 +37,7 @@ }, { "class": "inline_service", - "public": true, + "public": false, "synthetic": false, "lazy": false, "shared": true, diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.xml index 732f99f7839a1..e250060d75581 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.xml @@ -4,7 +4,7 @@ %parameter% - + arg1 arg2 @@ -13,7 +13,7 @@ foo - + From acb1cad841cf306c9fdd5e23cb71d6c3cdf1cb8b Mon Sep 17 00:00:00 2001 From: Kevin Frantz Date: Wed, 31 Jan 2018 23:22:47 +0100 Subject: [PATCH 030/166] Fixed issue #25985 --- src/Symfony/Component/Debug/DebugClassLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index 78bfb85388022..33e715a869737 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -141,7 +141,7 @@ public function loadClass($class) if ($this->isFinder && !isset($this->loaded[$class])) { $this->loaded[$class] = true; if ($file = $this->classLoader[0]->findFile($class) ?: false) { - $wasCached = \function_exists('opcache_is_script_cached') && opcache_is_script_cached($file); + $wasCached = \function_exists('opcache_is_script_cached') && @opcache_is_script_cached($file); require $file; From 45d730ba85967ac9104b1170e3a7c31cb3845f6b Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Thu, 1 Feb 2018 03:18:45 -0200 Subject: [PATCH 031/166] Fix typo --- .../Twig/Tests/Extension/FormExtensionBootstrap4LayoutTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap4LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap4LayoutTest.php index d3822ee77796a..d8cbde1017345 100644 --- a/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap4LayoutTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Extension/FormExtensionBootstrap4LayoutTest.php @@ -29,7 +29,7 @@ class FormExtensionBootstrap4LayoutTest extends AbstractBootstrap4LayoutTest { use RuntimeLoaderProvider; /** - * @var FormRenderer; + * @var FormRenderer */ private $renderer; From 566bb57428e526d2c07b7b3c041a2eceb80cd171 Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Thu, 1 Feb 2018 03:46:23 -0200 Subject: [PATCH 032/166] Fix typo --- src/Symfony/Component/Lock/Tests/Store/AbstractStoreTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Lock/Tests/Store/AbstractStoreTest.php b/src/Symfony/Component/Lock/Tests/Store/AbstractStoreTest.php index 630ba743cc4e8..2ab030b200f5e 100644 --- a/src/Symfony/Component/Lock/Tests/Store/AbstractStoreTest.php +++ b/src/Symfony/Component/Lock/Tests/Store/AbstractStoreTest.php @@ -22,7 +22,7 @@ abstract class AbstractStoreTest extends TestCase { /** - * @return StoreInterface; + * @return StoreInterface */ abstract protected function getStore(); From 829f59da7f88bc8945761ae95091aa0352c1e7e6 Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Thu, 1 Feb 2018 03:55:42 -0200 Subject: [PATCH 033/166] Improve assertions --- .../Bridge/Doctrine/Tests/ManagerRegistryTest.php | 2 +- src/Symfony/Bridge/Monolog/Tests/LoggerTest.php | 4 ++-- .../DependencyInjection/FrameworkExtensionTest.php | 2 +- .../Cache/Tests/Adapter/NullAdapterTest.php | 2 +- .../Cache/Tests/Adapter/ProxyAdapterTest.php | 2 +- .../Component/Cache/Tests/Simple/NullCacheTest.php | 2 +- .../Tests/Resource/ReflectionClassResourceTest.php | 2 +- .../DataCollector/FormDataCollectorTest.php | 4 ++-- .../Storage/Handler/NativeSessionHandlerTest.php | 2 +- .../Component/HttpKernel/Tests/KernelTest.php | 4 ++-- .../Tests/Profiler/FileProfilerStorageTest.php | 12 ++++++------ .../Routing/Tests/RouteCollectionBuilderTest.php | 2 +- 12 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Tests/ManagerRegistryTest.php b/src/Symfony/Bridge/Doctrine/Tests/ManagerRegistryTest.php index d1596a1968b76..490a48cfe6c6e 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/ManagerRegistryTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/ManagerRegistryTest.php @@ -40,7 +40,7 @@ public function testResetService() $registry->resetManager(); $this->assertSame($foo, $container->get('foo')); - $this->assertFalse(isset($foo->bar)); + $this->assertObjectNotHasAttribute('bar', $foo); } } diff --git a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php b/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php index a5fab0583c749..fdd36336cb4a5 100644 --- a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php @@ -28,7 +28,7 @@ public function testGetLogsWithDebugHandler() $logger = new Logger(__METHOD__, array($handler)); $this->assertTrue($logger->error('error message')); - $this->assertSame(1, count($logger->getLogs())); + $this->assertCount(1, $logger->getLogs()); } public function testGetLogsWithoutDebugProcessor() @@ -93,7 +93,7 @@ public function testGetLogsWithDebugProcessor() $logger = new Logger(__METHOD__, array($handler), array($processor)); $this->assertTrue($logger->error('error message')); - $this->assertSame(1, count($logger->getLogs())); + $this->assertCount(1, $logger->getLogs()); } public function testCountErrorsWithDebugProcessor() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index cabccb38c1b32..b40e735c98b73 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -1123,7 +1123,7 @@ private function assertCachePoolServiceDefinitionIsCreated(ContainerBuilder $con $this->assertFalse($poolDefinition->isAbstract(), sprintf('Service definition "%s" is not abstract.', $id)); $tag = $poolDefinition->getTag('cache.pool'); - $this->assertTrue(isset($tag[0]['default_lifetime']), 'The default lifetime is stored as an attribute of the "cache.pool" tag.'); + $this->assertArrayHasKey('default_lifetime', $tag[0], 'The default lifetime is stored as an attribute of the "cache.pool" tag.'); $this->assertSame($defaultLifetime, $tag[0]['default_lifetime'], 'The default lifetime is stored as an attribute of the "cache.pool" tag.'); $parentDefinition = $poolDefinition; diff --git a/src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php index c28a4550263df..73e5cad5529a9 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/NullAdapterTest.php @@ -53,7 +53,7 @@ public function testGetItems() $itemKey = $item->getKey(); $this->assertEquals($itemKey, $key, 'Keys must be preserved when fetching multiple items'); - $this->assertTrue(in_array($key, $keys), 'Cache key can not change.'); + $this->assertContains($key, $keys, 'Cache key can not change.'); $this->assertFalse($item->isHit()); // Remove $key for $keys diff --git a/src/Symfony/Component/Cache/Tests/Adapter/ProxyAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/ProxyAdapterTest.php index 5e6abd16c18c4..ff4b9d34bcbaf 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/ProxyAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/ProxyAdapterTest.php @@ -43,7 +43,7 @@ public function testProxyfiedItem() $proxyItem = $pool->getItem('foo'); - $this->assertFalse($proxyItem === $item); + $this->assertNotSame($item, $proxyItem); $pool->save($proxyItem->set('bar')); } } diff --git a/src/Symfony/Component/Cache/Tests/Simple/NullCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/NullCacheTest.php index 16dd7764d2ca1..7b760fd3bddaa 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/NullCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/NullCacheTest.php @@ -47,7 +47,7 @@ public function testGetMultiple() $count = 0; foreach ($items as $key => $item) { - $this->assertTrue(in_array($key, $keys), 'Cache key can not change.'); + $this->assertContains($key, $keys, 'Cache key can not change.'); $this->assertSame($default, $item); // Remove $key for $keys diff --git a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php index 4eca3d50e4a8b..b14099a9eb3c3 100644 --- a/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/ReflectionClassResourceTest.php @@ -100,7 +100,7 @@ public function testHashedSignature($changeExpected, $changedLine, $changedCode) $signature = implode("\n", iterator_to_array($generateSignature(new \ReflectionClass($class)))); if ($changeExpected) { - $this->assertTrue($expectedSignature !== $signature); + $this->assertNotSame($expectedSignature, $signature); } else { $this->assertSame($expectedSignature, $signature); } diff --git a/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php b/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php index 7e591d414e456..bd3f25bffb2a6 100644 --- a/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php @@ -690,9 +690,9 @@ public function testCollectSubmittedDataExpandedFormsErrors() $this->assertTrue($formData['has_children_error']); $this->assertTrue($child1Data['has_children_error']); - $this->assertFalse(isset($child11Data['has_children_error']), 'The leaf data does not contains "has_children_error" property.'); + $this->assertArrayNotHasKey('has_children_error', $child11Data, 'The leaf data does not contains "has_children_error" property.'); $this->assertFalse($child2Data['has_children_error']); - $this->assertFalse(isset($child21Data['has_children_error']), 'The leaf data does not contains "has_children_error" property.'); + $this->assertArrayNotHasKey('has_children_error', $child21Data, 'The leaf data does not contains "has_children_error" property.'); } public function testReset() diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php index 1a68d575e2c59..4a9fb600d2ddd 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php @@ -32,7 +32,7 @@ public function testConstruct() { $handler = new NativeSessionHandler(); - $this->assertTrue($handler instanceof \SessionHandler); + $this->assertInstanceOf('SessionHandler', $handler); $this->assertTrue($handler instanceof NativeSessionHandler); } } diff --git a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php index 755e1db2b7ddf..a16ac37deebce 100644 --- a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php @@ -849,14 +849,14 @@ public function testKernelReset() $kernel = new CustomProjectDirKernel(); $kernel->boot(); - $this->assertSame($containerClass, get_class($kernel->getContainer())); + $this->assertInstanceOf($containerClass, $kernel->getContainer()); $this->assertFileExists($containerFile); unlink(__DIR__.'/Fixtures/cache/custom/FixturesCustomDebugProjectContainer.php.meta'); $kernel = new CustomProjectDirKernel(function ($container) { $container->register('foo', 'stdClass')->setPublic(true); }); $kernel->boot(); - $this->assertTrue(get_class($kernel->getContainer()) !== $containerClass); + $this->assertNotInstanceOf($containerClass, $kernel->getContainer()); $this->assertFileExists($containerFile); $this->assertFileExists(dirname($containerFile).'.legacy'); } diff --git a/src/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php b/src/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php index 99ff207567439..a1db1d9c0ec61 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php @@ -83,22 +83,22 @@ public function testStoreSpecialCharsInUrl() $profile = new Profile('simple_quote'); $profile->setUrl('http://foo.bar/\''); $this->storage->write($profile); - $this->assertTrue(false !== $this->storage->read('simple_quote'), '->write() accepts single quotes in URL'); + $this->assertNotFalse($this->storage->read('simple_quote'), '->write() accepts single quotes in URL'); $profile = new Profile('double_quote'); $profile->setUrl('http://foo.bar/"'); $this->storage->write($profile); - $this->assertTrue(false !== $this->storage->read('double_quote'), '->write() accepts double quotes in URL'); + $this->assertNotFalse($this->storage->read('double_quote'), '->write() accepts double quotes in URL'); $profile = new Profile('backslash'); $profile->setUrl('http://foo.bar/\\'); $this->storage->write($profile); - $this->assertTrue(false !== $this->storage->read('backslash'), '->write() accepts backslash in URL'); + $this->assertNotFalse($this->storage->read('backslash'), '->write() accepts backslash in URL'); $profile = new Profile('comma'); $profile->setUrl('http://foo.bar/,'); $this->storage->write($profile); - $this->assertTrue(false !== $this->storage->read('comma'), '->write() accepts comma in URL'); + $this->assertNotFalse($this->storage->read('comma'), '->write() accepts comma in URL'); } public function testStoreDuplicateToken() @@ -247,7 +247,7 @@ public function testPurge() $profile->setMethod('GET'); $this->storage->write($profile); - $this->assertTrue(false !== $this->storage->read('token1')); + $this->assertNotFalse($this->storage->read('token1')); $this->assertCount(1, $this->storage->find('127.0.0.1', '', 10, 'GET')); $profile = new Profile('token2'); @@ -256,7 +256,7 @@ public function testPurge() $profile->setMethod('GET'); $this->storage->write($profile); - $this->assertTrue(false !== $this->storage->read('token2')); + $this->assertNotFalse($this->storage->read('token2')); $this->assertCount(2, $this->storage->find('127.0.0.1', '', 10, 'GET')); $this->storage->purge(); diff --git a/src/Symfony/Component/Routing/Tests/RouteCollectionBuilderTest.php b/src/Symfony/Component/Routing/Tests/RouteCollectionBuilderTest.php index f6af600bd4221..76a042d670b29 100644 --- a/src/Symfony/Component/Routing/Tests/RouteCollectionBuilderTest.php +++ b/src/Symfony/Component/Routing/Tests/RouteCollectionBuilderTest.php @@ -357,7 +357,7 @@ public function testAddsThePrefixOnlyOnceWhenLoadingMultipleCollections() $routeCollectionBuilder->import('/directory/recurse/*', '/other/', 'glob'); $routes = $routeCollectionBuilder->build()->all(); - $this->assertEquals(2, count($routes)); + $this->assertCount(2, $routes); $this->assertEquals('/other/a', $routes['a']->getPath()); $this->assertEquals('/other/b', $routes['b']->getPath()); } From 945c753d4413c6f6ebbc1036cc1ac8f72c130f9e Mon Sep 17 00:00:00 2001 From: Samuel ROZE Date: Thu, 1 Feb 2018 08:54:27 +0000 Subject: [PATCH 034/166] Add tests for glob loaders --- .../Tests/Loader/GlobFileLoaderTest.php | 44 ++++++++++++++++++ .../Tests/Loader/GlobFileLoaderTest.php | 45 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Loader/GlobFileLoaderTest.php create mode 100644 src/Symfony/Component/Routing/Tests/Loader/GlobFileLoaderTest.php diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/GlobFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/GlobFileLoaderTest.php new file mode 100644 index 0000000000000..a3be4dfd3b99a --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/GlobFileLoaderTest.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\GlobResource; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\GlobFileLoader; +use Symfony\Component\Config\FileLocator; + +class GlobFileLoaderTest extends TestCase +{ + public function testSupports() + { + $loader = new GlobFileLoader(new ContainerBuilder(), new FileLocator()); + + $this->assertTrue($loader->supports('any-path', 'glob'), '->supports() returns true if the resource has the glob type'); + $this->assertFalse($loader->supports('any-path'), '->supports() returns false if the resource is not of glob type'); + } + + public function testLoadAddsTheGlobResourceToTheContainer() + { + $loader = new GlobFileLoaderWithoutImport($container = new ContainerBuilder(), new FileLocator()); + $loader->load(__DIR__.'/../Fixtures/config/*'); + + $this->assertEquals(new GlobResource(__DIR__.'/../Fixtures/config', '/*', false), $container->getResources()[1]); + } +} + +class GlobFileLoaderWithoutImport extends GlobFileLoader +{ + public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null) + { + } +} diff --git a/src/Symfony/Component/Routing/Tests/Loader/GlobFileLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/GlobFileLoaderTest.php new file mode 100644 index 0000000000000..08d806a8a4af6 --- /dev/null +++ b/src/Symfony/Component/Routing/Tests/Loader/GlobFileLoaderTest.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\GlobResource; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Routing\Loader\GlobFileLoader; +use Symfony\Component\Routing\RouteCollection; + +class GlobFileLoaderTest extends TestCase +{ + public function testSupports() + { + $loader = new GlobFileLoader(new FileLocator()); + + $this->assertTrue($loader->supports('any-path', 'glob'), '->supports() returns true if the resource has the glob type'); + $this->assertFalse($loader->supports('any-path'), '->supports() returns false if the resource is not of glob type'); + } + + public function testLoadAddsTheGlobResourceToTheContainer() + { + $loader = new GlobFileLoaderWithoutImport(new FileLocator()); + $collection = $loader->load(__DIR__.'/../Fixtures/directory/*.yml'); + + $this->assertEquals(new GlobResource(__DIR__.'/../Fixtures/directory', '/*.yml', false), $collection->getResources()[0]); + } +} + +class GlobFileLoaderWithoutImport extends GlobFileLoader +{ + public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null) + { + return new RouteCollection(); + } +} From 6ab8dd92e9c06e691769b3b23e54a5e2f273ae83 Mon Sep 17 00:00:00 2001 From: "Israel J. Carberry" Date: Thu, 1 Feb 2018 09:00:52 -0600 Subject: [PATCH 035/166] Allow remember-me factory creation when multiple user providers are configured. --- .../DependencyInjection/SecurityExtension.php | 3 +++ .../SecurityExtensionTest.php | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index a2be3a24be751..6f43a4ce8cfef 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -515,6 +515,9 @@ private function createAuthenticationListeners($container, $id, $firewall, &$aut throw new InvalidConfigurationException(sprintf('Invalid firewall "%s": user provider "%s" not found.', $id, $firewall[$key]['provider'])); } $userProvider = $providerIds[$normalizedName]; + } elseif ('remember_me' === $key) { + // RememberMeFactory will use the firewall secret when created + $userProvider = null; } else { $userProvider = $defaultProvider ?: $this->getFirstProvider($id, $key, $providerIds); } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php index 7b5f6685c47b1..52a18d08ac494 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php @@ -259,6 +259,28 @@ public function testPerListenerProvider() $this->addToAssertionCount(1); } + public function testPerListenerProviderWithRememberMe() + { + $container = $this->getRawContainer(); + $container->loadFromExtension('security', array( + 'providers' => array( + 'first' => array('id' => 'foo'), + 'second' => array('id' => 'bar'), + ), + + 'firewalls' => array( + 'default' => array( + 'form_login' => array('provider' => 'second'), + 'logout_on_user_change' => true, + 'remember_me' => array('secret' => 'baz'), + ), + ), + )); + + $container->compile(); + $this->addToAssertionCount(1); + } + protected function getRawContainer() { $container = new ContainerBuilder(); From 5733e02960f683f2db278980ba96d80c2e013622 Mon Sep 17 00:00:00 2001 From: Victor Bocharsky Date: Thu, 28 Dec 2017 16:08:38 +0200 Subject: [PATCH 036/166] [Intl] Fixed the broken link --- src/Symfony/Component/Intl/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Intl/README.md b/src/Symfony/Component/Intl/README.md index 806c6275e83dd..9a9cb9b45614e 100644 --- a/src/Symfony/Component/Intl/README.md +++ b/src/Symfony/Component/Intl/README.md @@ -5,7 +5,7 @@ A PHP replacement layer for the C intl extension that also provides access to the localization data of the ICU library. The replacement layer is limited to the locale "en". If you want to use other -locales, you should [install the intl PHP extension] [0] instead. +locales, you should [install the intl PHP extension][0] instead. Resources --------- From e0132cc5d769c58b55013c45e49141ad838d19d5 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Fri, 2 Feb 2018 12:17:55 +0100 Subject: [PATCH 037/166] Update MongoDB extension on travis to make the builds green again. --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a3e945695143..c4eab3432309d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -100,8 +100,6 @@ before_install: [[ $PHP = 5.* ]] && echo extension = memcache.so >> $INI if [[ $PHP = 5.* ]]; then echo extension = mongo.so >> $INI - elif [[ $PHP = 7.* ]]; then - echo extension = mongodb.so >> $INI fi # Matrix lines for intermediate PHP versions are skipped for pull requests @@ -127,6 +125,7 @@ before_install: tfold ext.apcu4 'echo yes | pecl install -f apcu-4.0.11' elif [[ ! $skip && $PHP = 7.* ]]; then tfold ext.apcu5 'echo yes | pecl install -f apcu-5.1.6' + tfold ext.mongodb pecl install -f mongodb-1.4.0RC1 fi install: From d6f4f5129e24d27e64b1fa4b502bf5aa88215cca Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 3 Feb 2018 01:09:36 +0100 Subject: [PATCH 038/166] Removed unused parameter from flattenDataProvider(). --- .../Debug/Tests/Exception/FlattenExceptionTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php b/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php index d3b9ab2eb770a..269abf0f7bd63 100644 --- a/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php +++ b/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php @@ -105,7 +105,7 @@ public function testHeadersForHttpException() /** * @dataProvider flattenDataProvider */ - public function testFlattenHttpException(\Exception $exception, $statusCode) + public function testFlattenHttpException(\Exception $exception) { $flattened = FlattenException::create($exception); $flattened2 = FlattenException::create($exception); @@ -120,7 +120,7 @@ public function testFlattenHttpException(\Exception $exception, $statusCode) /** * @dataProvider flattenDataProvider */ - public function testPrevious(\Exception $exception, $statusCode) + public function testPrevious(\Exception $exception) { $flattened = FlattenException::create($exception); $flattened2 = FlattenException::create($exception); @@ -167,7 +167,7 @@ public function testFile(\Exception $exception) /** * @dataProvider flattenDataProvider */ - public function testToArray(\Exception $exception, $statusCode) + public function testToArray(\Exception $exception) { $flattened = FlattenException::create($exception); $flattened->setTrace(array(), 'foo.php', 123); @@ -187,7 +187,7 @@ public function testToArray(\Exception $exception, $statusCode) public function flattenDataProvider() { return array( - array(new \Exception('test', 123), 500), + array(new \Exception('test', 123)), ); } From 52c9cb402510cac50537cdc56ccfd563df500b6d Mon Sep 17 00:00:00 2001 From: Dmitriy Fedorenko Date: Sat, 3 Feb 2018 17:33:10 +1000 Subject: [PATCH 039/166] [Config] Only using filemtime to check file freshness --- src/Symfony/Component/Config/Resource/FileResource.php | 2 +- .../Component/Config/Resource/ReflectionClassResource.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index 5d71d87918c8f..1d373a623acfc 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -60,7 +60,7 @@ public function getResource() */ public function isFresh($timestamp) { - return file_exists($this->resource) && @filemtime($this->resource) <= $timestamp; + return false !== ($filemtime = @filemtime($this->resource)) && $filemtime <= $timestamp; } public function serialize() diff --git a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php index a8e1f9611b99a..11389aab423f1 100644 --- a/src/Symfony/Component/Config/Resource/ReflectionClassResource.php +++ b/src/Symfony/Component/Config/Resource/ReflectionClassResource.php @@ -37,11 +37,11 @@ public function isFresh($timestamp) } foreach ($this->files as $file => $v) { - if (!file_exists($file)) { + if (false === $filemtime = @filemtime($file)) { return false; } - if (@filemtime($file) > $timestamp) { + if ($filemtime > $timestamp) { return $this->hash === $this->computeHash(); } } From 76b40dc10e46814fd329d0cf1dd285820a3e822a Mon Sep 17 00:00:00 2001 From: Arnaud CHASSEUX Date: Wed, 4 Feb 2015 18:46:52 +0100 Subject: [PATCH 040/166] [CssSelector] For AND operator, the left operand should have parentheses, not only right operand --- .../CssSelector/Tests/CssSelectorTest.php | 2 +- .../CssSelector/Tests/XPath/TranslatorTest.php | 16 +++++++++------- .../Component/CssSelector/XPath/XPathExpr.php | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/CssSelector/Tests/CssSelectorTest.php b/src/Symfony/Component/CssSelector/Tests/CssSelectorTest.php index f1dee1ee11ee9..e05d398847a57 100644 --- a/src/Symfony/Component/CssSelector/Tests/CssSelectorTest.php +++ b/src/Symfony/Component/CssSelector/Tests/CssSelectorTest.php @@ -48,7 +48,7 @@ public function getCssToXPathWithoutPrefixTestData() array('h1', 'h1'), array('foo|h1', 'foo:h1'), array('h1, h2, h3', 'h1 | h2 | h3'), - array('h1:nth-child(3n+1)', "*/*[name() = 'h1' and (position() - 1 >= 0 and (position() - 1) mod 3 = 0)]"), + array('h1:nth-child(3n+1)', "*/*[(name() = 'h1') and (position() - 1 >= 0 and (position() - 1) mod 3 = 0)]"), array('h1 > p', 'h1/p'), array('h1#foo', "h1[@id = 'foo']"), array('h1.foo', "h1[@class and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"), diff --git a/src/Symfony/Component/CssSelector/Tests/XPath/TranslatorTest.php b/src/Symfony/Component/CssSelector/Tests/XPath/TranslatorTest.php index 218a3b43c1a78..519417835cefe 100644 --- a/src/Symfony/Component/CssSelector/Tests/XPath/TranslatorTest.php +++ b/src/Symfony/Component/CssSelector/Tests/XPath/TranslatorTest.php @@ -102,18 +102,20 @@ public function getCssToXPathTestData() array('e[foo^="bar"]', "e[@foo and starts-with(@foo, 'bar')]"), array('e[foo$="bar"]', "e[@foo and substring(@foo, string-length(@foo)-2) = 'bar']"), array('e[foo*="bar"]', "e[@foo and contains(@foo, 'bar')]"), + array('e[foo!="bar"]', "e[not(@foo) or @foo != 'bar']"), + array('e[foo!="bar"][foo!="baz"]', "e[(not(@foo) or @foo != 'bar') and (not(@foo) or @foo != 'baz')]"), array('e[hreflang|="en"]', "e[@hreflang and (@hreflang = 'en' or starts-with(@hreflang, 'en-'))]"), - array('e:nth-child(1)', "*/*[name() = 'e' and (position() = 1)]"), - array('e:nth-last-child(1)', "*/*[name() = 'e' and (position() = last() - 0)]"), - array('e:nth-last-child(2n+2)', "*/*[name() = 'e' and (last() - position() - 1 >= 0 and (last() - position() - 1) mod 2 = 0)]"), + array('e:nth-child(1)', "*/*[(name() = 'e') and (position() = 1)]"), + array('e:nth-last-child(1)', "*/*[(name() = 'e') and (position() = last() - 0)]"), + array('e:nth-last-child(2n+2)', "*/*[(name() = 'e') and (last() - position() - 1 >= 0 and (last() - position() - 1) mod 2 = 0)]"), array('e:nth-of-type(1)', '*/e[position() = 1]'), array('e:nth-last-of-type(1)', '*/e[position() = last() - 0]'), array('div e:nth-last-of-type(1) .aclass', "div/descendant-or-self::*/e[position() = last() - 0]/descendant-or-self::*/*[@class and contains(concat(' ', normalize-space(@class), ' '), ' aclass ')]"), - array('e:first-child', "*/*[name() = 'e' and (position() = 1)]"), - array('e:last-child', "*/*[name() = 'e' and (position() = last())]"), + array('e:first-child', "*/*[(name() = 'e') and (position() = 1)]"), + array('e:last-child', "*/*[(name() = 'e') and (position() = last())]"), array('e:first-of-type', '*/e[position() = 1]'), array('e:last-of-type', '*/e[position() = last()]'), - array('e:only-child', "*/*[name() = 'e' and (last() = 1)]"), + array('e:only-child', "*/*[(name() = 'e') and (last() = 1)]"), array('e:only-of-type', 'e[last() = 1]'), array('e:empty', 'e[not(*) and not(string-length())]'), array('e:EmPTY', 'e[not(*) and not(string-length())]'), @@ -127,7 +129,7 @@ public function getCssToXPathTestData() array('e:nOT(*)', 'e[0]'), array('e f', 'e/descendant-or-self::*/f'), array('e > f', 'e/f'), - array('e + f', "e/following-sibling::*[name() = 'f' and (position() = 1)]"), + array('e + f', "e/following-sibling::*[(name() = 'f') and (position() = 1)]"), array('e ~ f', 'e/following-sibling::f'), array('div#container p', "div[@id = 'container']/descendant-or-self::*/p"), ); diff --git a/src/Symfony/Component/CssSelector/XPath/XPathExpr.php b/src/Symfony/Component/CssSelector/XPath/XPathExpr.php index c0d2bd55a5a03..1c7aead7ed8bd 100644 --- a/src/Symfony/Component/CssSelector/XPath/XPathExpr.php +++ b/src/Symfony/Component/CssSelector/XPath/XPathExpr.php @@ -57,7 +57,7 @@ public function getElement() */ public function addCondition($condition) { - $this->condition = $this->condition ? sprintf('%s and (%s)', $this->condition, $condition) : $condition; + $this->condition = $this->condition ? sprintf('(%s) and (%s)', $this->condition, $condition) : $condition; return $this; } @@ -101,7 +101,7 @@ public function addStarPrefix() * * @return $this */ - public function join($combiner, XPathExpr $expr) + public function join($combiner, self $expr) { $path = $this->__toString().$combiner; From 48db494b19e3fbddeffef0b77a52b6414f5057a0 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 3 Feb 2018 15:55:47 +0100 Subject: [PATCH 041/166] fix merge --- .../Component/CssSelector/Tests/CssSelectorConverterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/CssSelector/Tests/CssSelectorConverterTest.php b/src/Symfony/Component/CssSelector/Tests/CssSelectorConverterTest.php index a27fadfef1e70..a3eea7ad21869 100644 --- a/src/Symfony/Component/CssSelector/Tests/CssSelectorConverterTest.php +++ b/src/Symfony/Component/CssSelector/Tests/CssSelectorConverterTest.php @@ -59,7 +59,7 @@ public function getCssToXPathWithoutPrefixTestData() array('h1', 'h1'), array('foo|h1', 'foo:h1'), array('h1, h2, h3', 'h1 | h2 | h3'), - array('h1:nth-child(3n+1)', "*/*[name() = 'h1' and (position() - 1 >= 0 and (position() - 1) mod 3 = 0)]"), + array('h1:nth-child(3n+1)', "*/*[(name() = 'h1') and (position() - 1 >= 0 and (position() - 1) mod 3 = 0)]"), array('h1 > p', 'h1/p'), array('h1#foo', "h1[@id = 'foo']"), array('h1.foo', "h1[@class and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]"), From b9def8ab5043149a8905dae143c543b6d5484e2b Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 4 Feb 2018 10:26:21 +0100 Subject: [PATCH 042/166] [travis] cache compiled php extensions --- .travis.yml | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index c4eab3432309d..7f13d5b60cea3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,7 @@ cache: directories: - .phpunit - php-$MIN_PHP + - php-ext services: mongodb @@ -102,6 +103,23 @@ before_install: echo extension = mongo.so >> $INI fi + # tpecl is a helper to compile and cache php extensions + tpecl () { + local ext_name=$1 + local ext_so=$2 + local ext_dir=$(php -r "echo ini_get('extension_dir');") + local ext_cache=~/php-ext/$(basename $ext_dir)/$ext_name + + if [[ -e $ext_cache/$ext_so ]]; then + echo extension = $ext_cache/$ext_so >> $INI + else + mkdir -p $ext_cache + echo yes | pecl install -f $ext_name && + cp $ext_dir/$ext_so $ext_cache + fi + } + export -f tpecl + # Matrix lines for intermediate PHP versions are skipped for pull requests if [[ ! $deps && ! $PHP = ${MIN_PHP%.*} && ! $PHP = hhvm* && $TRAVIS_PULL_REQUEST != false ]]; then deps=skip @@ -120,12 +138,12 @@ before_install: - | # Install extra PHP extensions if [[ ! $skip && $PHP = 5.* ]]; then - ([[ $deps ]] || tfold ext.symfony_debug 'cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo extension = $(pwd)/modules/symfony_debug.so >> '"$INI") && - tfold ext.memcached pecl install -f memcached-2.1.0 && - tfold ext.apcu4 'echo yes | pecl install -f apcu-4.0.11' + ([[ $deps ]] || tfold ext.symfony_debug 'cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo extension = $(pwd)/modules/symfony_debug.so >> '"$INI") + tfold ext.memcached tpecl memcached-2.1.0 memcached.so + tfold ext.apcu tpecl apcu-4.0.11 apcu.so elif [[ ! $skip && $PHP = 7.* ]]; then - tfold ext.apcu5 'echo yes | pecl install -f apcu-5.1.6' - tfold ext.mongodb pecl install -f mongodb-1.4.0RC1 + tfold ext.apcu tpecl apcu-5.1.6 apcu.so + tfold ext.mongodb tpecl mongodb-1.4.0RC1 mongodb.so fi install: From afbb8bec18bde61de24516a644a4e304c478360b Mon Sep 17 00:00:00 2001 From: Valouleloup Date: Sat, 3 Feb 2018 17:30:37 +0100 Subject: [PATCH 043/166] Fix lock strategy tests --- .../Component/Lock/Tests/Strategy/ConsensusStrategyTest.php | 2 +- .../Component/Lock/Tests/Strategy/UnanimousStrategyTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Lock/Tests/Strategy/ConsensusStrategyTest.php b/src/Symfony/Component/Lock/Tests/Strategy/ConsensusStrategyTest.php index 09215f9a94d63..87e83a9925695 100644 --- a/src/Symfony/Component/Lock/Tests/Strategy/ConsensusStrategyTest.php +++ b/src/Symfony/Component/Lock/Tests/Strategy/ConsensusStrategyTest.php @@ -82,7 +82,7 @@ public function testMet($success, $failure, $total, $isMet) /** * @dataProvider provideIndeterminate */ - public function canBeMet($success, $failure, $total, $isMet) + public function testCanBeMet($success, $failure, $total, $isMet) { $this->assertSame($isMet, $this->strategy->canBeMet($failure, $total)); } diff --git a/src/Symfony/Component/Lock/Tests/Strategy/UnanimousStrategyTest.php b/src/Symfony/Component/Lock/Tests/Strategy/UnanimousStrategyTest.php index 76ea68a41e3b3..beff54a685747 100644 --- a/src/Symfony/Component/Lock/Tests/Strategy/UnanimousStrategyTest.php +++ b/src/Symfony/Component/Lock/Tests/Strategy/UnanimousStrategyTest.php @@ -82,7 +82,7 @@ public function testMet($success, $failure, $total, $isMet) /** * @dataProvider provideIndeterminate */ - public function canBeMet($success, $failure, $total, $isMet) + public function testCanBeMet($success, $failure, $total, $isMet) { $this->assertSame($isMet, $this->strategy->canBeMet($failure, $total)); } From f2d54fe694a5d04991922b151c1b5107b91e5178 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 4 Feb 2018 14:10:03 +0100 Subject: [PATCH 044/166] fix merge --- .../SecurityBundle/DependencyInjection/SecurityExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index b8d9fb52e5b32..b5d08d596e7ec 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -412,7 +412,7 @@ private function createAuthenticationListeners($container, $id, $firewall, &$aut } elseif ('remember_me' === $key) { // RememberMeFactory will use the firewall secret when created $userProvider = null; - } elseif($defaultProvider) { + } elseif ($defaultProvider) { $userProvider = $defaultProvider; } else { throw new InvalidConfigurationException(sprintf('Not configuring explicitly the provider for the "%s" listener on "%s" firewall is ambiguous as there is more than one registered provider.', $key, $id)); From 81dafca6db4c837e8b27876d45f3feb1319b670c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 4 Feb 2018 14:31:10 +0100 Subject: [PATCH 045/166] fix merge --- .../Routing/Tests/Matcher/RedirectableUrlMatcherTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php index e49b784999775..5f226271bf85c 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php @@ -113,7 +113,7 @@ public function testSchemeRequirement() $coll = new RouteCollection(); $coll->add('foo', new Route('/foo', array(), array(), array(), '', array('https'))); $matcher = $this->getUrlMatcher($coll, new RequestContext()); - $matcher->expects($this->once())->method('redirect')->with('/foo', 'foo', 'https')->willReturn(array('_route' => 'foo')); + $matcher->expects($this->once())->method('redirect')->with('/foo', 'foo', 'https')->willReturn(array()); $this->assertSame(array('_route' => 'foo'), $matcher->match('/foo')); } From ae96700c206337b23f8e19d26fed0c8c367e2c71 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 4 Feb 2018 15:17:18 +0100 Subject: [PATCH 046/166] [PropertyInfo] Fix compat with recent phpdocumentor/type-resolver --- .../Component/PropertyInfo/Extractor/PhpDocExtractor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php index 2ce31a0170669..4224ded7d9ad8 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php @@ -204,7 +204,7 @@ private function getDocBlockFromProperty($class, $property) return; } - return $this->docBlockFactory->create($reflectionProperty, $this->contextFactory->createFromReflector($reflectionProperty)); + return $this->docBlockFactory->create($reflectionProperty, $this->contextFactory->createFromReflector($reflectionProperty->getDeclaringClass())); } /** From 12c1a01ac0f3441eecddae6990fb2c37725a1118 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 4 Feb 2018 15:28:36 +0100 Subject: [PATCH 047/166] fix merge --- ...er_class_constructor_without_arguments.php | 24 +++++++++++-------- ...s_with_mandatory_constructor_arguments.php | 24 +++++++++++-------- ...ss_with_optional_constructor_arguments.php | 24 +++++++++++-------- ...om_container_class_without_constructor.php | 24 +++++++++++-------- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_constructor_without_arguments.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_constructor_without_arguments.php index 3020602b89804..01caae6489535 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_constructor_without_arguments.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_constructor_without_arguments.php @@ -21,21 +21,24 @@ class ProjectServiceContainer extends \Symfony\Component\DependencyInjection\Tes private $parameters; private $targetDirs = array(); + /** + * @internal but protected for BC on cache:clear + */ + protected $privates = array(); + public function __construct() { parent::__construct(); - $this->services = array(); + $this->services = $this->privates = array(); $this->aliases = array(); } - public function getRemovedIds() + public function reset() { - return array( - 'Psr\\Container\\ContainerInterface' => true, - 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, - ); + $this->privates = array(); + parent::reset(); } public function compile() @@ -48,10 +51,11 @@ public function isCompiled() return true; } - public function isFrozen() + public function getRemovedIds() { - @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); - - return true; + return array( + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_mandatory_constructor_arguments.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_mandatory_constructor_arguments.php index dd9ed9cbb3141..e513fd7219147 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_mandatory_constructor_arguments.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_mandatory_constructor_arguments.php @@ -21,19 +21,22 @@ class ProjectServiceContainer extends \Symfony\Component\DependencyInjection\Tes private $parameters; private $targetDirs = array(); + /** + * @internal but protected for BC on cache:clear + */ + protected $privates = array(); + public function __construct() { - $this->services = array(); + $this->services = $this->privates = array(); $this->aliases = array(); } - public function getRemovedIds() + public function reset() { - return array( - 'Psr\\Container\\ContainerInterface' => true, - 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, - ); + $this->privates = array(); + parent::reset(); } public function compile() @@ -46,10 +49,11 @@ public function isCompiled() return true; } - public function isFrozen() + public function getRemovedIds() { - @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); - - return true; + return array( + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_optional_constructor_arguments.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_optional_constructor_arguments.php index d65ac7dfbcac9..1c20741bf7dc4 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_optional_constructor_arguments.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_with_optional_constructor_arguments.php @@ -21,21 +21,24 @@ class ProjectServiceContainer extends \Symfony\Component\DependencyInjection\Tes private $parameters; private $targetDirs = array(); + /** + * @internal but protected for BC on cache:clear + */ + protected $privates = array(); + public function __construct() { parent::__construct(); - $this->services = array(); + $this->services = $this->privates = array(); $this->aliases = array(); } - public function getRemovedIds() + public function reset() { - return array( - 'Psr\\Container\\ContainerInterface' => true, - 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, - ); + $this->privates = array(); + parent::reset(); } public function compile() @@ -48,10 +51,11 @@ public function isCompiled() return true; } - public function isFrozen() + public function getRemovedIds() { - @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); - - return true; + return array( + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_without_constructor.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_without_constructor.php index 4cf1ae40b44df..0a4975b7da395 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_without_constructor.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/custom_container_class_without_constructor.php @@ -21,19 +21,22 @@ class ProjectServiceContainer extends \Symfony\Component\DependencyInjection\Tes private $parameters; private $targetDirs = array(); + /** + * @internal but protected for BC on cache:clear + */ + protected $privates = array(); + public function __construct() { - $this->services = array(); + $this->services = $this->privates = array(); $this->aliases = array(); } - public function getRemovedIds() + public function reset() { - return array( - 'Psr\\Container\\ContainerInterface' => true, - 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, - ); + $this->privates = array(); + parent::reset(); } public function compile() @@ -46,10 +49,11 @@ public function isCompiled() return true; } - public function isFrozen() + public function getRemovedIds() { - @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); - - return true; + return array( + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ); } } From a0b40f5c4a5d46a2df789d223b46b91e08b339f8 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Wed, 4 Oct 2017 14:38:50 +0200 Subject: [PATCH 048/166] [Form] Make sure errors are a part of the label on bootstrap 4 - this is a requirement for WCAG2 --- .../bootstrap_4_horizontal_layout.html.twig | 2 - .../views/Form/bootstrap_4_layout.html.twig | 64 ++++++++++++++++--- ...AbstractBootstrap4HorizontalLayoutTest.php | 26 ++++++++ .../Tests/AbstractBootstrap4LayoutTest.php | 24 +++++++ 4 files changed, 106 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_horizontal_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_horizontal_layout.html.twig index e236d12cb709a..e23e6f8a29d09 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_horizontal_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_horizontal_layout.html.twig @@ -28,7 +28,6 @@ col-sm-2 {{- form_label(form) -}}
{{- form_widget(form) -}} - {{- form_errors(form) -}}
{##} {%- endif -%} @@ -40,7 +39,6 @@ col-sm-2 {{- form_label(form) -}}
{{- form_widget(form) -}} - {{- form_errors(form) -}}
{##} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig index 15413f1c9a0fe..12981e346232e 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig @@ -39,7 +39,41 @@ {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) -%} {% set valid = true %} {%- endif -%} - {{- parent() -}} + + {%- if widget == 'single_text' -%} + {{- block('form_widget_simple') -}} + {%- else -%} + {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} +
+
+ + + + {%- if with_years %}{% endif -%} + {%- if with_months %}{% endif -%} + {%- if with_weeks %}{% endif -%} + {%- if with_days %}{% endif -%} + {%- if with_hours %}{% endif -%} + {%- if with_minutes %}{% endif -%} + {%- if with_seconds %}{% endif -%} + + + + + {%- if with_years %}{% endif -%} + {%- if with_months %}{% endif -%} + {%- if with_weeks %}{% endif -%} + {%- if with_days %}{% endif -%} + {%- if with_hours %}{% endif -%} + {%- if with_minutes %}{% endif -%} + {%- if with_seconds %}{% endif -%} + + +
{{ form_label(form.years) }}{{ form_label(form.months) }}{{ form_label(form.weeks) }}{{ form_label(form.days) }}{{ form_label(form.hours) }}{{ form_label(form.minutes) }}{{ form_label(form.seconds) }}
{{ form_widget(form.years) }}{{ form_widget(form.months) }}{{ form_widget(form.weeks) }}{{ form_widget(form.days) }}{{ form_widget(form.hours) }}{{ form_widget(form.minutes) }}{{ form_widget(form.seconds) }}
+
+ {%- if with_invert %}{{ form_widget(form.invert) }}{% endif -%} +
+ {%- endif -%} {%- endblock dateinterval_widget %} {% block percent_widget -%} @@ -125,13 +159,28 @@ {# Labels #} {% block form_label -%} - {%- if compound is defined and compound -%} - {%- set element = 'legend' -%} - {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-legend')|trim}) -%} - {%- else -%} - {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%} + {% if label is not same as(false) -%} + {%- if compound is defined and compound -%} + {%- set element = 'legend' -%} + {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-legend')|trim}) -%} + {%- else -%} + {%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%} + {%- endif -%} + {% if required -%} + {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %} + {%- endif -%} + {% if label is empty -%} + {%- if label_format is not empty -%} + {% set label = label_format|replace({ + '%name%': name, + '%id%': id, + }) %} + {%- else -%} + {% set label = name|humanize %} + {%- endif -%} + {%- endif -%} + <{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}{% block form_label_errors %}{{- form_errors(form) -}}{% endblock form_label_errors %} {%- endif -%} - {{- parent() -}} {%- endblock form_label %} {% block checkbox_radio_label -%} @@ -169,7 +218,6 @@ <{{ element|default('div') }} class="form-group"> {{- form_label(form) -}} {{- form_widget(form) -}} - {{- form_errors(form) -}} {%- endblock form_row %} diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php index 2833de7d91de0..23e6f141cac9d 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Form\Tests; +use Symfony\Component\Form\FormError; + /** * Abstract class providing test cases for the Bootstrap 4 horizontal Twig form theme. * @@ -18,6 +20,30 @@ */ abstract class AbstractBootstrap4HorizontalLayoutTest extends AbstractBootstrap4LayoutTest { + public function testRow() + { + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType'); + $form->addError(new FormError('[trans]Error![/trans]')); + $view = $form->createView(); + $html = $this->renderRow($view); + + $this->assertMatchesXpath($html, + '/div + [ + ./label[@for="name"] + [ + ./div[ + ./ul + [./li[.="[trans]Error![/trans]"]] + [count(./li)=1] + ] + ] + /following-sibling::div[./input[@id="name"]] + ] +' + ); + } + public function testLabelOnForm() { $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType'); diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php index 88ebd261b2a44..fdaa07e1c15bc 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php @@ -20,6 +20,30 @@ */ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest { + public function testRow() + { + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType'); + $form->addError(new FormError('[trans]Error![/trans]')); + $view = $form->createView(); + $html = $this->renderRow($view); + + $this->assertMatchesXpath($html, + '/div + [ + ./label[@for="name"] + [ + ./div[ + ./ul + [./li[.="[trans]Error![/trans]"]] + [count(./li)=1] + ] + ] + /following-sibling::input[@id="name"] + ] +' + ); + } + public function testLabelOnForm() { $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType'); From f713a3e879b6d016254fe8b8275e99824146ffae Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Thu, 7 Dec 2017 10:40:47 +0100 Subject: [PATCH 049/166] Use the PCRE_DOLLAR_ENDONLY modifier in route regexes --- .../Console/Descriptor/ObjectsProvider.php | 13 ++++- .../Tests/Fixtures/Descriptor/route_1.json | 6 +- .../Tests/Fixtures/Descriptor/route_1.md | 6 +- .../Tests/Fixtures/Descriptor/route_1.txt | 6 +- .../Tests/Fixtures/Descriptor/route_1.xml | 6 +- .../Tests/Fixtures/Descriptor/route_2.json | 6 +- .../Tests/Fixtures/Descriptor/route_2.md | 6 +- .../Tests/Fixtures/Descriptor/route_2.txt | 6 +- .../Tests/Fixtures/Descriptor/route_2.xml | 6 +- .../Descriptor/route_collection_1.json | 12 ++-- .../Fixtures/Descriptor/route_collection_1.md | 12 ++-- .../Descriptor/route_collection_1.xml | 12 ++-- .../Component/Routing/RouteCompiler.php | 2 +- .../Tests/Fixtures/dumper/url_matcher1.php | 56 +++++++++---------- .../Tests/Fixtures/dumper/url_matcher2.php | 56 +++++++++---------- .../Tests/Fixtures/dumper/url_matcher3.php | 2 +- .../Routing/Tests/Matcher/UrlMatcherTest.php | 12 ++++ .../Routing/Tests/RouteCompilerTest.php | 44 +++++++-------- .../Component/Routing/Tests/RouteTest.php | 2 +- 19 files changed, 146 insertions(+), 125 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php index d6fc8b24ad264..108e53a7dff28 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php @@ -18,6 +18,7 @@ use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\CompiledRoute; use Symfony\Component\Routing\RouteCollection; class ObjectsProvider @@ -35,7 +36,7 @@ public static function getRouteCollections() public static function getRoutes() { return array( - 'route_1' => new Route( + 'route_1' => new RouteStub( '/hello/{name}', array('name' => 'Joseph'), array('name' => '[a-z]+'), @@ -44,7 +45,7 @@ public static function getRoutes() array('http', 'https'), array('get', 'head') ), - 'route_2' => new Route( + 'route_2' => new RouteStub( '/name/add', array(), array(), @@ -207,3 +208,11 @@ public static function staticMethod() { } } + +class RouteStub extends Route +{ + public function compile() + { + return new CompiledRoute('', '#PATH_REGEX#', array(), array(), '#HOST_REGEX#'); + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.json index beac79f1f8758..1108109fb0b48 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.json +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.json @@ -1,11 +1,11 @@ { "path": "\/hello\/{name}", - "pathRegex": "#^\/hello(?:\/(?P[a-z]+))?$#s", + "pathRegex": "#PATH_REGEX#", "host": "localhost", - "hostRegex": "#^localhost$#si", + "hostRegex": "#HOST_REGEX#", "scheme": "http|https", "method": "GET|HEAD", - "class": "Symfony\\Component\\Routing\\Route", + "class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\RouteStub", "defaults": { "name": "Joseph" }, diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.md index 5bfba18b2c814..c36d35c83e8ac 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.md +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.md @@ -1,10 +1,10 @@ - Path: /hello/{name} -- Path Regex: #^/hello(?:/(?P[a-z]+))?$#s +- Path Regex: #PATH_REGEX# - Host: localhost -- Host Regex: #^localhost$#si +- Host Regex: #HOST_REGEX# - Scheme: http|https - Method: GET|HEAD -- Class: Symfony\Component\Routing\Route +- Class: Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub - Defaults: - `name`: Joseph - Requirements: diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.txt b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.txt index 1c07ccde50119..ba7458d143c84 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.txt +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.txt @@ -1,10 +1,10 @@ Path /hello/{name} -Path Regex #^/hello(?:/(?P[a-z]+))?$#s +Path Regex #PATH_REGEX# Host localhost -Host Regex #^localhost$#si +Host Regex #HOST_REGEX# Scheme http|https Method GET|HEAD -Class Symfony\Component\Routing\Route +Class Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub Defaults name: Joseph Requirements name: [a-z]+ Options compiler_class: Symfony\Component\Routing\RouteCompiler diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.xml index b6040bdad160c..9ff531c92821a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_1.xml @@ -1,7 +1,7 @@ - - /hello/{name} - localhost + + /hello/{name} + localhost http https GET diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.json index 58caf26d537e7..e190ef0cbf89a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.json +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.json @@ -1,11 +1,11 @@ { "path": "\/name\/add", - "pathRegex": "#^\/name\/add$#s", + "pathRegex": "#PATH_REGEX#", "host": "localhost", - "hostRegex": "#^localhost$#si", + "hostRegex": "#HOST_REGEX#", "scheme": "http|https", "method": "PUT|POST", - "class": "Symfony\\Component\\Routing\\Route", + "class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\RouteStub", "defaults": [], "requirements": "NO CUSTOM", "options": { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.md index 0a3f84be17c70..1d776c5ffe49e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.md +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.md @@ -1,10 +1,10 @@ - Path: /name/add -- Path Regex: #^/name/add$#s +- Path Regex: #PATH_REGEX# - Host: localhost -- Host Regex: #^localhost$#si +- Host Regex: #HOST_REGEX# - Scheme: http|https - Method: PUT|POST -- Class: Symfony\Component\Routing\Route +- Class: Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub - Defaults: NONE - Requirements: NO CUSTOM - Options: diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.txt b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.txt index 560c474ae95c0..8e4e0cb009c3a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.txt +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.txt @@ -1,10 +1,10 @@ Path /name/add -Path Regex #^/name/add$#s +Path Regex #PATH_REGEX# Host localhost -Host Regex #^localhost$#si +Host Regex #HOST_REGEX# Scheme http|https Method PUT|POST -Class Symfony\Component\Routing\Route +Class Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub Defaults NONE Requirements NO CUSTOM Options compiler_class: Symfony\Component\Routing\RouteCompiler diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.xml index 0f94cf7c41764..584ab1b12de59 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_2.xml @@ -1,7 +1,7 @@ - - /name/add - localhost + + /name/add + localhost http https PUT diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_collection_1.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_collection_1.json index 350bffdb3a9c7..bd60070ed5cf4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_collection_1.json +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_collection_1.json @@ -1,12 +1,12 @@ { "route_1": { "path": "\/hello\/{name}", - "pathRegex": "#^\/hello(?:\/(?P[a-z]+))?$#s", + "pathRegex": "#PATH_REGEX#", "host": "localhost", - "hostRegex": "#^localhost$#si", + "hostRegex": "#HOST_REGEX#", "scheme": "http|https", "method": "GET|HEAD", - "class": "Symfony\\Component\\Routing\\Route", + "class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\RouteStub", "defaults": { "name": "Joseph" }, @@ -21,12 +21,12 @@ }, "route_2": { "path": "\/name\/add", - "pathRegex": "#^\/name\/add$#s", + "pathRegex": "#PATH_REGEX#", "host": "localhost", - "hostRegex": "#^localhost$#si", + "hostRegex": "#HOST_REGEX#", "scheme": "http|https", "method": "PUT|POST", - "class": "Symfony\\Component\\Routing\\Route", + "class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\RouteStub", "defaults": [], "requirements": "NO CUSTOM", "options": { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_collection_1.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_collection_1.md index 87efcc22e4718..f8b071d0ddac9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_collection_1.md +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_collection_1.md @@ -2,12 +2,12 @@ route_1 ------- - Path: /hello/{name} -- Path Regex: #^/hello(?:/(?P[a-z]+))?$#s +- Path Regex: #PATH_REGEX# - Host: localhost -- Host Regex: #^localhost$#si +- Host Regex: #HOST_REGEX# - Scheme: http|https - Method: GET|HEAD -- Class: Symfony\Component\Routing\Route +- Class: Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub - Defaults: - `name`: Joseph - Requirements: @@ -22,12 +22,12 @@ route_2 ------- - Path: /name/add -- Path Regex: #^/name/add$#s +- Path Regex: #PATH_REGEX# - Host: localhost -- Host Regex: #^localhost$#si +- Host Regex: #HOST_REGEX# - Scheme: http|https - Method: PUT|POST -- Class: Symfony\Component\Routing\Route +- Class: Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\RouteStub - Defaults: NONE - Requirements: NO CUSTOM - Options: diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_collection_1.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_collection_1.xml index 6d17820c3143d..666a53730dee0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_collection_1.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/route_collection_1.xml @@ -1,8 +1,8 @@ - - /hello/{name} - localhost + + /hello/{name} + localhost http https GET @@ -19,9 +19,9 @@ - - /name/add - localhost + + /name/add + localhost http https PUT diff --git a/src/Symfony/Component/Routing/RouteCompiler.php b/src/Symfony/Component/Routing/RouteCompiler.php index ecbc96422989a..244e2a9c35788 100644 --- a/src/Symfony/Component/Routing/RouteCompiler.php +++ b/src/Symfony/Component/Routing/RouteCompiler.php @@ -177,7 +177,7 @@ private static function compilePattern(Route $route, $pattern, $isHost) return array( 'staticPrefix' => 'text' === $tokens[0][0] ? $tokens[0][1] : '', - 'regex' => self::REGEX_DELIMITER.'^'.$regexp.'$'.self::REGEX_DELIMITER.'s'.($isHost ? 'i' : ''), + 'regex' => self::REGEX_DELIMITER.'^'.$regexp.'$'.self::REGEX_DELIMITER.'sD'.($isHost ? 'i' : ''), 'tokens' => array_reverse($tokens), 'variables' => $variables, ); diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php index a87f063af57ac..5b0703cb7fb84 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php @@ -23,13 +23,13 @@ public function match($rawPathinfo) $request = $this->request ?: $this->createRequest($pathinfo); // foo - if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?Pbaz|symfony)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?Pbaz|symfony)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo')), array ( 'def' => 'test',)); } if (0 === strpos($pathinfo, '/bar')) { // bar - if (preg_match('#^/bar/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/bar/(?P[^/]++)$#sD', $pathinfo, $matches)) { if (!in_array($this->context->getMethod(), array('GET', 'HEAD'))) { $allow = array_merge($allow, array('GET', 'HEAD')); goto not_bar; @@ -40,7 +40,7 @@ public function match($rawPathinfo) not_bar: // barhead - if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P[^/]++)$#sD', $pathinfo, $matches)) { if (!in_array($this->context->getMethod(), array('GET', 'HEAD'))) { $allow = array_merge($allow, array('GET', 'HEAD')); goto not_barhead; @@ -72,12 +72,12 @@ public function match($rawPathinfo) } // baz4 - if (preg_match('#^/test/(?P[^/]++)/$#s', $pathinfo, $matches)) { + if (preg_match('#^/test/(?P[^/]++)/$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'baz4')), array ()); } // baz5 - if (preg_match('#^/test/(?P[^/]++)/$#s', $pathinfo, $matches)) { + if (preg_match('#^/test/(?P[^/]++)/$#sD', $pathinfo, $matches)) { if ($this->context->getMethod() != 'POST') { $allow[] = 'POST'; goto not_baz5; @@ -88,7 +88,7 @@ public function match($rawPathinfo) not_baz5: // baz.baz6 - if (preg_match('#^/test/(?P[^/]++)/$#s', $pathinfo, $matches)) { + if (preg_match('#^/test/(?P[^/]++)/$#sD', $pathinfo, $matches)) { if ($this->context->getMethod() != 'PUT') { $allow[] = 'PUT'; goto not_bazbaz6; @@ -106,7 +106,7 @@ public function match($rawPathinfo) } // quoter - if (preg_match('#^/(?P[\']+)$#s', $pathinfo, $matches)) { + if (preg_match('#^/(?P[\']+)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'quoter')), array ()); } @@ -118,30 +118,30 @@ public function match($rawPathinfo) if (0 === strpos($pathinfo, '/a')) { if (0 === strpos($pathinfo, '/a/b\'b')) { // foo1 - if (preg_match('#^/a/b\'b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/a/b\'b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo1')), array ()); } // bar1 - if (preg_match('#^/a/b\'b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/a/b\'b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar1')), array ()); } } // overridden - if (preg_match('#^/a/(?P.*)$#s', $pathinfo, $matches)) { + if (preg_match('#^/a/(?P.*)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'overridden')), array ()); } if (0 === strpos($pathinfo, '/a/b\'b')) { // foo2 - if (preg_match('#^/a/b\'b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/a/b\'b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo2')), array ()); } // bar2 - if (preg_match('#^/a/b\'b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/a/b\'b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar2')), array ()); } @@ -151,7 +151,7 @@ public function match($rawPathinfo) if (0 === strpos($pathinfo, '/multi')) { // helloWorld - if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P[^/]++))?$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P[^/]++))?$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'helloWorld')), array ( 'who' => 'World!',)); } @@ -168,12 +168,12 @@ public function match($rawPathinfo) } // foo3 - if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo3')), array ()); } // bar3 - if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar3')), array ()); } @@ -184,7 +184,7 @@ public function match($rawPathinfo) } // foo4 - if (preg_match('#^/aba/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/aba/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo4')), array ()); } @@ -192,7 +192,7 @@ public function match($rawPathinfo) $host = $this->context->getHost(); - if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) { + if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) { // route1 if ('/route1' === $pathinfo) { return array('_route' => 'route1'); @@ -205,7 +205,7 @@ public function match($rawPathinfo) } - if (preg_match('#^b\\.example\\.com$#si', $host, $hostMatches)) { + if (preg_match('#^b\\.example\\.com$#sDi', $host, $hostMatches)) { // route3 if ('/c2/route3' === $pathinfo) { return array('_route' => 'route3'); @@ -213,7 +213,7 @@ public function match($rawPathinfo) } - if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) { + if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) { // route4 if ('/route4' === $pathinfo) { return array('_route' => 'route4'); @@ -221,7 +221,7 @@ public function match($rawPathinfo) } - if (preg_match('#^c\\.example\\.com$#si', $host, $hostMatches)) { + if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) { // route5 if ('/route5' === $pathinfo) { return array('_route' => 'route5'); @@ -234,7 +234,7 @@ public function match($rawPathinfo) return array('_route' => 'route6'); } - if (preg_match('#^(?P[^\\.]++)\\.example\\.com$#si', $host, $hostMatches)) { + if (preg_match('#^(?P[^\\.]++)\\.example\\.com$#sDi', $host, $hostMatches)) { if (0 === strpos($pathinfo, '/route1')) { // route11 if ('/route11' === $pathinfo) { @@ -247,12 +247,12 @@ public function match($rawPathinfo) } // route13 - if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route13')), array ()); } // route14 - if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route14')), array ( 'var1' => 'val',)); } @@ -260,9 +260,9 @@ public function match($rawPathinfo) } - if (preg_match('#^c\\.example\\.com$#si', $host, $hostMatches)) { + if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) { // route15 - if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'route15')), array ()); } @@ -270,7 +270,7 @@ public function match($rawPathinfo) if (0 === strpos($pathinfo, '/route1')) { // route16 - if (0 === strpos($pathinfo, '/route16') && preg_match('#^/route16/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/route16') && preg_match('#^/route16/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'route16')), array ( 'var1' => 'val',)); } @@ -289,12 +289,12 @@ public function match($rawPathinfo) if (0 === strpos($pathinfo, '/a/b')) { // b - if (preg_match('#^/a/b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/a/b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'b')), array ()); } // c - if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'c')), array ()); } diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php index 7ec89b8e2f457..a7e7ce75be537 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php @@ -23,13 +23,13 @@ public function match($rawPathinfo) $request = $this->request ?: $this->createRequest($pathinfo); // foo - if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?Pbaz|symfony)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?Pbaz|symfony)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo')), array ( 'def' => 'test',)); } if (0 === strpos($pathinfo, '/bar')) { // bar - if (preg_match('#^/bar/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/bar/(?P[^/]++)$#sD', $pathinfo, $matches)) { if (!in_array($this->context->getMethod(), array('GET', 'HEAD'))) { $allow = array_merge($allow, array('GET', 'HEAD')); goto not_bar; @@ -40,7 +40,7 @@ public function match($rawPathinfo) not_bar: // barhead - if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P[^/]++)$#sD', $pathinfo, $matches)) { if (!in_array($this->context->getMethod(), array('GET', 'HEAD'))) { $allow = array_merge($allow, array('GET', 'HEAD')); goto not_barhead; @@ -81,7 +81,7 @@ public function match($rawPathinfo) } // baz4 - if (preg_match('#^/test/(?P[^/]++)/?$#s', $pathinfo, $matches)) { + if (preg_match('#^/test/(?P[^/]++)/?$#sD', $pathinfo, $matches)) { if ('/' === substr($pathinfo, -1)) { // no-op } elseif (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) { @@ -95,7 +95,7 @@ public function match($rawPathinfo) not_baz4: // baz5 - if (preg_match('#^/test/(?P[^/]++)/$#s', $pathinfo, $matches)) { + if (preg_match('#^/test/(?P[^/]++)/$#sD', $pathinfo, $matches)) { if ($this->context->getMethod() != 'POST') { $allow[] = 'POST'; goto not_baz5; @@ -106,7 +106,7 @@ public function match($rawPathinfo) not_baz5: // baz.baz6 - if (preg_match('#^/test/(?P[^/]++)/$#s', $pathinfo, $matches)) { + if (preg_match('#^/test/(?P[^/]++)/$#sD', $pathinfo, $matches)) { if ($this->context->getMethod() != 'PUT') { $allow[] = 'PUT'; goto not_bazbaz6; @@ -124,7 +124,7 @@ public function match($rawPathinfo) } // quoter - if (preg_match('#^/(?P[\']+)$#s', $pathinfo, $matches)) { + if (preg_match('#^/(?P[\']+)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'quoter')), array ()); } @@ -136,30 +136,30 @@ public function match($rawPathinfo) if (0 === strpos($pathinfo, '/a')) { if (0 === strpos($pathinfo, '/a/b\'b')) { // foo1 - if (preg_match('#^/a/b\'b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/a/b\'b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo1')), array ()); } // bar1 - if (preg_match('#^/a/b\'b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/a/b\'b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar1')), array ()); } } // overridden - if (preg_match('#^/a/(?P.*)$#s', $pathinfo, $matches)) { + if (preg_match('#^/a/(?P.*)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'overridden')), array ()); } if (0 === strpos($pathinfo, '/a/b\'b')) { // foo2 - if (preg_match('#^/a/b\'b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/a/b\'b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo2')), array ()); } // bar2 - if (preg_match('#^/a/b\'b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/a/b\'b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar2')), array ()); } @@ -169,7 +169,7 @@ public function match($rawPathinfo) if (0 === strpos($pathinfo, '/multi')) { // helloWorld - if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P[^/]++))?$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P[^/]++))?$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'helloWorld')), array ( 'who' => 'World!',)); } @@ -195,12 +195,12 @@ public function match($rawPathinfo) } // foo3 - if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo3')), array ()); } // bar3 - if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/(?P<_locale>[^/]++)/b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'bar3')), array ()); } @@ -211,7 +211,7 @@ public function match($rawPathinfo) } // foo4 - if (preg_match('#^/aba/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/aba/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'foo4')), array ()); } @@ -219,7 +219,7 @@ public function match($rawPathinfo) $host = $this->context->getHost(); - if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) { + if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) { // route1 if ('/route1' === $pathinfo) { return array('_route' => 'route1'); @@ -232,7 +232,7 @@ public function match($rawPathinfo) } - if (preg_match('#^b\\.example\\.com$#si', $host, $hostMatches)) { + if (preg_match('#^b\\.example\\.com$#sDi', $host, $hostMatches)) { // route3 if ('/c2/route3' === $pathinfo) { return array('_route' => 'route3'); @@ -240,7 +240,7 @@ public function match($rawPathinfo) } - if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) { + if (preg_match('#^a\\.example\\.com$#sDi', $host, $hostMatches)) { // route4 if ('/route4' === $pathinfo) { return array('_route' => 'route4'); @@ -248,7 +248,7 @@ public function match($rawPathinfo) } - if (preg_match('#^c\\.example\\.com$#si', $host, $hostMatches)) { + if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) { // route5 if ('/route5' === $pathinfo) { return array('_route' => 'route5'); @@ -261,7 +261,7 @@ public function match($rawPathinfo) return array('_route' => 'route6'); } - if (preg_match('#^(?P[^\\.]++)\\.example\\.com$#si', $host, $hostMatches)) { + if (preg_match('#^(?P[^\\.]++)\\.example\\.com$#sDi', $host, $hostMatches)) { if (0 === strpos($pathinfo, '/route1')) { // route11 if ('/route11' === $pathinfo) { @@ -274,12 +274,12 @@ public function match($rawPathinfo) } // route13 - if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/route13') && preg_match('#^/route13/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route13')), array ()); } // route14 - if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/route14') && preg_match('#^/route14/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($hostMatches, $matches, array('_route' => 'route14')), array ( 'var1' => 'val',)); } @@ -287,9 +287,9 @@ public function match($rawPathinfo) } - if (preg_match('#^c\\.example\\.com$#si', $host, $hostMatches)) { + if (preg_match('#^c\\.example\\.com$#sDi', $host, $hostMatches)) { // route15 - if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/route15') && preg_match('#^/route15/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'route15')), array ()); } @@ -297,7 +297,7 @@ public function match($rawPathinfo) if (0 === strpos($pathinfo, '/route1')) { // route16 - if (0 === strpos($pathinfo, '/route16') && preg_match('#^/route16/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/route16') && preg_match('#^/route16/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'route16')), array ( 'var1' => 'val',)); } @@ -316,12 +316,12 @@ public function match($rawPathinfo) if (0 === strpos($pathinfo, '/a/b')) { // b - if (preg_match('#^/a/b/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/a/b/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'b')), array ()); } // c - if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'c')), array ()); } diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher3.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher3.php index f5234dd43bbec..09b5876bc9580 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher3.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher3.php @@ -29,7 +29,7 @@ public function match($rawPathinfo) } // dynamic - if (preg_match('#^/rootprefix/(?P[^/]++)$#s', $pathinfo, $matches)) { + if (preg_match('#^/rootprefix/(?P[^/]++)$#sD', $pathinfo, $matches)) { return $this->mergeDefaults(array_replace($matches, array('_route' => 'dynamic')), array ()); } diff --git a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php index de79a073eaf0c..ab8fcd39c9dd4 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php @@ -162,6 +162,18 @@ public function testMatchSpecialRouteName() $this->assertEquals(array('_route' => '$péß^a|'), $matcher->match('/bar')); } + /** + * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException + */ + public function testTrailingEncodedNewlineIsNotOverlooked() + { + $collection = new RouteCollection(); + $collection->add('foo', new Route('/foo')); + + $matcher = new UrlMatcher($collection, new RequestContext()); + $matcher->match('/foo%0a'); + } + public function testMatchNonAlpha() { $collection = new RouteCollection(); diff --git a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php index 8d89dae0f4a92..184eea048d17f 100644 --- a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php +++ b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php @@ -38,7 +38,7 @@ public function provideCompileData() array( 'Static route', array('/foo'), - '/foo', '#^/foo$#s', array(), array( + '/foo', '#^/foo$#sD', array(), array( array('text', '/foo'), ), ), @@ -46,7 +46,7 @@ public function provideCompileData() array( 'Route with a variable', array('/foo/{bar}'), - '/foo', '#^/foo/(?P[^/]++)$#s', array('bar'), array( + '/foo', '#^/foo/(?P[^/]++)$#sD', array('bar'), array( array('variable', '/', '[^/]++', 'bar'), array('text', '/foo'), ), @@ -55,7 +55,7 @@ public function provideCompileData() array( 'Route with a variable that has a default value', array('/foo/{bar}', array('bar' => 'bar')), - '/foo', '#^/foo(?:/(?P[^/]++))?$#s', array('bar'), array( + '/foo', '#^/foo(?:/(?P[^/]++))?$#sD', array('bar'), array( array('variable', '/', '[^/]++', 'bar'), array('text', '/foo'), ), @@ -64,7 +64,7 @@ public function provideCompileData() array( 'Route with several variables', array('/foo/{bar}/{foobar}'), - '/foo', '#^/foo/(?P[^/]++)/(?P[^/]++)$#s', array('bar', 'foobar'), array( + '/foo', '#^/foo/(?P[^/]++)/(?P[^/]++)$#sD', array('bar', 'foobar'), array( array('variable', '/', '[^/]++', 'foobar'), array('variable', '/', '[^/]++', 'bar'), array('text', '/foo'), @@ -74,7 +74,7 @@ public function provideCompileData() array( 'Route with several variables that have default values', array('/foo/{bar}/{foobar}', array('bar' => 'bar', 'foobar' => '')), - '/foo', '#^/foo(?:/(?P[^/]++)(?:/(?P[^/]++))?)?$#s', array('bar', 'foobar'), array( + '/foo', '#^/foo(?:/(?P[^/]++)(?:/(?P[^/]++))?)?$#sD', array('bar', 'foobar'), array( array('variable', '/', '[^/]++', 'foobar'), array('variable', '/', '[^/]++', 'bar'), array('text', '/foo'), @@ -84,7 +84,7 @@ public function provideCompileData() array( 'Route with several variables but some of them have no default values', array('/foo/{bar}/{foobar}', array('bar' => 'bar')), - '/foo', '#^/foo/(?P[^/]++)/(?P[^/]++)$#s', array('bar', 'foobar'), array( + '/foo', '#^/foo/(?P[^/]++)/(?P[^/]++)$#sD', array('bar', 'foobar'), array( array('variable', '/', '[^/]++', 'foobar'), array('variable', '/', '[^/]++', 'bar'), array('text', '/foo'), @@ -94,7 +94,7 @@ public function provideCompileData() array( 'Route with an optional variable as the first segment', array('/{bar}', array('bar' => 'bar')), - '', '#^/(?P[^/]++)?$#s', array('bar'), array( + '', '#^/(?P[^/]++)?$#sD', array('bar'), array( array('variable', '/', '[^/]++', 'bar'), ), ), @@ -102,7 +102,7 @@ public function provideCompileData() array( 'Route with a requirement of 0', array('/{bar}', array('bar' => null), array('bar' => '0')), - '', '#^/(?P0)?$#s', array('bar'), array( + '', '#^/(?P0)?$#sD', array('bar'), array( array('variable', '/', '0', 'bar'), ), ), @@ -110,7 +110,7 @@ public function provideCompileData() array( 'Route with an optional variable as the first segment with requirements', array('/{bar}', array('bar' => 'bar'), array('bar' => '(foo|bar)')), - '', '#^/(?P(foo|bar))?$#s', array('bar'), array( + '', '#^/(?P(foo|bar))?$#sD', array('bar'), array( array('variable', '/', '(foo|bar)', 'bar'), ), ), @@ -118,7 +118,7 @@ public function provideCompileData() array( 'Route with only optional variables', array('/{foo}/{bar}', array('foo' => 'foo', 'bar' => 'bar')), - '', '#^/(?P[^/]++)?(?:/(?P[^/]++))?$#s', array('foo', 'bar'), array( + '', '#^/(?P[^/]++)?(?:/(?P[^/]++))?$#sD', array('foo', 'bar'), array( array('variable', '/', '[^/]++', 'bar'), array('variable', '/', '[^/]++', 'foo'), ), @@ -127,7 +127,7 @@ public function provideCompileData() array( 'Route with a variable in last position', array('/foo-{bar}'), - '/foo', '#^/foo\-(?P[^/]++)$#s', array('bar'), array( + '/foo', '#^/foo\-(?P[^/]++)$#sD', array('bar'), array( array('variable', '-', '[^/]++', 'bar'), array('text', '/foo'), ), @@ -136,7 +136,7 @@ public function provideCompileData() array( 'Route with nested placeholders', array('/{static{var}static}'), - '/{static', '#^/\{static(?P[^/]+)static\}$#s', array('var'), array( + '/{static', '#^/\{static(?P[^/]+)static\}$#sD', array('var'), array( array('text', 'static}'), array('variable', '', '[^/]+', 'var'), array('text', '/{static'), @@ -146,7 +146,7 @@ public function provideCompileData() array( 'Route without separator between variables', array('/{w}{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => '(y|Y)')), - '', '#^/(?P[^/\.]+)(?P[^/\.]+)(?P(y|Y))(?:(?P[^/\.]++)(?:\.(?P<_format>[^/]++))?)?$#s', array('w', 'x', 'y', 'z', '_format'), array( + '', '#^/(?P[^/\.]+)(?P[^/\.]+)(?P(y|Y))(?:(?P[^/\.]++)(?:\.(?P<_format>[^/]++))?)?$#sD', array('w', 'x', 'y', 'z', '_format'), array( array('variable', '.', '[^/]++', '_format'), array('variable', '', '[^/\.]++', 'z'), array('variable', '', '(y|Y)', 'y'), @@ -158,7 +158,7 @@ public function provideCompileData() array( 'Route with a format', array('/foo/{bar}.{_format}'), - '/foo', '#^/foo/(?P[^/\.]++)\.(?P<_format>[^/]++)$#s', array('bar', '_format'), array( + '/foo', '#^/foo/(?P[^/\.]++)\.(?P<_format>[^/]++)$#sD', array('bar', '_format'), array( array('variable', '.', '[^/]++', '_format'), array('variable', '/', '[^/\.]++', 'bar'), array('text', '/foo'), @@ -221,21 +221,21 @@ public function provideCompileWithHostData() array( 'Route with host pattern', array('/hello', array(), array(), array(), 'www.example.com'), - '/hello', '#^/hello$#s', array(), array(), array( + '/hello', '#^/hello$#sD', array(), array(), array( array('text', '/hello'), ), - '#^www\.example\.com$#si', array(), array( + '#^www\.example\.com$#sDi', array(), array( array('text', 'www.example.com'), ), ), array( 'Route with host pattern and some variables', array('/hello/{name}', array(), array(), array(), 'www.example.{tld}'), - '/hello', '#^/hello/(?P[^/]++)$#s', array('tld', 'name'), array('name'), array( + '/hello', '#^/hello/(?P[^/]++)$#sD', array('tld', 'name'), array('name'), array( array('variable', '/', '[^/]++', 'name'), array('text', '/hello'), ), - '#^www\.example\.(?P[^\.]++)$#si', array('tld'), array( + '#^www\.example\.(?P[^\.]++)$#sDi', array('tld'), array( array('variable', '.', '[^\.]++', 'tld'), array('text', 'www.example'), ), @@ -243,10 +243,10 @@ public function provideCompileWithHostData() array( 'Route with variable at beginning of host', array('/hello', array(), array(), array(), '{locale}.example.{tld}'), - '/hello', '#^/hello$#s', array('locale', 'tld'), array(), array( + '/hello', '#^/hello$#sD', array('locale', 'tld'), array(), array( array('text', '/hello'), ), - '#^(?P[^\.]++)\.example\.(?P[^\.]++)$#si', array('locale', 'tld'), array( + '#^(?P[^\.]++)\.example\.(?P[^\.]++)$#sDi', array('locale', 'tld'), array( array('variable', '.', '[^\.]++', 'tld'), array('text', '.example'), array('variable', '', '[^\.]++', 'locale'), @@ -255,10 +255,10 @@ public function provideCompileWithHostData() array( 'Route with host variables that has a default value', array('/hello', array('locale' => 'a', 'tld' => 'b'), array(), array(), '{locale}.example.{tld}'), - '/hello', '#^/hello$#s', array('locale', 'tld'), array(), array( + '/hello', '#^/hello$#sD', array('locale', 'tld'), array(), array( array('text', '/hello'), ), - '#^(?P[^\.]++)\.example\.(?P[^\.]++)$#si', array('locale', 'tld'), array( + '#^(?P[^\.]++)\.example\.(?P[^\.]++)$#sDi', array('locale', 'tld'), array( array('variable', '.', '[^\.]++', 'tld'), array('text', '.example'), array('variable', '', '[^\.]++', 'locale'), diff --git a/src/Symfony/Component/Routing/Tests/RouteTest.php b/src/Symfony/Component/Routing/Tests/RouteTest.php index 18c0206474a34..edaf3b8cfddf3 100644 --- a/src/Symfony/Component/Routing/Tests/RouteTest.php +++ b/src/Symfony/Component/Routing/Tests/RouteTest.php @@ -272,7 +272,7 @@ public function testSerializeWhenCompiled() */ public function testSerializedRepresentationKeepsWorking() { - $serialized = 'C:31:"Symfony\Component\Routing\Route":934:{a:8:{s:4:"path";s:13:"/prefix/{foo}";s:4:"host";s:20:"{locale}.example.net";s:8:"defaults";a:1:{s:3:"foo";s:7:"default";}s:12:"requirements";a:1:{s:3:"foo";s:3:"\d+";}s:7:"options";a:1:{s:14:"compiler_class";s:39:"Symfony\Component\Routing\RouteCompiler";}s:7:"schemes";a:0:{}s:7:"methods";a:0:{}s:8:"compiled";C:39:"Symfony\Component\Routing\CompiledRoute":569:{a:8:{s:4:"vars";a:2:{i:0;s:6:"locale";i:1;s:3:"foo";}s:11:"path_prefix";s:7:"/prefix";s:10:"path_regex";s:30:"#^/prefix(?:/(?P\d+))?$#s";s:11:"path_tokens";a:2:{i:0;a:4:{i:0;s:8:"variable";i:1;s:1:"/";i:2;s:3:"\d+";i:3;s:3:"foo";}i:1;a:2:{i:0;s:4:"text";i:1;s:7:"/prefix";}}s:9:"path_vars";a:1:{i:0;s:3:"foo";}s:10:"host_regex";s:39:"#^(?P[^\.]++)\.example\.net$#si";s:11:"host_tokens";a:2:{i:0;a:2:{i:0;s:4:"text";i:1;s:12:".example.net";}i:1;a:4:{i:0;s:8:"variable";i:1;s:0:"";i:2;s:7:"[^\.]++";i:3;s:6:"locale";}}s:9:"host_vars";a:1:{i:0;s:6:"locale";}}}}}'; + $serialized = 'C:31:"Symfony\Component\Routing\Route":936:{a:8:{s:4:"path";s:13:"/prefix/{foo}";s:4:"host";s:20:"{locale}.example.net";s:8:"defaults";a:1:{s:3:"foo";s:7:"default";}s:12:"requirements";a:1:{s:3:"foo";s:3:"\d+";}s:7:"options";a:1:{s:14:"compiler_class";s:39:"Symfony\Component\Routing\RouteCompiler";}s:7:"schemes";a:0:{}s:7:"methods";a:0:{}s:8:"compiled";C:39:"Symfony\Component\Routing\CompiledRoute":571:{a:8:{s:4:"vars";a:2:{i:0;s:6:"locale";i:1;s:3:"foo";}s:11:"path_prefix";s:7:"/prefix";s:10:"path_regex";s:31:"#^/prefix(?:/(?P\d+))?$#sD";s:11:"path_tokens";a:2:{i:0;a:4:{i:0;s:8:"variable";i:1;s:1:"/";i:2;s:3:"\d+";i:3;s:3:"foo";}i:1;a:2:{i:0;s:4:"text";i:1;s:7:"/prefix";}}s:9:"path_vars";a:1:{i:0;s:3:"foo";}s:10:"host_regex";s:40:"#^(?P[^\.]++)\.example\.net$#sDi";s:11:"host_tokens";a:2:{i:0;a:2:{i:0;s:4:"text";i:1;s:12:".example.net";}i:1;a:4:{i:0;s:8:"variable";i:1;s:0:"";i:2;s:7:"[^\.]++";i:3;s:6:"locale";}}s:9:"host_vars";a:1:{i:0;s:6:"locale";}}}}}'; $unserialized = unserialize($serialized); $route = new Route('/prefix/{foo}', array('foo' => 'default'), array('foo' => '\d+')); From 3a470c4ecf25f921a36a549bca3205bb5d1cba77 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 4 Feb 2018 17:22:42 +0100 Subject: [PATCH 050/166] [Process] Check PHP_BINDIR before $PATH in PhpExecutableFinder --- src/Symfony/Component/Process/PhpExecutableFinder.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Process/PhpExecutableFinder.php b/src/Symfony/Component/Process/PhpExecutableFinder.php index fb297825fe364..25415eda793bd 100644 --- a/src/Symfony/Component/Process/PhpExecutableFinder.php +++ b/src/Symfony/Component/Process/PhpExecutableFinder.php @@ -62,6 +62,10 @@ public function find($includeArgs = true) } } + if (is_executable($php = PHP_BINDIR.'/php'.('\\' === DIRECTORY_SEPARATOR ? '.exe' : ''))) { + return $php; + } + $dirs = array(PHP_BINDIR); if ('\\' === DIRECTORY_SEPARATOR) { $dirs[] = 'C:\xampp\php\\'; From ae252916108f3006ebdc26545f130442054f0eec Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 4 Feb 2018 18:41:24 +0100 Subject: [PATCH 051/166] [HttpKernel] fix FC --- src/Symfony/Component/HttpKernel/Tests/ClientTest.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Tests/ClientTest.php b/src/Symfony/Component/HttpKernel/Tests/ClientTest.php index 1ac72c73595c2..051d5d47c0265 100644 --- a/src/Symfony/Component/HttpKernel/Tests/ClientTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/ClientTest.php @@ -97,6 +97,7 @@ public function testFilterResponseSupportsStreamedResponses() public function testUploadedFile() { $source = tempnam(sys_get_temp_dir(), 'source'); + file_put_contents($source, '1'); $target = sys_get_temp_dir().'/sf.moved.file'; @unlink($target); @@ -104,8 +105,8 @@ public function testUploadedFile() $client = new Client($kernel); $files = array( - array('tmp_name' => $source, 'name' => 'original', 'type' => 'mime/original', 'size' => 123, 'error' => UPLOAD_ERR_OK), - new UploadedFile($source, 'original', 'mime/original', 123, UPLOAD_ERR_OK, true), + array('tmp_name' => $source, 'name' => 'original', 'type' => 'mime/original', 'size' => 1, 'error' => UPLOAD_ERR_OK), + new UploadedFile($source, 'original', 'mime/original', 1, UPLOAD_ERR_OK, true), ); $file = null; @@ -120,7 +121,7 @@ public function testUploadedFile() $this->assertEquals('original', $file->getClientOriginalName()); $this->assertEquals('mime/original', $file->getClientMimeType()); - $this->assertEquals('123', $file->getClientSize()); + $this->assertSame(1, $file->getClientSize()); $this->assertTrue($file->isValid()); } From f167b505c427625fc283a1720be76a83262ae9e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 5 Feb 2018 08:51:00 +0100 Subject: [PATCH 052/166] [DI] minor: use a strict comparision in setDecoratedService --- src/Symfony/Component/DependencyInjection/Definition.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php index 6f2a3c7e82a7f..8286e9d1e70cd 100644 --- a/src/Symfony/Component/DependencyInjection/Definition.php +++ b/src/Symfony/Component/DependencyInjection/Definition.php @@ -144,7 +144,7 @@ public function setFactoryMethod($factoryMethod) */ public function setDecoratedService($id, $renamedId = null) { - if ($renamedId && $id == $renamedId) { + if ($renamedId && $id === $renamedId) { throw new \InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id)); } From 5f9471ef47c0f9e4a2d67dce797c653a87534add Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 5 Feb 2018 16:46:42 +0100 Subject: [PATCH 053/166] use libsodium to run Argon2i related tests --- .travis.yml | 8 ++++++++ .../DependencyInjection/Fixtures/yml/argon2i_encoder.yml | 2 +- .../Tests/Functional/UserPasswordEncoderCommandTest.php | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 245b37487624a..8cbcc71c82525 100644 --- a/.travis.yml +++ b/.travis.yml @@ -149,7 +149,15 @@ before_install: ([[ $deps ]] || tfold ext.symfony_debug 'cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo extension = $(pwd)/modules/symfony_debug.so >> '"$INI") tfold ext.apcu tpecl apcu-4.0.11 apcu.so elif [[ ! $skip && $PHP = 7.* ]]; then + # install libsodium + if [[ ! -e ~/php-ext/$(php -r "echo basename(ini_get('extension_dir'));")/libsodium/sodium.so ]]; then + sudo add-apt-repository ppa:ondrej/php -y + sudo apt-get update -q + sudo apt-get install libsodium-dev -y + fi + tfold ext.apcu tpecl apcu-5.1.6 apcu.so + tfold ext.libsodium tpecl libsodium sodium.so tfold ext.mongodb tpecl mongodb-1.4.0RC1 mongodb.so fi diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/argon2i_encoder.yml b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/argon2i_encoder.yml index a51e766005456..6a1f925160fbf 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/argon2i_encoder.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/argon2i_encoder.yml @@ -1,6 +1,6 @@ security: encoders: - JMS\FooBundle\Entity\User6: + JMS\FooBundle\Entity\User7: algorithm: argon2i providers: diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php index fa0be42c5d940..01b2ce303acfa 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php @@ -86,7 +86,7 @@ public function testEncodePasswordArgon2i() $this->assertContains('Password encoding succeeded', $output); $encoder = new Argon2iPasswordEncoder(); - preg_match('# Encoded password\s+(\$argon2i\$[\w\d,=\$+\/]+={0,2})\s+#', $output, $matches); + preg_match('# Encoded password\s+(\$argon2id\$[\w\d,=\$+\/]+={0,2})\s+#', $output, $matches); $hash = $matches[1]; $this->assertTrue($encoder->isPasswordValid($hash, 'password', null)); } @@ -272,7 +272,7 @@ protected function tearDown() private function setupArgon2i() { putenv('COLUMNS='.(119 + strlen(PHP_EOL))); - $kernel = $this->createKernel(array('test_case' => 'PasswordEncode', 'root_config' => 'argon2i')); + $kernel = $this->createKernel(array('test_case' => 'PasswordEncode', 'root_config' => 'argon2i.yml')); $kernel->boot(); $application = new Application($kernel); From 899ead2b66639c8fdc49c2ce1e1e80424a27943d Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Tue, 6 Feb 2018 07:47:25 -0200 Subject: [PATCH 054/166] Fix misspelling variable --- src/Symfony/Component/HttpFoundation/Tests/RequestTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index 5dad4057612d0..96f87958ed9c5 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -1982,11 +1982,11 @@ public function testMethodSafeChecksCacheable() /** * @dataProvider methodCacheableProvider */ - public function testMethodCacheable($method, $chacheable) + public function testMethodCacheable($method, $cacheable) { $request = new Request(); $request->setMethod($method); - $this->assertEquals($chacheable, $request->isMethodCacheable()); + $this->assertEquals($cacheable, $request->isMethodCacheable()); } public function methodCacheableProvider() From 54253ecfff7fc0a6b01c0e402490ce5cd916bbfb Mon Sep 17 00:00:00 2001 From: Jared Farrish Date: Sat, 27 Jan 2018 14:03:37 -0600 Subject: [PATCH 055/166] PhpDocExtractor::getTypes() throws fatal error when type omitted --- .../PropertyInfo/Extractor/PhpDocExtractor.php | 4 +++- .../Tests/Extractors/PhpDocExtractorTest.php | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php index 2ce31a0170669..a0d6f2e5e1034 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php @@ -131,7 +131,9 @@ public function getTypes($class, $property, array $context = array()) $types = array(); /** @var DocBlock\Tags\Var_|DocBlock\Tags\Return_|DocBlock\Tags\Param $tag */ foreach ($docBlock->getTagsByName($tag) as $tag) { - $types = array_merge($types, $this->phpDocTypeHelper->getTypes($tag->getType())); + if ($tag && null !== $tag->getType()) { + $types = array_merge($types, $this->phpDocTypeHelper->getTypes($tag->getType())); + } } if (!isset($types[0])) { diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php index 9cc0a8d6e1749..f16e29242cdfa 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php @@ -40,6 +40,11 @@ public function testExtract($property, array $type = null, $shortDescription, $l $this->assertSame($longDescription, $this->extractor->getLongDescription('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', $property)); } + public function testParamTagTypeIsOmitted() + { + $this->assertNull($this->extractor->getTypes(OmittedParamTagTypeDocBlock::class, 'omittedType')); + } + /** * @dataProvider typesWithCustomPrefixesProvider */ @@ -176,3 +181,13 @@ class EmptyDocBlock { public $foo; } + +class OmittedParamTagTypeDocBlock +{ + /** + * @param $omittedTagType + */ + public function setOmittedType(array $omittedTagType) + { + } +} From 8f0e47f6361399305c378407480d9c5575f02ca6 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Mon, 5 Feb 2018 09:49:20 +0100 Subject: [PATCH 056/166] [WebProfilerBundle] Fix sub request link --- .../Resources/views/Collector/request.html.twig | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig index 8f94f6f5f0bd3..903d009c98225 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -271,9 +271,7 @@
{% for child in profile.children %}

- - {{ helper.set_handler(child.getcollector('request').controller) }} - + {{ helper.set_handler(child.getcollector('request').controller) }} (token = {{ child.token }})

From c8465ed97f00d18a11161215dda7801dc1cc205f Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Wed, 10 Jan 2018 18:42:09 +0100 Subject: [PATCH 057/166] [TwigBundle] Register TwigBridge extensions first --- .../Compiler/TwigEnvironmentPass.php | 19 +++- .../Compiler/TwigEnvironmentPassTest.php | 89 +++++++++++++++++++ 2 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigEnvironmentPassTest.php diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TwigEnvironmentPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TwigEnvironmentPass.php index f520ab11f0096..d5e6cb6c4acb2 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TwigEnvironmentPass.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TwigEnvironmentPass.php @@ -34,11 +34,22 @@ public function process(ContainerBuilder $container) // For instance, global variable definitions must be registered // afterward. If not, the globals from the extensions will never // be registered. - $calls = $definition->getMethodCalls(); - $definition->setMethodCalls(array()); + $currentMethodCalls = $definition->getMethodCalls(); + $twigBridgeExtensionsMethodCalls = array(); + $othersExtensionsMethodCalls = array(); foreach ($container->findTaggedServiceIds('twig.extension', true) as $id => $attributes) { - $definition->addMethodCall('addExtension', array(new Reference($id))); + $methodCall = array('addExtension', array(new Reference($id))); + $extensionClass = $container->getDefinition($id)->getClass(); + + if (is_string($extensionClass) && 0 === strpos($extensionClass, 'Symfony\Bridge\Twig\Extension')) { + $twigBridgeExtensionsMethodCalls[] = $methodCall; + } else { + $othersExtensionsMethodCalls[] = $methodCall; + } + } + + if (!empty($twigBridgeExtensionsMethodCalls) || !empty($othersExtensionsMethodCalls)) { + $definition->setMethodCalls(array_merge($twigBridgeExtensionsMethodCalls, $othersExtensionsMethodCalls, $currentMethodCalls)); } - $definition->setMethodCalls(array_merge($definition->getMethodCalls(), $calls)); } } diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigEnvironmentPassTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigEnvironmentPassTest.php new file mode 100644 index 0000000000000..b8fdf1af6afe8 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigEnvironmentPassTest.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\TwigBundle\Tests\DependencyInjection\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigEnvironmentPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +class TwigEnvironmentPassTest extends TestCase +{ + public function testTwigBridgeExtensionsAreRegisteredFirst() + { + $twigDefinition = new Definition('twig'); + + $containerBuilderMock = $this->getMockBuilder(ContainerBuilder::class) + ->setMethods(array('hasDefinition', 'get', 'findTaggedServiceIds', 'getDefinition')) + ->getMock(); + $containerBuilderMock + ->expects($this->once()) + ->method('hasDefinition') + ->with('twig') + ->will($this->returnValue(true)); + $containerBuilderMock + ->expects($this->once()) + ->method('findTaggedServiceIds') + ->with('twig.extension') + ->will($this->returnValue(array( + 'other_extension' => array( + array() + ), + 'twig_bridge_extension' => array( + array() + ) + ))); + + $otherExtensionDefinitionMock = $this->getMockBuilder(Definition::class) + ->setMethods(array('getClass')) + ->getMock(); + $otherExtensionDefinitionMock + ->expects($this->once()) + ->method('getClass') + ->will($this->returnValue('Foo\\Bar')); + + $twigExtensionDefinitionMock = $this->getMockBuilder(Definition::class) + ->setMethods(array('getClass')) + ->getMock(); + $twigExtensionDefinitionMock + ->expects($this->once()) + ->method('getClass') + ->will($this->returnValue('Symfony\\Bridge\\Twig\\Extension\\Foo')); + + $containerBuilderMock + ->expects($this->exactly(3)) + ->method('getDefinition') + ->withConsecutive(array('twig'), array('other_extension'), array('twig_bridge_extension')) + ->willReturnOnConsecutiveCalls( + $this->returnValue($twigDefinition), + $this->returnValue($otherExtensionDefinitionMock), + $this->returnValue($twigExtensionDefinitionMock) + ); + + $twigEnvironmentPass = new TwigEnvironmentPass(); + $twigEnvironmentPass->process($containerBuilderMock); + + $methodCalls = $twigDefinition->getMethodCalls(); + $this->assertCount(2, $methodCalls); + + $twigBridgeExtensionReference = $methodCalls[0][1][0]; + $this->assertInstanceOf(Reference::class, $twigBridgeExtensionReference); + /* @var Reference $twigBridgeExtensionReference */ + $this->assertEquals('twig_bridge_extension', $twigBridgeExtensionReference->__toString()); + + $otherExtensionReference = $methodCalls[1][1][0]; + $this->assertInstanceOf(Reference::class, $otherExtensionReference); + /* @var Reference $otherExtensionReference */ + $this->assertEquals('other_extension', $otherExtensionReference->__toString()); + } +} From 39e88ed3128933d7540eadd847d5650c8b52f5ba Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 7 Feb 2018 06:34:13 +0100 Subject: [PATCH 058/166] fixed CS --- .../Compiler/TwigEnvironmentPassTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigEnvironmentPassTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigEnvironmentPassTest.php index b8fdf1af6afe8..dfc5e3059d2bd 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigEnvironmentPassTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigEnvironmentPassTest.php @@ -37,11 +37,11 @@ public function testTwigBridgeExtensionsAreRegisteredFirst() ->with('twig.extension') ->will($this->returnValue(array( 'other_extension' => array( - array() + array(), ), 'twig_bridge_extension' => array( - array() - ) + array(), + ), ))); $otherExtensionDefinitionMock = $this->getMockBuilder(Definition::class) From 8bba882512b6f57545631f5cee96b02523a70967 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 7 Feb 2018 18:55:42 +0100 Subject: [PATCH 059/166] do not mock the container builder or definitions --- .../Compiler/TwigEnvironmentPassTest.php | 64 +++---------------- 1 file changed, 10 insertions(+), 54 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigEnvironmentPassTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigEnvironmentPassTest.php index dfc5e3059d2bd..0af3fe4b32532 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigEnvironmentPassTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigEnvironmentPassTest.php @@ -12,78 +12,34 @@ namespace Symfony\Bundle\TwigBundle\Tests\DependencyInjection\Compiler; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Twig\Extension\FormExtension; use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigEnvironmentPass; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; class TwigEnvironmentPassTest extends TestCase { public function testTwigBridgeExtensionsAreRegisteredFirst() { - $twigDefinition = new Definition('twig'); - - $containerBuilderMock = $this->getMockBuilder(ContainerBuilder::class) - ->setMethods(array('hasDefinition', 'get', 'findTaggedServiceIds', 'getDefinition')) - ->getMock(); - $containerBuilderMock - ->expects($this->once()) - ->method('hasDefinition') - ->with('twig') - ->will($this->returnValue(true)); - $containerBuilderMock - ->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('twig.extension') - ->will($this->returnValue(array( - 'other_extension' => array( - array(), - ), - 'twig_bridge_extension' => array( - array(), - ), - ))); - - $otherExtensionDefinitionMock = $this->getMockBuilder(Definition::class) - ->setMethods(array('getClass')) - ->getMock(); - $otherExtensionDefinitionMock - ->expects($this->once()) - ->method('getClass') - ->will($this->returnValue('Foo\\Bar')); - - $twigExtensionDefinitionMock = $this->getMockBuilder(Definition::class) - ->setMethods(array('getClass')) - ->getMock(); - $twigExtensionDefinitionMock - ->expects($this->once()) - ->method('getClass') - ->will($this->returnValue('Symfony\\Bridge\\Twig\\Extension\\Foo')); - - $containerBuilderMock - ->expects($this->exactly(3)) - ->method('getDefinition') - ->withConsecutive(array('twig'), array('other_extension'), array('twig_bridge_extension')) - ->willReturnOnConsecutiveCalls( - $this->returnValue($twigDefinition), - $this->returnValue($otherExtensionDefinitionMock), - $this->returnValue($twigExtensionDefinitionMock) - ); + $container = new ContainerBuilder(); + $twigDefinition = $container->register('twig'); + $container->register('other_extension', 'Foo\Bar') + ->addTag('twig.extension'); + $container->register('twig_bridge_extension', FormExtension::class) + ->addTag('twig.extension'); $twigEnvironmentPass = new TwigEnvironmentPass(); - $twigEnvironmentPass->process($containerBuilderMock); + $twigEnvironmentPass->process($container); $methodCalls = $twigDefinition->getMethodCalls(); $this->assertCount(2, $methodCalls); $twigBridgeExtensionReference = $methodCalls[0][1][0]; $this->assertInstanceOf(Reference::class, $twigBridgeExtensionReference); - /* @var Reference $twigBridgeExtensionReference */ - $this->assertEquals('twig_bridge_extension', $twigBridgeExtensionReference->__toString()); + $this->assertSame('twig_bridge_extension', (string) $twigBridgeExtensionReference); $otherExtensionReference = $methodCalls[1][1][0]; $this->assertInstanceOf(Reference::class, $otherExtensionReference); - /* @var Reference $otherExtensionReference */ - $this->assertEquals('other_extension', $otherExtensionReference->__toString()); + $this->assertSame('other_extension', (string) $otherExtensionReference); } } From 132bba6d2495a413ebafb444875e9638d801bafb Mon Sep 17 00:00:00 2001 From: David Maicher Date: Wed, 7 Feb 2018 20:03:36 +0100 Subject: [PATCH 060/166] [Cache][WebProfiler] fix collecting cache stats with sub-requests + allow clearing calls --- .../Component/Cache/Adapter/TraceableAdapter.php | 11 ++++++----- .../Cache/DataCollector/CacheDataCollector.php | 3 +-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php b/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php index e8563521baef8..98d0e526933b9 100644 --- a/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php @@ -204,11 +204,12 @@ public function reset() public function getCalls() { - try { - return $this->calls; - } finally { - $this->calls = array(); - } + return $this->calls; + } + + public function clearCalls() + { + $this->calls = array(); } protected function start($name) diff --git a/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php b/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php index 62d502f01fd6b..ceef45aa0b185 100644 --- a/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php +++ b/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php @@ -57,8 +57,7 @@ public function reset() { $this->data = array(); foreach ($this->instances as $instance) { - // Calling getCalls() will clear the calls. - $instance->getCalls(); + $instance->clearCalls(); } } From dab422287fa0f2b89a95c2d705969081fe6c76b3 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 7 Feb 2018 21:12:42 +0100 Subject: [PATCH 061/166] do not mock the container builder in tests --- .../Compiler/AddCacheWarmerPassTest.php | 70 ++++------- .../AddConstraintValidatorsPassTest.php | 72 ++++-------- .../LegacyFragmentRendererPassTest.php | 63 ++-------- .../Compiler/LoggingTranslatorPassTest.php | 73 ++++-------- .../Compiler/ProfilerPassTest.php | 63 +++------- .../Compiler/SerializerPassTest.php | 85 +++++--------- .../Compiler/TranslatorPassTest.php | 35 +++--- .../ConstraintValidatorFactoryTest.php | 38 +++--- .../Compiler/TwigLoaderPassTest.php | 100 ++++------------ .../Compiler/ExtensionCompilerPassTest.php | 58 ++++++--- .../Tests/Extension/ExtensionTest.php | 56 +++------ .../RegisterListenersPassTest.php | 61 ++-------- .../FragmentRendererPassTest.php | 110 ++++-------------- .../MergeExtensionConfigurationPassTest.php | 59 +++++----- 14 files changed, 289 insertions(+), 654 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddCacheWarmerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddCacheWarmerPassTest.php index 330deae6463d7..e58ed97724481 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddCacheWarmerPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddCacheWarmerPassTest.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass; @@ -19,73 +20,44 @@ class AddCacheWarmerPassTest extends TestCase { public function testThatCacheWarmersAreProcessedInPriorityOrder() { - $services = array( - 'my_cache_warmer_service1' => array(0 => array('priority' => 100)), - 'my_cache_warmer_service2' => array(0 => array('priority' => 200)), - 'my_cache_warmer_service3' => array(), - ); - - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('findTaggedServiceIds', 'getDefinition', 'hasDefinition'))->getMock(); + $container = new ContainerBuilder(); + $cacheWarmerDefinition = $container->register('cache_warmer')->addArgument(array()); + $container->register('my_cache_warmer_service1')->addTag('kernel.cache_warmer', array('priority' => 100)); + $container->register('my_cache_warmer_service2')->addTag('kernel.cache_warmer', array('priority' => 200)); + $container->register('my_cache_warmer_service3')->addTag('kernel.cache_warmer'); - $container->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue($services)); - $container->expects($this->atLeastOnce()) - ->method('getDefinition') - ->with('cache_warmer') - ->will($this->returnValue($definition)); - $container->expects($this->atLeastOnce()) - ->method('hasDefinition') - ->with('cache_warmer') - ->will($this->returnValue(true)); + $addCacheWarmerPass = new AddCacheWarmerPass(); + $addCacheWarmerPass->process($container); - $definition->expects($this->once()) - ->method('replaceArgument') - ->with(0, array( + $this->assertEquals( + array( new Reference('my_cache_warmer_service2'), new Reference('my_cache_warmer_service1'), new Reference('my_cache_warmer_service3'), - )); - - $addCacheWarmerPass = new AddCacheWarmerPass(); - $addCacheWarmerPass->process($container); + ), + $cacheWarmerDefinition->getArgument(0) + ); } public function testThatCompilerPassIsIgnoredIfThereIsNoCacheWarmerDefinition() { - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - - $container->expects($this->never())->method('findTaggedServiceIds'); - $container->expects($this->never())->method('getDefinition'); - $container->expects($this->atLeastOnce()) - ->method('hasDefinition') - ->with('cache_warmer') - ->will($this->returnValue(false)); - $definition->expects($this->never())->method('replaceArgument'); + $container = new ContainerBuilder(); $addCacheWarmerPass = new AddCacheWarmerPass(); $addCacheWarmerPass->process($container); + + // we just check that the pass does not break if no cache warmer is registered + $this->addToAssertionCount(1); } public function testThatCacheWarmersMightBeNotDefined() { - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - - $container->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue(array())); - $container->expects($this->never())->method('getDefinition'); - $container->expects($this->atLeastOnce()) - ->method('hasDefinition') - ->with('cache_warmer') - ->will($this->returnValue(true)); - - $definition->expects($this->never())->method('replaceArgument'); + $container = new ContainerBuilder(); + $cacheWarmerDefinition = $container->register('cache_warmer')->addArgument(array()); $addCacheWarmerPass = new AddCacheWarmerPass(); $addCacheWarmerPass->process($container); + + $this->assertSame(array(), $cacheWarmerDefinition->getArgument(0)); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConstraintValidatorsPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConstraintValidatorsPassTest.php index e58068900fc8f..0be1f77d5189e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConstraintValidatorsPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/AddConstraintValidatorsPassTest.php @@ -13,72 +13,40 @@ use PHPUnit\Framework\TestCase; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintValidatorsPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; class AddConstraintValidatorsPassTest extends TestCase { public function testThatConstraintValidatorServicesAreProcessed() { - $services = array( - 'my_constraint_validator_service1' => array(0 => array('alias' => 'my_constraint_validator_alias1')), - 'my_constraint_validator_service2' => array(), - ); - - $validatorFactoryDefinition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('findTaggedServiceIds', 'getDefinition', 'hasDefinition'))->getMock(); - - $validatorDefinition1 = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->setMethods(array('getClass'))->getMock(); - $validatorDefinition2 = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->setMethods(array('getClass'))->getMock(); - - $validatorDefinition1->expects($this->atLeastOnce()) - ->method('getClass') - ->willReturn('My\Fully\Qualified\Class\Named\Validator1'); - $validatorDefinition2->expects($this->atLeastOnce()) - ->method('getClass') - ->willReturn('My\Fully\Qualified\Class\Named\Validator2'); + $container = new ContainerBuilder(); + $constraintValidatorFactoryDefinition = $container->register('validator.validator_factory') + ->setArguments(array(new Reference('service_container'), array())); + $container->register('my_constraint_validator_service1', 'My\Fully\Qualified\Class\Named\Validator1') + ->addTag('validator.constraint_validator', array('alias' => 'my_constraint_validator_alias1')); + $container->register('my_constraint_validator_service2', 'My\Fully\Qualified\Class\Named\Validator2') + ->addTag('validator.constraint_validator'); - $container->expects($this->any()) - ->method('getDefinition') - ->with($this->anything()) - ->will($this->returnValueMap(array( - array('my_constraint_validator_service1', $validatorDefinition1), - array('my_constraint_validator_service2', $validatorDefinition2), - array('validator.validator_factory', $validatorFactoryDefinition), - ))); - - $container->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue($services)); - $container->expects($this->atLeastOnce()) - ->method('hasDefinition') - ->with('validator.validator_factory') - ->will($this->returnValue(true)); + $addConstraintValidatorsPass = new AddConstraintValidatorsPass(); + $addConstraintValidatorsPass->process($container); - $validatorFactoryDefinition->expects($this->once()) - ->method('replaceArgument') - ->with(1, array( + $this->assertEquals( + array( 'My\Fully\Qualified\Class\Named\Validator1' => 'my_constraint_validator_service1', 'my_constraint_validator_alias1' => 'my_constraint_validator_service1', 'My\Fully\Qualified\Class\Named\Validator2' => 'my_constraint_validator_service2', - )); - - $addConstraintValidatorsPass = new AddConstraintValidatorsPass(); - $addConstraintValidatorsPass->process($container); + ), + $constraintValidatorFactoryDefinition->getArgument(1) + ); } public function testThatCompilerPassIsIgnoredIfThereIsNoConstraintValidatorFactoryDefinition() { - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - - $container->expects($this->never())->method('findTaggedServiceIds'); - $container->expects($this->never())->method('getDefinition'); - $container->expects($this->atLeastOnce()) - ->method('hasDefinition') - ->with('validator.validator_factory') - ->will($this->returnValue(false)); - $definition->expects($this->never())->method('replaceArgument'); - $addConstraintValidatorsPass = new AddConstraintValidatorsPass(); - $addConstraintValidatorsPass->process($container); + $addConstraintValidatorsPass->process(new ContainerBuilder()); + + // we just check that the pass does not fail if no constraint validator factory is registered + $this->addToAssertionCount(1); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LegacyFragmentRendererPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LegacyFragmentRendererPassTest.php index d4f75ee95c204..b275047939062 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LegacyFragmentRendererPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LegacyFragmentRendererPassTest.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpFoundation\Request; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FragmentRendererPass; @@ -29,29 +30,10 @@ class LegacyFragmentRendererPassTest extends TestCase */ public function testContentRendererWithoutInterface() { - // one service, not implementing any interface - $services = array( - 'my_content_renderer' => array(), - ); - - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $definition->expects($this->atLeastOnce()) - ->method('getClass') - ->will($this->returnValue('stdClass')); - - $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - $builder->expects($this->any()) - ->method('hasDefinition') - ->will($this->returnValue(true)); - - // We don't test kernel.fragment_renderer here - $builder->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue($services)); - - $builder->expects($this->atLeastOnce()) - ->method('getDefinition') - ->will($this->returnValue($definition)); + $builder = new ContainerBuilder(); + $builder->register('fragment.handler'); + $builder->register('my_content_renderer', 'stdClass') + ->addTag('kernel.fragment_renderer'); $pass = new FragmentRendererPass(); $pass->process($builder); @@ -59,38 +41,15 @@ public function testContentRendererWithoutInterface() public function testValidContentRenderer() { - $services = array( - 'my_content_renderer' => array(), - ); - - $renderer = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $renderer - ->expects($this->once()) - ->method('addMethodCall') - ->with('addRenderer', array(new Reference('my_content_renderer'))) - ; - - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $definition->expects($this->atLeastOnce()) - ->method('getClass') - ->will($this->returnValue('Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler\RendererService')); - - $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - $builder->expects($this->any()) - ->method('hasDefinition') - ->will($this->returnValue(true)); - - // We don't test kernel.fragment_renderer here - $builder->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue($services)); - - $builder->expects($this->atLeastOnce()) - ->method('getDefinition') - ->will($this->onConsecutiveCalls($renderer, $definition)); + $builder = new ContainerBuilder(); + $fragmentHandlerDefinition = $builder->register('fragment.handler'); + $builder->register('my_content_renderer', 'Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler\RendererService') + ->addTag('kernel.fragment_renderer'); $pass = new FragmentRendererPass(); $pass->process($builder); + + $this->assertEquals(array(array('addRenderer', array(new Reference('my_content_renderer')))), $fragmentHandlerDefinition->getMethodCalls()); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php index db6557913b06e..00da2724d14f2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php @@ -13,75 +13,52 @@ use PHPUnit\Framework\TestCase; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\LoggingTranslatorPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; class LoggingTranslatorPassTest extends TestCase { public function testProcess() { - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->getMock(); - $parameterBag = $this->getMockBuilder('Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface')->getMock(); - - $container->expects($this->exactly(2)) - ->method('hasAlias') - ->will($this->returnValue(true)); - - $container->expects($this->once()) - ->method('getParameter') - ->will($this->returnValue(true)); - - $container->expects($this->once()) - ->method('getAlias') - ->will($this->returnValue('translation.default')); - - $container->expects($this->exactly(3)) - ->method('getDefinition') - ->will($this->returnValue($definition)); - - $container->expects($this->once()) - ->method('hasParameter') - ->with('translator.logging') - ->will($this->returnValue(true)); - - $definition->expects($this->once()) - ->method('getClass') - ->will($this->returnValue('%translator.class%')); - - $parameterBag->expects($this->once()) - ->method('resolveValue') - ->will($this->returnValue("Symfony\Bundle\FrameworkBundle\Translation\Translator")); - - $container->expects($this->once()) - ->method('getParameterBag') - ->will($this->returnValue($parameterBag)); + $container = new ContainerBuilder(); + $container->setParameter('translator.logging', true); + $container->setParameter('translator.class', 'Symfony\Component\Translation\Translator'); + $container->register('monolog.logger'); + $container->setAlias('logger', 'monolog.logger'); + $container->register('translator.default', '%translator.class%'); + $container->register('translator.logging', '%translator.class%'); + $container->setAlias('translator', 'translator.default'); + $translationWarmerDefinition = $container->register('translation.warmer')->addArgument(new Reference('translator')); $pass = new LoggingTranslatorPass(); $pass->process($container); + + $this->assertEquals(new Reference('translator.logging.inner'), $translationWarmerDefinition->getArgument(0)); } public function testThatCompilerPassIsIgnoredIfThereIsNotLoggerDefinition() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->getMock(); - $container->expects($this->once()) - ->method('hasAlias') - ->will($this->returnValue(false)); + $container = new ContainerBuilder(); + $container->register('identity_translator'); + $container->setAlias('translator', 'identity_translator'); $pass = new LoggingTranslatorPass(); $pass->process($container); + + // we just check that the compiler pass does not break if a logger is not registered + $this->addToAssertionCount(1); } public function testThatCompilerPassIsIgnoredIfThereIsNotTranslatorDefinition() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->getMock(); - $container->expects($this->at(0)) - ->method('hasAlias') - ->will($this->returnValue(true)); - - $container->expects($this->at(0)) - ->method('hasAlias') - ->will($this->returnValue(false)); + $container = new ContainerBuilder(); + $container->register('monolog.logger'); + $container->setAlias('logger', 'monolog.logger'); $pass = new LoggingTranslatorPass(); $pass->process($container); + + // we just check that the compiler pass does not break if a translator is not registered + $this->addToAssertionCount(1); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php index e064ce9f17f02..9fcae720b20b9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ProfilerPassTest.php @@ -12,18 +12,11 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; use PHPUnit\Framework\TestCase; -use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ProfilerPass; class ProfilerPassTest extends TestCase { - private $profilerDefinition; - - protected function setUp() - { - $this->profilerDefinition = new Definition('ProfilerClass'); - } - /** * Tests that collectors that specify a template but no "id" will throw * an exception (both are needed if the template is specified). @@ -31,17 +24,15 @@ protected function setUp() * Thus, a fully-valid tag looks something like this: * * + * + * @expectedException \InvalidArgumentException */ public function testTemplateNoIdThrowsException() { - // one service, with a template key, but no id - $services = array( - 'my_collector_service' => array(0 => array('template' => 'foo')), - ); - - $builder = $this->createContainerMock($services); - - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException'); + $builder = new ContainerBuilder(); + $builder->register('profiler', 'ProfilerClass'); + $builder->register('my_collector_service') + ->addTag('data_collector', array('template' => 'foo')); $profilerPass = new ProfilerPass(); $profilerPass->process($builder); @@ -49,45 +40,19 @@ public function testTemplateNoIdThrowsException() public function testValidCollector() { - // one service, with a template key, but no id - $services = array( - 'my_collector_service' => array(0 => array('template' => 'foo', 'id' => 'my_collector')), - ); - - $container = $this->createContainerMock($services); - - // fake the getDefinition() to return a Profiler definition - $container->expects($this->atLeastOnce()) - ->method('getDefinition'); - - // assert that the data_collector.templates parameter should be set - $container->expects($this->once()) - ->method('setParameter') - ->with('data_collector.templates', array('my_collector_service' => array('my_collector', 'foo'))); + $container = new ContainerBuilder(); + $profilerDefinition = $container->register('profiler', 'ProfilerClass'); + $container->register('my_collector_service') + ->addTag('data_collector', array('template' => 'foo', 'id' => 'my_collector')); $profilerPass = new ProfilerPass(); $profilerPass->process($container); + $this->assertSame(array('my_collector_service' => array('my_collector', 'foo')), $container->getParameter('data_collector.templates')); + // grab the method calls off of the "profiler" definition - $methodCalls = $this->profilerDefinition->getMethodCalls(); + $methodCalls = $profilerDefinition->getMethodCalls(); $this->assertCount(1, $methodCalls); $this->assertEquals('add', $methodCalls[0][0]); // grab the method part of the first call } - - private function createContainerMock($services) - { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'getDefinition', 'findTaggedServiceIds', 'setParameter'))->getMock(); - $container->expects($this->any()) - ->method('hasDefinition') - ->with($this->equalTo('profiler')) - ->will($this->returnValue(true)); - $container->expects($this->any()) - ->method('getDefinition') - ->will($this->returnValue($this->profilerDefinition)); - $container->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue($services)); - - return $container; - } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SerializerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SerializerPassTest.php index 6fa27be17a3db..12e9e1c34bbb7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SerializerPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SerializerPassTest.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\SerializerPass; @@ -22,48 +23,30 @@ */ class SerializerPassTest extends TestCase { + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage You must tag at least one service as "serializer.normalizer" to use the Serializer service + */ public function testThrowExceptionWhenNoNormalizers() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds'))->getMock(); - - $container->expects($this->once()) - ->method('hasDefinition') - ->with('serializer') - ->will($this->returnValue(true)); - - $container->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('serializer.normalizer') - ->will($this->returnValue(array())); - - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('RuntimeException'); + $container = new ContainerBuilder(); + $container->register('serializer'); $serializerPass = new SerializerPass(); $serializerPass->process($container); } + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage You must tag at least one service as "serializer.encoder" to use the Serializer service + */ public function testThrowExceptionWhenNoEncoders() { - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - - $container->expects($this->once()) - ->method('hasDefinition') - ->with('serializer') - ->will($this->returnValue(true)); - - $container->expects($this->any()) - ->method('findTaggedServiceIds') - ->will($this->onConsecutiveCalls( - array('n' => array('serializer.normalizer')), - array() - )); - - $container->expects($this->once()) - ->method('getDefinition') - ->will($this->returnValue($definition)); - - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('RuntimeException'); + $container = new ContainerBuilder(); + $container->register('serializer') + ->addArgument(array()) + ->addArgument(array()); + $container->register('normalizer')->addTag('serializer.normalizer'); $serializerPass = new SerializerPass(); $serializerPass->process($container); @@ -71,34 +54,18 @@ public function testThrowExceptionWhenNoEncoders() public function testServicesAreOrderedAccordingToPriority() { - $services = array( - 'n3' => array(array()), - 'n1' => array(array('priority' => 200)), - 'n2' => array(array('priority' => 100)), - ); - - $expected = array( - new Reference('n1'), - new Reference('n2'), - new Reference('n3'), - ); - - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('findTaggedServiceIds'))->getMock(); - - $container->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue($services)); + $container = new ContainerBuilder(); + $serializerDefinition = $container->register('serializer') + ->addArgument(array()) + ->addArgument(array()); + $container->register('normalizer3')->addTag('serializer.normalizer'); + $container->register('normalizer1')->addTag('serializer.normalizer', array('priority' => 200)); + $container->register('normalizer2')->addTag('serializer.normalizer', array('priority' => 100)); + $container->register('encoder')->addTag('serializer.encoder'); $serializerPass = new SerializerPass(); + $serializerPass->process($container); - $method = new \ReflectionMethod( - 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\SerializerPass', - 'findAndSortTaggedServices' - ); - $method->setAccessible(true); - - $actual = $method->invoke($serializerPass, 'tag', $container); - - $this->assertEquals($expected, $actual); + $this->assertEquals(array(new Reference('normalizer1'), new Reference('normalizer2'), new Reference('normalizer3')), $serializerDefinition->getArgument(0)); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php index 10a38aabdb402..e176c7534a343 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslatorPass; @@ -19,28 +20,22 @@ class TranslatorPassTest extends TestCase { public function testValidCollector() { - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $definition->expects($this->at(0)) - ->method('addMethodCall') - ->with('addLoader', array('xliff', new Reference('xliff'))); - $definition->expects($this->at(1)) - ->method('addMethodCall') - ->with('addLoader', array('xlf', new Reference('xliff'))); + $container = new ContainerBuilder(); + $container->register('translator.default') + ->setArguments(array(null, null, array())); + $translationLoaderDefinition = $container->register('translation.loader'); + $container->register('xliff') + ->addTag('translation.loader', array('alias' => 'xliff', 'legacy-alias' => 'xlf')); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'getDefinition', 'findTaggedServiceIds', 'findDefinition'))->getMock(); - $container->expects($this->any()) - ->method('hasDefinition') - ->will($this->returnValue(true)); - $container->expects($this->once()) - ->method('getDefinition') - ->will($this->returnValue($definition)); - $container->expects($this->once()) - ->method('findTaggedServiceIds') - ->will($this->returnValue(array('xliff' => array(array('alias' => 'xliff', 'legacy-alias' => 'xlf'))))); - $container->expects($this->once()) - ->method('findDefinition') - ->will($this->returnValue($this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock())); $pass = new TranslatorPass(); $pass->process($container); + + $this->assertEquals( + array( + array('addLoader', array('xliff', new Reference('xliff'))), + array('addLoader', array('xlf', new Reference('xliff'))), + ), + $translationLoaderDefinition->getMethodCalls() + ); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php index 6cf9574ece96b..995048455f7b2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php @@ -14,7 +14,9 @@ use PHPUnit\Framework\TestCase; use Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory; use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraints\Blank as BlankConstraint; +use Symfony\Component\Validator\ConstraintValidator; class ConstraintValidatorFactoryTest extends TestCase { @@ -42,26 +44,13 @@ public function testGetInstanceReturnsExistingValidator() public function testGetInstanceReturnsService() { - $service = 'validator_constraint_service'; - $alias = 'validator_constraint_alias'; - $validator = $this->getMockForAbstractClass('Symfony\\Component\\Validator\\ConstraintValidator'); + $validator = new DummyConstraintValidator(); - // mock ContainerBuilder b/c it implements TaggedContainerInterface - $container = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\ContainerBuilder')->setMethods(array('get'))->getMock(); - $container - ->expects($this->once()) - ->method('get') - ->with($service) - ->will($this->returnValue($validator)); - - $constraint = $this->getMockBuilder('Symfony\\Component\\Validator\\Constraint')->getMock(); - $constraint - ->expects($this->once()) - ->method('validatedBy') - ->will($this->returnValue($alias)); + $container = new Container(); + $container->set('validator_constraint_service', $validator); $factory = new ConstraintValidatorFactory($container, array('validator_constraint_alias' => 'validator_constraint_service')); - $this->assertSame($validator, $factory->getInstance($constraint)); + $this->assertSame($validator, $factory->getInstance(new ConstraintStub())); } /** @@ -79,3 +68,18 @@ public function testGetInstanceInvalidValidatorClass() $factory->getInstance($constraint); } } + +class ConstraintStub extends Constraint +{ + public function validatedBy() + { + return 'validator_constraint_alias'; + } +} + +class DummyConstraintValidator extends ConstraintValidator +{ + public function validate($value, Constraint $constraint) + { + } +} diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigLoaderPassTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigLoaderPassTest.php index 10bcf3e8f66a8..b7870ac56c06e 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigLoaderPassTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigLoaderPassTest.php @@ -12,13 +12,14 @@ namespace Symfony\Bundle\TwigBundle\Tests\DependencyInjection\Compiler; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigLoaderPass; class TwigLoaderPassTest extends TestCase { /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var ContainerBuilder */ private $builder; /** @@ -32,62 +33,33 @@ class TwigLoaderPassTest extends TestCase protected function setUp() { - $this->builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'setAlias', 'getDefinition'))->getMock(); + $this->builder = new ContainerBuilder(); + $this->builder->register('twig'); $this->chainLoader = new Definition('loader'); $this->pass = new TwigLoaderPass(); } - public function testMapperPassWithOneTaggedLoaders() + public function testMapperPassWithOneTaggedLoader() { - $serviceIds = array( - 'test_loader_1' => array( - array(), - ), - ); - - $this->builder->expects($this->once()) - ->method('hasDefinition') - ->with('twig') - ->will($this->returnValue(true)); - $this->builder->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('twig.loader') - ->will($this->returnValue($serviceIds)); - $this->builder->expects($this->once()) - ->method('setAlias') - ->with('twig.loader', 'test_loader_1'); + $this->builder->register('test_loader_1') + ->addTag('twig.loader'); $this->pass->process($this->builder); + + $this->assertSame('test_loader_1', (string) $this->builder->getAlias('twig.loader')); } public function testMapperPassWithTwoTaggedLoaders() { - $serviceIds = array( - 'test_loader_1' => array( - array(), - ), - 'test_loader_2' => array( - array(), - ), - ); - - $this->builder->expects($this->once()) - ->method('hasDefinition') - ->with('twig') - ->will($this->returnValue(true)); - $this->builder->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('twig.loader') - ->will($this->returnValue($serviceIds)); - $this->builder->expects($this->once()) - ->method('getDefinition') - ->with('twig.loader.chain') - ->will($this->returnValue($this->chainLoader)); - $this->builder->expects($this->once()) - ->method('setAlias') - ->with('twig.loader', 'twig.loader.chain'); + $this->builder->setDefinition('twig.loader.chain', $this->chainLoader); + $this->builder->register('test_loader_1') + ->addTag('twig.loader'); + $this->builder->register('test_loader_2') + ->addTag('twig.loader'); $this->pass->process($this->builder); + + $this->assertSame('twig.loader.chain', (string) $this->builder->getAlias('twig.loader')); $calls = $this->chainLoader->getMethodCalls(); $this->assertCount(2, $calls); $this->assertEquals('addLoader', $calls[0][0]); @@ -98,32 +70,15 @@ public function testMapperPassWithTwoTaggedLoaders() public function testMapperPassWithTwoTaggedLoadersWithPriority() { - $serviceIds = array( - 'test_loader_1' => array( - array('priority' => 100), - ), - 'test_loader_2' => array( - array('priority' => 200), - ), - ); - - $this->builder->expects($this->once()) - ->method('hasDefinition') - ->with('twig') - ->will($this->returnValue(true)); - $this->builder->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('twig.loader') - ->will($this->returnValue($serviceIds)); - $this->builder->expects($this->once()) - ->method('getDefinition') - ->with('twig.loader.chain') - ->will($this->returnValue($this->chainLoader)); - $this->builder->expects($this->once()) - ->method('setAlias') - ->with('twig.loader', 'twig.loader.chain'); + $this->builder->setDefinition('twig.loader.chain', $this->chainLoader); + $this->builder->register('test_loader_1') + ->addTag('twig.loader', array('priority' => 100)); + $this->builder->register('test_loader_2') + ->addTag('twig.loader', array('priority' => 200)); $this->pass->process($this->builder); + + $this->assertSame('twig.loader.chain', (string) $this->builder->getAlias('twig.loader')); $calls = $this->chainLoader->getMethodCalls(); $this->assertCount(2, $calls); $this->assertEquals('addLoader', $calls[0][0]); @@ -137,15 +92,6 @@ public function testMapperPassWithTwoTaggedLoadersWithPriority() */ public function testMapperPassWithZeroTaggedLoaders() { - $this->builder->expects($this->once()) - ->method('hasDefinition') - ->with('twig') - ->will($this->returnValue(true)); - $this->builder->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('twig.loader') - ->will($this->returnValue(array())); - $this->pass->process($this->builder); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ExtensionCompilerPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ExtensionCompilerPassTest.php index e083611458770..f4c4353abe9ed 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ExtensionCompilerPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ExtensionCompilerPassTest.php @@ -12,7 +12,10 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\ExtensionCompilerPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; /** * @author Wouter J @@ -24,33 +27,52 @@ class ExtensionCompilerPassTest extends TestCase protected function setUp() { - $this->container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->getMock(); + $this->container = new ContainerBuilder(); $this->pass = new ExtensionCompilerPass(); } public function testProcess() { - $extension1 = $this->createExtensionMock(true); - $extension1->expects($this->once())->method('process'); - $extension2 = $this->createExtensionMock(false); - $extension3 = $this->createExtensionMock(false); - $extension4 = $this->createExtensionMock(true); - $extension4->expects($this->once())->method('process'); - - $this->container->expects($this->any()) - ->method('getExtensions') - ->will($this->returnValue(array($extension1, $extension2, $extension3, $extension4))) - ; + $extension1 = new CompilerPassExtension('extension1'); + $extension2 = new DummyExtension('extension2'); + $extension3 = new DummyExtension('extension3'); + $extension4 = new CompilerPassExtension('extension4'); + + $this->container->registerExtension($extension1); + $this->container->registerExtension($extension2); + $this->container->registerExtension($extension3); + $this->container->registerExtension($extension4); $this->pass->process($this->container); + + $this->assertCount(2, $this->container->getDefinitions()); } +} + +class DummyExtension extends Extension +{ + private $alias; - private function createExtensionMock($hasInlineCompile) + public function __construct($alias) { - return $this->getMockBuilder('Symfony\Component\DependencyInjection\\'.( - $hasInlineCompile - ? 'Compiler\CompilerPassInterface' - : 'Extension\ExtensionInterface' - ))->getMock(); + $this->alias = $alias; } + + public function getAlias() + { + return $this->alias; + } + + public function load(array $configs, ContainerBuilder $container) + { + } + + public function process(ContainerBuilder $container) + { + $container->register($this->alias); + } +} + +class CompilerPassExtension extends DummyExtension implements CompilerPassInterface +{ } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Extension/ExtensionTest.php b/src/Symfony/Component/DependencyInjection/Tests/Extension/ExtensionTest.php index 90852c359e514..9f66bfd7c6802 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Extension/ExtensionTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Extension/ExtensionTest.php @@ -12,6 +12,8 @@ namespace Symfony\Component\DependencyInjection\Tests\Extension; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; class ExtensionTest extends TestCase { @@ -20,36 +22,8 @@ class ExtensionTest extends TestCase */ public function testIsConfigEnabledReturnsTheResolvedValue($enabled) { - $pb = $this->getMockBuilder('Symfony\Component\DependencyInjection\ParameterBag\ParameterBag') - ->setMethods(array('resolveValue')) - ->getMock() - ; - - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') - ->setMethods(array('getParameterBag')) - ->getMock() - ; - - $pb->expects($this->once()) - ->method('resolveValue') - ->with($this->equalTo($enabled)) - ->will($this->returnValue($enabled)) - ; - - $container->expects($this->once()) - ->method('getParameterBag') - ->will($this->returnValue($pb)) - ; - - $extension = $this->getMockBuilder('Symfony\Component\DependencyInjection\Extension\Extension') - ->setMethods(array()) - ->getMockForAbstractClass() - ; - - $r = new \ReflectionMethod('Symfony\Component\DependencyInjection\Extension\Extension', 'isConfigEnabled'); - $r->setAccessible(true); - - $r->invoke($extension, $container, array('enabled' => $enabled)); + $extension = new EnableableExtension(); + $this->assertSame($enabled, $extension->isConfigEnabled(new ContainerBuilder(), array('enabled' => $enabled))); } public function getResolvedEnabledFixtures() @@ -66,18 +40,20 @@ public function getResolvedEnabledFixtures() */ public function testIsConfigEnabledOnNonEnableableConfig() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder') - ->getMock() - ; + $extension = new EnableableExtension(); - $extension = $this->getMockBuilder('Symfony\Component\DependencyInjection\Extension\Extension') - ->setMethods(array()) - ->getMockForAbstractClass() - ; + $extension->isConfigEnabled(new ContainerBuilder(), array()); + } +} - $r = new \ReflectionMethod('Symfony\Component\DependencyInjection\Extension\Extension', 'isConfigEnabled'); - $r->setAccessible(true); +class EnableableExtension extends Extension +{ + public function load(array $configs, ContainerBuilder $container) + { + } - $r->invoke($extension, $container, array()); + public function isConfigEnabled(ContainerBuilder $container, array $config) + { + return parent::isConfigEnabled($container, $config); } } diff --git a/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php b/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php index 53d7282b37a7a..7490d0d25fda8 100644 --- a/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php +++ b/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php @@ -25,32 +25,10 @@ class RegisterListenersPassTest extends TestCase */ public function testEventSubscriberWithoutInterface() { - // one service, not implementing any interface - $services = array( - 'my_event_subscriber' => array(0 => array()), - ); - - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $definition->expects($this->atLeastOnce()) - ->method('isPublic') - ->will($this->returnValue(true)); - $definition->expects($this->atLeastOnce()) - ->method('getClass') - ->will($this->returnValue('stdClass')); - - $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - $builder->expects($this->any()) - ->method('hasDefinition') - ->will($this->returnValue(true)); - - // We don't test kernel.event_listener here - $builder->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->onConsecutiveCalls(array(), $services)); - - $builder->expects($this->atLeastOnce()) - ->method('getDefinition') - ->will($this->returnValue($definition)); + $builder = new ContainerBuilder(); + $builder->register('event_dispatcher'); + $builder->register('my_event_subscriber', 'stdClass') + ->addTag('kernel.event_subscriber'); $registerListenersPass = new RegisterListenersPass(); $registerListenersPass->process($builder); @@ -62,34 +40,15 @@ public function testValidEventSubscriber() 'my_event_subscriber' => array(0 => array()), ); - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $definition->expects($this->atLeastOnce()) - ->method('isPublic') - ->will($this->returnValue(true)); - $definition->expects($this->atLeastOnce()) - ->method('getClass') - ->will($this->returnValue('Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService')); - - $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition', 'findDefinition'))->getMock(); - $builder->expects($this->any()) - ->method('hasDefinition') - ->will($this->returnValue(true)); - - // We don't test kernel.event_listener here - $builder->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->onConsecutiveCalls(array(), $services)); - - $builder->expects($this->atLeastOnce()) - ->method('getDefinition') - ->will($this->returnValue($definition)); - - $builder->expects($this->atLeastOnce()) - ->method('findDefinition') - ->will($this->returnValue($definition)); + $builder = new ContainerBuilder(); + $eventDispatcherDefinition = $builder->register('event_dispatcher'); + $builder->register('my_event_subscriber', 'Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService') + ->addTag('kernel.event_subscriber'); $registerListenersPass = new RegisterListenersPass(); $registerListenersPass->process($builder); + + $this->assertEquals(array(array('addSubscriberService', array('my_event_subscriber', 'Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService'))), $eventDispatcherDefinition->getMethodCalls()); } /** diff --git a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/FragmentRendererPassTest.php b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/FragmentRendererPassTest.php index 2a27fcac21461..8bac207d176cd 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/FragmentRendererPassTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/FragmentRendererPassTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\HttpKernel\Tests\DependencyInjection; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\DependencyInjection\FragmentRendererPass; @@ -24,118 +25,47 @@ class FragmentRendererPassTest extends TestCase */ public function testLegacyFragmentRedererWithoutAlias() { - // no alias - $services = array( - 'my_content_renderer' => array(array()), - ); - - $renderer = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $renderer - ->expects($this->once()) - ->method('addMethodCall') - ->with('addRenderer', array(new Reference('my_content_renderer'))) - ; - - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $definition->expects($this->atLeastOnce()) - ->method('getClass') - ->will($this->returnValue('Symfony\Component\HttpKernel\Tests\DependencyInjection\RendererService')); - $definition - ->expects($this->once()) - ->method('isPublic') - ->will($this->returnValue(true)) - ; - - $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - $builder->expects($this->any()) - ->method('hasDefinition') - ->will($this->returnValue(true)); - - // We don't test kernel.fragment_renderer here - $builder->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue($services)); - - $builder->expects($this->atLeastOnce()) - ->method('getDefinition') - ->will($this->onConsecutiveCalls($renderer, $definition)); + $builder = new ContainerBuilder(); + $fragmentHandlerDefinition = $builder->register('fragment.handler'); + $builder->register('my_content_renderer', 'Symfony\Component\HttpKernel\Tests\DependencyInjection\RendererService') + ->addTag('kernel.fragment_renderer'); $pass = new FragmentRendererPass(); $pass->process($builder); + + $this->assertEquals(array(array('addRenderer', array(new Reference('my_content_renderer')))), $fragmentHandlerDefinition->getMethodCalls()); } /** * Tests that content rendering not implementing FragmentRendererInterface - * trigger an exception. + * triggers an exception. * * @expectedException \InvalidArgumentException */ public function testContentRendererWithoutInterface() { - // one service, not implementing any interface - $services = array( - 'my_content_renderer' => array(array('alias' => 'foo')), - ); - - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - - $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - $builder->expects($this->any()) - ->method('hasDefinition') - ->will($this->returnValue(true)); - - // We don't test kernel.fragment_renderer here - $builder->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue($services)); - - $builder->expects($this->atLeastOnce()) - ->method('getDefinition') - ->will($this->returnValue($definition)); + $builder = new ContainerBuilder(); + $fragmentHandlerDefinition = $builder->register('fragment.handler'); + $builder->register('my_content_renderer', 'Symfony\Component\DependencyInjection\Definition') + ->addTag('kernel.fragment_renderer', array('alias' => 'foo')); $pass = new FragmentRendererPass(); $pass->process($builder); + + $this->assertEquals(array(array('addRendererService', array('foo', 'my_content_renderer'))), $fragmentHandlerDefinition->getMethodCalls()); } public function testValidContentRenderer() { - $services = array( - 'my_content_renderer' => array(array('alias' => 'foo')), - ); - - $renderer = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $renderer - ->expects($this->once()) - ->method('addMethodCall') - ->with('addRendererService', array('foo', 'my_content_renderer')) - ; - - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $definition->expects($this->atLeastOnce()) - ->method('getClass') - ->will($this->returnValue('Symfony\Component\HttpKernel\Tests\DependencyInjection\RendererService')); - $definition - ->expects($this->once()) - ->method('isPublic') - ->will($this->returnValue(true)) - ; - - $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - $builder->expects($this->any()) - ->method('hasDefinition') - ->will($this->returnValue(true)); - - // We don't test kernel.fragment_renderer here - $builder->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue($services)); - - $builder->expects($this->atLeastOnce()) - ->method('getDefinition') - ->will($this->onConsecutiveCalls($renderer, $definition)); + $builder = new ContainerBuilder(); + $fragmentHandlerDefinition = $builder->register('fragment.handler'); + $builder->register('my_content_renderer', 'Symfony\Component\HttpKernel\Tests\DependencyInjection\RendererService') + ->addTag('kernel.fragment_renderer', array('alias' => 'foo')); $pass = new FragmentRendererPass(); $pass->process($builder); + + $this->assertEquals(array(array('addRendererService', array('foo', 'my_content_renderer'))), $fragmentHandlerDefinition->getMethodCalls()); } } diff --git a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/MergeExtensionConfigurationPassTest.php b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/MergeExtensionConfigurationPassTest.php index 81fc8b455d183..ae421d919bfd8 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/MergeExtensionConfigurationPassTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/MergeExtensionConfigurationPassTest.php @@ -12,44 +12,39 @@ namespace Symfony\Component\HttpKernel\Tests\DependencyInjection; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass; class MergeExtensionConfigurationPassTest extends TestCase { public function testAutoloadMainExtension() { - $container = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\ContainerBuilder')->setMethods(array('getExtensionConfig', 'loadFromExtension', 'getParameterBag', 'getDefinitions', 'getAliases', 'getExtensions'))->getMock(); - $params = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBag')->getMock(); - - $container->expects($this->at(0)) - ->method('getExtensionConfig') - ->with('loaded') - ->will($this->returnValue(array(array()))); - $container->expects($this->at(1)) - ->method('getExtensionConfig') - ->with('notloaded') - ->will($this->returnValue(array())); - $container->expects($this->once()) - ->method('loadFromExtension') - ->with('notloaded', array()); - - $container->expects($this->any()) - ->method('getParameterBag') - ->will($this->returnValue($params)); - $params->expects($this->any()) - ->method('all') - ->will($this->returnValue(array())); - $container->expects($this->any()) - ->method('getDefinitions') - ->will($this->returnValue(array())); - $container->expects($this->any()) - ->method('getAliases') - ->will($this->returnValue(array())); - $container->expects($this->any()) - ->method('getExtensions') - ->will($this->returnValue(array())); - - $configPass = new MergeExtensionConfigurationPass(array('loaded', 'notloaded')); + $container = new ContainerBuilder(); + $container->registerExtension(new LoadedExtension()); + $container->registerExtension(new NotLoadedExtension()); + $container->loadFromExtension('loaded', array()); + + $configPass = new MergeExtensionConfigurationPass(array('loaded', 'not_loaded')); $configPass->process($container); + + $this->assertTrue($container->hasDefinition('loaded.foo')); + $this->assertTrue($container->hasDefinition('not_loaded.bar')); + } +} + +class LoadedExtension extends Extension +{ + public function load(array $configs, ContainerBuilder $container) + { + $container->register('loaded.foo'); + } +} + +class NotLoadedExtension extends Extension +{ + public function load(array $configs, ContainerBuilder $container) + { + $container->register('not_loaded.bar'); } } From a9ab167abfda01b46c1d77a2d85078f860998046 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 9 Feb 2018 08:49:27 +0100 Subject: [PATCH 062/166] backport regression test from 3.4 --- .../Tests/Extractors/PhpDocExtractorTest.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php index 6477ba1967721..4110c6b8a5bf4 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php @@ -74,4 +74,21 @@ public function typesProvider() array('staticSetter', null, null, null), ); } + + public function testParamTagTypeIsOmitted() + { + $this->assertNull($this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\PhpDocExtractors\OmittedParamTagTypeDocBlock', 'omittedType')); + } +} + +class OmittedParamTagTypeDocBlock +{ + /** + * The type is omitted here to ensure that the extractor doesn't choke on missing types. + * + * @param $omittedTagType + */ + public function setOmittedType(array $omittedTagType) + { + } } From aeffc5fdffcfac52333d8b0761a8b30dc2fe4746 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Fri, 9 Feb 2018 13:00:05 +0100 Subject: [PATCH 063/166] Bump default PHPUnit version from 6.3 to 6.5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR bumps the default PHPUnit version for php ≥ 7.2 from the outdated 6.3 to the currently maintained version 6.5. --- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit index fbcedeca8c6ab..fd7c800fedfd7 100755 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit @@ -17,7 +17,7 @@ error_reporting(-1); if (PHP_VERSION_ID >= 70200) { // PHPUnit 6 is required for PHP 7.2+ - $PHPUNIT_VERSION = getenv('SYMFONY_PHPUNIT_VERSION') ?: '6.3'; + $PHPUNIT_VERSION = getenv('SYMFONY_PHPUNIT_VERSION') ?: '6.5'; } elseif (PHP_VERSION_ID >= 50600) { // PHPUnit 4 does not support PHP 7 $PHPUNIT_VERSION = getenv('SYMFONY_PHPUNIT_VERSION') ?: '5.7'; From 51d9008d682c09a594bda0a8e38652ec9b820ce8 Mon Sep 17 00:00:00 2001 From: David Maicher Date: Fri, 9 Feb 2018 13:42:37 +0100 Subject: [PATCH 064/166] [Security] fix merge of 2.7 into 2.8 + add test case --- .../UsernamePasswordFormAuthenticationListener.php | 10 +++++++--- ...ernamePasswordFormAuthenticationListenerTest.php | 13 +++++++++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php index d7802c76d2166..f8466278da63b 100644 --- a/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php @@ -96,9 +96,13 @@ protected function attemptAuthentication(Request $request) } } - $requestBag = $this->options['post_only'] ? $request->request : $request; - $username = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['username_parameter']); - $password = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['password_parameter']); + if ($this->options['post_only']) { + $username = ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']); + $password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']); + } else { + $username = ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']); + $password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']); + } if (!\is_string($username) || (\is_object($username) && !\method_exists($username, '__toString'))) { throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], \gettype($username))); diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php index 2e99f70e7e26b..106740e56fe3c 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php @@ -77,10 +77,11 @@ public function testHandleWhenUsernameLength($username, $ok) } /** + * @dataProvider postOnlyDataProvider * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException * @expectedExceptionMessage The key "_username" must be a string, "array" given. */ - public function testHandleNonStringUsername() + public function testHandleNonStringUsername($postOnly) { $request = Request::create('/login_check', 'POST', array('_username' => array())); $request->setSession($this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock()); @@ -93,7 +94,7 @@ public function testHandleNonStringUsername() 'foo', new DefaultAuthenticationSuccessHandler($httpUtils), new DefaultAuthenticationFailureHandler($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $httpUtils), - array('require_previous_session' => false) + array('require_previous_session' => false, 'post_only' => $postOnly) ); $event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST); @@ -101,6 +102,14 @@ public function testHandleNonStringUsername() $listener->handle($event); } + public function postOnlyDataProvider() + { + return array( + array(true), + array(false), + ); + } + public function getUsernameForLength() { return array( From d195a6f0600fdfb0665f4a7844dc32646f73b1ab Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Fri, 9 Feb 2018 13:55:03 +0100 Subject: [PATCH 065/166] [SecurityBundle] Backport test --- ...amePasswordFormAuthenticationListenerTest.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php index 2e99f70e7e26b..8634eca017386 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php @@ -77,14 +77,14 @@ public function testHandleWhenUsernameLength($username, $ok) } /** + * @dataProvider postOnlyDataProvider * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException * @expectedExceptionMessage The key "_username" must be a string, "array" given. */ - public function testHandleNonStringUsername() + public function testHandleNonStringUsername($postOnly) { $request = Request::create('/login_check', 'POST', array('_username' => array())); $request->setSession($this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock()); - $listener = new UsernamePasswordFormAuthenticationListener( new TokenStorage(), $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock(), @@ -93,14 +93,20 @@ public function testHandleNonStringUsername() 'foo', new DefaultAuthenticationSuccessHandler($httpUtils), new DefaultAuthenticationFailureHandler($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $httpUtils), - array('require_previous_session' => false) + array('require_previous_session' => false, 'post_only' => $postOnly) ); - $event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST); - $listener->handle($event); } + public function postOnlyDataProvider() + { + return array( + array(true), + array(false), + ); + } + public function getUsernameForLength() { return array( From bdf9efc78e7a34543be98b6e3e066c9590bb3fbd Mon Sep 17 00:00:00 2001 From: dsmink Date: Fri, 9 Feb 2018 13:27:46 +0100 Subject: [PATCH 066/166] Env var maps to undefined constant. When I try to use a constant as an environment variable, as described in the blog item, I run into the following problem. Env var "SOME_CONST" maps to undefined constant "App\\Util\\SomeClass::SOME_CONST". The proposed solution works for me, however, I'm not sure if this is the best and conform Symfony standards. Blog: https://symfony.com/blog/new-in-symfony-3-4-advanced-environment-variables --- src/Symfony/Component/DependencyInjection/EnvVarProcessor.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php b/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php index bf34c593d638a..508ebac966bfe 100644 --- a/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php +++ b/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php @@ -110,11 +110,13 @@ public function getEnv($prefix, $name, \Closure $getEnv) } if ('const' === $prefix) { + $env = \str_replace("\\\\","\\", $env); + if (!defined($env)) { throw new RuntimeException(sprintf('Env var "%s" maps to undefined constant "%s".', $name, $env)); } - return constant($name); + return constant($env); } if ('base64' === $prefix) { From da39e01eb9ce3bcc083006c1baf8eadc4cf146a7 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Fri, 9 Feb 2018 15:45:43 +0100 Subject: [PATCH 067/166] [TwigBundle][WebProfilerBundle] Fix JS collision --- .../Resources/views/base_js.html.twig | 22 +++++++++++-------- .../views/Profiler/base_js.html.twig | 22 +++++++++++-------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/base_js.html.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/base_js.html.twig index 0ac832ee0610d..1bc9ccf14c06d 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/views/base_js.html.twig +++ b/src/Symfony/Bundle/TwigBundle/Resources/views/base_js.html.twig @@ -37,7 +37,7 @@ addEventListener: addEventListener, createTabs: function() { - var tabGroups = document.querySelectorAll('.sf-tabs'); + var tabGroups = document.querySelectorAll('.sf-tabs:not([data-processed=true])'); /* create the tab navigation for each group of tabs */ for (var i = 0; i < tabGroups.length; i++) { @@ -99,11 +99,13 @@ document.getElementById(activeTabId).className = 'block'; }); } + + tabGroups[i].setAttribute('data-processed', 'true'); } }, createToggles: function() { - var toggles = document.querySelectorAll('.sf-toggle'); + var toggles = document.querySelectorAll('.sf-toggle:not([data-processed=true])'); for (var i = 0; i < toggles.length; i++) { var elementSelector = toggles[i].getAttribute('data-toggle-selector'); @@ -156,14 +158,16 @@ var altContent = toggle.getAttribute('data-toggle-alt-content'); toggle.innerHTML = currentContent !== altContent ? altContent : originalContent; }); - } - /* Prevents from disallowing clicks on links inside toggles */ - var toggleLinks = document.querySelectorAll('.sf-toggle a'); - for (var i = 0; i < toggleLinks.length; i++) { - addEventListener(toggleLinks[i], 'click', function(e) { - e.stopPropagation(); - }); + /* Prevents from disallowing clicks on links inside toggles */ + var toggleLinks = toggles[i].querySelectorAll('a'); + for (var j = 0; j < toggleLinks.length; j++) { + addEventListener(toggleLinks[j], 'click', function(e) { + e.stopPropagation(); + }); + } + + toggles[i].setAttribute('data-processed', 'true'); } } }; diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig index 7b26275ca8907..5c2be8c74c030 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig @@ -393,7 +393,7 @@ }, createTabs: function() { - var tabGroups = document.querySelectorAll('.sf-tabs'); + var tabGroups = document.querySelectorAll('.sf-tabs:not([data-processed=true])'); /* create the tab navigation for each group of tabs */ for (var i = 0; i < tabGroups.length; i++) { @@ -455,11 +455,13 @@ document.getElementById(activeTabId).className = 'block'; }); } + + tabGroups[i].setAttribute('data-processed', 'true'); } }, createToggles: function() { - var toggles = document.querySelectorAll('.sf-toggle'); + var toggles = document.querySelectorAll('.sf-toggle:not([data-processed=true])'); for (var i = 0; i < toggles.length; i++) { var elementSelector = toggles[i].getAttribute('data-toggle-selector'); @@ -512,14 +514,16 @@ var altContent = toggle.getAttribute('data-toggle-alt-content'); toggle.innerHTML = currentContent !== altContent ? altContent : originalContent; }); - } - /* Prevents from disallowing clicks on links inside toggles */ - var toggleLinks = document.querySelectorAll('.sf-toggle a'); - for (var i = 0; i < toggleLinks.length; i++) { - addEventListener(toggleLinks[i], 'click', function(e) { - e.stopPropagation(); - }); + /* Prevents from disallowing clicks on links inside toggles */ + var toggleLinks = toggles[i].querySelectorAll('a'); + for (var j = 0; j < toggleLinks.length; j++) { + addEventListener(toggleLinks[j], 'click', function(e) { + e.stopPropagation(); + }); + } + + toggles[i].setAttribute('data-processed', 'true'); } } }; From 99c5b77319dcbfa9ea1378a27c315feba7eeabd6 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 9 Feb 2018 16:04:34 +0100 Subject: [PATCH 068/166] fix merge --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3eea9310f5fc3..7ed8c84c6e56d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -133,9 +133,6 @@ before_install: - | # Install extra PHP extensions if [[ ! $skip ]]; then - ([[ $deps ]] || tfold ext.symfony_debug 'cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo extension = $(pwd)/modules/symfony_debug.so >> '"$INI") - tfold ext.apcu tpecl apcu-4.0.11 apcu.so - elif [[ ! $skip && $PHP = 7.* ]]; then # install libsodium if [[ ! -e ~/php-ext/$(php -r "echo basename(ini_get('extension_dir'));")/libsodium/sodium.so ]]; then sudo add-apt-repository ppa:ondrej/php -y From ed42760b4115cef776dadb88cd5f9b4a0e08d5d0 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 10 Feb 2018 11:55:44 +0100 Subject: [PATCH 069/166] [Routing] fix typo --- .../Component/Routing/Tests/Fixtures/dumper/url_matcher4.php | 2 +- .../Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher4.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher4.php index 89f2b10e22783..182fcd8f23ad9 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher4.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher4.php @@ -62,7 +62,7 @@ public function match($rawPathinfo) not_get_and_head: // post_and_head - if ('/post_and_get' === $pathinfo) { + if ('/post_and_head' === $pathinfo) { if (!in_array($requestMethod, array('POST', 'HEAD'))) { $allow = array_merge($allow, array('POST', 'HEAD')); goto not_post_and_head; diff --git a/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php b/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php index e4c18c47b144f..f29a6d6a30a17 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php @@ -354,7 +354,7 @@ public function getRouteCollections() array('GET', 'HEAD') )); $headMatchCasesCollection->add('post_and_head', new Route( - '/post_and_get', + '/post_and_head', array(), array(), array(), From b4259a6bf369e27ec22ad6b60bea27c355c70766 Mon Sep 17 00:00:00 2001 From: Lars Strojny Date: Sat, 10 Feb 2018 12:14:07 +0100 Subject: [PATCH 070/166] Use 0 for unlimited expiry --- .../Component/Cache/Traits/FilesystemTrait.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Cache/Traits/FilesystemTrait.php b/src/Symfony/Component/Cache/Traits/FilesystemTrait.php index bcb940cb0f754..23974b3bc5487 100644 --- a/src/Symfony/Component/Cache/Traits/FilesystemTrait.php +++ b/src/Symfony/Component/Cache/Traits/FilesystemTrait.php @@ -36,9 +36,9 @@ public function prune() continue; } - if ($time >= (int) $expiresAt = fgets($h)) { + if (($expiresAt = (int) fgets($h)) && $time >= $expiresAt) { fclose($h); - $pruned = isset($expiresAt[0]) && @unlink($file) && !file_exists($file) && $pruned; + $pruned = @unlink($file) && !file_exists($file) && $pruned; } else { fclose($h); } @@ -60,11 +60,9 @@ protected function doFetch(array $ids) if (!file_exists($file) || !$h = @fopen($file, 'rb')) { continue; } - if ($now >= (int) $expiresAt = fgets($h)) { + if (($expiresAt = (int) fgets($h)) && $now >= $expiresAt) { fclose($h); - if (isset($expiresAt[0])) { - @unlink($file); - } + @unlink($file); } else { $i = rawurldecode(rtrim(fgets($h))); $value = stream_get_contents($h); @@ -94,7 +92,7 @@ protected function doHave($id) protected function doSave(array $values, $lifetime) { $ok = true; - $expiresAt = time() + ($lifetime ?: 31557600); // 31557600s = 1 year + $expiresAt = $lifetime ? (time() + $lifetime) : 0; foreach ($values as $id => $value) { $ok = $this->write($this->getFile($id, true), $expiresAt."\n".rawurlencode($id)."\n".serialize($value), $expiresAt) && $ok; From 48e8249da93e135cca356c9152744200dea7c1a1 Mon Sep 17 00:00:00 2001 From: Lars Strojny Date: Sat, 10 Feb 2018 00:41:50 +0100 Subject: [PATCH 071/166] Make kernel build time optionally deterministic --- src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php | 3 ++- src/Symfony/Component/HttpKernel/Kernel.php | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 0e34dc43da84b..9461e1ccb53f1 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -119,6 +119,7 @@ public function dump(array $options = array()) 'debug' => true, 'hot_path_tag' => 'container.hot_path', 'inline_class_loader_parameter' => 'container.dumper.inline_class_loader', + 'build_time' => time(), ), $options); $this->namespace = $options['namespace']; @@ -216,7 +217,7 @@ public function dump(array $options = array()) array_pop($code); $code["Container{$hash}/{$options['class']}.php"] = substr_replace($files[$options['class'].'.php'], "namespace ? "\nnamespace {$this->namespace};\n" : ''; - $time = time(); + $time = $options['build_time']; $id = hash('crc32', $hash.$time); $code[$options['class'].'.php'] = << true, 'debug' => $this->debug, 'inline_class_loader_parameter' => \PHP_VERSION_ID >= 70000 && !$this->loadClassCache && !class_exists(ClassCollectionLoader::class, false) ? 'container.dumper.inline_class_loader' : null, + 'build_time' => $container->hasParameter('kernel.container_build_time') ? $container->getParameter('kernel.container_build_time') : time(), )); $rootCode = array_pop($content); From 09b9eb2395aa0ea5f5fe55b732e27134e7256df3 Mon Sep 17 00:00:00 2001 From: Tobias Schultze Date: Sun, 11 Feb 2018 01:53:06 +0100 Subject: [PATCH 072/166] [HttpKernel] don't try to wire Request argument with controller.service_arguments This does not make sense as Request is not a service and it's already handled by RequestValueResolver. --- .../RegisterControllerArgumentLocatorsPass.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php index 985dfb71d7064..cb88594e3a042 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php @@ -22,6 +22,7 @@ use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\TypedReference; +use Symfony\Component\HttpFoundation\Request; /** * Creates the service-locators required by ServiceValueResolver. @@ -148,6 +149,10 @@ public function process(ContainerBuilder $container) continue; } + if (Request::class === $type) { + continue; + } + if ($type && !$p->isOptional() && !$p->allowsNull() && !class_exists($type) && !interface_exists($type, false)) { $message = sprintf('Cannot determine controller argument for "%s::%s()": the $%s argument is type-hinted with the non-existent class or interface: "%s".', $class, $r->name, $p->name, $type); From e88e1ff494f9fdd3a91407993d8b4a918698c340 Mon Sep 17 00:00:00 2001 From: Matthieu Napoli Date: Sat, 10 Feb 2018 18:16:30 +0100 Subject: [PATCH 073/166] Document explicitly that dotfiles and vcs files are ignored by default This change makes it clear whether or not each of those two options are enabled by default. Without this documentation one has to look into the code. --- src/Symfony/Component/Finder/Finder.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php index 5784df439b0bf..7b4d71d74eb38 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -402,6 +402,8 @@ public function exclude($dirs) /** * Excludes "hidden" directories and files (starting with a dot). * + * This option is enabled by default. + * * @param bool $ignoreDotFiles Whether to exclude "hidden" files or not * * @return $this @@ -422,6 +424,8 @@ public function ignoreDotFiles($ignoreDotFiles) /** * Forces the finder to ignore version control directories. * + * This option is enabled by default. + * * @param bool $ignoreVCS Whether to exclude VCS files or not * * @return $this From 37fbbca086ae9f7519ed95f141becb1110a6e091 Mon Sep 17 00:00:00 2001 From: Gaylord Poillon Date: Fri, 9 Feb 2018 14:55:34 +0100 Subject: [PATCH 074/166] isCsrfTokenValid() replace string by ?string --- .../Bundle/FrameworkBundle/Controller/ControllerTrait.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php index 6fc94bc8a2a20..1fb263f00f4d3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php @@ -370,12 +370,12 @@ protected function getUser() /** * Checks the validity of a CSRF token. * - * @param string $id The id used when generating the token - * @param string $token The actual token sent with the request that should be validated + * @param string $id The id used when generating the token + * @param string|null $token The actual token sent with the request that should be validated * * @final since version 3.4 */ - protected function isCsrfTokenValid(string $id, string $token): bool + protected function isCsrfTokenValid(string $id, ?string $token): bool { if (!$this->container->has('security.csrf.token_manager')) { throw new \LogicException('CSRF protection is not enabled in your application. Enable it with the "csrf_protection" key in "config/packages/framework.yaml".'); From a9568d7c60a5251c651cb0f4d46f8acc8a6a4003 Mon Sep 17 00:00:00 2001 From: Zan Baldwin Date: Thu, 8 Feb 2018 14:20:36 +0000 Subject: [PATCH 075/166] Update Repository Symlink Helper Add workaround for GLOB_BRACE, which is unavailable on certain platforms (such as Alpine). --- link | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/link b/link index a5030d0683379..6a2ec15e22102 100755 --- a/link +++ b/link @@ -37,7 +37,12 @@ if (!is_dir("$argv[1]/vendor/symfony")) { $sfPackages = array('symfony/symfony' => __DIR__); $filesystem = new Filesystem(); -foreach (glob(__DIR__.'/src/Symfony/{Bundle,Bridge,Component,Component/Security}/*', GLOB_BRACE | GLOB_ONLYDIR | GLOB_NOSORT) as $dir) { +$braces = array('Bundle', 'Bridge', 'Component', 'Component/Security'); +$directories = call_user_func_array('array_merge', array_values(array_map(function ($part) { + return glob(__DIR__.'/src/Symfony/'.$part.'/*', GLOB_ONLYDIR | GLOB_NOSORT); +}, $braces))); + +foreach ($directories as $dir) { if ($filesystem->exists($composer = "$dir/composer.json")) { $sfPackages[json_decode(file_get_contents($composer))->name] = $dir; } From 6f8d5e263edcd8df82c4502c6651e0f1c954320b Mon Sep 17 00:00:00 2001 From: andrey1s Date: Sun, 4 Feb 2018 23:55:07 +0300 Subject: [PATCH 076/166] add context to serialize and deserialize --- src/Symfony/Component/Serializer/CHANGELOG.md | 1 + src/Symfony/Component/Serializer/Serializer.php | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Serializer/CHANGELOG.md b/src/Symfony/Component/Serializer/CHANGELOG.md index 057275e11baef..450640d160227 100644 --- a/src/Symfony/Component/Serializer/CHANGELOG.md +++ b/src/Symfony/Component/Serializer/CHANGELOG.md @@ -10,6 +10,7 @@ CHANGELOG * added getter for extra attributes in `ExtraAttributesException` * improved `CsvEncoder` to handle variable nested structures * CSV headers can be passed to the `CsvEncoder` via the `csv_headers` serialization context variable + * added `$context` when checking for encoding, decoding and normalizing in `Serializer` 3.3.0 ----- diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index 8a689dc61d077..1b244177c78a0 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -108,11 +108,11 @@ public function __construct(array $normalizers = array(), array $encoders = arra */ final public function serialize($data, $format, array $context = array()) { - if (!$this->supportsEncoding($format)) { + if (!$this->supportsEncoding($format, $context)) { throw new NotEncodableValueException(sprintf('Serialization for the format %s is not supported', $format)); } - if ($this->encoder->needsNormalization($format)) { + if ($this->encoder->needsNormalization($format, $context)) { $data = $this->normalize($data, $format, $context); } @@ -124,7 +124,7 @@ final public function serialize($data, $format, array $context = array()) */ final public function deserialize($data, $type, $format, array $context = array()) { - if (!$this->supportsDecoding($format)) { + if (!$this->supportsDecoding($format, $context)) { throw new NotEncodableValueException(sprintf('Deserialization for the format %s is not supported', $format)); } From 2a74edb0f987abd1d132f8d9db79d47d6ef08161 Mon Sep 17 00:00:00 2001 From: Amrouche Hamza Date: Fri, 2 Feb 2018 13:35:25 +0100 Subject: [PATCH 077/166] [Lock] Log already-locked errors as "notice" instead of "warning" --- src/Symfony/Component/Lock/Lock.php | 10 +++---- src/Symfony/Component/Lock/Tests/LockTest.php | 30 +++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Lock/Lock.php b/src/Symfony/Component/Lock/Lock.php index e81878a43725c..77fd032bf1075 100644 --- a/src/Symfony/Component/Lock/Lock.php +++ b/src/Symfony/Component/Lock/Lock.php @@ -89,7 +89,7 @@ public function acquire($blocking = false) return true; } catch (LockConflictedException $e) { $this->dirty = false; - $this->logger->warning('Failed to acquire the "{resource}" lock. Someone else already acquired the lock.', array('resource' => $this->key)); + $this->logger->notice('Failed to acquire the "{resource}" lock. Someone else already acquired the lock.', array('resource' => $this->key)); if ($blocking) { throw $e; @@ -97,7 +97,7 @@ public function acquire($blocking = false) return false; } catch (\Exception $e) { - $this->logger->warning('Failed to acquire the "{resource}" lock.', array('resource' => $this->key, 'exception' => $e)); + $this->logger->notice('Failed to acquire the "{resource}" lock.', array('resource' => $this->key, 'exception' => $e)); throw new LockAcquiringException(sprintf('Failed to acquire the "%s" lock.', $this->key), 0, $e); } } @@ -123,10 +123,10 @@ public function refresh() $this->logger->info('Expiration defined for "{resource}" lock for "{ttl}" seconds.', array('resource' => $this->key, 'ttl' => $this->ttl)); } catch (LockConflictedException $e) { $this->dirty = false; - $this->logger->warning('Failed to define an expiration for the "{resource}" lock, someone else acquired the lock.', array('resource' => $this->key)); + $this->logger->notice('Failed to define an expiration for the "{resource}" lock, someone else acquired the lock.', array('resource' => $this->key)); throw $e; } catch (\Exception $e) { - $this->logger->warning('Failed to define an expiration for the "{resource}" lock.', array('resource' => $this->key, 'exception' => $e)); + $this->logger->notice('Failed to define an expiration for the "{resource}" lock.', array('resource' => $this->key, 'exception' => $e)); throw new LockAcquiringException(sprintf('Failed to define an expiration for the "%s" lock.', $this->key), 0, $e); } } @@ -148,7 +148,7 @@ public function release() $this->dirty = false; if ($this->store->exists($this->key)) { - $this->logger->warning('Failed to release the "{resource}" lock.', array('resource' => $this->key)); + $this->logger->notice('Failed to release the "{resource}" lock.', array('resource' => $this->key)); throw new LockReleasingException(sprintf('Failed to release the "%s" lock.', $this->key)); } } diff --git a/src/Symfony/Component/Lock/Tests/LockTest.php b/src/Symfony/Component/Lock/Tests/LockTest.php index ece5cf667963a..7913644b9a79e 100644 --- a/src/Symfony/Component/Lock/Tests/LockTest.php +++ b/src/Symfony/Component/Lock/Tests/LockTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Lock\Tests; use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; use Symfony\Component\Lock\Exception\LockConflictedException; use Symfony\Component\Lock\Key; use Symfony\Component\Lock\Lock; @@ -192,6 +193,35 @@ public function testReleaseThrowsExceptionIfNotWellDeleted() $lock->release(); } + /** + * @expectedException \Symfony\Component\Lock\Exception\LockReleasingException + */ + public function testReleaseThrowsAndLog() + { + $key = new Key(uniqid(__METHOD__, true)); + $store = $this->getMockBuilder(StoreInterface::class)->getMock(); + $logger = $this->getMockBuilder(LoggerInterface::class)->getMock(); + $lock = new Lock($key, $store, 10, true); + $lock->setLogger($logger); + + $logger->expects($this->atLeastOnce()) + ->method('notice') + ->with('Failed to release the "{resource}" lock.', array('resource' => $key)); + + $store + ->expects($this->once()) + ->method('delete') + ->with($key); + + $store + ->expects($this->once()) + ->method('exists') + ->with($key) + ->willReturn(true); + + $lock->release(); + } + /** * @dataProvider provideExpiredDates */ From a175a25d972b8f5eb758988da9d42ad39dc99191 Mon Sep 17 00:00:00 2001 From: Douglas Greenshields Date: Fri, 2 Feb 2018 15:21:07 +0000 Subject: [PATCH 078/166] [PhpBridge] add PHPUnit 7 support to SymfonyTestsListener --- .../Bridge/PhpUnit/SymfonyTestsListener.php | 6 +- .../SymfonyTestsListenerWithReturnTypes.php | 69 +++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Bridge/PhpUnit/SymfonyTestsListenerWithReturnTypes.php diff --git a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php index c11fde9526eab..7115f31485cbb 100644 --- a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php +++ b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php @@ -16,10 +16,12 @@ use PHPUnit\Framework\TestSuite; use PHPUnit\Framework\Warning; -if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { - class_alias('Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListener', 'Symfony\Bridge\PhpUnit\SymfonyTestsListener'); // Using an early return instead of a else does not work when using the PHPUnit phar due to some weird PHP behavior (the class // gets defined without executing the code before it and so the definition is not properly conditional) +if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { + class_alias('Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListener', 'Symfony\Bridge\PhpUnit\SymfonyTestsListener'); +} elseif (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0', '>=')) { + class_alias('Symfony\Bridge\PhpUnit\SymfonyTestsListenerWithReturnTypes', 'Symfony\Bridge\PhpUnit\SymfonyTestsListener'); } else { /** * Collects and replays skipped tests. diff --git a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListenerWithReturnTypes.php b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListenerWithReturnTypes.php new file mode 100644 index 0000000000000..dfe13afb3f218 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListenerWithReturnTypes.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit; + +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestListener; +use PHPUnit\Framework\TestListenerDefaultImplementation; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Framework\Warning; + +/** + * Collects and replays skipped tests. + * + * (Version of SymfonyTestsListener for PHPUnit 7+, and PHP 7.1+.) + * + * @author Nicolas Grekas + * + * @final + */ +class SymfonyTestsListenerWithReturnTypes implements TestListener +{ + use TestListenerDefaultImplementation; + + private $trait; + + public function __construct(array $mockedNamespaces = array()) + { + $this->trait = new Legacy\SymfonyTestsListenerTrait($mockedNamespaces); + } + + public function globalListenerDisabled() + { + $this->trait->globalListenerDisabled(); + } + + public function startTestSuite(TestSuite $suite): void + { + $this->trait->startTestSuite($suite); + } + + public function addSkippedTest(Test $test, \Throwable $t, float $time): void + { + $this->trait->addSkippedTest($test, $t, $time); + } + + public function startTest(Test $test): void + { + $this->trait->startTest($test); + } + + public function addWarning(Test $test, Warning $e, float $time): void + { + $this->trait->addWarning($test, $e, $time); + } + + public function endTest(Test $test, float $time): void + { + $this->trait->endTest($test, $time); + } +} From c41681cb800194fd084f3e0a96e5615c0b5bcaa3 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 11 Feb 2018 15:19:16 +0100 Subject: [PATCH 079/166] [Bridge\PhpUnit] Cleanup BC layer --- ...ener.php => SymfonyTestsListenerForV5.php} | 12 ++-- .../Legacy/SymfonyTestsListenerForV6.php | 64 +++++++++++++++++++ .../SymfonyTestsListenerForV7.php} | 8 +-- .../Bridge/PhpUnit/SymfonyTestsListener.php | 60 ++--------------- 4 files changed, 77 insertions(+), 67 deletions(-) rename src/Symfony/Bridge/PhpUnit/Legacy/{SymfonyTestsListener.php => SymfonyTestsListenerForV5.php} (76%) create mode 100644 src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV6.php rename src/Symfony/Bridge/PhpUnit/{SymfonyTestsListenerWithReturnTypes.php => Legacy/SymfonyTestsListenerForV7.php} (86%) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListener.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV5.php similarity index 76% rename from src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListener.php rename to src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV5.php index 5ed545a5127cc..2da40f2c204f1 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListener.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV5.php @@ -18,7 +18,7 @@ * * @internal */ -class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener +class SymfonyTestsListenerForV5 extends \PHPUnit_Framework_BaseTestListener { private $trait; @@ -34,26 +34,26 @@ public function globalListenerDisabled() public function startTestSuite(\PHPUnit_Framework_TestSuite $suite) { - return $this->trait->startTestSuite($suite); + $this->trait->startTestSuite($suite); } public function addSkippedTest(\PHPUnit_Framework_Test $test, \Exception $e, $time) { - return $this->trait->addSkippedTest($test, $e, $time); + $this->trait->addSkippedTest($test, $e, $time); } public function startTest(\PHPUnit_Framework_Test $test) { - return $this->trait->startTest($test); + $this->trait->startTest($test); } public function addWarning(\PHPUnit_Framework_Test $test, \PHPUnit_Framework_Warning $e, $time) { - return $this->trait->addWarning($test, $e, $time); + $this->trait->addWarning($test, $e, $time); } public function endTest(\PHPUnit_Framework_Test $test, $time) { - return $this->trait->endTest($test, $time); + $this->trait->endTest($test, $time); } } diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV6.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV6.php new file mode 100644 index 0000000000000..d8e74e81924d5 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV6.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\Legacy; + +use PHPUnit\Framework\BaseTestListener; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Framework\Warning; + +/** + * Collects and replays skipped tests. + * + * @author Nicolas Grekas + * + * @internal + */ +class SymfonyTestsListenerForV6 extends BaseTestListener +{ + private $trait; + + public function __construct(array $mockedNamespaces = array()) + { + $this->trait = new Legacy\SymfonyTestsListenerTrait($mockedNamespaces); + } + + public function globalListenerDisabled() + { + $this->trait->globalListenerDisabled(); + } + + public function startTestSuite(TestSuite $suite) + { + $this->trait->startTestSuite($suite); + } + + public function addSkippedTest(Test $test, \Exception $e, $time) + { + $this->trait->addSkippedTest($test, $e, $time); + } + + public function startTest(Test $test) + { + $this->trait->startTest($test); + } + + public function addWarning(Test $test, Warning $e, $time) + { + $this->trait->addWarning($test, $e, $time); + } + + public function endTest(Test $test, $time) + { + $this->trait->endTest($test, $time); + } +} diff --git a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListenerWithReturnTypes.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV7.php similarity index 86% rename from src/Symfony/Bridge/PhpUnit/SymfonyTestsListenerWithReturnTypes.php rename to src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV7.php index dfe13afb3f218..d3acd53960d29 100644 --- a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListenerWithReturnTypes.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV7.php @@ -20,13 +20,11 @@ /** * Collects and replays skipped tests. * - * (Version of SymfonyTestsListener for PHPUnit 7+, and PHP 7.1+.) - * * @author Nicolas Grekas * - * @final + * @internal */ -class SymfonyTestsListenerWithReturnTypes implements TestListener +class SymfonyTestsListenerForV7 implements TestListener { use TestListenerDefaultImplementation; @@ -34,7 +32,7 @@ class SymfonyTestsListenerWithReturnTypes implements TestListener public function __construct(array $mockedNamespaces = array()) { - $this->trait = new Legacy\SymfonyTestsListenerTrait($mockedNamespaces); + $this->trait = new SymfonyTestsListenerTrait($mockedNamespaces); } public function globalListenerDisabled() diff --git a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php index 7115f31485cbb..d46a79e00eadc 100644 --- a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php +++ b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php @@ -11,62 +11,10 @@ namespace Symfony\Bridge\PhpUnit; -use PHPUnit\Framework\BaseTestListener; -use PHPUnit\Framework\Test; -use PHPUnit\Framework\TestSuite; -use PHPUnit\Framework\Warning; - -// Using an early return instead of a else does not work when using the PHPUnit phar due to some weird PHP behavior (the class -// gets defined without executing the code before it and so the definition is not properly conditional) if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { - class_alias('Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListener', 'Symfony\Bridge\PhpUnit\SymfonyTestsListener'); -} elseif (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0', '>=')) { - class_alias('Symfony\Bridge\PhpUnit\SymfonyTestsListenerWithReturnTypes', 'Symfony\Bridge\PhpUnit\SymfonyTestsListener'); + class_alias('Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerForV5', 'Symfony\Bridge\PhpUnit\SymfonyTestsListener'); +} elseif (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0', '<')) { + class_alias('Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerForV6', 'Symfony\Bridge\PhpUnit\SymfonyTestsListener'); } else { - /** - * Collects and replays skipped tests. - * - * @author Nicolas Grekas - * - * @final - */ - class SymfonyTestsListener extends BaseTestListener - { - private $trait; - - public function __construct(array $mockedNamespaces = array()) - { - $this->trait = new Legacy\SymfonyTestsListenerTrait($mockedNamespaces); - } - - public function globalListenerDisabled() - { - $this->trait->globalListenerDisabled(); - } - - public function startTestSuite(TestSuite $suite) - { - return $this->trait->startTestSuite($suite); - } - - public function addSkippedTest(Test $test, \Exception $e, $time) - { - return $this->trait->addSkippedTest($test, $e, $time); - } - - public function startTest(Test $test) - { - return $this->trait->startTest($test); - } - - public function addWarning(Test $test, Warning $e, $time) - { - return $this->trait->addWarning($test, $e, $time); - } - - public function endTest(Test $test, $time) - { - return $this->trait->endTest($test, $time); - } - } + class_alias('Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerForV7', 'Symfony\Bridge\PhpUnit\SymfonyTestsListener'); } From 97370a3dd9b34bc6447b8921be611d200cdbac14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Thu, 1 Feb 2018 23:45:44 +0100 Subject: [PATCH 080/166] [Bridge\PhpUnit] Exit as late as possible People might want to register other shutdown functions that should be able to control the exit code themselves, without the deprecation error handler taking over. The php manual says: > If you call exit() within one registered shutdown function, processing > will stop completely and no other registered shutdown functions will be > called. See https://secure.php.net/manual/en/function.register-shutdown-function.php --- .../PhpUnit/DeprecationErrorHandler.php | 53 +++++++---- .../DeprecationErrorHandler/default.phpt | 5 + .../shutdown_deprecations.phpt | 91 +++++++++++++++++++ 3 files changed, 133 insertions(+), 16 deletions(-) create mode 100644 src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/shutdown_deprecations.phpt diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index f73690db00553..b0f241c862496 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -127,32 +127,53 @@ public static function register($mode = false) return $b['count'] - $a['count']; }; - foreach (array('unsilenced', 'remaining', 'legacy', 'other') as $group) { - if ($deprecations[$group.'Count']) { - echo "\n", $colorize(sprintf('%s deprecation notices (%d)', ucfirst($group), $deprecations[$group.'Count']), 'legacy' !== $group), "\n"; + $displayDeprecations = function ($deprecations) use ($colorize, $cmp) { + foreach (array('unsilenced', 'remaining', 'legacy', 'other') as $group) { + if ($deprecations[$group.'Count']) { + echo "\n", $colorize(sprintf('%s deprecation notices (%d)', ucfirst($group), $deprecations[$group.'Count']), 'legacy' !== $group), "\n"; - uasort($deprecations[$group], $cmp); + uasort($deprecations[$group], $cmp); - foreach ($deprecations[$group] as $msg => $notices) { - echo "\n ", $notices['count'], 'x: ', $msg, "\n"; + foreach ($deprecations[$group] as $msg => $notices) { + echo "\n ", $notices['count'], 'x: ', $msg, "\n"; - arsort($notices); + arsort($notices); - foreach ($notices as $method => $count) { - if ('count' !== $method) { - echo ' ', $count, 'x in ', preg_replace('/(.*)\\\\(.*?::.*?)$/', '$2 from $1', $method), "\n"; + foreach ($notices as $method => $count) { + if ('count' !== $method) { + echo ' ', $count, 'x in ', preg_replace('/(.*)\\\\(.*?::.*?)$/', '$2 from $1', $method), "\n"; + } } } } } - } - if (!empty($notices)) { - echo "\n"; - } + if (!empty($notices)) { + echo "\n"; + } + }; + + $displayDeprecations($deprecations); - if ('weak' !== $mode && ($deprecations['unsilenced'] || $deprecations['remaining'] || $deprecations['other'])) { - exit(1); + // store failing status + $isFailing = 'weak' !== $mode && ($deprecations['unsilenced'] || $deprecations['remaining'] || $deprecations['other']); + + // reset deprecations array + foreach ($deprecations as $group => $arrayOrInt) { + $deprecations[$group] = is_int($arrayOrInt) ? 0 : array(); } + + register_shutdown_function(function () use (&$deprecations, $isFailing, $displayDeprecations, $mode) { + foreach ($deprecations as $group => $arrayOrInt) { + if (0 < (is_int($arrayOrInt) ? $arrayOrInt : count($arrayOrInt))) { + echo "Shutdown-time deprecations:\n"; + break; + } + } + $displayDeprecations($deprecations); + if ($isFailing || 'weak' !== $mode && ($deprecations['unsilenced'] || $deprecations['remaining'] || $deprecations['other'])) { + exit(1); + } + }); }); } } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt index 39a3e985865fd..7a0595a7ddebc 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/default.phpt @@ -59,6 +59,10 @@ $foo = new FooTestCase(); $foo->testLegacyFoo(); $foo->testNonLegacyBar(); +register_shutdown_function(function () { + exit('I get precedence over any exit statements inside the deprecation error handler.'); +}); + ?> --EXPECTF-- Unsilenced deprecation notices (3) @@ -80,3 +84,4 @@ Other deprecation notices (1) 1x: root deprecation +I get precedence over any exit statements inside the deprecation error handler. diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/shutdown_deprecations.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/shutdown_deprecations.phpt new file mode 100644 index 0000000000000..fddeed6085dea --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/shutdown_deprecations.phpt @@ -0,0 +1,91 @@ +--TEST-- +Test DeprecationErrorHandler in default mode +--FILE-- +testLegacyFoo(); +$foo->testNonLegacyBar(); + +register_shutdown_function(function () { + @trigger_error('root deprecation during shutdown', E_USER_DEPRECATED); +}); + +?> +--EXPECTF-- +Unsilenced deprecation notices (3) + + 2x: unsilenced foo deprecation + 2x in FooTestCase::testLegacyFoo + + 1x: unsilenced bar deprecation + 1x in FooTestCase::testNonLegacyBar + +Remaining deprecation notices (1) + + 1x: silenced bar deprecation + 1x in FooTestCase::testNonLegacyBar + +Legacy deprecation notices (1) + +Other deprecation notices (1) + + 1x: root deprecation + +Shutdown-time deprecations: + +Other deprecation notices (1) + + 1x: root deprecation during shutdown From aa956636ab538d7ad5210b69087dbc6af5b12d28 Mon Sep 17 00:00:00 2001 From: Thomas Counsell Date: Tue, 6 Feb 2018 16:18:24 +0000 Subject: [PATCH 081/166] [YAML] Issue #26065: leading spaces in YAML multi-line string literals --- src/Symfony/Component/Yaml/Dumper.php | 5 ++++- src/Symfony/Component/Yaml/Tests/DumperTest.php | 11 +++++++++++ ...s_as_literal_block_leading_space_in_first_line.yml | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 41562358bc988..0513044d2fcd3 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -98,7 +98,10 @@ public function dump($input, $inline = 0, $indent = 0, $flags = 0) foreach ($input as $key => $value) { if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r\n")) { - $output .= sprintf("%s%s%s |\n", $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', ''); + // If the first line starts with a space character, the spec requires a blockIndicationIndicator + // http://www.yaml.org/spec/1.2/spec.html#id2793979 + $blockIndentationIndicator = (' ' === substr($value, 0, 1)) ? (string) $this->indentation : ''; + $output .= sprintf("%s%s%s |%s\n", $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '', $blockIndentationIndicator); foreach (preg_split('/\n|\r\n/', $value) as $row) { $output .= sprintf("%s%s%s\n", $prefix, str_repeat(' ', $this->indentation), $row); diff --git a/src/Symfony/Component/Yaml/Tests/DumperTest.php b/src/Symfony/Component/Yaml/Tests/DumperTest.php index a29dff20f76db..b474391132286 100644 --- a/src/Symfony/Component/Yaml/Tests/DumperTest.php +++ b/src/Symfony/Component/Yaml/Tests/DumperTest.php @@ -454,6 +454,17 @@ public function testDumpMultiLineStringAsScalarBlock() $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)); } + public function testDumpMultiLineStringAsScalarBlockWhenFirstLineHasLeadingSpace() + { + $data = array( + 'data' => array( + 'multi_line' => " the first line has leading spaces\nThe second line does not.", + ), + ); + + $this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml'), $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); + } + public function testCarriageReturnIsMaintainedWhenDumpingAsMultiLineLiteralBlock() { $this->assertSame("- \"a\\r\\nb\\nc\"\n", $this->dumper->dump(array("a\r\nb\nc"), 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); diff --git a/src/Symfony/Component/Yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml b/src/Symfony/Component/Yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml new file mode 100644 index 0000000000000..3f2dedd10e682 --- /dev/null +++ b/src/Symfony/Component/Yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml @@ -0,0 +1,4 @@ +data: + multi_line: |4 + the first line has leading spaces + The second line does not. From c8c27e5434b5938cda443aa889ea7949e6951496 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 11 Feb 2018 18:30:10 +0100 Subject: [PATCH 082/166] fix merge --- src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index 44cbf9e618fd7..90cea694c35b6 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -215,13 +215,13 @@ public static function register($mode = 0) return $b['count'] - $a['count']; }; - $displayDeprecations = function ($deprecations) use ($colorize, $cmp) { - $groups = array('unsilenced', 'remaining'); - if (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode) { + $groups = array('unsilenced', 'remaining'); + if (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode) { $groups[] = 'remaining vendor'; - } - array_push($groups, 'legacy', 'other'); + } + array_push($groups, 'legacy', 'other'); + $displayDeprecations = function ($deprecations) use ($colorize, $cmp, $groups) { foreach ($groups as $group) { if ($deprecations[$group.'Count']) { echo "\n", $colorize( From 292fb56c70309e84dff1a82ad77ac09e6d7666ea Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 11 Feb 2018 18:56:58 +0100 Subject: [PATCH 083/166] [Bridge/PhpUnit] hotfix --- .../Legacy/SymfonyTestsListenerForV6.php | 2 +- .../Bridge/PhpUnit/Legacy/TestRunner.php | 4 +- src/Symfony/Bridge/PhpUnit/TextUI/Command.php | 24 ++++----- .../Bridge/PhpUnit/TextUI/TestRunner.php | 50 +++++++++---------- 4 files changed, 38 insertions(+), 42 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV6.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV6.php index d8e74e81924d5..5b864bfe58a32 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV6.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV6.php @@ -29,7 +29,7 @@ class SymfonyTestsListenerForV6 extends BaseTestListener public function __construct(array $mockedNamespaces = array()) { - $this->trait = new Legacy\SymfonyTestsListenerTrait($mockedNamespaces); + $this->trait = new SymfonyTestsListenerTrait($mockedNamespaces); } public function globalListenerDisabled() diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/TestRunner.php b/src/Symfony/Bridge/PhpUnit/Legacy/TestRunner.php index 4bbf2f1cb9724..8a57416bd241f 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/TestRunner.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/TestRunner.php @@ -23,7 +23,7 @@ class TestRunner extends \PHPUnit_TextUI_TestRunner */ protected function handleConfiguration(array &$arguments) { - $listener = new SymfonyTestsListener(); + $listener = new SymfonyTestsListenerForV5(); $result = parent::handleConfiguration($arguments); @@ -32,7 +32,7 @@ protected function handleConfiguration(array &$arguments) $registeredLocally = false; foreach ($arguments['listeners'] as $registeredListener) { - if ($registeredListener instanceof SymfonyTestsListener) { + if ($registeredListener instanceof SymfonyTestsListenerForV5) { $registeredListener->globalListenerDisabled(); $registeredLocally = true; break; diff --git a/src/Symfony/Bridge/PhpUnit/TextUI/Command.php b/src/Symfony/Bridge/PhpUnit/TextUI/Command.php index 408533292a656..869a8a8dbe85d 100644 --- a/src/Symfony/Bridge/PhpUnit/TextUI/Command.php +++ b/src/Symfony/Bridge/PhpUnit/TextUI/Command.php @@ -15,22 +15,20 @@ if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { class_alias('Symfony\Bridge\PhpUnit\Legacy\Command', 'Symfony\Bridge\PhpUnit\TextUI\Command'); - - return; -} - -/** - * {@inheritdoc} - * - * @internal - */ -class Command extends BaseCommand -{ +} else { /** * {@inheritdoc} + * + * @internal */ - protected function createRunner() + class Command extends BaseCommand { - return new TestRunner($this->arguments['loader']); + /** + * {@inheritdoc} + */ + protected function createRunner() + { + return new TestRunner($this->arguments['loader']); + } } } diff --git a/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php b/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php index 07fe2d165b627..4e1fdca4d54be 100644 --- a/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php +++ b/src/Symfony/Bridge/PhpUnit/TextUI/TestRunner.php @@ -16,42 +16,40 @@ if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunner', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner'); - - return; -} - -/** - * {@inheritdoc} - * - * @internal - */ -class TestRunner extends BaseRunner -{ +} else { /** * {@inheritdoc} + * + * @internal */ - protected function handleConfiguration(array &$arguments) + class TestRunner extends BaseRunner { - $listener = new SymfonyTestsListener(); + /** + * {@inheritdoc} + */ + protected function handleConfiguration(array &$arguments) + { + $listener = new SymfonyTestsListener(); - $result = parent::handleConfiguration($arguments); + $result = parent::handleConfiguration($arguments); - $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array(); + $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array(); - $registeredLocally = false; + $registeredLocally = false; - foreach ($arguments['listeners'] as $registeredListener) { - if ($registeredListener instanceof SymfonyTestsListener) { - $registeredListener->globalListenerDisabled(); - $registeredLocally = true; - break; + foreach ($arguments['listeners'] as $registeredListener) { + if ($registeredListener instanceof SymfonyTestsListener) { + $registeredListener->globalListenerDisabled(); + $registeredLocally = true; + break; + } } - } - if (!$registeredLocally) { - $arguments['listeners'][] = $listener; - } + if (!$registeredLocally) { + $arguments['listeners'][] = $listener; + } - return $result; + return $result; + } } } From edd507af788decb13eab076e801896879b7c09ba Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 11 Feb 2018 19:37:22 +0100 Subject: [PATCH 084/166] [Bridge/PhpUnit] fix tests --- .../weak_vendors_on_eval_d_deprecation.phpt | 2 ++ .../weak_vendors_on_phar_deprecation.phpt | 2 ++ .../weak_vendors_on_vendor.phpt | 11 +++++++++++ 3 files changed, 15 insertions(+) diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_eval_d_deprecation.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_eval_d_deprecation.phpt index 6bba1c86be5ac..8fa436e20178b 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_eval_d_deprecation.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_eval_d_deprecation.phpt @@ -21,3 +21,5 @@ eval("@trigger_error('who knows where I come from?', E_USER_DEPRECATED);") --EXPECTF-- Other deprecation notices (1) + + 1x: who knows where I come from? diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_phar_deprecation.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_phar_deprecation.phpt index 4c4879e61156d..7a583f95337d9 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_phar_deprecation.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_phar_deprecation.phpt @@ -23,3 +23,5 @@ include 'phar://deprecation.phar/deprecation.php'; --EXPECTF-- Other deprecation notices (1) + + 1x: I come from… afar! :D diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt index 7e9c6f8ed7682..67e5458a17507 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt @@ -22,8 +22,19 @@ require __DIR__.'/fake_vendor/acme/lib/deprecation_riddled.php'; --EXPECTF-- Unsilenced deprecation notices (2) + 1x: unsilenced foo deprecation + 1x in FooTestCase::testLegacyFoo + + 1x: unsilenced bar deprecation + 1x in FooTestCase::testNonLegacyBar + Remaining vendor deprecation notices (1) + 1x: silenced bar deprecation + 1x in FooTestCase::testNonLegacyBar + Legacy deprecation notices (1) Other deprecation notices (1) + + 1x: root deprecation From 9a9c0f6142d5685c0ca9684825683faed5eaa788 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 11 Feb 2018 22:40:17 +0100 Subject: [PATCH 085/166] [Bridge/PhpUnit] Fix tests by backporting #25997 to 3.4 --- src/Symfony/Bridge/PhpUnit/CHANGELOG.md | 2 ++ .../Bridge/PhpUnit/DeprecationErrorHandler.php | 11 +++++------ .../fake_vendor/acme/lib/deprecation_riddled.php | 2 ++ .../PhpUnit/Tests/DeprecationErrorHandler/weak.phpt | 1 - .../weak_vendors_on_vendor.phpt | 8 ++++---- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/CHANGELOG.md b/src/Symfony/Bridge/PhpUnit/CHANGELOG.md index 39ae3a881b3b1..5c6ee47309d95 100644 --- a/src/Symfony/Bridge/PhpUnit/CHANGELOG.md +++ b/src/Symfony/Bridge/PhpUnit/CHANGELOG.md @@ -5,6 +5,8 @@ CHANGELOG ----- * added a `CoverageListener` to enhance the code coverage report + * all deprecations but those from tests marked with `@group legacy` are always + displayed when not in `weak` mode 3.3.0 ----- diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index 90cea694c35b6..e14d218708c77 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -110,8 +110,7 @@ public static function register($mode = 0) $trace = debug_backtrace(true); $group = 'other'; - $isVendor = false; - $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = $inVendors($file)); + $isVendor = DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $inVendors($file); $i = count($trace); while (1 < $i && (!isset($trace[--$i]['class']) || ('ReflectionMethod' === $trace[$i]['class'] || 0 === strpos($trace[$i]['class'], 'PHPUnit_') || 0 === strpos($trace[$i]['class'], 'PHPUnit\\')))) { @@ -128,7 +127,7 @@ public static function register($mode = 0) // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest() // then we need to use the serialized information to determine // if the error has been triggered from vendor code. - $isWeak = DeprecationErrorHandler::MODE_WEAK === $mode || (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor = isset($parsedMsg['triggering_file']) && $inVendors($parsedMsg['triggering_file'])); + $isVendor = DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && isset($parsedMsg['triggering_file']) && $inVendors($parsedMsg['triggering_file']); } else { $class = isset($trace[$i]['object']) ? get_class($trace[$i]['object']) : $trace[$i]['class']; $method = $trace[$i]['function']; @@ -145,7 +144,7 @@ public static function register($mode = 0) || in_array('legacy', $Test::getGroups($class, $method), true) ) { $group = 'legacy'; - } elseif (DeprecationErrorHandler::MODE_WEAK_VENDORS === $mode && $isVendor) { + } elseif ($isVendor) { $group = 'remaining vendor'; } else { $group = 'remaining'; @@ -165,13 +164,13 @@ public static function register($mode = 0) exit(1); } - if ('legacy' !== $group && !$isWeak) { + if ('legacy' !== $group && DeprecationErrorHandler::MODE_WEAK !== $mode) { $ref = &$deprecations[$group][$msg]['count']; ++$ref; $ref = &$deprecations[$group][$msg][$class.'::'.$method]; ++$ref; } - } elseif (!$isWeak) { + } elseif (DeprecationErrorHandler::MODE_WEAK !== $mode) { $ref = &$deprecations[$group][$msg]['count']; ++$ref; } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/deprecation_riddled.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/deprecation_riddled.php index 6f5123d4feb0c..16a58246d2115 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/deprecation_riddled.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/deprecation_riddled.php @@ -21,6 +21,8 @@ public function testLegacyFoo() { @trigger_error('silenced foo deprecation', E_USER_DEPRECATED); trigger_error('unsilenced foo deprecation', E_USER_DEPRECATED); + @trigger_error('silenced foo deprecation', E_USER_DEPRECATED); + trigger_error('unsilenced foo deprecation', E_USER_DEPRECATED); } public function testNonLegacyBar() diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak.phpt index 9e78d96e70efb..8137a2ff44876 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak.phpt @@ -37,4 +37,3 @@ Unsilenced deprecation notices (1) Legacy deprecation notices (1) Other deprecation notices (1) - diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt index 67e5458a17507..68e233df7d0d9 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt @@ -20,10 +20,10 @@ require __DIR__.'/fake_vendor/acme/lib/deprecation_riddled.php'; ?> --EXPECTF-- -Unsilenced deprecation notices (2) +Unsilenced deprecation notices (3) - 1x: unsilenced foo deprecation - 1x in FooTestCase::testLegacyFoo + 2x: unsilenced foo deprecation + 2x in FooTestCase::testLegacyFoo 1x: unsilenced bar deprecation 1x in FooTestCase::testNonLegacyBar @@ -33,7 +33,7 @@ Remaining vendor deprecation notices (1) 1x: silenced bar deprecation 1x in FooTestCase::testNonLegacyBar -Legacy deprecation notices (1) +Legacy deprecation notices (2) Other deprecation notices (1) From a0d8b04f7fe93de908869633ebaa5647d051384b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rokas=20Mikalk=C4=97nas?= Date: Mon, 12 Feb 2018 08:50:32 +0200 Subject: [PATCH 086/166] Typo fix in security component lithuanian translation. --- .../Security/Core/Resources/translations/security.lt.xlf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.lt.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.lt.xlf index da6c332b43829..63e1ed662ee37 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.lt.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.lt.xlf @@ -8,7 +8,7 @@ Authentication credentials could not be found. - Nepavyko rasti autentifikacijos duomneų. + Nepavyko rasti autentifikacijos duomenų. Authentication request could not be processed due to a system problem. From 2f7f9efbc67c400141242c1a0e12b486ef161af1 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 12 Feb 2018 08:05:20 +0100 Subject: [PATCH 087/166] fixed typo --- .../Component/Security/Resources/translations/security.lt.xlf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Security/Resources/translations/security.lt.xlf b/src/Symfony/Component/Security/Resources/translations/security.lt.xlf index da6c332b43829..63e1ed662ee37 100644 --- a/src/Symfony/Component/Security/Resources/translations/security.lt.xlf +++ b/src/Symfony/Component/Security/Resources/translations/security.lt.xlf @@ -8,7 +8,7 @@ Authentication credentials could not be found. - Nepavyko rasti autentifikacijos duomneų. + Nepavyko rasti autentifikacijos duomenų. Authentication request could not be processed due to a system problem. From 60abecafb91dce9d4cccc7fb7abcff3ea3ccc762 Mon Sep 17 00:00:00 2001 From: ergiegonzaga <36328355+ergiegonzaga@users.noreply.github.com> Date: Sat, 10 Feb 2018 18:44:21 +0800 Subject: [PATCH 088/166] [Security][Validator] Add translations for Tagalog --- .../Resources/translations/security.tl.xlf | 71 ++++ .../Resources/translations/validators.tl.xlf | 319 ++++++++++++++++++ 2 files changed, 390 insertions(+) create mode 100644 src/Symfony/Component/Security/Core/Resources/translations/security.tl.xlf create mode 100644 src/Symfony/Component/Validator/Resources/translations/validators.tl.xlf diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.tl.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.tl.xlf new file mode 100644 index 0000000000000..c74b10aea83ab --- /dev/null +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.tl.xlf @@ -0,0 +1,71 @@ + + + + + + An authentication exception occurred. + Isang pambihirang pagpaptunay ang nangyari. + + + Authentication credentials could not be found. + Hindi mahanap ang mga kinakailangan na dokumento para sa pagpapatunay. + + + Authentication request could not be processed due to a system problem. + Hindi maproseso ang iyong hiling dahil may problema sa sistema. + + + Invalid credentials. + Hindi balidong mga dokumento. + + + Cookie has already been used by someone else. + Ang Cookie ay ginamit na ng ibang tao. + + + Not privileged to request the resource. + Walang pribilehiyo upang humingi ng mga bagong mapagkukunan. + + + Invalid CSRF token. + Hindi balidong mga token ng CSRF. + + + Digest nonce has expired. + Na-expire na ang Digest nonce. + + + No authentication provider found to support the authentication token. + Walang nakitang nagbibibagay ng suporta sa token ng pagpapatunay. + + + No session available, it either timed out or cookies are not enabled. + Walang sesyon ng magagamit, ito ay nawalan ng oras o hindi pinagana. + + + No token could be found. + Walang token na nahanap. + + + Username could not be found. + Walang username na makita. + + + Account has expired. + Ang akawnt ay nag-expire na. + + + Credentials have expired. + .ng mga kinakailangang dokumento ay nag expire na. + + + Account is disabled. + Ang akawnt ay hindi pinagana. + + + Account is locked. + ng akawnt ay nakasara. + + + + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.tl.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.tl.xlf new file mode 100644 index 0000000000000..75dc329589730 --- /dev/null +++ b/src/Symfony/Component/Validator/Resources/translations/validators.tl.xlf @@ -0,0 +1,319 @@ + + + + + + This value should be false. + Ang halaga nito ay dapat na huwad. + + + This value should be true. + Ang halaga nito ay dapat totoo. + + + This value should be of type {{ type }}. + Ang halaga nito ay dapat sa uri {{ type }}. + + + This value should be blank. + Ang halaga nito ay dapat walang laman. + + + The value you selected is not a valid choice. + Ang halaga ng iyong pinili ay hindi balidong pagpili. + + + You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. + Kailangan mong pumili ng pinakamababang {{ limit }} ng pagpilian.|Kailangan mong pumili ng pinakamababang {{ limit }} ng mga pagpipilian. + + + You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. + Kailangan mong pumili ng pinakamataas {{ limit }} ng pagpipilian.|Kailangan mong pumili ng pinakamataas {{ limit }} ng mga pagpipilian. + + + One or more of the given values is invalid. + Isa o higit pang mga halaga na binigay ay hindi balido. + + + This field was not expected. + Ang larangang ito ay hindi inaasahan. + + + This field is missing. + Ang patlang na ito ay nawawala. + + + This value is not a valid date. + Ang halagang ito ay hindi balidong petsa. + + + This value is not a valid datetime. + Ang halagang ito ay hindi wastong petsa/oras. + + + This value is not a valid email address. + Ang halagang ito ay hindi balidong address ng email. + + + The file could not be found. + Ang file na ito ay hindi makita. + + + The file is not readable. + Ang file na ito ay hindi mabasa. + + + The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. + Ang file na ito ay masyadong malaki ({{ size }} {{ suffix }}). Ang pinakamalaking sukat {{ limit }} {{ suffix }}. + + + The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. + Ang uri ng file ng mime ay hindi balido ({{ type }}).Ang mga pinapayagang uri ng mime ay ang {{ types }}. + + + This value should be {{ limit }} or less. + Ang halaga nito ay dapat na {{ limit }} or maliit pa. + + + This value is too long. It should have {{ limit }} character or less.|This value is too long. It should have {{ limit }} characters or less. + Ang halaga nito ay masyadong mahaba.Ito ay dapat na {{ limit }} karakter o maliit pa.|Ang halaga nito ay masyadong mahaba. Ito ay dapat na {{ limit }} mga karakter o maliit pa. + + + This value should be {{ limit }} or more. + Ang halaga nito ay dapat na {{ limit }} o mas marami pa. + + + This value is too short. It should have {{ limit }} character or more.|This value is too short. It should have {{ limit }} characters or more. + Ang halaga nito ay masyadong maliit. Ito ay dapat na {{ limit }} karakter o marami pa.|Ang halaga nito ay masyadong maliit. Ito ay dapat na {{ limit }} mga karakter o marami pa. + + + This value should not be blank. + Ang halaga na ito ay dapat na may laman. + + + This value should not be null. + Meron dapt itong halaga. + + + This value should be null. + Wala dapat itong halaga. + + + This value is not valid. + Hindi balido ang halagang ito. + + + This value is not a valid time. + Ang halagang ito ay hindi wastong oras. + + + This value is not a valid URL. + Hindi ito isang balidong URL. + + + The two values should be equal. + Ang dalwang halaga ay dapat magkapareha. + + + The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. + Ang file ay masyadong malaki. Ang pinapayagan halaga lamang ay {{ limit}} {{ suffix }}. + + + The file is too large. + Ang file na ito ay masyadong malaki. + + + The file could not be uploaded. + Ang file na ito ay hindi ma-upload. + + + This value should be a valid number. + Ang halaga nito ay dapat na wastong numero. + + + This file is not a valid image. + Ang file na ito ay hindi wastong imahe. + + + This is not a valid IP address. + Ito ay hindi wastong IP address. + + + This value is not a valid language. + Ang halaga na ito ay hindi balidong wika. + + + This value is not a valid locale. + Ito ay isang hindi wastong locale na halaga. + + + This value is not a valid country. + ng halaga na ito ay hindi wastong bansa. + + + This value is already used. + Ang halaga na ito ay ginamit na. + + + The size of the image could not be detected. + Ang sukat ng imahe ay hindi madetect. + + + The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. + Ang lapad ng imahe ay masyadong malaki ({{ width }}px). Ang pinapayagang lapay ay {{ max_width }}px. + + + The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. + Ang lapad ng imahe ay masyadong maliit ({{ width }}px). Ang pinakamaliit na pinapayagang lapad ay {{ min_width }}px. + + + The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. + Ang haba ng imahe ay masyadong mataas ({{ height }}px). Ang pinakmataas na haba ay {{ max_height }}px. + + + The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. + Ang haba ng imahe ay masyadong maliit ({{ height }}px). Ang inaasahang haba ay {{ min_height }}px. + + + This value should be the user's current password. + Ang halagang ito ay dapat na password ng kasalukuyang gumagamit. + + + This value should have exactly {{ limit }} character.|This value should have exactly {{ limit }} characters. + Ang halagang ito ay dapat na eksakto sa {{ limit}} karakter.|Ang halagang ito ay dapat na eksakto sa {{ limit }} mga karakter. + + + The file was only partially uploaded. + Ang file na ito ay kahalating na upload lamang. + + + No file was uploaded. + Walang na upload na file. + + + No temporary folder was configured in php.ini. + Walang temporaryong folder ang naayos sa php.ini. + + + Cannot write temporary file to disk. + Temporaryong hindi makasulat ng file sa disk. + + + A PHP extension caused the upload to fail. + Ang dahilan ng pagkabigo ng pagupload ng files ay isang extension ng PHP. + + + This collection should contain {{ limit }} element or more.|This collection should contain {{ limit }} elements or more. + Ang koleksyon na ito ay dapat magkaroon ng {{ limit }} elemento o marami pa.|Ang koleksyon na ito ay dapat magkaroon ng {{ limit }} mga elemento o marami pa. + + + This collection should contain {{ limit }} element or less.|This collection should contain {{ limit }} elements or less. + Ang koleksyon na ito ay dapat magkaroon ng {{ limit }} elemento o maliit pa.|Ang koleksyon na ito ay dapat magkaroon ng {{ limit }} mga elemento o maliit pa. + + + This collection should contain exactly {{ limit }} element.|This collection should contain exactly {{ limit }} elements. + Ang koleksyong ito ay magkaroon ng eksaktong {{ limit }} elemento.|Ang koleksyong ito ay magkaroon ng eksaktong {{ limit }} mga elemento. + + + Invalid card number. + Hindi wastong numero ng kard. + + + Unsupported card type or invalid card number. + Hindi supportadong uri ng kard o hindi wastong numero ng kard. + + + This is not a valid International Bank Account Number (IBAN). + Ito ay hindi isang balidong International Bank Account Number (IBAN). + + + This value is not a valid ISBN-10. + Ang halagang ito ay hindi balidong SBN-10. + + + This value is not a valid ISBN-13. + Ang halagang ito ay hindi balidong ISBN-13. + + + This value is neither a valid ISBN-10 nor a valid ISBN-13. + Ang halagang ito ay pwdeng isang balidong ISBN-10 o isang balidong ISBN-13. + + + This value is not a valid ISSN. + Ang halangang ito ay hindi isang balidong ISSN. + + + This value is not a valid currency. + Ang halagang ito ay hindi balidong pera. + + + This value should be equal to {{ compared_value }}. + Ito ay hindi dapat magkapareho sa {{ compared_value }}. + + + This value should be greater than {{ compared_value }}. + Ang halagang ito ay dapat tataas sa {{ compared_value }}. + + + This value should be greater than or equal to {{ compared_value }}. + Ang halagang ito ay dapat mas mataas o magkapareha sa {{ compared_value }}. + + + This value should be identical to {{ compared_value_type }} {{ compared_value }}. + Ang halagang ito ay dapat kapareha ng {{ compared_value_type }} {{ compared_value }}. + + + This value should be less than {{ compared_value }}. + Ang halagang ito ay dapat mas maliit sa {{ compared_value }}. + + + This value should be less than or equal to {{ compared_value }}. + Ang halagang ito ay dapat mas mmaliit o magkapareha sa {{ compared_value }}. + + + This value should not be equal to {{ compared_value }}. + Ang halagang ito ay hindi dapat magkapareha sa {{ compared_value }}. + + + This value should not be identical to {{ compared_value_type }} {{ compared_value }}. + Ang halagang ito ay hindi dapat magkapareha sa {{ compared_value_type }} {{ compared_value }}. + + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Ang ratio ng imahe ay masyadong malaki ({{ ratio }}). Ang pinakamalaking ratio ay {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + ng ratio ng imahe ay masyadong maliit ({{ ratio }}). Ang pinamaliit na ratio ay {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Ang imahe ay kwadrado ({{ width }}x{{ height }}px). Ang mga kwadradong imahe ay hindi pwede. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Ang orientasyon ng imahe ay nakalandscape ({{ width }}x{{ height }}px). Ang mga imaheng nakalandscape ang orientasyon ay hindi pwede. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Ang orientasyon ng imahe ay nakaportrait ({{ width }}x{{ height }}px). PAng mga imaheng nakaportrait ang orientasyon ay hindi pwede. + + + An empty file is not allowed. + Ang file na walang laman ay hindi pwede. + + + The host could not be resolved. + Hindi maresolba ang host. + + + This value does not match the expected {{ charset }} charset. + Ang halaga ay hindi kapareha sa inaasahang {{ charset }} set ng karater. + + + This is not a valid Business Identifier Code (BIC). + Ito ay hindi isang balidong Business Identifier Code (BIC). + + + + From 45d288a4ae365c10035775cacee7262df1b92c7f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 12 Feb 2018 15:12:46 +0100 Subject: [PATCH 089/166] Add security.tl.xlf to legacy directory --- .../Resources/translations/security.tl.xlf | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/Symfony/Component/Security/Resources/translations/security.tl.xlf diff --git a/src/Symfony/Component/Security/Resources/translations/security.tl.xlf b/src/Symfony/Component/Security/Resources/translations/security.tl.xlf new file mode 100644 index 0000000000000..c74b10aea83ab --- /dev/null +++ b/src/Symfony/Component/Security/Resources/translations/security.tl.xlf @@ -0,0 +1,71 @@ + + + + + + An authentication exception occurred. + Isang pambihirang pagpaptunay ang nangyari. + + + Authentication credentials could not be found. + Hindi mahanap ang mga kinakailangan na dokumento para sa pagpapatunay. + + + Authentication request could not be processed due to a system problem. + Hindi maproseso ang iyong hiling dahil may problema sa sistema. + + + Invalid credentials. + Hindi balidong mga dokumento. + + + Cookie has already been used by someone else. + Ang Cookie ay ginamit na ng ibang tao. + + + Not privileged to request the resource. + Walang pribilehiyo upang humingi ng mga bagong mapagkukunan. + + + Invalid CSRF token. + Hindi balidong mga token ng CSRF. + + + Digest nonce has expired. + Na-expire na ang Digest nonce. + + + No authentication provider found to support the authentication token. + Walang nakitang nagbibibagay ng suporta sa token ng pagpapatunay. + + + No session available, it either timed out or cookies are not enabled. + Walang sesyon ng magagamit, ito ay nawalan ng oras o hindi pinagana. + + + No token could be found. + Walang token na nahanap. + + + Username could not be found. + Walang username na makita. + + + Account has expired. + Ang akawnt ay nag-expire na. + + + Credentials have expired. + .ng mga kinakailangang dokumento ay nag expire na. + + + Account is disabled. + Ang akawnt ay hindi pinagana. + + + Account is locked. + ng akawnt ay nakasara. + + + + From d317496b6b7f783c4a76871c169eb05cda3c714c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 12 Feb 2018 15:17:16 +0100 Subject: [PATCH 090/166] [Process] fix test case --- src/Symfony/Component/Process/PhpExecutableFinder.php | 2 +- src/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Process/PhpExecutableFinder.php b/src/Symfony/Component/Process/PhpExecutableFinder.php index 25415eda793bd..4bc27fe4d4574 100644 --- a/src/Symfony/Component/Process/PhpExecutableFinder.php +++ b/src/Symfony/Component/Process/PhpExecutableFinder.php @@ -62,7 +62,7 @@ public function find($includeArgs = true) } } - if (is_executable($php = PHP_BINDIR.'/php'.('\\' === DIRECTORY_SEPARATOR ? '.exe' : ''))) { + if (is_executable($php = PHP_BINDIR.('\\' === DIRECTORY_SEPARATOR ? '\\php.exe' : '/php'))) { return $php; } diff --git a/src/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php b/src/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php index 23465e9e808d1..250534d675a90 100644 --- a/src/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php +++ b/src/Symfony/Component/Process/Tests/PhpExecutableFinderTest.php @@ -94,7 +94,7 @@ public function testFindWithSuffix() //TODO maybe php executable is custom or even Windows if ('\\' === DIRECTORY_SEPARATOR) { $this->assertTrue(is_executable($current)); - $this->assertTrue((bool) preg_match('/'.addslashes(DIRECTORY_SEPARATOR).'php\.(exe|bat|cmd|com)$/i', $current), '::find() returns the executable PHP with suffixes'); + $this->assertRegExp('/\\\\php\.(exe|bat|cmd|com)$/i', $current, '::find() returns the executable PHP with suffixes'); } } } From 92842814f6693ee3c4e24cca5d061eb4de50eb5d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 8 Feb 2018 21:27:30 +0100 Subject: [PATCH 091/166] [Routing] Throw 405 instead of 404 when redirect is not possible --- .../Matcher/Dumper/PhpMatcherDumper.php | 55 +++++++++++-------- .../Tests/Fixtures/dumper/url_matcher2.php | 15 +++++ .../DumpedRedirectableUrlMatcherTest.php | 8 +++ 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php index 28ab3679f9fa8..ac48ca978fd3f 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -217,7 +217,7 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren $methods[] = 'HEAD'; } - $supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('HEAD', $methods)); + $supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('GET', $methods)); if (!count($compiledRoute->getPathVariables()) && false !== preg_match('#^(.)\^(?P.*?)\$\1#', $compiledRoute->getRegex(), $m)) { if ($supportsTrailingSlash && '/' === substr($m['url'], -1)) { @@ -258,34 +258,13 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren EOF; $gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name); - if ($methods) { - if (1 === count($methods)) { - $code .= <<context->getMethod() != '$methods[0]') { - \$allow[] = '$methods[0]'; - goto $gotoname; - } - - -EOF; - } else { - $methods = implode("', '", $methods); - $code .= <<context->getMethod(), array('$methods'))) { - \$allow = array_merge(\$allow, array('$methods')); - goto $gotoname; - } - - -EOF; - } - } if ($hasTrailingSlash) { $code .= <<context->getMethod(), array('HEAD', 'GET'))) { + \$allow[] = 'GET'; goto $gotoname; } else { return \$this->redirect(\$rawPathinfo.'/', '$name'); @@ -303,6 +282,11 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren $code .= <<context->getScheme()])) { + if (!in_array(\$this->context->getMethod(), array('HEAD', 'GET'))) { + \$allow[] = 'GET'; + goto $gotoname; + } + return \$this->redirect(\$rawPathinfo, '$name', key(\$requiredSchemes)); } @@ -310,6 +294,29 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren EOF; } + if ($methods) { + if (1 === count($methods)) { + $code .= <<context->getMethod() != '$methods[0]') { + \$allow[] = '$methods[0]'; + goto $gotoname; + } + + +EOF; + } else { + $methods = implode("', '", $methods); + $code .= <<context->getMethod(), array('$methods'))) { + \$allow = array_merge(\$allow, array('$methods')); + goto $gotoname; + } + + +EOF; + } + } + // optimize parameters array if ($matches || $hostMatches) { $vars = array(); @@ -333,7 +340,7 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren } $code .= " }\n"; - if ($methods || $hasTrailingSlash) { + if ($hasTrailingSlash || $schemes || $methods) { $code .= " $gotoname:\n"; } diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php index a7e7ce75be537..467d53b3ed2df 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php @@ -69,6 +69,7 @@ public function match($rawPathinfo) if ('/' === substr($pathinfo, -1)) { // no-op } elseif (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) { + $allow[] = 'GET'; goto not_baz3; } else { return $this->redirect($rawPathinfo.'/', 'baz3'); @@ -85,6 +86,7 @@ public function match($rawPathinfo) if ('/' === substr($pathinfo, -1)) { // no-op } elseif (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) { + $allow[] = 'GET'; goto not_baz4; } else { return $this->redirect($rawPathinfo.'/', 'baz4'); @@ -183,6 +185,7 @@ public function match($rawPathinfo) if ('/' === substr($pathinfo, -1)) { // no-op } elseif (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) { + $allow[] = 'GET'; goto not_hey; } else { return $this->redirect($rawPathinfo.'/', 'hey'); @@ -333,21 +336,33 @@ public function match($rawPathinfo) if ('/secure' === $pathinfo) { $requiredSchemes = array ( 'https' => 0,); if (!isset($requiredSchemes[$this->context->getScheme()])) { + if (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) { + $allow[] = 'GET'; + goto not_secure; + } + return $this->redirect($rawPathinfo, 'secure', key($requiredSchemes)); } return array('_route' => 'secure'); } + not_secure: // nonsecure if ('/nonsecure' === $pathinfo) { $requiredSchemes = array ( 'http' => 0,); if (!isset($requiredSchemes[$this->context->getScheme()])) { + if (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) { + $allow[] = 'GET'; + goto not_nonsecure; + } + return $this->redirect($rawPathinfo, 'nonsecure', key($requiredSchemes)); } return array('_route' => 'nonsecure'); } + not_nonsecure: throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException(); } diff --git a/src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php index 28f65aeeb5aa7..7ea8aa2834167 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/DumpedRedirectableUrlMatcherTest.php @@ -19,6 +19,14 @@ class DumpedRedirectableUrlMatcherTest extends RedirectableUrlMatcherTest { + /** + * @expectedException \Symfony\Component\Routing\Exception\MethodNotAllowedException + */ + public function testRedirectWhenNoSlashForNonSafeMethod() + { + parent::testRedirectWhenNoSlashForNonSafeMethod(); + } + protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null) { static $i = 0; From 01ccae828ce19cc1b682f50e0c6b081808382d05 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 12 Feb 2018 19:00:05 +0100 Subject: [PATCH 092/166] Fix merge --- .../Component/Routing/Matcher/Dumper/PhpMatcherDumper.php | 2 +- .../Component/Routing/Tests/Fixtures/dumper/url_matcher2.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php index 1e2b6ccc20f2d..5d1839b2de02a 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -327,7 +327,7 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren $code .= <<getScheme()])) { - if (!in_array(\$this->context->getMethod(), array('HEAD', 'GET'))) { + if ('GET' !== \$canonicalMethod) { \$allow[] = 'GET'; goto $gotoname; } diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php index 85f91690d478d..7f27184d8a2a4 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php @@ -347,7 +347,7 @@ public function match($rawPathinfo) $ret = array('_route' => 'secure'); $requiredSchemes = array ( 'https' => 0,); if (!isset($requiredSchemes[$context->getScheme()])) { - if (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) { + if ('GET' !== $canonicalMethod) { $allow[] = 'GET'; goto not_secure; } @@ -364,7 +364,7 @@ public function match($rawPathinfo) $ret = array('_route' => 'nonsecure'); $requiredSchemes = array ( 'http' => 0,); if (!isset($requiredSchemes[$context->getScheme()])) { - if (!in_array($this->context->getMethod(), array('HEAD', 'GET'))) { + if ('GET' !== $canonicalMethod) { $allow[] = 'GET'; goto not_nonsecure; } From 6d4e5e0d0ae329b43cd3966d4afb0583be6233fa Mon Sep 17 00:00:00 2001 From: Ergie Gonzaga <36328355+ergiegonzaga@users.noreply.github.com> Date: Tue, 13 Feb 2018 11:42:56 +0800 Subject: [PATCH 093/166] [Form] Add translations for Tagalog --- .../Resources/translations/validators.tl.xlf | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/Symfony/Component/Form/Resources/translations/validators.tl.xlf diff --git a/src/Symfony/Component/Form/Resources/translations/validators.tl.xlf b/src/Symfony/Component/Form/Resources/translations/validators.tl.xlf new file mode 100644 index 0000000000000..02def0bf31f6f --- /dev/null +++ b/src/Symfony/Component/Form/Resources/translations/validators.tl.xlf @@ -0,0 +1,19 @@ + + + + + + This form should not contain extra fields. + Ang pormang itong ay hindi dapat magkarron ng dagdag na mga patlang. + + + The uploaded file was too large. Please try to upload a smaller file. + Ang ini-upload na file ay masyadong malaki. Pakiulit muling mag-upload ng mas maliit na file. + + + The CSRF token is invalid. Please try to resubmit the form. + Hindi balido ang CSRF token. Maagpasa muli ng isang pang porma. + + + + From cf4e95662ee85ed46e9110b525a368401fc06af1 Mon Sep 17 00:00:00 2001 From: Mathieu Piot Date: Mon, 8 Jan 2018 10:39:34 +0100 Subject: [PATCH 094/166] [TwigBridge] Apply some changes to support Bootstrap4-stable --- .../views/Form/bootstrap_4_layout.html.twig | 106 ++++++++++-------- .../Form/bootstrap_base_layout.html.twig | 2 +- 2 files changed, 61 insertions(+), 47 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig index 12981e346232e..34fc47e8ecc9b 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig @@ -3,11 +3,25 @@ {# Widgets #} {% block money_widget -%} - {% if not valid %} - {% set group_class = ' form-control is-invalid' %} - {% set valid = true %} - {% endif %} - {{- parent() -}} + {%- set prepend = not (money_pattern starts with '{{') -%} + {%- set append = not (money_pattern ends with '}}') -%} + {%- if prepend or append -%} +
+ {%- if prepend -%} +
+ {{ money_pattern|replace({ '{{ widget }}':''}) }} +
+ {%- endif -%} + {{- block('form_widget_simple') -}} + {%- if append -%} +
+ {{ money_pattern|replace({ '{{ widget }}':''}) }} +
+ {%- endif -%} +
+ {%- else -%} + {{- block('form_widget_simple') -}} + {%- endif -%} {%- endblock money_widget %} {% block datetime_widget -%} @@ -39,7 +53,6 @@ {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) -%} {% set valid = true %} {%- endif -%} - {%- if widget == 'single_text' -%} {{- block('form_widget_simple') -}} {%- else -%} @@ -80,7 +93,9 @@
{% set valid = true %} {{- block('form_widget_simple') -}} - % +
+ % +
{%- endblock percent_widget %} @@ -93,7 +108,7 @@ {%- block widget_attributes -%} {%- if not valid %} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) %} + {% set attr = attr|merge({class: (attr.class|default('') ~ ' is-invalid')|trim}) %} {% endif -%} {{ parent() }} {%- endblock widget_attributes -%} @@ -105,15 +120,14 @@ {% block checkbox_widget -%} {%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%} - {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%} - {% if 'checkbox-inline' in parent_label_class %} - {{- form_label(form, null, { widget: parent() }) -}} - {% elseif 'form-check-inline' in parent_label_class %} -
+ {%- if 'checkbox-custom' in parent_label_class -%} + {%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-control-input')|trim}) -%} +
{{- form_label(form, null, { widget: parent() }) -}}
- {% else -%} -
+ {%- else -%} + {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%} +
{{- form_label(form, null, { widget: parent() }) -}}
{%- endif -%} @@ -121,18 +135,21 @@ {% block radio_widget -%} {%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%} - {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%} - {%- if 'radio-inline' in parent_label_class -%} - {{- form_label(form, null, { widget: parent() }) -}} + {%- if 'radio-custom' in parent_label_class -%} + {%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-control-input')|trim}) -%} +
+ {{- form_label(form, null, { widget: parent() }) -}} +
{%- else -%} -
+ {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%} +
{{- form_label(form, null, { widget: parent() }) -}}
{%- endif -%} {%- endblock radio_widget %} {% block choice_widget_expanded -%} - {% if '-inline' in label_attr.class|default('') -%} +
{%- for child in form %} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), @@ -140,20 +157,7 @@ valid: valid, }) -}} {% endfor -%} - {%- else -%} - {%- if not valid -%} - {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) %} - {%- endif -%} -
- {%- for child in form %} - {{- form_widget(child, { - parent_label_class: label_attr.class|default(''), - translation_domain: choice_translation_domain, - valid: true, - }) -}} - {% endfor -%} -
- {%- endif %} +
{%- endblock choice_widget_expanded %} {# Labels #} @@ -162,7 +166,7 @@ {% if label is not same as(false) -%} {%- if compound is defined and compound -%} {%- set element = 'legend' -%} - {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-legend')|trim}) -%} + {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-label')|trim}) -%} {%- else -%} {%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%} {%- endif -%} @@ -179,19 +183,26 @@ {% set label = name|humanize %} {%- endif -%} {%- endif -%} - <{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}{% block form_label_errors %}{{- form_errors(form) -}}{% endblock form_label_errors %} + <{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}{{- form_errors(form) -}} {%- endif -%} {%- endblock form_label %} {% block checkbox_radio_label -%} {#- Do not display the label if widget is not defined in order to prevent double label rendering -#} {%- if widget is defined -%} - {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' form-check-label')|trim}) -%} + {%- if parent_label_class is defined and ('checkbox-custom' in parent_label_class or 'radio-custom' in parent_label_class) -%} + {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' custom-control-label')|trim}) -%} + {%- else %} + {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' form-check-label')|trim}) -%} + {%- endif %} + {%- if not compound -%} + {% set label_attr = label_attr|merge({'for': id}) %} + {%- endif -%} {%- if required -%} {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) -%} {%- endif -%} {%- if parent_label_class is defined -%} - {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) -%} + {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|replace({'checkbox-inline': '', 'radio-inline': '', 'checkbox-custom': '', 'radio-custom': ''})|trim}) -%} {%- endif -%} {%- if label is not same as(false) and label is empty -%} {%- if label_format is not empty -%} @@ -203,8 +214,11 @@ {%- set label = name|humanize -%} {%- endif -%} {%- endif -%} + + {{ widget|raw }} - {{- widget|raw }} {{ label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans({}, translation_domain)) -}} + {{ label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans({}, translation_domain)) -}} + {{- form_errors(form) -}} {%- endif -%} {%- endblock checkbox_radio_label %} @@ -225,12 +239,12 @@ {% block form_errors -%} {%- if errors|length > 0 -%} -
-
    - {%- for error in errors -%} -
  • {{ error.message }}
  • - {%- endfor -%} -
-
+
+
    + {%- for error in errors -%} +
  • {{ error.message }}
  • + {%- endfor -%} +
+
{%- endif %} {%- endblock form_errors %} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig index d57978220f330..71aedf99ad1fa 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig @@ -147,7 +147,7 @@ {% block choice_label -%} {# remove the checkbox-inline and radio-inline class, it's only useful for embed labels #} - {%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': ''})|trim}) -%} + {%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': '', 'checkbox-custom': '', 'radio-custom': ''})|trim}) -%} {{- block('form_label') -}} {% endblock choice_label %} From 34d27817d40aae56b492d152f6458b5c26350169 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Tue, 13 Feb 2018 18:35:53 +0100 Subject: [PATCH 095/166] Avoid running the remove command without any packages As the exit code of the command was not checked, the failure was not breaking things, but it was still printing a confusing error message. --- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit index fd7c800fedfd7..2f97e32e11819 100755 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit @@ -77,7 +77,9 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__ $zip->extractTo(getcwd()); $zip->close(); chdir("phpunit-$PHPUNIT_VERSION"); - passthru("$COMPOSER remove --no-update ".$SYMFONY_PHPUNIT_REMOVE); + if ($SYMFONY_PHPUNIT_REMOVE) { + passthru("$COMPOSER remove --no-update ".$SYMFONY_PHPUNIT_REMOVE); + } if (5.1 <= $PHPUNIT_VERSION && $PHPUNIT_VERSION < 5.4) { passthru("$COMPOSER require --no-update phpunit/phpunit-mock-objects \"~3.1.0\""); } From 1fc5df683b99374c7210d677f002f1dc9373c106 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 14 Feb 2018 10:05:17 +0100 Subject: [PATCH 096/166] fix accessing request values --- .../Http/Firewall/SimpleFormAuthenticationListener.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php b/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php index 1ec87da4cb1a3..9d87c59c888eb 100644 --- a/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php @@ -119,9 +119,13 @@ protected function attemptAuthentication(Request $request) } } - $requestBag = $this->options['post_only'] ? $request->request : $request; - $username = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['username_parameter']); - $password = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['password_parameter']); + if ($this->options['post_only']) { + $username = ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']); + $password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']); + } else { + $username = ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']); + $password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']); + } if (!\is_string($username) || (\is_object($username) && !\method_exists($username, '__toString'))) { throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], \gettype($username))); From 6c0e6af47a5f36b906892537f5b2fbf15dab30b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Thu, 8 Feb 2018 11:41:17 +0100 Subject: [PATCH 097/166] [PhpUnitBridge] Added support for PHPUnit 7 in Coverage Listener --- .../Bridge/PhpUnit/CoverageListener.php | 32 ++------------- ...Listener.php => CoverageListenerForV5.php} | 2 +- .../PhpUnit/Legacy/CoverageListenerForV6.php | 38 +++++++++++++++++ .../PhpUnit/Legacy/CoverageListenerForV7.php | 41 +++++++++++++++++++ .../PhpUnit/Tests/CoverageListenerTest.php | 4 +- .../Fixtures/coverage/tests/bootstrap.php | 8 +++- 6 files changed, 94 insertions(+), 31 deletions(-) rename src/Symfony/Bridge/PhpUnit/Legacy/{CoverageListener.php => CoverageListenerForV5.php} (91%) create mode 100644 src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerForV6.php create mode 100644 src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerForV7.php diff --git a/src/Symfony/Bridge/PhpUnit/CoverageListener.php b/src/Symfony/Bridge/PhpUnit/CoverageListener.php index e6b4e7ec98b8b..79333fbd00221 100644 --- a/src/Symfony/Bridge/PhpUnit/CoverageListener.php +++ b/src/Symfony/Bridge/PhpUnit/CoverageListener.php @@ -11,34 +11,10 @@ namespace Symfony\Bridge\PhpUnit; -use PHPUnit\Framework\BaseTestListener; -use PHPUnit\Framework\Test; -use Symfony\Bridge\PhpUnit\Legacy\CoverageListenerTrait; - if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { - class_alias('Symfony\Bridge\PhpUnit\Legacy\CoverageListener', 'Symfony\Bridge\PhpUnit\CoverageListener'); -// Using an early return instead of a else does not work when using the PHPUnit -// phar due to some weird PHP behavior (the class gets defined without executing -// the code before it and so the definition is not properly conditional) + class_alias('Symfony\Bridge\PhpUnit\Legacy\CoverageListenerForV5', 'Symfony\Bridge\PhpUnit\CoverageListener'); +} elseif (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0', '<')) { + class_alias('Symfony\Bridge\PhpUnit\Legacy\CoverageListenerForV6', 'Symfony\Bridge\PhpUnit\CoverageListener'); } else { - /** - * CoverageListener adds `@covers ` on each test suite when possible - * to make the code coverage more accurate. - * - * @author Grégoire Pineau - */ - class CoverageListener extends BaseTestListener - { - private $trait; - - public function __construct(callable $sutFqcnResolver = null, $warningOnSutNotFound = false) - { - $this->trait = new CoverageListenerTrait($sutFqcnResolver, $warningOnSutNotFound); - } - - public function startTest(Test $test) - { - $this->trait->startTest($test); - } - } + class_alias('Symfony\Bridge\PhpUnit\Legacy\CoverageListenerForV7', 'Symfony\Bridge\PhpUnit\CoverageListener'); } diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListener.php b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerForV5.php similarity index 91% rename from src/Symfony/Bridge/PhpUnit/Legacy/CoverageListener.php rename to src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerForV5.php index 0227828515760..4bf19223f3c16 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListener.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerForV5.php @@ -19,7 +19,7 @@ * * @internal */ -class CoverageListener extends \PHPUnit_Framework_BaseTestListener +class CoverageListenerForV5 extends \PHPUnit_Framework_BaseTestListener { private $trait; diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerForV6.php b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerForV6.php new file mode 100644 index 0000000000000..f0dfc7577cd03 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerForV6.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\Legacy; + +use PHPUnit\Framework\BaseTestListener; +use PHPUnit\Framework\Test; + +/** + * CoverageListener adds `@covers ` on each test suite when possible + * to make the code coverage more accurate. + * + * @author Grégoire Pineau + * + * @internal + */ +class CoverageListenerForV6 extends BaseTestListener +{ + private $trait; + + public function __construct(callable $sutFqcnResolver = null, $warningOnSutNotFound = false) + { + $this->trait = new CoverageListenerTrait($sutFqcnResolver, $warningOnSutNotFound); + } + + public function startTest(Test $test) + { + $this->trait->startTest($test); + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerForV7.php b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerForV7.php new file mode 100644 index 0000000000000..699d4bde35cc4 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerForV7.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\Legacy; + +use PHPUnit\Framework\TestListener; +use PHPUnit\Framework\TestListenerDefaultImplementation; +use PHPUnit\Framework\TestSuite; + +/** + * CoverageListener adds `@covers ` on each test suite when possible + * to make the code coverage more accurate. + * + * @author Grégoire Pineau + * + * @internal + */ +class CoverageListenerForV7 implements TestListener +{ + use TestListenerDefaultImplementation; + + private $trait; + + public function __construct(callable $sutFqcnResolver = null, $warningOnSutNotFound = false) + { + $this->trait = new CoverageListenerTrait($sutFqcnResolver, $warningOnSutNotFound); + } + + public function startTestSuite(TestSuite $suite): void + { + $this->trait->startTest($test); + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php b/src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php index b07effe3d27dc..957499dfb6a2b 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php @@ -16,7 +16,9 @@ public function test() $this->markTestSkipped('This test cannot be run on HHVM.'); } - if (\PHP_VERSION_ID >= 70000) { + exec('type phpdbg', $output, $returnCode); + + if (\PHP_VERSION_ID >= 70000 && 0 === $returnCode) { $php = 'phpdbg -qrr'; } else { exec('php --ri xdebug -d zend_extension=xdebug.so 2> /dev/null', $output, $returnCode); diff --git a/src/Symfony/Bridge/PhpUnit/Tests/Fixtures/coverage/tests/bootstrap.php b/src/Symfony/Bridge/PhpUnit/Tests/Fixtures/coverage/tests/bootstrap.php index 925f4831ac89d..241006431acea 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/Fixtures/coverage/tests/bootstrap.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/Fixtures/coverage/tests/bootstrap.php @@ -13,7 +13,13 @@ require __DIR__.'/../src/FooCov.php'; require __DIR__.'/../../../../Legacy/CoverageListenerTrait.php'; + if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) { - require __DIR__.'/../../../../Legacy/CoverageListener.php'; + require_once __DIR__.'/../../../../Legacy/CoverageListenerForV5.php'; +} elseif (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0', '<')) { + require_once __DIR__.'/../../../../Legacy/CoverageListenerForV6.php'; +} else { + require_once __DIR__.'/../../../../Legacy/CoverageListenerForV7.php'; } + require __DIR__.'/../../../../CoverageListener.php'; From 777acfbac996c2c8d8a2805a5e57e6137dde5709 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 7 Feb 2018 21:12:42 +0100 Subject: [PATCH 098/166] do not mock the container builder in tests --- .../Compiler/CachePoolPrunerPassTest.php | 24 ++-- .../Compiler/ConfigCachePassTest.php | 11 +- .../Compiler/LoggingTranslatorPassTest.php | 109 +++++++----------- .../Compiler/PropertyInfoPassTest.php | 24 ++-- .../Compiler/SerializerPassTest.php | 48 +++----- .../Compiler/UnusedTagsPassTest.php | 25 ++-- .../ConstraintValidatorFactoryTest.php | 82 ++++++------- .../Compiler/TwigLoaderPassTest.php | 1 - .../ConfigCachePassTest.php | 11 +- .../Compiler/ExtensionCompilerPassTest.php | 61 +++++++--- .../RegisterListenersPassTest.php | 65 ++++------- .../FragmentRendererPassTest.php | 70 +++-------- .../PropertyInfoPassTest.php | 24 ++-- .../SerializerPassTest.php | 48 +++----- .../TranslationDumperPassTest.php | 46 +++----- .../TranslationExtractorPassTest.php | 69 +++-------- ...ontainerConstraintValidatorFactoryTest.php | 53 ++++----- .../AddConstraintValidatorsPassTest.php | 18 ++- .../ValidateWorkflowsPassTest.php | 28 ++--- 19 files changed, 306 insertions(+), 511 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPrunerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPrunerPassTest.php index 0006070f51ddb..105760641c34f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPrunerPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPrunerPassTest.php @@ -44,27 +44,17 @@ public function testCompilerPassReplacesCommandArgument() public function testCompilePassIsIgnoredIfCommandDoesNotExist() { - $container = $this - ->getMockBuilder(ContainerBuilder::class) - ->setMethods(array('hasDefinition', 'getDefinition', 'findTaggedServiceIds')) - ->getMock(); - - $container - ->expects($this->atLeastOnce()) - ->method('hasDefinition') - ->with(CachePoolPruneCommand::class) - ->will($this->returnValue(false)); - - $container - ->expects($this->never()) - ->method('getDefinition'); + $container = new ContainerBuilder(); - $container - ->expects($this->never()) - ->method('findTaggedServiceIds'); + $definitionsBefore = count($container->getDefinitions()); + $aliasesBefore = count($container->getAliases()); $pass = new CachePoolPrunerPass(); $pass->process($container); + + // the container is untouched (i.e. no new definitions or aliases) + $this->assertCount($definitionsBefore, $container->getDefinitions()); + $this->assertCount($aliasesBefore, $container->getAliases()); } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ConfigCachePassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ConfigCachePassTest.php index e2348972d09c7..e229108cbc422 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ConfigCachePassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/ConfigCachePassTest.php @@ -44,13 +44,16 @@ public function testThatCheckersAreProcessedInPriorityOrder() public function testThatCheckersCanBeMissing() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('findTaggedServiceIds'))->getMock(); + $container = new ContainerBuilder(); - $container->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue(array())); + $definitionsBefore = count($container->getDefinitions()); + $aliasesBefore = count($container->getAliases()); $pass = new ConfigCachePass(); $pass->process($container); + + // the container is untouched (i.e. no new definitions or aliases) + $this->assertCount($definitionsBefore, $container->getDefinitions()); + $this->assertCount($aliasesBefore, $container->getAliases()); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php index a93d8ca5d0015..2a9b3329142cb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php @@ -13,96 +13,69 @@ use PHPUnit\Framework\TestCase; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\LoggingTranslatorPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; class LoggingTranslatorPassTest extends TestCase { public function testProcess() { - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->getMock(); - $parameterBag = $this->getMockBuilder('Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface')->getMock(); - - $container->expects($this->exactly(2)) - ->method('hasAlias') - ->will($this->returnValue(true)); - - $container->expects($this->once()) - ->method('getParameter') - ->will($this->returnValue(true)); - - $container->expects($this->once()) - ->method('getAlias') - ->will($this->returnValue('translation.default')); - - $container->expects($this->exactly(3)) - ->method('getDefinition') - ->will($this->returnValue($definition)); - - $container->expects($this->once()) - ->method('hasParameter') - ->with('translator.logging') - ->will($this->returnValue(true)); - - $definition->expects($this->once()) - ->method('getClass') - ->will($this->returnValue('Symfony\Bundle\FrameworkBundle\Translation\Translator')); - - $parameterBag->expects($this->once()) - ->method('resolveValue') - ->will($this->returnValue("Symfony\Bundle\FrameworkBundle\Translation\Translator")); - - $container->expects($this->once()) - ->method('getParameterBag') - ->will($this->returnValue($parameterBag)); - - $container->expects($this->once()) - ->method('getReflectionClass') - ->with('Symfony\Bundle\FrameworkBundle\Translation\Translator') - ->will($this->returnValue(new \ReflectionClass('Symfony\Bundle\FrameworkBundle\Translation\Translator'))); - - $definition->expects($this->once()) - ->method('getTag') - ->with('container.service_subscriber') - ->willReturn(array(array('id' => 'translator'), array('id' => 'foo'))); - - $definition->expects($this->once()) - ->method('clearTag') - ->with('container.service_subscriber'); - - $definition->expects($this->any()) - ->method('addTag') - ->withConsecutive( - array('container.service_subscriber', array('id' => 'foo')), - array('container.service_subscriber', array('key' => 'translator', 'id' => 'translator.logging.inner')) - ); + $container = new ContainerBuilder(); + $container->setParameter('translator.logging', true); + $container->setParameter('translator.class', 'Symfony\Component\Translation\Translator'); + $container->register('monolog.logger'); + $container->setAlias('logger', 'monolog.logger'); + $container->register('translator.default', '%translator.class%'); + $container->register('translator.logging', '%translator.class%'); + $container->setAlias('translator', 'translator.default'); + $translationWarmerDefinition = $container->register('translation.warmer') + ->addArgument(new Reference('translator')) + ->addTag('container.service_subscriber', array('id' => 'translator')) + ->addTag('container.service_subscriber', array('id' => 'foo')); $pass = new LoggingTranslatorPass(); $pass->process($container); + + $this->assertEquals( + array('container.service_subscriber' => array( + array('id' => 'foo'), + array('key' => 'translator', 'id' => 'translator.logging.inner'), + )), + $translationWarmerDefinition->getTags() + ); } public function testThatCompilerPassIsIgnoredIfThereIsNotLoggerDefinition() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->getMock(); - $container->expects($this->once()) - ->method('hasAlias') - ->will($this->returnValue(false)); + $container = new ContainerBuilder(); + $container->register('identity_translator'); + $container->setAlias('translator', 'identity_translator'); + + $definitionsBefore = count($container->getDefinitions()); + $aliasesBefore = count($container->getAliases()); $pass = new LoggingTranslatorPass(); $pass->process($container); + + // the container is untouched (i.e. no new definitions or aliases) + $this->assertCount($definitionsBefore, $container->getDefinitions()); + $this->assertCount($aliasesBefore, $container->getAliases()); } public function testThatCompilerPassIsIgnoredIfThereIsNotTranslatorDefinition() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->getMock(); - $container->expects($this->at(0)) - ->method('hasAlias') - ->will($this->returnValue(true)); + $container = new ContainerBuilder(); + $container->register('monolog.logger'); + $container->setAlias('logger', 'monolog.logger'); - $container->expects($this->at(0)) - ->method('hasAlias') - ->will($this->returnValue(false)); + $definitionsBefore = count($container->getDefinitions()); + $aliasesBefore = count($container->getAliases()); $pass = new LoggingTranslatorPass(); $pass->process($container); + + // the container is untouched (i.e. no new definitions or aliases) + $this->assertCount($definitionsBefore, $container->getDefinitions()); + $this->assertCount($aliasesBefore, $container->getAliases()); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/PropertyInfoPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/PropertyInfoPassTest.php index 19b25bccb9729..c7b2e3927b61b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/PropertyInfoPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/PropertyInfoPassTest.php @@ -57,24 +57,16 @@ public function provideTags() public function testReturningEmptyArrayWhenNoService() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('findTaggedServiceIds'))->getMock(); - - $container - ->expects($this->any()) - ->method('findTaggedServiceIds') - ->will($this->returnValue(array())) - ; + $container = new ContainerBuilder(); + $propertyInfoExtractorDefinition = $container->register('property_info') + ->setArguments(array(array(), array(), array(), array())); $propertyInfoPass = new PropertyInfoPass(); + $propertyInfoPass->process($container); - $method = new \ReflectionMethod( - 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PropertyInfoPass', - 'findAndSortTaggedServices' - ); - $method->setAccessible(true); - - $actual = $method->invoke($propertyInfoPass, 'tag', $container); - - $this->assertEquals(array(), $actual); + $this->assertEquals(new IteratorArgument(array()), $propertyInfoExtractorDefinition->getArgument(0)); + $this->assertEquals(new IteratorArgument(array()), $propertyInfoExtractorDefinition->getArgument(1)); + $this->assertEquals(new IteratorArgument(array()), $propertyInfoExtractorDefinition->getArgument(2)); + $this->assertEquals(new IteratorArgument(array()), $propertyInfoExtractorDefinition->getArgument(3)); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SerializerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SerializerPassTest.php index 8ad759e834592..6dfb4255dd4fb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SerializerPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/SerializerPassTest.php @@ -25,48 +25,30 @@ */ class SerializerPassTest extends TestCase { + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage You must tag at least one service as "serializer.normalizer" to use the "serializer" service + */ public function testThrowExceptionWhenNoNormalizers() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds'))->getMock(); - - $container->expects($this->once()) - ->method('hasDefinition') - ->with('serializer') - ->will($this->returnValue(true)); - - $container->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('serializer.normalizer') - ->will($this->returnValue(array())); - - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('RuntimeException'); + $container = new ContainerBuilder(); + $container->register('serializer'); $serializerPass = new SerializerPass(); $serializerPass->process($container); } + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage You must tag at least one service as "serializer.encoder" to use the "serializer" service + */ public function testThrowExceptionWhenNoEncoders() { - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - - $container->expects($this->once()) - ->method('hasDefinition') - ->with('serializer') - ->will($this->returnValue(true)); - - $container->expects($this->any()) - ->method('findTaggedServiceIds') - ->will($this->onConsecutiveCalls( - array('n' => array('serializer.normalizer')), - array() - )); - - $container->expects($this->any()) - ->method('getDefinition') - ->will($this->returnValue($definition)); - - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('RuntimeException'); + $container = new ContainerBuilder(); + $container->register('serializer') + ->addArgument(array()) + ->addArgument(array()); + $container->register('normalizer')->addTag('serializer.normalizer'); $serializerPass = new SerializerPass(); $serializerPass->process($container); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/UnusedTagsPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/UnusedTagsPassTest.php index 6c6f15899559c..d91c806bc8c10 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/UnusedTagsPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/UnusedTagsPassTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\UnusedTagsPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; class UnusedTagsPassTest extends TestCase { @@ -20,24 +21,14 @@ public function testProcess() { $pass = new UnusedTagsPass(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('findTaggedServiceIds', 'findUnusedTags', 'findTags', 'log'))->getMock(); - $container->expects($this->once()) - ->method('log') - ->with($pass, 'Tag "kenrel.event_subscriber" was defined on service(s) "foo", "bar", but was never used. Did you mean "kernel.event_subscriber"?'); - $container->expects($this->once()) - ->method('findTags') - ->will($this->returnValue(array('kenrel.event_subscriber'))); - $container->expects($this->once()) - ->method('findUnusedTags') - ->will($this->returnValue(array('kenrel.event_subscriber', 'form.type'))); - $container->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('kenrel.event_subscriber') - ->will($this->returnValue(array( - 'foo' => array(), - 'bar' => array(), - ))); + $container = new ContainerBuilder(); + $container->register('foo') + ->addTag('kenrel.event_subscriber'); + $container->register('bar') + ->addTag('kenrel.event_subscriber'); $pass->process($container); + + $this->assertSame(array(sprintf('%s: Tag "kenrel.event_subscriber" was defined on service(s) "foo", "bar", but was never used. Did you mean "kernel.event_subscriber"?', UnusedTagsPass::class)), $container->getCompiler()->getLog()); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php index f619584023a77..f82c3f450d4c6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Validator/ConstraintValidatorFactoryTest.php @@ -14,7 +14,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory; use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraints\Blank as BlankConstraint; use Symfony\Component\Validator\ConstraintValidator; @@ -26,16 +25,8 @@ class ConstraintValidatorFactoryTest extends TestCase { public function testGetInstanceCreatesValidator() { - $class = get_class($this->getMockForAbstractClass('Symfony\\Component\\Validator\\ConstraintValidator')); - - $constraint = $this->getMockBuilder('Symfony\\Component\\Validator\\Constraint')->getMock(); - $constraint - ->expects($this->exactly(2)) - ->method('validatedBy') - ->will($this->returnValue($class)); - $factory = new ConstraintValidatorFactory(new Container()); - $this->assertInstanceOf($class, $factory->getInstance($constraint)); + $this->assertInstanceOf(DummyConstraintValidator::class, $factory->getInstance(new DummyConstraint())); } public function testGetInstanceReturnsExistingValidator() @@ -48,54 +39,24 @@ public function testGetInstanceReturnsExistingValidator() public function testGetInstanceReturnsService() { - $service = 'validator_constraint_service'; - $validator = $this->getMockForAbstractClass(ConstraintValidator::class); - - // mock ContainerBuilder b/c it implements TaggedContainerInterface - $container = $this->getMockBuilder(ContainerBuilder::class)->setMethods(array('get', 'has'))->getMock(); - $container - ->expects($this->once()) - ->method('get') - ->with($service) - ->willReturn($validator); - $container - ->expects($this->once()) - ->method('has') - ->with($service) - ->willReturn(true); - - $constraint = $this->getMockBuilder(Constraint::class)->getMock(); - $constraint - ->expects($this->exactly(2)) - ->method('validatedBy') - ->will($this->returnValue($service)); + $validator = new DummyConstraintValidator(); + $container = new Container(); + $container->set(DummyConstraintValidator::class, $validator); $factory = new ConstraintValidatorFactory($container); - $this->assertSame($validator, $factory->getInstance($constraint)); + + $this->assertSame($validator, $factory->getInstance(new DummyConstraint())); } public function testGetInstanceReturnsServiceWithAlias() { - $service = 'validator_constraint_service'; - $alias = 'validator_constraint_alias'; - $validator = $this->getMockForAbstractClass('Symfony\\Component\\Validator\\ConstraintValidator'); - - // mock ContainerBuilder b/c it implements TaggedContainerInterface - $container = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\ContainerBuilder')->setMethods(array('get'))->getMock(); - $container - ->expects($this->once()) - ->method('get') - ->with($service) - ->will($this->returnValue($validator)); + $validator = new DummyConstraintValidator(); - $constraint = $this->getMockBuilder('Symfony\\Component\\Validator\\Constraint')->getMock(); - $constraint - ->expects($this->once()) - ->method('validatedBy') - ->will($this->returnValue($alias)); + $container = new Container(); + $container->set('validator_constraint_service', $validator); $factory = new ConstraintValidatorFactory($container, array('validator_constraint_alias' => 'validator_constraint_service')); - $this->assertSame($validator, $factory->getInstance($constraint)); + $this->assertSame($validator, $factory->getInstance(new ConstraintAliasStub())); } /** @@ -113,3 +74,26 @@ public function testGetInstanceInvalidValidatorClass() $factory->getInstance($constraint); } } + +class ConstraintAliasStub extends Constraint +{ + public function validatedBy() + { + return 'validator_constraint_alias'; + } +} + +class DummyConstraint extends Constraint +{ + public function validatedBy() + { + return DummyConstraintValidator::class; + } +} + +class DummyConstraintValidator extends ConstraintValidator +{ + public function validate($value, Constraint $constraint) + { + } +} diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigLoaderPassTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigLoaderPassTest.php index e142d18a84af6..b7870ac56c06e 100644 --- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigLoaderPassTest.php +++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/Compiler/TwigLoaderPassTest.php @@ -12,7 +12,6 @@ namespace Symfony\Bundle\TwigBundle\Tests\DependencyInjection\Compiler; use PHPUnit\Framework\TestCase; -use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigLoaderPass; diff --git a/src/Symfony/Component/Config/Tests/DependencyInjection/ConfigCachePassTest.php b/src/Symfony/Component/Config/Tests/DependencyInjection/ConfigCachePassTest.php index 4f9c12f8c4ff0..c0a064a7afe1d 100644 --- a/src/Symfony/Component/Config/Tests/DependencyInjection/ConfigCachePassTest.php +++ b/src/Symfony/Component/Config/Tests/DependencyInjection/ConfigCachePassTest.php @@ -44,13 +44,16 @@ public function testThatCheckersAreProcessedInPriorityOrder() public function testThatCheckersCanBeMissing() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('findTaggedServiceIds'))->getMock(); + $container = new ContainerBuilder(); - $container->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue(array())); + $definitionsBefore = count($container->getDefinitions()); + $aliasesBefore = count($container->getAliases()); $pass = new ConfigCachePass(); $pass->process($container); + + // the container is untouched (i.e. no new definitions or aliases) + $this->assertCount($definitionsBefore, $container->getDefinitions()); + $this->assertCount($aliasesBefore, $container->getAliases()); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ExtensionCompilerPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ExtensionCompilerPassTest.php index e083611458770..810fbe48a573f 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ExtensionCompilerPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ExtensionCompilerPassTest.php @@ -12,7 +12,10 @@ namespace Symfony\Component\DependencyInjection\Tests\Compiler; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\ExtensionCompilerPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; /** * @author Wouter J @@ -24,33 +27,55 @@ class ExtensionCompilerPassTest extends TestCase protected function setUp() { - $this->container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->getMock(); + $this->container = new ContainerBuilder(); $this->pass = new ExtensionCompilerPass(); } public function testProcess() { - $extension1 = $this->createExtensionMock(true); - $extension1->expects($this->once())->method('process'); - $extension2 = $this->createExtensionMock(false); - $extension3 = $this->createExtensionMock(false); - $extension4 = $this->createExtensionMock(true); - $extension4->expects($this->once())->method('process'); - - $this->container->expects($this->any()) - ->method('getExtensions') - ->will($this->returnValue(array($extension1, $extension2, $extension3, $extension4))) - ; + $extension1 = new CompilerPassExtension('extension1'); + $extension2 = new DummyExtension('extension2'); + $extension3 = new DummyExtension('extension3'); + $extension4 = new CompilerPassExtension('extension4'); + + $this->container->registerExtension($extension1); + $this->container->registerExtension($extension2); + $this->container->registerExtension($extension3); + $this->container->registerExtension($extension4); $this->pass->process($this->container); + + $this->assertTrue($this->container->hasDefinition('extension1')); + $this->assertFalse($this->container->hasDefinition('extension2')); + $this->assertFalse($this->container->hasDefinition('extension3')); + $this->assertTrue($this->container->hasDefinition('extension4')); } +} + +class DummyExtension extends Extension +{ + private $alias; - private function createExtensionMock($hasInlineCompile) + public function __construct($alias) { - return $this->getMockBuilder('Symfony\Component\DependencyInjection\\'.( - $hasInlineCompile - ? 'Compiler\CompilerPassInterface' - : 'Extension\ExtensionInterface' - ))->getMock(); + $this->alias = $alias; } + + public function getAlias() + { + return $this->alias; + } + + public function load(array $configs, ContainerBuilder $container) + { + } + + public function process(ContainerBuilder $container) + { + $container->register($this->alias); + } +} + +class CompilerPassExtension extends DummyExtension implements CompilerPassInterface +{ } diff --git a/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php b/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php index dbb1aa5c57b57..c1b49f75b8a47 100644 --- a/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php +++ b/src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php @@ -27,29 +27,10 @@ class RegisterListenersPassTest extends TestCase */ public function testEventSubscriberWithoutInterface() { - // one service, not implementing any interface - $services = array( - 'my_event_subscriber' => array(0 => array()), - ); - - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $definition->expects($this->atLeastOnce()) - ->method('getClass') - ->will($this->returnValue('stdClass')); - - $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - $builder->expects($this->any()) - ->method('hasDefinition') - ->will($this->returnValue(true)); - - // We don't test kernel.event_listener here - $builder->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->onConsecutiveCalls(array(), $services)); - - $builder->expects($this->atLeastOnce()) - ->method('getDefinition') - ->will($this->returnValue($definition)); + $builder = new ContainerBuilder(); + $builder->register('event_dispatcher'); + $builder->register('my_event_subscriber', 'stdClass') + ->addTag('kernel.event_subscriber'); $registerListenersPass = new RegisterListenersPass(); $registerListenersPass->process($builder); @@ -61,31 +42,25 @@ public function testValidEventSubscriber() 'my_event_subscriber' => array(0 => array()), ); - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $definition->expects($this->atLeastOnce()) - ->method('getClass') - ->will($this->returnValue('Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService')); - - $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition', 'findDefinition'))->getMock(); - $builder->expects($this->any()) - ->method('hasDefinition') - ->will($this->returnValue(true)); - - // We don't test kernel.event_listener here - $builder->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->onConsecutiveCalls(array(), $services)); - - $builder->expects($this->atLeastOnce()) - ->method('getDefinition') - ->will($this->returnValue($definition)); - - $builder->expects($this->atLeastOnce()) - ->method('findDefinition') - ->will($this->returnValue($definition)); + $builder = new ContainerBuilder(); + $eventDispatcherDefinition = $builder->register('event_dispatcher'); + $builder->register('my_event_subscriber', 'Symfony\Component\EventDispatcher\Tests\DependencyInjection\SubscriberService') + ->addTag('kernel.event_subscriber'); $registerListenersPass = new RegisterListenersPass(); $registerListenersPass->process($builder); + + $expectedCalls = array( + array( + 'addListener', + array( + 'event', + array(new ServiceClosureArgument(new Reference('my_event_subscriber')), 'onEvent'), + 0, + ), + ), + ); + $this->assertEquals($expectedCalls, $eventDispatcherDefinition->getMethodCalls()); } /** diff --git a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/FragmentRendererPassTest.php b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/FragmentRendererPassTest.php index d28c6eca57d92..e8957bb3ccfac 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/FragmentRendererPassTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/FragmentRendererPassTest.php @@ -12,8 +12,10 @@ namespace Symfony\Component\HttpKernel\Tests\DependencyInjection; use PHPUnit\Framework\TestCase; -use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceLocator; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\DependencyInjection\FragmentRendererPass; use Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface; @@ -22,73 +24,37 @@ class FragmentRendererPassTest extends TestCase { /** * Tests that content rendering not implementing FragmentRendererInterface - * trigger an exception. + * triggers an exception. * * @expectedException \InvalidArgumentException */ public function testContentRendererWithoutInterface() { - // one service, not implementing any interface - $services = array( - 'my_content_renderer' => array(array('alias' => 'foo')), - ); - - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - - $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - $builder->expects($this->any()) - ->method('hasDefinition') - ->will($this->returnValue(true)); - - // We don't test kernel.fragment_renderer here - $builder->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue($services)); - - $builder->expects($this->atLeastOnce()) - ->method('getDefinition') - ->will($this->returnValue($definition)); + $builder = new ContainerBuilder(); + $fragmentHandlerDefinition = $builder->register('fragment.handler'); + $builder->register('my_content_renderer', 'Symfony\Component\DependencyInjection\Definition') + ->addTag('kernel.fragment_renderer', array('alias' => 'foo')); $pass = new FragmentRendererPass(); $pass->process($builder); + + $this->assertEquals(array(array('addRendererService', array('foo', 'my_content_renderer'))), $fragmentHandlerDefinition->getMethodCalls()); } public function testValidContentRenderer() { - $services = array( - 'my_content_renderer' => array(array('alias' => 'foo')), - ); - - $renderer = new Definition('', array(null)); - - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $definition->expects($this->atLeastOnce()) - ->method('getClass') - ->will($this->returnValue('Symfony\Component\HttpKernel\Tests\DependencyInjection\RendererService')); - - $builder = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition', 'getReflectionClass'))->getMock(); - $builder->expects($this->any()) - ->method('hasDefinition') - ->will($this->returnValue(true)); - - // We don't test kernel.fragment_renderer here - $builder->expects($this->atLeastOnce()) - ->method('findTaggedServiceIds') - ->will($this->returnValue($services)); - - $builder->expects($this->atLeastOnce()) - ->method('getDefinition') - ->will($this->onConsecutiveCalls($renderer, $definition)); - - $builder->expects($this->atLeastOnce()) - ->method('getReflectionClass') - ->with('Symfony\Component\HttpKernel\Tests\DependencyInjection\RendererService') - ->will($this->returnValue(new \ReflectionClass('Symfony\Component\HttpKernel\Tests\DependencyInjection\RendererService'))); + $builder = new ContainerBuilder(); + $fragmentHandlerDefinition = $builder->register('fragment.handler') + ->addArgument(null); + $builder->register('my_content_renderer', 'Symfony\Component\HttpKernel\Tests\DependencyInjection\RendererService') + ->addTag('kernel.fragment_renderer', array('alias' => 'foo')); $pass = new FragmentRendererPass(); $pass->process($builder); - $this->assertInstanceOf(Reference::class, $renderer->getArgument(0)); + $serviceLocatorDefinition = $builder->getDefinition((string) $fragmentHandlerDefinition->getArgument(0)); + $this->assertSame(ServiceLocator::class, $serviceLocatorDefinition->getClass()); + $this->assertEquals(array('foo' => new ServiceClosureArgument(new Reference('my_content_renderer'))), $serviceLocatorDefinition->getArgument(0)); } } diff --git a/src/Symfony/Component/PropertyInfo/Tests/DependencyInjection/PropertyInfoPassTest.php b/src/Symfony/Component/PropertyInfo/Tests/DependencyInjection/PropertyInfoPassTest.php index 21eace4d61254..031e34af97451 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/DependencyInjection/PropertyInfoPassTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/DependencyInjection/PropertyInfoPassTest.php @@ -54,24 +54,16 @@ public function provideTags() public function testReturningEmptyArrayWhenNoService() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('findTaggedServiceIds'))->getMock(); - - $container - ->expects($this->any()) - ->method('findTaggedServiceIds') - ->will($this->returnValue(array())) - ; + $container = new ContainerBuilder(); + $propertyInfoExtractorDefinition = $container->register('property_info') + ->setArguments(array(array(), array(), array(), array())); $propertyInfoPass = new PropertyInfoPass(); + $propertyInfoPass->process($container); - $method = new \ReflectionMethod( - 'Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass', - 'findAndSortTaggedServices' - ); - $method->setAccessible(true); - - $actual = $method->invoke($propertyInfoPass, 'tag', $container); - - $this->assertEquals(array(), $actual); + $this->assertEquals(new IteratorArgument(array()), $propertyInfoExtractorDefinition->getArgument(0)); + $this->assertEquals(new IteratorArgument(array()), $propertyInfoExtractorDefinition->getArgument(1)); + $this->assertEquals(new IteratorArgument(array()), $propertyInfoExtractorDefinition->getArgument(2)); + $this->assertEquals(new IteratorArgument(array()), $propertyInfoExtractorDefinition->getArgument(3)); } } diff --git a/src/Symfony/Component/Serializer/Tests/DependencyInjection/SerializerPassTest.php b/src/Symfony/Component/Serializer/Tests/DependencyInjection/SerializerPassTest.php index 91704032cc2d5..fa12454fd094e 100644 --- a/src/Symfony/Component/Serializer/Tests/DependencyInjection/SerializerPassTest.php +++ b/src/Symfony/Component/Serializer/Tests/DependencyInjection/SerializerPassTest.php @@ -23,48 +23,30 @@ */ class SerializerPassTest extends TestCase { + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage You must tag at least one service as "serializer.normalizer" to use the "serializer" service + */ public function testThrowExceptionWhenNoNormalizers() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds'))->getMock(); - - $container->expects($this->once()) - ->method('hasDefinition') - ->with('serializer') - ->will($this->returnValue(true)); - - $container->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('serializer.normalizer') - ->will($this->returnValue(array())); - - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(\RuntimeException::class); + $container = new ContainerBuilder(); + $container->register('serializer'); $serializerPass = new SerializerPass(); $serializerPass->process($container); } + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage You must tag at least one service as "serializer.encoder" to use the "serializer" service + */ public function testThrowExceptionWhenNoEncoders() { - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); - - $container->expects($this->once()) - ->method('hasDefinition') - ->with('serializer') - ->will($this->returnValue(true)); - - $container->expects($this->any()) - ->method('findTaggedServiceIds') - ->will($this->onConsecutiveCalls( - array('n' => array('serializer.normalizer')), - array() - )); - - $container->expects($this->any()) - ->method('getDefinition') - ->will($this->returnValue($definition)); - - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(\RuntimeException::class); + $container = new ContainerBuilder(); + $container->register('serializer') + ->addArgument(array()) + ->addArgument(array()); + $container->register('normalizer')->addTag('serializer.normalizer'); $serializerPass = new SerializerPass(); $serializerPass->process($container); diff --git a/src/Symfony/Component/Translation/Tests/DependencyInjection/TranslationDumperPassTest.php b/src/Symfony/Component/Translation/Tests/DependencyInjection/TranslationDumperPassTest.php index 845200e71251a..3e02cb434edde 100644 --- a/src/Symfony/Component/Translation/Tests/DependencyInjection/TranslationDumperPassTest.php +++ b/src/Symfony/Component/Translation/Tests/DependencyInjection/TranslationDumperPassTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Translation\Tests\DependencyInjection; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\Translation\DependencyInjection\TranslationDumperPass; @@ -19,48 +20,29 @@ class TranslationDumperPassTest extends TestCase { public function testProcess() { - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->disableOriginalConstructor()->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->disableOriginalConstructor()->getMock(); - - $container->expects($this->once()) - ->method('hasDefinition') - ->with('translation.writer') - ->will($this->returnValue(true)); - - $container->expects($this->once()) - ->method('getDefinition') - ->with('translation.writer') - ->will($this->returnValue($definition)); - - $valueTaggedServiceIdsFound = array( - 'foo.id' => array( - array('alias' => 'bar.alias'), - ), - ); - $container->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('translation.dumper', true) - ->will($this->returnValue($valueTaggedServiceIdsFound)); - - $definition->expects($this->once())->method('addMethodCall')->with('addDumper', array('bar.alias', new Reference('foo.id'))); + $container = new ContainerBuilder(); + $writerDefinition = $container->register('translation.writer'); + $container->register('foo.id') + ->addTag('translation.dumper', array('alias' => 'bar.alias')); $translationDumperPass = new TranslationDumperPass(); $translationDumperPass->process($container); + + $this->assertEquals(array(array('addDumper', array('bar.alias', new Reference('foo.id')))), $writerDefinition->getMethodCalls()); } public function testProcessNoDefinitionFound() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->disableOriginalConstructor()->getMock(); - - $container->expects($this->once()) - ->method('hasDefinition') - ->with('translation.writer') - ->will($this->returnValue(false)); + $container = new ContainerBuilder(); - $container->expects($this->never())->method('getDefinition'); - $container->expects($this->never())->method('findTaggedServiceIds'); + $definitionsBefore = count($container->getDefinitions()); + $aliasesBefore = count($container->getAliases()); $translationDumperPass = new TranslationDumperPass(); $translationDumperPass->process($container); + + // the container is untouched (i.e. no new definitions or aliases) + $this->assertCount($definitionsBefore, $container->getDefinitions()); + $this->assertCount($aliasesBefore, $container->getAliases()); } } diff --git a/src/Symfony/Component/Translation/Tests/DependencyInjection/TranslationExtractorPassTest.php b/src/Symfony/Component/Translation/Tests/DependencyInjection/TranslationExtractorPassTest.php index 76d2b999cfd83..b3313e63eeb42 100644 --- a/src/Symfony/Component/Translation/Tests/DependencyInjection/TranslationExtractorPassTest.php +++ b/src/Symfony/Component/Translation/Tests/DependencyInjection/TranslationExtractorPassTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Translation\Tests\DependencyInjection; use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\Translation\DependencyInjection\TranslationExtractorPass; @@ -19,49 +20,30 @@ class TranslationExtractorPassTest extends TestCase { public function testProcess() { - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->disableOriginalConstructor()->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->disableOriginalConstructor()->getMock(); - - $container->expects($this->once()) - ->method('hasDefinition') - ->with('translation.extractor') - ->will($this->returnValue(true)); - - $container->expects($this->once()) - ->method('getDefinition') - ->with('translation.extractor') - ->will($this->returnValue($definition)); - - $valueTaggedServiceIdsFound = array( - 'foo.id' => array( - array('alias' => 'bar.alias'), - ), - ); - $container->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('translation.extractor', true) - ->will($this->returnValue($valueTaggedServiceIdsFound)); - - $definition->expects($this->once())->method('addMethodCall')->with('addExtractor', array('bar.alias', new Reference('foo.id'))); + $container = new ContainerBuilder(); + $extractorDefinition = $container->register('translation.extractor'); + $container->register('foo.id') + ->addTag('translation.extractor', array('alias' => 'bar.alias')); $translationDumperPass = new TranslationExtractorPass(); $translationDumperPass->process($container); + + $this->assertEquals(array(array('addExtractor', array('bar.alias', new Reference('foo.id')))), $extractorDefinition->getMethodCalls()); } public function testProcessNoDefinitionFound() { - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->disableOriginalConstructor()->getMock(); + $container = new ContainerBuilder(); - $container->expects($this->once()) - ->method('hasDefinition') - ->with('translation.extractor') - ->will($this->returnValue(false)); - - $container->expects($this->never())->method('getDefinition'); - $container->expects($this->never())->method('findTaggedServiceIds'); + $definitionsBefore = count($container->getDefinitions()); + $aliasesBefore = count($container->getAliases()); $translationDumperPass = new TranslationExtractorPass(); $translationDumperPass->process($container); + + // the container is untouched (i.e. no new definitions or aliases) + $this->assertCount($definitionsBefore, $container->getDefinitions()); + $this->assertCount($aliasesBefore, $container->getAliases()); } /** @@ -71,25 +53,10 @@ public function testProcessNoDefinitionFound() public function testProcessMissingAlias() { $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->disableOriginalConstructor()->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->disableOriginalConstructor()->getMock(); - - $container->expects($this->once()) - ->method('hasDefinition') - ->with('translation.extractor') - ->will($this->returnValue(true)); - - $container->expects($this->once()) - ->method('getDefinition') - ->with('translation.extractor') - ->will($this->returnValue($definition)); - - $valueTaggedServiceIdsFound = array( - 'foo.id' => array(), - ); - $container->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('translation.extractor', true) - ->will($this->returnValue($valueTaggedServiceIdsFound)); + $container = new ContainerBuilder(); + $container->register('translation.extractor'); + $container->register('foo.id') + ->addTag('translation.extractor', array()); $definition->expects($this->never())->method('addMethodCall'); diff --git a/src/Symfony/Component/Validator/Tests/ContainerConstraintValidatorFactoryTest.php b/src/Symfony/Component/Validator/Tests/ContainerConstraintValidatorFactoryTest.php index 92091484e2905..3782fba46c3b1 100644 --- a/src/Symfony/Component/Validator/Tests/ContainerConstraintValidatorFactoryTest.php +++ b/src/Symfony/Component/Validator/Tests/ContainerConstraintValidatorFactoryTest.php @@ -13,7 +13,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraints\Blank as BlankConstraint; use Symfony\Component\Validator\ConstraintValidator; @@ -23,16 +22,8 @@ class ContainerConstraintValidatorFactoryTest extends TestCase { public function testGetInstanceCreatesValidator() { - $class = get_class($this->getMockForAbstractClass(ConstraintValidator::class)); - - $constraint = $this->getMockBuilder(Constraint::class)->getMock(); - $constraint - ->expects($this->once()) - ->method('validatedBy') - ->will($this->returnValue($class)); - $factory = new ContainerConstraintValidatorFactory(new Container()); - $this->assertInstanceOf($class, $factory->getInstance($constraint)); + $this->assertInstanceOf(DummyConstraintValidator::class, $factory->getInstance(new DummyConstraint())); } public function testGetInstanceReturnsExistingValidator() @@ -45,30 +36,13 @@ public function testGetInstanceReturnsExistingValidator() public function testGetInstanceReturnsService() { - $service = 'validator_constraint_service'; - $validator = $this->getMockForAbstractClass(ConstraintValidator::class); - - // mock ContainerBuilder b/c it implements TaggedContainerInterface - $container = $this->getMockBuilder(ContainerBuilder::class)->setMethods(array('get', 'has'))->getMock(); - $container - ->expects($this->once()) - ->method('get') - ->with($service) - ->willReturn($validator); - $container - ->expects($this->once()) - ->method('has') - ->with($service) - ->willReturn(true); - - $constraint = $this->getMockBuilder(Constraint::class)->getMock(); - $constraint - ->expects($this->once()) - ->method('validatedBy') - ->will($this->returnValue($service)); + $validator = new DummyConstraintValidator(); + $container = new Container(); + $container->set(DummyConstraintValidator::class, $validator); $factory = new ContainerConstraintValidatorFactory($container); - $this->assertSame($validator, $factory->getInstance($constraint)); + + $this->assertSame($validator, $factory->getInstance(new DummyConstraint())); } /** @@ -86,3 +60,18 @@ public function testGetInstanceInvalidValidatorClass() $factory->getInstance($constraint); } } + +class DummyConstraint extends Constraint +{ + public function validatedBy() + { + return DummyConstraintValidator::class; + } +} + +class DummyConstraintValidator extends ConstraintValidator +{ + public function validate($value, Constraint $constraint) + { + } +} diff --git a/src/Symfony/Component/Validator/Tests/DependencyInjection/AddConstraintValidatorsPassTest.php b/src/Symfony/Component/Validator/Tests/DependencyInjection/AddConstraintValidatorsPassTest.php index ba4ea36b2b8c3..05167e84ca17e 100644 --- a/src/Symfony/Component/Validator/Tests/DependencyInjection/AddConstraintValidatorsPassTest.php +++ b/src/Symfony/Component/Validator/Tests/DependencyInjection/AddConstraintValidatorsPassTest.php @@ -50,7 +50,7 @@ public function testThatConstraintValidatorServicesAreProcessed() public function testAbstractConstraintValidator() { $container = new ContainerBuilder(); - $validatorFactory = $container->register('validator.validator_factory') + $container->register('validator.validator_factory') ->addArgument(array()); $container->register('my_abstract_constraint_validator') @@ -63,18 +63,16 @@ public function testAbstractConstraintValidator() public function testThatCompilerPassIsIgnoredIfThereIsNoConstraintValidatorFactoryDefinition() { - $definition = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')->setMethods(array('hasDefinition', 'findTaggedServiceIds', 'getDefinition'))->getMock(); + $container = new ContainerBuilder(); - $container->expects($this->never())->method('findTaggedServiceIds'); - $container->expects($this->never())->method('getDefinition'); - $container->expects($this->atLeastOnce()) - ->method('hasDefinition') - ->with('validator.validator_factory') - ->will($this->returnValue(false)); - $definition->expects($this->never())->method('replaceArgument'); + $definitionsBefore = count($container->getDefinitions()); + $aliasesBefore = count($container->getAliases()); $addConstraintValidatorsPass = new AddConstraintValidatorsPass(); $addConstraintValidatorsPass->process($container); + + // the container is untouched (i.e. no new definitions or aliases) + $this->assertCount($definitionsBefore, $container->getDefinitions()); + $this->assertCount($aliasesBefore, $container->getAliases()); } } diff --git a/src/Symfony/Component/Workflow/Tests/DependencyInjection/ValidateWorkflowsPassTest.php b/src/Symfony/Component/Workflow/Tests/DependencyInjection/ValidateWorkflowsPassTest.php index d728cc1195570..1a38588f27cdb 100644 --- a/src/Symfony/Component/Workflow/Tests/DependencyInjection/ValidateWorkflowsPassTest.php +++ b/src/Symfony/Component/Workflow/Tests/DependencyInjection/ValidateWorkflowsPassTest.php @@ -4,7 +4,8 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\Workflow\Definition; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\Workflow\Definition as WorkflowDefinition; use Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass; use Symfony\Component\Workflow\Transition; @@ -12,19 +13,20 @@ class ValidateWorkflowsPassTest extends TestCase { public function testProcess() { - $container = $this->getMockBuilder(ContainerBuilder::class)->getMock(); - $container - ->expects($this->once()) - ->method('findTaggedServiceIds') - ->with('workflow.definition') - ->willReturn(array('definition1' => array('workflow.definition' => array('name' => 'wf1', 'type' => 'state_machine', 'marking_store' => 'foo')))); - - $container - ->expects($this->once()) - ->method('get') - ->with('definition1') - ->willReturn(new Definition(array('a', 'b', 'c'), array(new Transition('t1', 'a', 'b'), new Transition('t2', 'a', 'c')))); + $container = new ContainerBuilder(); + $container->register('definition1', WorkflowDefinition::class) + ->addArgument(array('a', 'b', 'c')) + ->addArgument(array( + new Definition(Transition::class, array('t1', 'a', 'b')), + new Definition(Transition::class, array('t2', 'a', 'c')), + )) + ->addTag('workflow.definition', array('name' => 'wf1', 'type' => 'state_machine', 'marking_store' => 'foo')); (new ValidateWorkflowsPass())->process($container); + + $workflowDefinition = $container->get('definition1'); + + $this->assertSame(array('a' => 'a', 'b' => 'b', 'c' => 'c'), $workflowDefinition->getPlaces()); + $this->assertEquals(array(new Transition('t1', 'a', 'b'), new Transition('t2', 'a', 'c')), $workflowDefinition->getTransitions()); } } From 14e22825134c4bca807f8ea42b48a1ddfa4deae5 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Tue, 13 Feb 2018 23:04:19 +0100 Subject: [PATCH 099/166] Fixed broken tests --- .../views/Form/bootstrap_4_layout.html.twig | 2 +- src/Symfony/Bridge/Twig/composer.json | 4 +- ...AbstractBootstrap4HorizontalLayoutTest.php | 4 +- .../Tests/AbstractBootstrap4LayoutTest.php | 428 ++++++++---------- 4 files changed, 202 insertions(+), 236 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig index 34fc47e8ecc9b..7ecc26b7b9727 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig @@ -217,7 +217,7 @@ {{ widget|raw }} - {{ label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans({}, translation_domain)) -}} + {{- label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans({}, translation_domain)) -}} {{- form_errors(form) -}} {%- endif -%} diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index aea0d10a67791..ffec118f502c8 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -23,7 +23,7 @@ "symfony/asset": "~2.8|~3.0|~4.0", "symfony/dependency-injection": "~2.8|~3.0|~4.0", "symfony/finder": "~2.8|~3.0|~4.0", - "symfony/form": "~3.4|~4.0", + "symfony/form": "^3.4.5|^4.0.5", "symfony/http-foundation": "^3.3.11|~4.0", "symfony/http-kernel": "~3.2|~4.0", "symfony/polyfill-intl-icu": "~1.0", @@ -41,7 +41,7 @@ "symfony/workflow": "~3.3|~4.0" }, "conflict": { - "symfony/form": "<3.4", + "symfony/form": "<3.4.5", "symfony/console": "<3.4" }, "suggest": { diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php index 23e6f141cac9d..5934479a90093 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php @@ -53,7 +53,7 @@ public function testLabelOnForm() $this->assertMatchesXpath($html, '/legend - [@class="col-form-label col-sm-2 col-form-legend required"] + [@class="col-form-label col-sm-2 col-form-label required"] [.="[trans]Name[/trans]"] ' ); @@ -144,7 +144,7 @@ public function testLegendOnExpandedType() $this->assertMatchesXpath($html, '/legend - [@class="col-sm-2 col-form-legend required"] + [@class="col-sm-2 col-form-label required"] [.="[trans]Custom label[/trans]"] ' ); diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php index fdaa07e1c15bc..197f3ab8d6854 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php @@ -53,7 +53,7 @@ public function testLabelOnForm() $this->assertMatchesXpath($html, '/legend - [@class="col-form-legend required"] + [@class="col-form-label required"] [.="[trans]Name[/trans]"] ' ); @@ -144,7 +144,7 @@ public function testLegendOnExpandedType() $this->assertMatchesXpath($html, '/legend - [@class="col-form-legend required"] + [@class="col-form-label required"] [.="[trans]Custom label[/trans]"] ' ); @@ -184,12 +184,10 @@ public function testCheckedCheckbox() '/div [@class="form-check"] [ - ./label - [.=" [trans]Name[/trans]"] + ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][@checked="checked"][@value="1"] + /following-sibling::label + [.="[trans]Name[/trans]"] [@class="form-check-label required"] - [ - ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][@checked="checked"][@value="1"] - ] ] ' ); @@ -234,20 +232,16 @@ public function testSingleExpandedChoiceAttributesWithMainAttributes() ./div [@class="form-check"] [ - ./label - [.=" [trans]Choice&A[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] - ] + ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] + /following-sibling::label + [.="[trans]Choice&A[/trans]"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" [trans]Choice&B[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] - ] + ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] + /following-sibling::label + [.="[trans]Choice&B[/trans]"] ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -263,11 +257,9 @@ public function testUncheckedCheckbox() '/div [@class="form-check"] [ - ./label - [.=" [trans]Name[/trans]"] - [ - ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][not(@checked)] - ] + ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][not(@checked)] + /following-sibling::label + [.="[trans]Name[/trans]"] ] ' ); @@ -283,11 +275,9 @@ public function testCheckboxWithValue() '/div [@class="form-check"] [ - ./label - [.=" [trans]Name[/trans]"] - [ - ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][@value="foo&bar"] - ] + ./input[@type="checkbox"][@name="name"][@id="my&id"][@class="my&class form-check-input"][@value="foo&bar"] + /following-sibling::label + [.="[trans]Name[/trans]"] ] ' ); @@ -307,20 +297,16 @@ public function testSingleChoiceExpanded() ./div [@class="form-check"] [ - ./label - [.=" [trans]Choice&A[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] - ] + ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] + /following-sibling::label + [.="[trans]Choice&A[/trans]"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" [trans]Choice&B[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] - ] + ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] + /following-sibling::label + [.="[trans]Choice&B[/trans]"] ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -343,18 +329,14 @@ public function testSingleChoiceExpandedWithLabelsAsFalse() ./div [@class="form-check"] [ - ./label - [ - ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] - ] + ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] + /following-sibling::label ] /following-sibling::div [@class="form-check"] [ - ./label - [ - ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] - ] + ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] + /following-sibling::label ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -383,28 +365,22 @@ public function testSingleChoiceExpandedWithLabelsSetByCallable() ./div [@class="form-check"] [ - ./label - [.=" [trans]label.&a[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] - ] + ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] + /following-sibling::label + [.="[trans]label.&a[/trans]"] ] /following-sibling::div [@class="form-check"] [ - ./label - [ - ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] - ] + ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] + /following-sibling::label ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" [trans]label.&c[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_2"][@value="&c"][not(@checked)] - ] + ./input[@type="radio"][@name="name"][@id="name_2"][@value="&c"][not(@checked)] + /following-sibling::label + [.="[trans]label.&c[/trans]"] ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -429,18 +405,14 @@ public function testSingleChoiceExpandedWithLabelsSetFalseByCallable() ./div [@class="form-check"] [ - ./label - [ - ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] - ] + ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] + /following-sibling::label ] /following-sibling::div [@class="form-check"] [ - ./label - [ - ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] - ] + ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] + /following-sibling::label ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -463,20 +435,16 @@ public function testSingleChoiceExpandedWithoutTranslation() ./div [@class="form-check"] [ - ./label - [.=" Choice&A"] - [ - ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] - ] + ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] + /following-sibling::label + [.="Choice&A"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" Choice&B"] - [ - ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] - ] + ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)] + /following-sibling::label + [.="Choice&B"] ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -499,20 +467,16 @@ public function testSingleChoiceExpandedAttributes() ./div [@class="form-check"] [ - ./label - [.=" [trans]Choice&A[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] - ] + ./input[@type="radio"][@name="name"][@id="name_0"][@value="&a"][@checked] + /following-sibling::label + [.="[trans]Choice&A[/trans]"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" [trans]Choice&B[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)][@class="foo&bar form-check-input"] - ] + ./input[@type="radio"][@name="name"][@id="name_1"][@value="&b"][not(@checked)][@class="foo&bar form-check-input"] + /following-sibling::label + [.="[trans]Choice&B[/trans]"] ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -536,29 +500,23 @@ public function testSingleChoiceExpandedWithPlaceholder() ./div [@class="form-check"] [ - ./label - [.=" [trans]Test&Me[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)] - ] + ./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)] + /following-sibling::label + [.="[trans]Test&Me[/trans]"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" [trans]Choice&A[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_0"][@checked] - ] + ./input[@type="radio"][@name="name"][@id="name_0"][@checked] + /following-sibling::label + [.="[trans]Choice&A[/trans]"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" [trans]Choice&B[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)] - ] + ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)] + /following-sibling::label + [.="[trans]Choice&B[/trans]"] ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -583,29 +541,23 @@ public function testSingleChoiceExpandedWithPlaceholderWithoutTranslation() ./div [@class="form-check"] [ - ./label - [.=" Placeholder&Not&Translated"] - [ - ./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)] - ] + ./input[@type="radio"][@name="name"][@id="name_placeholder"][not(@checked)] + /following-sibling::label + [.="Placeholder&Not&Translated"] ] /following-sibling::div [@class="form-check"] - [ - ./label - [.=" Choice&A"] - [ - ./input[@type="radio"][@name="name"][@id="name_0"][@checked] - ] + [ + ./input[@type="radio"][@name="name"][@id="name_0"][@checked] + /following-sibling::label + [.="Choice&A"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" Choice&B"] - [ - ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)] - ] + ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)] + /following-sibling::label + [.="Choice&B"] ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -627,20 +579,16 @@ public function testSingleChoiceExpandedWithBooleanValue() ./div [@class="form-check"] [ - ./label - [.=" [trans]Choice&A[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_0"][@checked] - ] + ./input[@type="radio"][@name="name"][@id="name_0"][@checked] + /following-sibling::label + [.="[trans]Choice&A[/trans]"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" [trans]Choice&B[/trans]"] - [ - ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)] - ] + ./input[@type="radio"][@name="name"][@id="name_1"][not(@checked)] + /following-sibling::label + [.="[trans]Choice&B[/trans]"] ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -663,29 +611,23 @@ public function testMultipleChoiceExpanded() ./div [@class="form-check"] [ - ./label - [.=" [trans]Choice&A[/trans]"] - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)] + /following-sibling::label + [.="[trans]Choice&A[/trans]"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" [trans]Choice&B[/trans]"] - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)] + /following-sibling::label + [.="[trans]Choice&B[/trans]"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" [trans]Choice&C[/trans]"] - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)] + /following-sibling::label + [.="[trans]Choice&C[/trans]"] ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -708,18 +650,14 @@ public function testMultipleChoiceExpandedWithLabelsAsFalse() ./div [@class="form-check"] [ - ./label - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked] + /following-sibling::label ] /following-sibling::div [@class="form-check"] [ - ./label - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)] + /following-sibling::label ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -748,28 +686,22 @@ public function testMultipleChoiceExpandedWithLabelsSetByCallable() ./div [@class="form-check"] [ - ./label - [.=" [trans]label.&a[/trans]"] - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked] + /following-sibling::label + [.="[trans]label.&a[/trans]"] ] /following-sibling::div [@class="form-check"] [ - ./label - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)] + /following-sibling::label ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" [trans]label.&c[/trans]"] - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@value="&c"][not(@checked)] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@value="&c"][not(@checked)] + /following-sibling::label + [.="[trans]label.&c[/trans]"] ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -794,18 +726,14 @@ public function testMultipleChoiceExpandedWithLabelsSetFalseByCallable() ./div [@class="form-check"] [ - ./label - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@value="&a"][@checked] + /following-sibling::label ] /following-sibling::div [@class="form-check"] [ - ./label - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_1"][@value="&b"][not(@checked)] + /following-sibling::label ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -829,29 +757,23 @@ public function testMultipleChoiceExpandedWithoutTranslation() ./div [@class="form-check"] [ - ./label - [.=" Choice&A"] - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)] + /following-sibling::label + [.="Choice&A"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" Choice&B"] - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)] + /following-sibling::label + [.="Choice&B"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" Choice&C"] - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)] + /following-sibling::label + [.="Choice&C"] ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -875,29 +797,23 @@ public function testMultipleChoiceExpandedAttributes() ./div [@class="form-check"] [ - ./label - [.=" [trans]Choice&A[/trans]"] - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_0"][@checked][not(@required)] + /following-sibling::label + [.="[trans]Choice&A[/trans]"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" [trans]Choice&B[/trans]"] - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)][@class="foo&bar form-check-input"] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_1"][not(@checked)][not(@required)][@class="foo&bar form-check-input"] + /following-sibling::label + [.="[trans]Choice&B[/trans]"] ] /following-sibling::div [@class="form-check"] [ - ./label - [.=" [trans]Choice&C[/trans]"] - [ - ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)] - ] + ./input[@type="checkbox"][@name="name[]"][@id="name_2"][@checked][not(@required)] + /following-sibling::label + [.="[trans]Choice&C[/trans]"] ] /following-sibling::input[@type="hidden"][@id="name__token"] ] @@ -913,17 +829,15 @@ public function testCheckedRadio() '/div [@class="form-check"] [ - ./label + ./input + [@id="my&id"] + [@type="radio"] + [@name="name"] + [@class="my&class form-check-input"] + [@checked="checked"] + [@value="1"] + /following-sibling::label [@class="form-check-label required"] - [ - ./input - [@id="my&id"] - [@type="radio"] - [@name="name"] - [@class="my&class form-check-input"] - [@checked="checked"] - [@value="1"] - ] ] ' ); @@ -937,16 +851,14 @@ public function testUncheckedRadio() '/div [@class="form-check"] [ - ./label + ./input + [@id="my&id"] + [@type="radio"] + [@name="name"] + [@class="my&class form-check-input"] + [not(@checked)] + /following-sibling::label [@class="form-check-label required"] - [ - ./input - [@id="my&id"] - [@type="radio"] - [@name="name"] - [@class="my&class form-check-input"] - [not(@checked)] - ] ] ' ); @@ -962,16 +874,15 @@ public function testRadioWithValue() '/div [@class="form-check"] [ - ./label + ./input + [@id="my&id"] + [@type="radio"] + [@name="name"] + [@class="my&class form-check-input"] + [@value="foo&bar"] + /following-sibling::label [@class="form-check-label required"] - [ - ./input - [@id="my&id"] - [@type="radio"] - [@name="name"] - [@class="my&class form-check-input"] - [@value="foo&bar"] - ] + [@for="my&id"] ] ' ); @@ -996,6 +907,61 @@ public function testFile() $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class form-control-file')), '/input [@type="file"] +' + ); + } + + public function testMoney() + { + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\MoneyType', 1234.56, array( + 'currency' => 'EUR', + )); + + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), + '/div + [@class="input-group"] + [ + ./div + [@class="input-group-prepend"] + [ + ./span + [@class="input-group-text"] + [contains(.., "€")] + ] + /following-sibling::input + [@id="my&id"] + [@type="text"] + [@name="name"] + [@class="my&class form-control"] + [@value="1234.56"] + ] +' + ); + } + + public function testPercent() + { + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PercentType', 0.1); + + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), + '/div + [@class="input-group"] + [ + ./input + [@id="my&id"] + [@type="text"] + [@name="name"] + [@class="my&class form-control"] + [@value="10"] + /following-sibling::div + [@class="input-group-append"] + [ + ./span + [@class="input-group-text"] + [contains(.., "%")] + ] + + ] ' ); } From 8ee83879ebec38c8a2eb19f9948c2cb89518c11e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 11 Feb 2018 19:19:04 +0100 Subject: [PATCH 100/166] [Serializer] optims and cleanup --- .../Serializer/Annotation/Groups.php | 10 +++---- .../Serializer/Encoder/JsonEncoder.php | 2 +- .../Serializer/Encoder/XmlEncoder.php | 28 +++++++++---------- .../Serializer/Mapping/AttributeMetadata.php | 2 +- .../Mapping/Factory/ClassMetadataFactory.php | 6 ++-- .../Serializer/Mapping/Loader/LoaderChain.php | 2 +- .../Mapping/Loader/YamlFileLoader.php | 10 +++---- .../CamelCaseToSnakeCaseNameConverter.php | 6 ++-- .../Normalizer/AbstractNormalizer.php | 20 ++++++------- .../Normalizer/GetSetMethodNormalizer.php | 16 +++++------ .../Normalizer/ObjectNormalizer.php | 10 +++---- .../Normalizer/PropertyNormalizer.php | 12 ++++---- .../Component/Serializer/Serializer.php | 6 ++-- 13 files changed, 65 insertions(+), 65 deletions(-) diff --git a/src/Symfony/Component/Serializer/Annotation/Groups.php b/src/Symfony/Component/Serializer/Annotation/Groups.php index d0339552a74f4..be29135ae8d97 100644 --- a/src/Symfony/Component/Serializer/Annotation/Groups.php +++ b/src/Symfony/Component/Serializer/Annotation/Groups.php @@ -34,16 +34,16 @@ class Groups public function __construct(array $data) { if (!isset($data['value']) || !$data['value']) { - throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" cannot be empty.', get_class($this))); + throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" cannot be empty.', \get_class($this))); } - if (!is_array($data['value'])) { - throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" must be an array of strings.', get_class($this))); + if (!\is_array($data['value'])) { + throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" must be an array of strings.', \get_class($this))); } foreach ($data['value'] as $group) { - if (!is_string($group)) { - throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" must be an array of strings.', get_class($this))); + if (!\is_string($group)) { + throw new InvalidArgumentException(sprintf('Parameter of annotation "%s" must be an array of strings.', \get_class($this))); } } diff --git a/src/Symfony/Component/Serializer/Encoder/JsonEncoder.php b/src/Symfony/Component/Serializer/Encoder/JsonEncoder.php index 66d94f85af858..2a084f1426a35 100644 --- a/src/Symfony/Component/Serializer/Encoder/JsonEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/JsonEncoder.php @@ -96,7 +96,7 @@ public function supportsDecoding($format) */ public static function getLastErrorMessage() { - if (function_exists('json_last_error_msg')) { + if (\function_exists('json_last_error_msg')) { return json_last_error_msg(); } diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php index 005b565d12113..5ce58fb07bd9a 100644 --- a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php @@ -179,7 +179,7 @@ public function getRootNodeName() */ final protected function appendXMLString(\DOMNode $node, $val) { - if (strlen($val) > 0) { + if (\strlen($val) > 0) { $frag = $this->dom->createDocumentFragment(); $frag->appendXML($val); $node->appendChild($frag); @@ -260,17 +260,17 @@ private function parseXml(\DOMNode $node) $value = $this->parseXmlValue($node); - if (!count($data)) { + if (!\count($data)) { return $value; } - if (!is_array($value)) { + if (!\is_array($value)) { $data['#'] = $value; return $data; } - if (1 === count($value) && key($value)) { + if (1 === \count($value) && key($value)) { $data[key($value)] = current($value); return $data; @@ -326,7 +326,7 @@ private function parseXmlValue(\DOMNode $node) return $node->nodeValue; } - if (1 === $node->childNodes->length && in_array($node->firstChild->nodeType, array(XML_TEXT_NODE, XML_CDATA_SECTION_NODE))) { + if (1 === $node->childNodes->length && \in_array($node->firstChild->nodeType, array(XML_TEXT_NODE, XML_CDATA_SECTION_NODE))) { return $node->firstChild->nodeValue; } @@ -351,7 +351,7 @@ private function parseXmlValue(\DOMNode $node) } foreach ($value as $key => $val) { - if (is_array($val) && 1 === count($val)) { + if (\is_array($val) && 1 === \count($val)) { $value[$key] = current($val); } } @@ -374,7 +374,7 @@ private function buildXml(\DOMNode $parentNode, $data, $xmlRootNodeName = null) { $append = true; - if (is_array($data) || ($data instanceof \Traversable && !$this->serializer->supportsNormalization($data, $this->format))) { + if (\is_array($data) || ($data instanceof \Traversable && !$this->serializer->supportsNormalization($data, $this->format))) { foreach ($data as $key => $data) { //Ah this is the magic @ attribute types. if (0 === strpos($key, '@') && $this->isElementNameValid($attributeName = substr($key, 1))) { @@ -384,7 +384,7 @@ private function buildXml(\DOMNode $parentNode, $data, $xmlRootNodeName = null) $parentNode->setAttribute($attributeName, $data); } elseif ('#' === $key) { $append = $this->selectNodeType($parentNode, $data); - } elseif (is_array($data) && false === is_numeric($key)) { + } elseif (\is_array($data) && false === is_numeric($key)) { // Is this array fully numeric keys? if (ctype_digit(implode('', array_keys($data)))) { /* @@ -408,7 +408,7 @@ private function buildXml(\DOMNode $parentNode, $data, $xmlRootNodeName = null) return $append; } - if (is_object($data)) { + if (\is_object($data)) { $data = $this->serializer->normalize($data, $this->format, $this->context); if (null !== $data && !is_scalar($data)) { return $this->buildXml($parentNode, $data, $xmlRootNodeName); @@ -477,22 +477,22 @@ private function needsCdataWrapping($val) */ private function selectNodeType(\DOMNode $node, $val) { - if (is_array($val)) { + if (\is_array($val)) { return $this->buildXml($node, $val); } elseif ($val instanceof \SimpleXMLElement) { $child = $this->dom->importNode(dom_import_simplexml($val), true); $node->appendChild($child); } elseif ($val instanceof \Traversable) { $this->buildXml($node, $val); - } elseif (is_object($val)) { + } elseif (\is_object($val)) { return $this->selectNodeType($node, $this->serializer->normalize($val, $this->format, $this->context)); } elseif (is_numeric($val)) { return $this->appendText($node, (string) $val); - } elseif (is_string($val) && $this->needsCdataWrapping($val)) { + } elseif (\is_string($val) && $this->needsCdataWrapping($val)) { return $this->appendCData($node, $val); - } elseif (is_string($val)) { + } elseif (\is_string($val)) { return $this->appendText($node, $val); - } elseif (is_bool($val)) { + } elseif (\is_bool($val)) { return $this->appendText($node, (int) $val); } elseif ($val instanceof \DOMNode) { $child = $this->dom->importNode($val, true); diff --git a/src/Symfony/Component/Serializer/Mapping/AttributeMetadata.php b/src/Symfony/Component/Serializer/Mapping/AttributeMetadata.php index 600e17be4f976..1d8496179a1f5 100644 --- a/src/Symfony/Component/Serializer/Mapping/AttributeMetadata.php +++ b/src/Symfony/Component/Serializer/Mapping/AttributeMetadata.php @@ -55,7 +55,7 @@ public function getName() */ public function addGroup($group) { - if (!in_array($group, $this->groups)) { + if (!\in_array($group, $this->groups)) { $this->groups[] = $group; } } diff --git a/src/Symfony/Component/Serializer/Mapping/Factory/ClassMetadataFactory.php b/src/Symfony/Component/Serializer/Mapping/Factory/ClassMetadataFactory.php index 2babf7e27d442..c058e021df42c 100644 --- a/src/Symfony/Component/Serializer/Mapping/Factory/ClassMetadataFactory.php +++ b/src/Symfony/Component/Serializer/Mapping/Factory/ClassMetadataFactory.php @@ -40,7 +40,7 @@ public function getMetadataFor($value) { $class = $this->getClass($value); if (!$class) { - throw new InvalidArgumentException(sprintf('Cannot create metadata for non-objects. Got: "%s"', gettype($value))); + throw new InvalidArgumentException(sprintf('Cannot create metadata for non-objects. Got: "%s"', \gettype($value))); } if (isset($this->loadedClasses[$class])) { @@ -96,10 +96,10 @@ public function hasMetadataFor($value) */ private function getClass($value) { - if (!is_object($value) && !is_string($value)) { + if (!\is_object($value) && !\is_string($value)) { return false; } - return ltrim(is_object($value) ? get_class($value) : $value, '\\'); + return ltrim(\is_object($value) ? \get_class($value) : $value, '\\'); } } diff --git a/src/Symfony/Component/Serializer/Mapping/Loader/LoaderChain.php b/src/Symfony/Component/Serializer/Mapping/Loader/LoaderChain.php index 3b0192b7e458c..461001fe57543 100644 --- a/src/Symfony/Component/Serializer/Mapping/Loader/LoaderChain.php +++ b/src/Symfony/Component/Serializer/Mapping/Loader/LoaderChain.php @@ -40,7 +40,7 @@ public function __construct(array $loaders) { foreach ($loaders as $loader) { if (!$loader instanceof LoaderInterface) { - throw new MappingException(sprintf('Class %s is expected to implement LoaderInterface', get_class($loader))); + throw new MappingException(sprintf('Class %s is expected to implement LoaderInterface', \get_class($loader))); } } diff --git a/src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php b/src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php index be2de7b6f1aff..ac48d8161439d 100644 --- a/src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php @@ -30,7 +30,7 @@ class YamlFileLoader extends FileLoader * * @var array */ - private $classes = null; + private $classes; /** * {@inheritdoc} @@ -53,7 +53,7 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata) } // not an array - if (!is_array($classes)) { + if (!\is_array($classes)) { throw new MappingException(sprintf('The file "%s" must contain a YAML array.', $this->file)); } @@ -66,7 +66,7 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata) $yaml = $this->classes[$classMetadata->getName()]; - if (isset($yaml['attributes']) && is_array($yaml['attributes'])) { + if (isset($yaml['attributes']) && \is_array($yaml['attributes'])) { $attributesMetadata = $classMetadata->getAttributesMetadata(); foreach ($yaml['attributes'] as $attribute => $data) { @@ -78,12 +78,12 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata) } if (isset($data['groups'])) { - if (!is_array($data['groups'])) { + if (!\is_array($data['groups'])) { throw new MappingException(sprintf('The "groups" key must be an array of strings in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName())); } foreach ($data['groups'] as $group) { - if (!is_string($group)) { + if (!\is_string($group)) { throw new MappingException(sprintf('Group names must be strings in "%s" for the attribute "%s" of the class "%s".', $this->file, $attribute, $classMetadata->getName())); } diff --git a/src/Symfony/Component/Serializer/NameConverter/CamelCaseToSnakeCaseNameConverter.php b/src/Symfony/Component/Serializer/NameConverter/CamelCaseToSnakeCaseNameConverter.php index ca2705cf2ac6c..9241d40357268 100644 --- a/src/Symfony/Component/Serializer/NameConverter/CamelCaseToSnakeCaseNameConverter.php +++ b/src/Symfony/Component/Serializer/NameConverter/CamelCaseToSnakeCaseNameConverter.php @@ -36,11 +36,11 @@ public function __construct(array $attributes = null, $lowerCamelCase = true) */ public function normalize($propertyName) { - if (null === $this->attributes || in_array($propertyName, $this->attributes)) { + if (null === $this->attributes || \in_array($propertyName, $this->attributes)) { $lcPropertyName = lcfirst($propertyName); $snakeCasedName = ''; - $len = strlen($lcPropertyName); + $len = \strlen($lcPropertyName); for ($i = 0; $i < $len; ++$i) { if (ctype_upper($lcPropertyName[$i])) { $snakeCasedName .= '_'.strtolower($lcPropertyName[$i]); @@ -68,7 +68,7 @@ public function denormalize($propertyName) $camelCasedName = lcfirst($camelCasedName); } - if (null === $this->attributes || in_array($camelCasedName, $this->attributes)) { + if (null === $this->attributes || \in_array($camelCasedName, $this->attributes)) { return $camelCasedName; } diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index 031bcf7d08c5c..88f5f9273dae4 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -100,7 +100,7 @@ public function setCircularReferenceLimit($circularReferenceLimit) */ public function setCircularReferenceHandler($circularReferenceHandler) { - if (!is_callable($circularReferenceHandler)) { + if (!\is_callable($circularReferenceHandler)) { throw new InvalidArgumentException('The given circular reference handler is not callable.'); } @@ -121,7 +121,7 @@ public function setCircularReferenceHandler($circularReferenceHandler) public function setCallbacks(array $callbacks) { foreach ($callbacks as $attribute => $callback) { - if (!is_callable($callback)) { + if (!\is_callable($callback)) { throw new InvalidArgumentException(sprintf( 'The given callback for attribute "%s" is not callable.', $attribute @@ -220,10 +220,10 @@ protected function isCircularReference($object, &$context) protected function handleCircularReference($object) { if ($this->circularReferenceHandler) { - return call_user_func($this->circularReferenceHandler, $object); + return \call_user_func($this->circularReferenceHandler, $object); } - throw new CircularReferenceException(sprintf('A circular reference has been detected when serializing the object of class "%s" (configured limit: %d)', get_class($object), $this->circularReferenceLimit)); + throw new CircularReferenceException(sprintf('A circular reference has been detected when serializing the object of class "%s" (configured limit: %d)', \get_class($object), $this->circularReferenceLimit)); } /** @@ -253,13 +253,13 @@ protected function formatAttribute($attributeName) */ protected function getAllowedAttributes($classOrObject, array $context, $attributesAsString = false) { - if (!$this->classMetadataFactory || !isset($context[static::GROUPS]) || !is_array($context[static::GROUPS])) { + if (!$this->classMetadataFactory || !isset($context[static::GROUPS]) || !\is_array($context[static::GROUPS])) { return false; } $allowedAttributes = array(); foreach ($this->classMetadataFactory->getMetadataFor($classOrObject)->getAttributesMetadata() as $attributeMetadata) { - if (count(array_intersect($attributeMetadata->getGroups(), $context[static::GROUPS]))) { + if (array_intersect($attributeMetadata->getGroups(), $context[static::GROUPS])) { $allowedAttributes[] = $attributesAsString ? $attributeMetadata->getName() : $attributeMetadata; } } @@ -302,7 +302,7 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref { if ( isset($context[static::OBJECT_TO_POPULATE]) && - is_object($context[static::OBJECT_TO_POPULATE]) && + \is_object($context[static::OBJECT_TO_POPULATE]) && $context[static::OBJECT_TO_POPULATE] instanceof $class ) { $object = $context[static::OBJECT_TO_POPULATE]; @@ -320,11 +320,11 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref $paramName = $constructorParameter->name; $key = $this->nameConverter ? $this->nameConverter->normalize($paramName) : $paramName; - $allowed = false === $allowedAttributes || in_array($paramName, $allowedAttributes); - $ignored = in_array($paramName, $this->ignoredAttributes); + $allowed = false === $allowedAttributes || \in_array($paramName, $allowedAttributes); + $ignored = \in_array($paramName, $this->ignoredAttributes); if (method_exists($constructorParameter, 'isVariadic') && $constructorParameter->isVariadic()) { if ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) { - if (!is_array($data[$paramName])) { + if (!\is_array($data[$paramName])) { throw new RuntimeException(sprintf('Cannot create an instance of %s from serialized data because the variadic parameter %s can only accept an array.', $class, $constructorParameter->name)); } diff --git a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php index 6eec32160d02e..d8cfc1d201d45 100644 --- a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php @@ -58,17 +58,17 @@ public function normalize($object, $format = null, array $context = array()) foreach ($reflectionMethods as $method) { if ($this->isGetMethod($method)) { $attributeName = lcfirst(substr($method->name, 0 === strpos($method->name, 'is') ? 2 : 3)); - if (in_array($attributeName, $this->ignoredAttributes)) { + if (\in_array($attributeName, $this->ignoredAttributes)) { continue; } - if (false !== $allowedAttributes && !in_array($attributeName, $allowedAttributes)) { + if (false !== $allowedAttributes && !\in_array($attributeName, $allowedAttributes)) { continue; } $attributeValue = $method->invoke($object); if (isset($this->callbacks[$attributeName])) { - $attributeValue = call_user_func($this->callbacks[$attributeName], $attributeValue); + $attributeValue = \call_user_func($this->callbacks[$attributeName], $attributeValue); } if (null !== $attributeValue && !is_scalar($attributeValue)) { if (!$this->serializer instanceof NormalizerInterface) { @@ -108,13 +108,13 @@ public function denormalize($data, $class, $format = null, array $context = arra $attribute = $this->nameConverter->denormalize($attribute); } - $allowed = false === $allowedAttributes || in_array($attribute, $allowedAttributes); - $ignored = in_array($attribute, $this->ignoredAttributes); + $allowed = false === $allowedAttributes || \in_array($attribute, $allowedAttributes); + $ignored = \in_array($attribute, $this->ignoredAttributes); if ($allowed && !$ignored) { $setter = 'set'.ucfirst($attribute); - if (in_array($setter, $classMethods) && !$reflectionClass->getMethod($setter)->isStatic()) { + if (\in_array($setter, $classMethods) && !$reflectionClass->getMethod($setter)->isStatic()) { $object->$setter($value); } } @@ -128,7 +128,7 @@ public function denormalize($data, $class, $format = null, array $context = arra */ public function supportsNormalization($data, $format = null) { - return is_object($data) && !$data instanceof \Traversable && $this->supports(get_class($data)); + return \is_object($data) && !$data instanceof \Traversable && $this->supports(\get_class($data)); } /** @@ -166,7 +166,7 @@ private function supports($class) */ private function isGetMethod(\ReflectionMethod $method) { - $methodLength = strlen($method->name); + $methodLength = \strlen($method->name); return !$method->isStatic() && diff --git a/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php index 5c64e156c34e6..dc3a49ff7e115 100644 --- a/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php @@ -45,7 +45,7 @@ public function __construct(ClassMetadataFactoryInterface $classMetadataFactory */ public function supportsNormalization($data, $format = null) { - return is_object($data) && !$data instanceof \Traversable; + return \is_object($data) && !$data instanceof \Traversable; } /** @@ -98,14 +98,14 @@ public function normalize($object, $format = null, array $context = array()) } foreach ($attributes as $attribute) { - if (in_array($attribute, $this->ignoredAttributes)) { + if (\in_array($attribute, $this->ignoredAttributes)) { continue; } $attributeValue = $this->propertyAccessor->getValue($object, $attribute); if (isset($this->callbacks[$attribute])) { - $attributeValue = call_user_func($this->callbacks[$attribute], $attributeValue); + $attributeValue = \call_user_func($this->callbacks[$attribute], $attributeValue); } if (null !== $attributeValue && !is_scalar($attributeValue)) { @@ -150,8 +150,8 @@ public function denormalize($data, $class, $format = null, array $context = arra $attribute = $this->nameConverter->denormalize($attribute); } - $allowed = false === $allowedAttributes || in_array($attribute, $allowedAttributes); - $ignored = in_array($attribute, $this->ignoredAttributes); + $allowed = false === $allowedAttributes || \in_array($attribute, $allowedAttributes); + $ignored = \in_array($attribute, $this->ignoredAttributes); if ($allowed && !$ignored) { try { diff --git a/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php index a5764244fe4cc..89e1057277211 100644 --- a/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php @@ -50,11 +50,11 @@ public function normalize($object, $format = null, array $context = array()) $allowedAttributes = $this->getAllowedAttributes($object, $context, true); foreach ($reflectionObject->getProperties() as $property) { - if (in_array($property->name, $this->ignoredAttributes) || $property->isStatic()) { + if (\in_array($property->name, $this->ignoredAttributes) || $property->isStatic()) { continue; } - if (false !== $allowedAttributes && !in_array($property->name, $allowedAttributes)) { + if (false !== $allowedAttributes && !\in_array($property->name, $allowedAttributes)) { continue; } @@ -66,7 +66,7 @@ public function normalize($object, $format = null, array $context = array()) $attributeValue = $property->getValue($object); if (isset($this->callbacks[$property->name])) { - $attributeValue = call_user_func($this->callbacks[$property->name], $attributeValue); + $attributeValue = \call_user_func($this->callbacks[$property->name], $attributeValue); } if (null !== $attributeValue && !is_scalar($attributeValue)) { if (!$this->serializer instanceof NormalizerInterface) { @@ -105,8 +105,8 @@ public function denormalize($data, $class, $format = null, array $context = arra $propertyName = $this->nameConverter->denormalize($propertyName); } - $allowed = false === $allowedAttributes || in_array($propertyName, $allowedAttributes); - $ignored = in_array($propertyName, $this->ignoredAttributes); + $allowed = false === $allowedAttributes || \in_array($propertyName, $allowedAttributes); + $ignored = \in_array($propertyName, $this->ignoredAttributes); if ($allowed && !$ignored && $reflectionClass->hasProperty($propertyName)) { $property = $reflectionClass->getProperty($propertyName); @@ -131,7 +131,7 @@ public function denormalize($data, $class, $format = null, array $context = arra */ public function supportsNormalization($data, $format = null) { - return is_object($data) && !$data instanceof \Traversable && $this->supports(get_class($data)); + return \is_object($data) && !$data instanceof \Traversable && $this->supports(\get_class($data)); } /** diff --git a/src/Symfony/Component/Serializer/Serializer.php b/src/Symfony/Component/Serializer/Serializer.php index 37b49f3493b8b..34e4193c6aa45 100644 --- a/src/Symfony/Component/Serializer/Serializer.php +++ b/src/Symfony/Component/Serializer/Serializer.php @@ -132,7 +132,7 @@ public function normalize($data, $format = null, array $context = array()) return $data; } - if (is_array($data) || $data instanceof \Traversable) { + if (\is_array($data) || $data instanceof \Traversable) { $normalized = array(); foreach ($data as $key => $val) { $normalized[$key] = $this->normalize($val, $format, $context); @@ -141,12 +141,12 @@ public function normalize($data, $format = null, array $context = array()) return $normalized; } - if (is_object($data)) { + if (\is_object($data)) { if (!$this->normalizers) { throw new LogicException('You must register at least one normalizer to be able to normalize objects.'); } - throw new UnexpectedValueException(sprintf('Could not normalize object of type %s, no supporting normalizer found.', get_class($data))); + throw new UnexpectedValueException(sprintf('Could not normalize object of type %s, no supporting normalizer found.', \get_class($data))); } throw new UnexpectedValueException(sprintf('An unexpected value could not be normalized: %s', var_export($data, true))); From 538b2570419b1e3f1c5796cc12cecd960be32d2d Mon Sep 17 00:00:00 2001 From: Dariusz Ruminski Date: Thu, 15 Feb 2018 00:24:28 +0100 Subject: [PATCH 101/166] Fix undiscoverablility of SymfonyTestsListenerForV7 --- src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV7.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV7.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV7.php index d3acd53960d29..18bbdbeba0f03 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV7.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerForV7.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Bridge\PhpUnit; +namespace Symfony\Bridge\PhpUnit\Legacy; use PHPUnit\Framework\Test; use PHPUnit\Framework\TestListener; From a5f05a04864f67f6738ef83d734039a7b85cc5ac Mon Sep 17 00:00:00 2001 From: "changmin.keum" Date: Thu, 15 Feb 2018 14:08:21 +0900 Subject: [PATCH 102/166] [DI] Add null check for removeChild --- .../Component/DependencyInjection/Loader/XmlFileLoader.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index 93ca3c669b7d3..abf91b181ca3e 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -324,7 +324,9 @@ private function processAnonymousServices(\DOMDocument $xml, $file) $domElement->parentNode->replaceChild($tmpDomElement, $domElement); $tmpDomElement->setAttribute('id', $id); } else { - $domElement->parentNode->removeChild($domElement); + if (null !== $domElement->parentNode) { + $domElement->parentNode->removeChild($domElement); + } } } } From ba3e19ae21ce4c0cd93b402d262c2a749ecd00a6 Mon Sep 17 00:00:00 2001 From: Ian Jenkins Date: Thu, 15 Feb 2018 15:19:03 +0000 Subject: [PATCH 103/166] [HttpFoundation] Add x-zip-compressed to MimeTypeExtensionGuesser. Zip files uploaded on Windows often have a mime type of `x-zip-compressed`. This patch adds support for this mime type to `MimeTypeExtensionGuesser`. The mime type seems to be a valid mime type for zip files according to http://filext.com/file-extension/ZIP --- .../HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php b/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php index 49c323c1f55e8..36271afe4a906 100644 --- a/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php +++ b/src/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php @@ -599,6 +599,7 @@ class MimeTypeExtensionGuesser implements ExtensionGuesserInterface 'application/x-xliff+xml' => 'xlf', 'application/x-xpinstall' => 'xpi', 'application/x-xz' => 'xz', + 'application/x-zip-compressed' => 'zip', 'application/x-zmachine' => 'z1', 'application/xaml+xml' => 'xaml', 'application/xcap-diff+xml' => 'xdf', From bc1b652b171fcdb6085ba0ffc7544552d5f9ff55 Mon Sep 17 00:00:00 2001 From: Wouter J Date: Tue, 30 Jan 2018 22:23:40 +0100 Subject: [PATCH 104/166] Added a README entry to the PR template --- .github/PULL_REQUEST_TEMPLATE.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e51cf88761451..f52d3571ceb93 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -11,8 +11,10 @@ | Doc PR | symfony/symfony-docs#... From b32fdf1ca3ae87098876a761b1cf128852842517 Mon Sep 17 00:00:00 2001 From: Greg Anderson Date: Mon, 12 Feb 2018 14:05:44 -0800 Subject: [PATCH 105/166] Fixes #26136: Avoid emitting warning in hasParameterOption() --- src/Symfony/Component/Console/Input/ArgvInput.php | 4 ++-- .../Console/Tests/Input/ArgvInputTest.php | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Console/Input/ArgvInput.php b/src/Symfony/Component/Console/Input/ArgvInput.php index da064598d0741..62c658b4f9c6a 100644 --- a/src/Symfony/Component/Console/Input/ArgvInput.php +++ b/src/Symfony/Component/Console/Input/ArgvInput.php @@ -283,7 +283,7 @@ public function hasParameterOption($values) // For long options, test for '--option=' at beginning // For short options, test for '-o' at beginning $leading = 0 === strpos($value, '--') ? $value.'=' : $value; - if ($token === $value || 0 === strpos($token, $leading)) { + if ($token === $value || '' !== $leading && 0 === strpos($token, $leading)) { return true; } } @@ -311,7 +311,7 @@ public function getParameterOption($values, $default = false) // For long options, test for '--option=' at beginning // For short options, test for '-o' at beginning $leading = 0 === strpos($value, '--') ? $value.'=' : $value; - if (0 === strpos($token, $leading)) { + if ('' !== $leading && 0 === strpos($token, $leading)) { return substr($token, strlen($leading)); } } diff --git a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php index 04f5ce3157c44..c2a277a93fa78 100644 --- a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php +++ b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php @@ -337,6 +337,21 @@ public function testHasParameterOptionEdgeCasesAndLimitations() $this->assertFalse($input->hasParameterOption('-fh'), '->hasParameterOption() returns true if the given short option is in the raw input'); } + public function testNoWarningOnInvalidParameterOption() + { + $input = new ArgvInput(array('cli.php', '-edev')); + + // Control. + $this->assertTrue($input->hasParameterOption(array('-e', ''))); + // No warning is thrown if https://github.com/symfony/symfony/pull/26156 is fixed + $this->assertFalse($input->hasParameterOption(array('-m', ''))); + + // Control. + $this->assertEquals('dev', $input->getParameterOption(array('-e', ''))); + // No warning is thrown if https://github.com/symfony/symfony/pull/26156 is fixed + $this->assertFalse($input->getParameterOption(array('-m', ''))); + } + public function testToString() { $input = new ArgvInput(array('cli.php', '-f', 'foo')); From 800cadfb82fd072e75b88f0cca3be6207b9c3263 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 16 Feb 2018 06:42:51 +0100 Subject: [PATCH 106/166] removed extra-verbose comments --- src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php index c2a277a93fa78..5f813ee39fa60 100644 --- a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php +++ b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php @@ -341,14 +341,12 @@ public function testNoWarningOnInvalidParameterOption() { $input = new ArgvInput(array('cli.php', '-edev')); - // Control. $this->assertTrue($input->hasParameterOption(array('-e', ''))); - // No warning is thrown if https://github.com/symfony/symfony/pull/26156 is fixed + // No warning thrown $this->assertFalse($input->hasParameterOption(array('-m', ''))); - // Control. $this->assertEquals('dev', $input->getParameterOption(array('-e', ''))); - // No warning is thrown if https://github.com/symfony/symfony/pull/26156 is fixed + // No warning thrown $this->assertFalse($input->getParameterOption(array('-m', ''))); } From a7e2a49a78379e835adb755111fb11fc57b5a75c Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Sat, 13 Jan 2018 21:35:11 +0000 Subject: [PATCH 107/166] Yaml parser regression with comments and non-strings --- src/Symfony/Component/Yaml/Parser.php | 59 +++++++------------ .../Component/Yaml/Tests/ParserTest.php | 36 +++++++++++ 2 files changed, 58 insertions(+), 37 deletions(-) diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 752d2d30fd0f9..4721a7ea6ec5c 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -390,54 +390,39 @@ private function doParse($value, $flags) // try to parse the value as a multi-line string as a last resort if (0 === $this->currentLineNb) { - $parseError = false; $previousLineWasNewline = false; $previousLineWasTerminatedWithBackslash = false; $value = ''; foreach ($this->lines as $line) { - try { - if (isset($line[0]) && ('"' === $line[0] || "'" === $line[0])) { - $parsedLine = $line; - } else { - $parsedLine = Inline::parse($line, $flags, $this->refs); - } - - if (!is_string($parsedLine)) { - $parseError = true; - break; - } - - if ('' === trim($parsedLine)) { - $value .= "\n"; - } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) { - $value .= ' '; - } + if ('' === trim($line)) { + $value .= "\n"; + } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) { + $value .= ' '; + } - if ('' !== trim($parsedLine) && '\\' === substr($parsedLine, -1)) { - $value .= ltrim(substr($parsedLine, 0, -1)); - } elseif ('' !== trim($parsedLine)) { - $value .= trim($parsedLine); - } + if ('' !== trim($line) && '\\' === substr($line, -1)) { + $value .= ltrim(substr($line, 0, -1)); + } elseif ('' !== trim($line)) { + $value .= trim($line); + } - if ('' === trim($parsedLine)) { - $previousLineWasNewline = true; - $previousLineWasTerminatedWithBackslash = false; - } elseif ('\\' === substr($parsedLine, -1)) { - $previousLineWasNewline = false; - $previousLineWasTerminatedWithBackslash = true; - } else { - $previousLineWasNewline = false; - $previousLineWasTerminatedWithBackslash = false; - } - } catch (ParseException $e) { - $parseError = true; - break; + if ('' === trim($line)) { + $previousLineWasNewline = true; + $previousLineWasTerminatedWithBackslash = false; + } elseif ('\\' === substr($line, -1)) { + $previousLineWasNewline = false; + $previousLineWasTerminatedWithBackslash = true; + } else { + $previousLineWasNewline = false; + $previousLineWasTerminatedWithBackslash = false; } } - if (!$parseError) { + try { return Inline::parse(trim($value)); + } catch (ParseException $e) { + // fall-through to the ParseException thrown below } } diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 8090bd37bbad1..ca7bd0f244977 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -776,6 +776,42 @@ public function testSequenceFollowedByCommentEmbeddedInMapping() $this->assertSame($expected, $this->parser->parse($yaml)); } + public function testNonStringFollowedByCommentEmbeddedInMapping() + { + $yaml = <<<'EOT' +a: + b: + {} +# comment + d: + 1.1 +# another comment +EOT; + $expected = array( + 'a' => array( + 'b' => array(), + 'd' => 1.1, + ), + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testMultiLineStringLastResortParsing() + { + $yaml = <<<'EOT' +test: + You can have things that don't look like strings here + true + yes you can +EOT; + $expected = array( + 'test' => 'You can have things that don\'t look like strings here true yes you can', + ); + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + /** * @expectedException \Symfony\Component\Yaml\Exception\ParseException */ From bbcaaef547f525f96fae449f4893c8744098fc31 Mon Sep 17 00:00:00 2001 From: Amrouche Hamza Date: Fri, 16 Feb 2018 11:10:07 +0100 Subject: [PATCH 108/166] [Serializer] remove unneeded php doc line --- src/Symfony/Component/Serializer/Encoder/XmlEncoder.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php index 43f8fac85b8e4..2fac8ce1bac6e 100644 --- a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php @@ -41,8 +41,7 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa /** * Construct new XmlEncoder and allow to change the root node element name. * - * @param string $rootNodeName - * @param int|null $loadOptions A bit field of LIBXML_* constants + * @param int|null $loadOptions A bit field of LIBXML_* constants */ public function __construct(string $rootNodeName = 'response', int $loadOptions = null) { @@ -346,7 +345,6 @@ private function parseXmlValue(\DOMNode $node, array $context = array()) /** * Parse the data and convert it to DOMElements. * - * @param \DOMNode $parentNode * @param array|object $data * * @throws NotEncodableValueException @@ -412,7 +410,6 @@ private function buildXml(\DOMNode $parentNode, $data, string $xmlRootNodeName = /** * Selects the type of node to create and appends it to the parent. * - * @param \DOMNode $parentNode * @param array|object $data */ private function appendNode(\DOMNode $parentNode, $data, string $nodeName, string $key = null): bool @@ -441,8 +438,7 @@ private function needsCdataWrapping(string $val): bool /** * Tests the value being passed and decide what sort of element to create. * - * @param \DOMNode $node - * @param mixed $val + * @param mixed $val * * @throws NotEncodableValueException */ From 0f1605663a0b4104277f6d4f01fd692590426808 Mon Sep 17 00:00:00 2001 From: Lars Strojny Date: Wed, 14 Feb 2018 13:12:35 +0100 Subject: [PATCH 109/166] Retro-fit proxy code to make it deterministic for older proxy manager implementations --- .../LazyProxy/PhpDumper/ProxyDumper.php | 39 +++++++++++++++++-- .../LazyProxy/PhpDumper/ProxyDumperTest.php | 8 ++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index 2b827324fa7b6..316cc8250173f 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -13,6 +13,7 @@ use ProxyManager\Generator\ClassGenerator; use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy; +use ProxyManager\Version; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface; @@ -94,11 +95,35 @@ public function getProxyFactoryCode(Definition $definition, $id, $factoryCode = */ public function getProxyCode(Definition $definition) { - return preg_replace( + $code = $this->classGenerator->generate($this->generateProxyClass($definition)); + + $code = preg_replace( '/(\$this->initializer[0-9a-f]++) && \1->__invoke\(\$this->(valueHolder[0-9a-f]++), (.*?), \1\);/', '$1 && ($1->__invoke(\$$2, $3, $1) || 1) && $this->$2 = \$$2;', - $this->classGenerator->generate($this->generateProxyClass($definition)) + $code ); + + if (version_compare(self::getProxyManagerVersion(), '2.2', '<')) { + $code = preg_replace( + '/((?:\$(?:this|initializer|instance)->)?(?:publicProperties|initializer|valueHolder))[0-9a-f]++/', + '${1}'.$this->getIdentifierSuffix($definition), + $code + ); + } + + return $code; + } + + /** + * @return string + */ + private static function getProxyManagerVersion() + { + if (!\class_exists(Version::class)) { + return '0.0.1'; + } + + return defined(Version::class.'::VERSION') ? Version::VERSION : Version::getVersion(); } /** @@ -108,7 +133,7 @@ public function getProxyCode(Definition $definition) */ private function getProxyClassName(Definition $definition) { - return preg_replace('/^.*\\\\/', '', $definition->getClass()).'_'.substr(hash('sha256', $definition->getClass().$this->salt), -7); + return preg_replace('/^.*\\\\/', '', $definition->getClass()).'_'.$this->getIdentifierSuffix($definition); } /** @@ -122,4 +147,12 @@ private function generateProxyClass(Definition $definition) return $generatedClass; } + + /** + * @return string + */ + private function getIdentifierSuffix(Definition $definition) + { + return substr(hash('sha256', $definition->getClass().$this->salt), -7); + } } diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php index 640290e2b45a2..b4ce2106d8f2b 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php @@ -61,6 +61,14 @@ public function testGetProxyCode() ); } + public function testDeterministicProxyCode() + { + $definition = new Definition(__CLASS__); + $definition->setLazy(true); + + $this->assertSame($this->dumper->getProxyCode($definition), $this->dumper->getProxyCode($definition)); + } + public function testGetProxyFactoryCode() { $definition = new Definition(__CLASS__); From 8278a47caa5f116086873dce01090d5937b5cde2 Mon Sep 17 00:00:00 2001 From: Lukas Kahwe Smith Date: Sat, 17 Feb 2018 15:55:25 +0100 Subject: [PATCH 110/166] updated StopwatchEvent phpdoc due to the additional of optional float precision introduced in 0db8d7fb6a5396f84f2907e5e595c114982772ff --- src/Symfony/Component/Stopwatch/StopwatchEvent.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Stopwatch/StopwatchEvent.php b/src/Symfony/Component/Stopwatch/StopwatchEvent.php index d8f9d1361d586..d93167e7e66c2 100644 --- a/src/Symfony/Component/Stopwatch/StopwatchEvent.php +++ b/src/Symfony/Component/Stopwatch/StopwatchEvent.php @@ -150,7 +150,7 @@ public function getPeriods() /** * Gets the relative time of the start of the first period. * - * @return int The time (in milliseconds) + * @return int|float The time (in milliseconds) */ public function getStartTime() { @@ -160,7 +160,7 @@ public function getStartTime() /** * Gets the relative time of the end of the last period. * - * @return int The time (in milliseconds) + * @return int|float The time (in milliseconds) */ public function getEndTime() { @@ -172,7 +172,7 @@ public function getEndTime() /** * Gets the duration of the events (including all periods). * - * @return int The duration (in milliseconds) + * @return int|float The duration (in milliseconds) */ public function getDuration() { From 43f942159d05eebdb88efb28a606ea3b07eaac68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Klva=C4=8D?= Date: Sun, 18 Feb 2018 14:02:56 +0100 Subject: [PATCH 111/166] Suppress warning from sapi_windows_vt100_support on stream other than STDIO --- src/Symfony/Component/Console/Output/StreamOutput.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/Output/StreamOutput.php b/src/Symfony/Component/Console/Output/StreamOutput.php index d32b1cfb54cae..d36e6f9560159 100644 --- a/src/Symfony/Component/Console/Output/StreamOutput.php +++ b/src/Symfony/Component/Console/Output/StreamOutput.php @@ -90,7 +90,7 @@ protected function hasColorSupport() { if (DIRECTORY_SEPARATOR === '\\') { return - function_exists('sapi_windows_vt100_support') && sapi_windows_vt100_support($this->stream) + function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support($this->stream) || '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD || false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') From 5c4566ca731f04548d34c2113d5f0c9717b76983 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Sun, 18 Feb 2018 12:51:02 +0100 Subject: [PATCH 112/166] [WebProfilerBundle] Tweak default route name --- .../Resources/views/Collector/request.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig index 903d009c98225..a1ff4afd01f63 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -58,7 +58,7 @@
Route name - {{ collector.route|default('NONE') }} + {{ collector.route|default('n/a') }}
From 0e4d26a5688f3b0292e12fdfa32815c37969159e Mon Sep 17 00:00:00 2001 From: Matthieu Napoli Date: Sun, 18 Feb 2018 18:35:19 +0100 Subject: [PATCH 113/166] Improve the documentation of --- src/Symfony/Component/Filesystem/Filesystem.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 575ebaac4adb1..5c3b2a2d9cb8e 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -431,13 +431,18 @@ public function makePathRelative($endPath, $startPath) /** * Mirrors a directory to another. * + * Copies files and directories from the origin directory into the target directory. By default: + * + * - existing files in the target directory will be overwritten, except if they are newer (see the `override` option) + * - files in the target directory that do not exist in the source directory will not be deleted (see the `delete` option) + * * @param string $originDir The origin directory * @param string $targetDir The target directory - * @param \Traversable $iterator A Traversable instance + * @param \Traversable $iterator Iterator that filters which files and directories to copy * @param array $options An array of boolean options * Valid options are: - * - $options['override'] Whether to override an existing file on copy or not (see copy()) - * - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink()) + * - $options['override'] If true, target files newer than origin files are overwritten (see copy(), defaults to false) + * - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink(), defaults to false) * - $options['delete'] Whether to delete files that are not in the source directory (defaults to false) * * @throws IOException When file type is unknown From 98f5d5354e319d5dc8959a02d31a90df0e083adf Mon Sep 17 00:00:00 2001 From: Remon van de Kamp Date: Mon, 12 Feb 2018 23:59:35 +0100 Subject: [PATCH 114/166] [HttpKernel] Send new session cookie from AbstractTestSessionListener after session invalidation --- .../AbstractTestSessionListener.php | 8 ++++-- .../EventListener/TestSessionListenerTest.php | 25 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php b/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php index 5f0ea5c0a9c08..0a153dd943297 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/AbstractTestSessionListener.php @@ -29,6 +29,8 @@ */ abstract class AbstractTestSessionListener implements EventSubscriberInterface { + private $sessionId; + public function onKernelRequest(GetResponseEvent $event) { if (!$event->isMasterRequest()) { @@ -44,7 +46,8 @@ public function onKernelRequest(GetResponseEvent $event) $cookies = $event->getRequest()->cookies; if ($cookies->has($session->getName())) { - $session->setId($cookies->get($session->getName())); + $this->sessionId = $cookies->get($session->getName()); + $session->setId($this->sessionId); } } @@ -66,9 +69,10 @@ public function onKernelResponse(FilterResponseEvent $event) $session->save(); } - if ($session instanceof Session ? !$session->isEmpty() : $wasStarted) { + if ($session instanceof Session ? !$session->isEmpty() || $session->getId() !== $this->sessionId : $wasStarted) { $params = session_get_cookie_params(); $event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly'])); + $this->sessionId = $session->getId(); } } diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php index 4452f48771b8b..0a2263d5a8e78 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php @@ -13,8 +13,10 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ServiceSubscriberInterface; +use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\EventListener\SessionListener; @@ -86,6 +88,22 @@ public function testEmptySessionDoesNotSendCookie() $this->assertSame(array(), $response->headers->getCookies()); } + public function testEmptySessionWithNewSessionIdDoesSendCookie() + { + $this->sessionHasBeenStarted(); + $this->sessionIsEmpty(); + $this->fixSessionId('456'); + + $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(); + $request = Request::create('/', 'GET', array(), array(new Cookie('MOCKSESSID', '123'))); + $event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST); + $this->listener->onKernelRequest($event); + + $response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST); + + $this->assertNotEmpty($response->headers->getCookies()); + } + public function testUnstartedSessionIsNotSave() { $this->sessionHasNotBeenStarted(); @@ -150,6 +168,13 @@ private function sessionIsEmpty() ->will($this->returnValue(true)); } + private function fixSessionId($sessionId) + { + $this->session->expects($this->any()) + ->method('getId') + ->will($this->returnValue($sessionId)); + } + private function getSession() { $mock = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\Session') From 7490f0b0606255e1b60a13ef82f57017e585d3d4 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 19 Feb 2018 12:59:32 +0100 Subject: [PATCH 115/166] [HttpFoundation] Fix missing "throw" in JsonResponse --- src/Symfony/Component/HttpFoundation/JsonResponse.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php index 4ec2fa19a0f47..51852443c115c 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -148,6 +148,7 @@ public function setData($data = array()) if (\PHP_VERSION_ID < 50500 || !interface_exists('JsonSerializable', false)) { restore_error_handler(); } + throw $e; } catch (\Exception $e) { if (\PHP_VERSION_ID < 50500 || !interface_exists('JsonSerializable', false)) { restore_error_handler(); From ed27b12d2cdbbbcfc3f209f4330afa89e46236bd Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 19 Feb 2018 13:18:43 +0100 Subject: [PATCH 116/166] removed version in @final @internal for version < 4.0 --- .../LazyProxy/PhpDumper/ProxyDumper.php | 2 +- .../Twig/Extension/RoutingExtension.php | 2 +- .../CacheWarmer/RouterCacheWarmer.php | 2 +- .../FrameworkBundle/Command/AboutCommand.php | 2 +- .../Command/AssetsInstallCommand.php | 2 +- .../Command/CacheClearCommand.php | 2 +- .../Command/CacheWarmupCommand.php | 2 +- .../Command/ConfigDebugCommand.php | 2 +- .../Command/ConfigDumpReferenceCommand.php | 2 +- .../Command/ContainerDebugCommand.php | 2 +- .../Command/EventDispatcherDebugCommand.php | 2 +- .../Command/RouterDebugCommand.php | 2 +- .../Command/RouterMatchCommand.php | 2 +- .../Command/TranslationDebugCommand.php | 2 +- .../Command/TranslationUpdateCommand.php | 2 +- .../Command/WorkflowDumpCommand.php | 2 +- .../Command/XliffLintCommand.php | 2 +- .../Command/YamlLintCommand.php | 2 +- .../FrameworkBundle/Controller/Controller.php | 2 +- .../Controller/ControllerTrait.php | 42 ++++----- .../Controller/RedirectController.php | 2 +- .../Controller/TemplateController.php | 2 +- .../Command/UserPasswordEncoderCommand.php | 2 +- .../Debug/Tests/DebugClassLoaderTest.php | 8 +- .../Debug/Tests/Fixtures/AnnotatedClass.php | 2 +- .../Debug/Tests/Fixtures/FinalClass.php | 2 +- .../Debug/Tests/Fixtures/FinalMethod.php | 2 +- .../Debug/Tests/Fixtures/InternalClass.php | 2 +- .../Debug/Tests/Fixtures/InternalTrait2.php | 2 +- .../Debug/Tests/phpt/debug_class_loader.phpt | 2 +- .../Compiler/ServiceReferenceGraph.php | 2 +- .../DependencyInjection/ContainerBuilder.php | 2 +- .../LazyProxy/PhpDumper/NullDumper.php | 2 +- .../Component/HttpFoundation/Response.php | 92 +++++++++---------- .../CacheClearer/ChainCacheClearer.php | 2 +- .../CacheWarmer/CacheWarmerAggregate.php | 2 +- .../EventListener/SessionListener.php | 2 +- .../EventListener/TestSessionListener.php | 2 +- src/Symfony/Component/Process/Process.php | 6 +- .../Extractor/PhpDocExtractor.php | 2 +- .../Extractor/ReflectionExtractor.php | 2 +- .../Extractor/SerializerExtractor.php | 2 +- .../PropertyInfoCacheExtractor.php | 2 +- .../PropertyInfo/PropertyInfoExtractor.php | 2 +- src/Symfony/Component/PropertyInfo/Type.php | 2 +- .../Guard/GuardAuthenticatorHandler.php | 2 +- .../Serializer/Encoder/ChainDecoder.php | 2 +- .../Serializer/Encoder/ChainEncoder.php | 2 +- .../Normalizer/ArrayDenormalizer.php | 2 +- src/Symfony/Component/Yaml/Dumper.php | 2 +- src/Symfony/Component/Yaml/Parser.php | 2 +- src/Symfony/Component/Yaml/Yaml.php | 2 +- 52 files changed, 122 insertions(+), 122 deletions(-) diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index c15f6d2014c8a..02fa1e11f9195 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -22,7 +22,7 @@ * * @author Marco Pivetta * - * @final since version 3.3 + * @final */ class ProxyDumper implements DumperInterface { diff --git a/src/Symfony/Bridge/Twig/Extension/RoutingExtension.php b/src/Symfony/Bridge/Twig/Extension/RoutingExtension.php index 4875b1fab8452..57e8902dce98a 100644 --- a/src/Symfony/Bridge/Twig/Extension/RoutingExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/RoutingExtension.php @@ -91,7 +91,7 @@ public function getUrl($name, $parameters = array(), $schemeRelative = false) * * @return array An array with the contexts the URL is safe * - * @final since version 3.4 + * @final */ public function isUrlGenerationSafe(Node $argsNode) { diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/RouterCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/RouterCacheWarmer.php index 5c360bc334409..131d889cd46f4 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/RouterCacheWarmer.php +++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/RouterCacheWarmer.php @@ -22,7 +22,7 @@ * * @author Fabien Potencier * - * @final since version 3.4 + * @final */ class RouterCacheWarmer implements CacheWarmerInterface, ServiceSubscriberInterface { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php index 3c352b4c051a2..b6860a24ec03c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AboutCommand.php @@ -25,7 +25,7 @@ * * @author Roland Franssen * - * @final since version 3.4 + * @final */ class AboutCommand extends Command { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php index ea122cf80305a..ac3262baac35d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php @@ -28,7 +28,7 @@ * @author Fabien Potencier * @author Gábor Egyed * - * @final since version 3.4 + * @final */ class AssetsInstallCommand extends Command { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php index a33b3f3d908dd..a0872338a51b5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php @@ -29,7 +29,7 @@ * @author Francis Besset * @author Fabien Potencier * - * @final since version 3.4 + * @final */ class CacheClearCommand extends Command { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php index 5219e1dbbad39..ccd315cad502b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheWarmupCommand.php @@ -23,7 +23,7 @@ * * @author Fabien Potencier * - * @final since version 3.4 + * @final */ class CacheWarmupCommand extends Command { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php index d2fb64e763d62..cfef898242961 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php @@ -25,7 +25,7 @@ * * @author Grégoire Pineau * - * @final since version 3.4 + * @final */ class ConfigDebugCommand extends AbstractConfigCommand { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php index 06900cc2c40e5..8850efa373da8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php @@ -26,7 +26,7 @@ * @author Wouter J * @author Grégoire Pineau * - * @final since version 3.4 + * @final */ class ConfigDumpReferenceCommand extends AbstractConfigCommand { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php index cd3e2da829aae..9830609d969ad 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php @@ -29,7 +29,7 @@ * * @author Ryan Weaver * - * @internal since version 3.4 + * @internal */ class ContainerDebugCommand extends Command { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php index 75d98807984d0..bc525f2e73425 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/EventDispatcherDebugCommand.php @@ -25,7 +25,7 @@ * * @author Matthieu Auger * - * @final since version 3.4 + * @final */ class EventDispatcherDebugCommand extends Command { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php index 425f607f84a07..ce932575335b9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php @@ -29,7 +29,7 @@ * @author Fabien Potencier * @author Tobias Schultze * - * @final since version 3.4 + * @final */ class RouterDebugCommand extends Command { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.php index 74ef9fdc96a07..83be4ceab81ac 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.php @@ -26,7 +26,7 @@ * * @author Fabien Potencier * - * @final since version 3.4 + * @final */ class RouterMatchCommand extends Command { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php index a444df3a5affb..50737aa75c645 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php @@ -33,7 +33,7 @@ * * @author Florian Voutzinos * - * @final since version 3.4 + * @final */ class TranslationDebugCommand extends Command { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php index 2404dbdba7c5f..a29e3081f36e6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php @@ -31,7 +31,7 @@ * * @author Michel Salib * - * @final since version 3.4 + * @final */ class TranslationUpdateCommand extends Command { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php index 1c031f5999acf..e527da1d06e37 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php @@ -22,7 +22,7 @@ /** * @author Grégoire Pineau * - * @final since version 3.4 + * @final */ class WorkflowDumpCommand extends Command { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/XliffLintCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/XliffLintCommand.php index 42ee30e145077..0b5bb061d66e2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/XliffLintCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/XliffLintCommand.php @@ -20,7 +20,7 @@ * @author Robin Chalas * @author Javier Eguiluz * - * @final since version 3.4 + * @final */ class XliffLintCommand extends BaseLintCommand { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php index 4edd92ff6974e..1163ff1c28fb1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/YamlLintCommand.php @@ -19,7 +19,7 @@ * @author Grégoire Pineau * @author Robin Chalas * - * @final since version 3.4 + * @final */ class YamlLintCommand extends BaseLintCommand { diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php b/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php index c104ba10c2465..51ac58b9fae83 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php @@ -31,7 +31,7 @@ abstract class Controller implements ContainerAwareInterface * * @return mixed * - * @final since version 3.4 + * @final */ protected function getParameter(string $name) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php index 1fb263f00f4d3..69639f65d65ab 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php @@ -42,7 +42,7 @@ trait ControllerTrait /** * Returns true if the service id is defined. * - * @final since version 3.4 + * @final */ protected function has(string $id): bool { @@ -54,7 +54,7 @@ protected function has(string $id): bool * * @return object The service * - * @final since version 3.4 + * @final */ protected function get(string $id) { @@ -66,7 +66,7 @@ protected function get(string $id) * * @see UrlGeneratorInterface * - * @final since version 3.4 + * @final */ protected function generateUrl(string $route, array $parameters = array(), int $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH): string { @@ -78,7 +78,7 @@ protected function generateUrl(string $route, array $parameters = array(), int $ * * @param string $controller The controller name (a string like BlogBundle:Post:index) * - * @final since version 3.4 + * @final */ protected function forward(string $controller, array $path = array(), array $query = array()): Response { @@ -93,7 +93,7 @@ protected function forward(string $controller, array $path = array(), array $que /** * Returns a RedirectResponse to the given URL. * - * @final since version 3.4 + * @final */ protected function redirect(string $url, int $status = 302): RedirectResponse { @@ -103,7 +103,7 @@ protected function redirect(string $url, int $status = 302): RedirectResponse /** * Returns a RedirectResponse to the given route with the given parameters. * - * @final since version 3.4 + * @final */ protected function redirectToRoute(string $route, array $parameters = array(), int $status = 302): RedirectResponse { @@ -113,7 +113,7 @@ protected function redirectToRoute(string $route, array $parameters = array(), i /** * Returns a JsonResponse that uses the serializer component if enabled, or json_encode. * - * @final since version 3.4 + * @final */ protected function json($data, int $status = 200, array $headers = array(), array $context = array()): JsonResponse { @@ -133,7 +133,7 @@ protected function json($data, int $status = 200, array $headers = array(), arra * * @param \SplFileInfo|string $file File object or path to file to be sent as response * - * @final since version 3.4 + * @final */ protected function file($file, string $fileName = null, string $disposition = ResponseHeaderBag::DISPOSITION_ATTACHMENT): BinaryFileResponse { @@ -148,7 +148,7 @@ protected function file($file, string $fileName = null, string $disposition = Re * * @throws \LogicException * - * @final since version 3.4 + * @final */ protected function addFlash(string $type, string $message) { @@ -164,7 +164,7 @@ protected function addFlash(string $type, string $message) * * @throws \LogicException * - * @final since version 3.4 + * @final */ protected function isGranted($attributes, $subject = null): bool { @@ -181,7 +181,7 @@ protected function isGranted($attributes, $subject = null): bool * * @throws AccessDeniedException * - * @final since version 3.4 + * @final */ protected function denyAccessUnlessGranted($attributes, $subject = null, string $message = 'Access Denied.') { @@ -197,7 +197,7 @@ protected function denyAccessUnlessGranted($attributes, $subject = null, string /** * Returns a rendered view. * - * @final since version 3.4 + * @final */ protected function renderView(string $view, array $parameters = array()): string { @@ -215,7 +215,7 @@ protected function renderView(string $view, array $parameters = array()): string /** * Renders a view. * - * @final since version 3.4 + * @final */ protected function render(string $view, array $parameters = array(), Response $response = null): Response { @@ -239,7 +239,7 @@ protected function render(string $view, array $parameters = array(), Response $r /** * Streams a view. * - * @final since version 3.4 + * @final */ protected function stream(string $view, array $parameters = array(), StreamedResponse $response = null): StreamedResponse { @@ -275,7 +275,7 @@ protected function stream(string $view, array $parameters = array(), StreamedRes * * throw $this->createNotFoundException('Page not found!'); * - * @final since version 3.4 + * @final */ protected function createNotFoundException(string $message = 'Not Found', \Exception $previous = null): NotFoundHttpException { @@ -291,7 +291,7 @@ protected function createNotFoundException(string $message = 'Not Found', \Excep * * @throws \LogicException If the Security component is not available * - * @final since version 3.4 + * @final */ protected function createAccessDeniedException(string $message = 'Access Denied.', \Exception $previous = null): AccessDeniedException { @@ -305,7 +305,7 @@ protected function createAccessDeniedException(string $message = 'Access Denied. /** * Creates and returns a Form instance from the type of the form. * - * @final since version 3.4 + * @final */ protected function createForm(string $type, $data = null, array $options = array()): FormInterface { @@ -315,7 +315,7 @@ protected function createForm(string $type, $data = null, array $options = array /** * Creates and returns a form builder instance. * - * @final since version 3.4 + * @final */ protected function createFormBuilder($data = null, array $options = array()): FormBuilderInterface { @@ -327,7 +327,7 @@ protected function createFormBuilder($data = null, array $options = array()): Fo * * @throws \LogicException If DoctrineBundle is not available * - * @final since version 3.4 + * @final */ protected function getDoctrine(): ManagerRegistry { @@ -347,7 +347,7 @@ protected function getDoctrine(): ManagerRegistry * * @see TokenInterface::getUser() * - * @final since version 3.4 + * @final */ protected function getUser() { @@ -373,7 +373,7 @@ protected function getUser() * @param string $id The id used when generating the token * @param string|null $token The actual token sent with the request that should be validated * - * @final since version 3.4 + * @final */ protected function isCsrfTokenValid(string $id, ?string $token): bool { diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php b/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php index 8e6ce84408d09..37430d6ef7ce1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php @@ -22,7 +22,7 @@ * * @author Fabien Potencier * - * @final since version 3.4 + * @final */ class RedirectController { diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/TemplateController.php b/src/Symfony/Bundle/FrameworkBundle/Controller/TemplateController.php index c15cde111578b..2273075ed1969 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/TemplateController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/TemplateController.php @@ -20,7 +20,7 @@ * * @author Fabien Potencier * - * @final since version 3.4 + * @final */ class TemplateController { diff --git a/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php b/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php index a09d5c3651f96..0ddbdb429d9e0 100644 --- a/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php +++ b/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php @@ -27,7 +27,7 @@ * * @author Sarah Khalil * - * @final since version 3.4 + * @final */ class UserPasswordEncoderCommand extends Command { diff --git a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php index 25a7d3b19673c..1580ca993ba58 100644 --- a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php +++ b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php @@ -212,7 +212,7 @@ class_exists('Test\\'.__NAMESPACE__.'\\ExtendsFinalClass', true); $xError = array( 'type' => E_USER_DEPRECATED, - 'message' => 'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass" class is considered final since version 3.3. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass".', + 'message' => 'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass".', ); $this->assertSame($xError, $lastError); @@ -234,7 +234,7 @@ class_exists(__NAMESPACE__.'\\Fixtures\\ExtendedFinalMethod', true); $xError = array( 'type' => E_USER_DEPRECATED, - 'message' => 'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final since version 3.3. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".', + 'message' => 'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".', ); $this->assertSame($xError, $lastError); @@ -269,10 +269,10 @@ class_exists('Test\\'.__NAMESPACE__.'\\ExtendsInternals', true); restore_error_handler(); $this->assertSame($deprecations, array( - 'The "Symfony\Component\Debug\Tests\Fixtures\InternalClass" class is considered internal since version 3.4. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternalsParent".', + 'The "Symfony\Component\Debug\Tests\Fixtures\InternalClass" class is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternalsParent".', 'The "Symfony\Component\Debug\Tests\Fixtures\InternalInterface" interface is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternalsParent".', 'The "Symfony\Component\Debug\Tests\Fixtures\InternalTrait" trait is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".', - 'The "Symfony\Component\Debug\Tests\Fixtures\InternalTrait2::internalMethod()" method is considered internal since version 3.4. It may change without further notice. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".', + 'The "Symfony\Component\Debug\Tests\Fixtures\InternalTrait2::internalMethod()" method is considered internal. It may change without further notice. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".', )); } } diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/AnnotatedClass.php b/src/Symfony/Component/Debug/Tests/Fixtures/AnnotatedClass.php index dff9517d0a046..4eecb6d3f1668 100644 --- a/src/Symfony/Component/Debug/Tests/Fixtures/AnnotatedClass.php +++ b/src/Symfony/Component/Debug/Tests/Fixtures/AnnotatedClass.php @@ -5,7 +5,7 @@ class AnnotatedClass { /** - * @deprecated since version 3.4. + * @deprecated */ public function deprecatedMethod() { diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/FinalClass.php b/src/Symfony/Component/Debug/Tests/Fixtures/FinalClass.php index 2cf26b19e4fc8..f4c69b85322b7 100644 --- a/src/Symfony/Component/Debug/Tests/Fixtures/FinalClass.php +++ b/src/Symfony/Component/Debug/Tests/Fixtures/FinalClass.php @@ -3,7 +3,7 @@ namespace Symfony\Component\Debug\Tests\Fixtures; /** - * @final since version 3.3. + * @final */ class FinalClass { diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod.php b/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod.php index 92ec421863f3f..d8c673a5c51b0 100644 --- a/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod.php +++ b/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod.php @@ -5,7 +5,7 @@ class FinalMethod { /** - * @final since version 3.3. + * @final */ public function finalMethod() { diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/InternalClass.php b/src/Symfony/Component/Debug/Tests/Fixtures/InternalClass.php index 119842c260027..30efe79b333af 100644 --- a/src/Symfony/Component/Debug/Tests/Fixtures/InternalClass.php +++ b/src/Symfony/Component/Debug/Tests/Fixtures/InternalClass.php @@ -3,7 +3,7 @@ namespace Symfony\Component\Debug\Tests\Fixtures; /** - * @internal since version 3.4. + * @internal */ class InternalClass { diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/InternalTrait2.php b/src/Symfony/Component/Debug/Tests/Fixtures/InternalTrait2.php index 05f18e83e4a9e..e4cbe12aec298 100644 --- a/src/Symfony/Component/Debug/Tests/Fixtures/InternalTrait2.php +++ b/src/Symfony/Component/Debug/Tests/Fixtures/InternalTrait2.php @@ -8,7 +8,7 @@ trait InternalTrait2 { /** - * @internal since version 3.4 + * @internal */ public function internalMethod() { diff --git a/src/Symfony/Component/Debug/Tests/phpt/debug_class_loader.phpt b/src/Symfony/Component/Debug/Tests/phpt/debug_class_loader.phpt index b9d3d7288714e..685280bc8a18f 100644 --- a/src/Symfony/Component/Debug/Tests/phpt/debug_class_loader.phpt +++ b/src/Symfony/Component/Debug/Tests/phpt/debug_class_loader.phpt @@ -23,4 +23,4 @@ class_exists(ExtendedFinalMethod::class); ?> --EXPECTF-- -The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final since version 3.3. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod". +The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod". diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php b/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php index 5a370398408dc..721e87568326e 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php @@ -21,7 +21,7 @@ * * @author Johannes M. Schmitt * - * @final since version 3.4 + * @final */ class ServiceReferenceGraph { diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 6bd7e1974466c..8d7011c1b015c 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -1397,7 +1397,7 @@ public function log(CompilerPassInterface $pass, string $message) * * @return array An array of Service conditionals * - * @internal since version 3.4 + * @internal */ public static function getServiceConditionals($value) { diff --git a/src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/NullDumper.php b/src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/NullDumper.php index 67f9fae94dbf8..57c644ca795cb 100644 --- a/src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/NullDumper.php +++ b/src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/NullDumper.php @@ -18,7 +18,7 @@ * * @author Marco Pivetta * - * @final since version 3.3 + * @final */ class NullDumper implements DumperInterface { diff --git a/src/Symfony/Component/HttpFoundation/Response.php b/src/Symfony/Component/HttpFoundation/Response.php index 9449dc10af6f5..d16530880f1fb 100644 --- a/src/Symfony/Component/HttpFoundation/Response.php +++ b/src/Symfony/Component/HttpFoundation/Response.php @@ -412,7 +412,7 @@ public function getContent() * * @return $this * - * @final since version 3.2 + * @final */ public function setProtocolVersion(string $version) { @@ -424,7 +424,7 @@ public function setProtocolVersion(string $version) /** * Gets the HTTP protocol version. * - * @final since version 3.2 + * @final */ public function getProtocolVersion(): string { @@ -441,7 +441,7 @@ public function getProtocolVersion(): string * * @throws \InvalidArgumentException When the HTTP status code is not valid * - * @final since version 3.2 + * @final */ public function setStatusCode(int $code, $text = null) { @@ -470,7 +470,7 @@ public function setStatusCode(int $code, $text = null) /** * Retrieves the status code for the current web response. * - * @final since version 3.2 + * @final */ public function getStatusCode(): int { @@ -482,7 +482,7 @@ public function getStatusCode(): int * * @return $this * - * @final since version 3.2 + * @final */ public function setCharset(string $charset) { @@ -494,7 +494,7 @@ public function setCharset(string $charset) /** * Retrieves the response charset. * - * @final since version 3.2 + * @final */ public function getCharset(): ?string { @@ -510,7 +510,7 @@ public function getCharset(): ?string * Responses with neither a freshness lifetime (Expires, max-age) nor cache * validator (Last-Modified, ETag) are considered uncacheable. * - * @final since version 3.3 + * @final */ public function isCacheable(): bool { @@ -532,7 +532,7 @@ public function isCacheable(): bool * origin. A response is considered fresh when it includes a Cache-Control/max-age * indicator or Expires header and the calculated age is less than the freshness lifetime. * - * @final since version 3.3 + * @final */ public function isFresh(): bool { @@ -543,7 +543,7 @@ public function isFresh(): bool * Returns true if the response includes headers that can be used to validate * the response with the origin server using a conditional GET request. * - * @final since version 3.3 + * @final */ public function isValidateable(): bool { @@ -557,7 +557,7 @@ public function isValidateable(): bool * * @return $this * - * @final since version 3.2 + * @final */ public function setPrivate() { @@ -574,7 +574,7 @@ public function setPrivate() * * @return $this * - * @final since version 3.2 + * @final */ public function setPublic() { @@ -620,7 +620,7 @@ public function isImmutable(): bool * When present, the TTL of the response should not be overridden to be * greater than the value provided by the origin. * - * @final since version 3.3 + * @final */ public function mustRevalidate(): bool { @@ -632,7 +632,7 @@ public function mustRevalidate(): bool * * @throws \RuntimeException When the header is not parseable * - * @final since version 3.2 + * @final */ public function getDate(): ?\DateTimeInterface { @@ -644,7 +644,7 @@ public function getDate(): ?\DateTimeInterface * * @return $this * - * @final since version 3.2 + * @final */ public function setDate(\DateTimeInterface $date) { @@ -661,7 +661,7 @@ public function setDate(\DateTimeInterface $date) /** * Returns the age of the response in seconds. * - * @final since version 3.2 + * @final */ public function getAge(): int { @@ -689,7 +689,7 @@ public function expire() /** * Returns the value of the Expires header as a DateTime instance. * - * @final since version 3.2 + * @final */ public function getExpires(): ?\DateTimeInterface { @@ -708,7 +708,7 @@ public function getExpires(): ?\DateTimeInterface * * @return $this * - * @final since version 3.2 + * @final */ public function setExpires(\DateTimeInterface $date = null) { @@ -735,7 +735,7 @@ public function setExpires(\DateTimeInterface $date = null) * First, it checks for a s-maxage directive, then a max-age directive, and then it falls * back on an expires header. It returns null when no maximum age can be established. * - * @final since version 3.2 + * @final */ public function getMaxAge(): ?int { @@ -761,7 +761,7 @@ public function getMaxAge(): ?int * * @return $this * - * @final since version 3.2 + * @final */ public function setMaxAge(int $value) { @@ -777,7 +777,7 @@ public function setMaxAge(int $value) * * @return $this * - * @final since version 3.2 + * @final */ public function setSharedMaxAge(int $value) { @@ -795,7 +795,7 @@ public function setSharedMaxAge(int $value) * When the responses TTL is <= 0, the response may not be served from cache without first * revalidating with the origin. * - * @final since version 3.2 + * @final */ public function getTtl(): ?int { @@ -811,7 +811,7 @@ public function getTtl(): ?int * * @return $this * - * @final since version 3.2 + * @final */ public function setTtl(int $seconds) { @@ -827,7 +827,7 @@ public function setTtl(int $seconds) * * @return $this * - * @final since version 3.2 + * @final */ public function setClientTtl(int $seconds) { @@ -841,7 +841,7 @@ public function setClientTtl(int $seconds) * * @throws \RuntimeException When the HTTP header is not parseable * - * @final since version 3.2 + * @final */ public function getLastModified(): ?\DateTimeInterface { @@ -855,7 +855,7 @@ public function getLastModified(): ?\DateTimeInterface * * @return $this * - * @final since version 3.2 + * @final */ public function setLastModified(\DateTimeInterface $date = null) { @@ -878,7 +878,7 @@ public function setLastModified(\DateTimeInterface $date = null) /** * Returns the literal value of the ETag HTTP header. * - * @final since version 3.2 + * @final */ public function getEtag(): ?string { @@ -893,7 +893,7 @@ public function getEtag(): ?string * * @return $this * - * @final since version 3.2 + * @final */ public function setEtag(string $etag = null, bool $weak = false) { @@ -919,7 +919,7 @@ public function setEtag(string $etag = null, bool $weak = false) * * @throws \InvalidArgumentException * - * @final since version 3.3 + * @final */ public function setCache(array $options) { @@ -976,7 +976,7 @@ public function setCache(array $options) * * @see http://tools.ietf.org/html/rfc2616#section-10.3.5 * - * @final since version 3.3 + * @final */ public function setNotModified() { @@ -994,7 +994,7 @@ public function setNotModified() /** * Returns true if the response includes a Vary header. * - * @final since version 3.2 + * @final */ public function hasVary(): bool { @@ -1004,7 +1004,7 @@ public function hasVary(): bool /** * Returns an array of header names given in the Vary header. * - * @final since version 3.2 + * @final */ public function getVary(): array { @@ -1028,7 +1028,7 @@ public function getVary(): array * * @return $this * - * @final since version 3.2 + * @final */ public function setVary($headers, bool $replace = true) { @@ -1046,7 +1046,7 @@ public function setVary($headers, bool $replace = true) * * @return bool true if the Response validators match the Request, false otherwise * - * @final since version 3.3 + * @final */ public function isNotModified(Request $request): bool { @@ -1078,7 +1078,7 @@ public function isNotModified(Request $request): bool * * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html * - * @final since version 3.2 + * @final */ public function isInvalid(): bool { @@ -1088,7 +1088,7 @@ public function isInvalid(): bool /** * Is response informative? * - * @final since version 3.3 + * @final */ public function isInformational(): bool { @@ -1098,7 +1098,7 @@ public function isInformational(): bool /** * Is response successful? * - * @final since version 3.2 + * @final */ public function isSuccessful(): bool { @@ -1108,7 +1108,7 @@ public function isSuccessful(): bool /** * Is the response a redirect? * - * @final since version 3.2 + * @final */ public function isRedirection(): bool { @@ -1118,7 +1118,7 @@ public function isRedirection(): bool /** * Is there a client error? * - * @final since version 3.2 + * @final */ public function isClientError(): bool { @@ -1128,7 +1128,7 @@ public function isClientError(): bool /** * Was there a server side error? * - * @final since version 3.3 + * @final */ public function isServerError(): bool { @@ -1138,7 +1138,7 @@ public function isServerError(): bool /** * Is the response OK? * - * @final since version 3.2 + * @final */ public function isOk(): bool { @@ -1148,7 +1148,7 @@ public function isOk(): bool /** * Is the response forbidden? * - * @final since version 3.2 + * @final */ public function isForbidden(): bool { @@ -1158,7 +1158,7 @@ public function isForbidden(): bool /** * Is the response a not found error? * - * @final since version 3.2 + * @final */ public function isNotFound(): bool { @@ -1168,7 +1168,7 @@ public function isNotFound(): bool /** * Is the response a redirect of some form? * - * @final since version 3.2 + * @final */ public function isRedirect(string $location = null): bool { @@ -1178,7 +1178,7 @@ public function isRedirect(string $location = null): bool /** * Is the response empty? * - * @final since version 3.2 + * @final */ public function isEmpty(): bool { @@ -1190,7 +1190,7 @@ public function isEmpty(): bool * * Resulting level can be greater than target level if a non-removable buffer has been encountered. * - * @final since version 3.3 + * @final */ public static function closeOutputBuffers(int $targetLevel, bool $flush) { @@ -1212,7 +1212,7 @@ public static function closeOutputBuffers(int $targetLevel, bool $flush) * * @see http://support.microsoft.com/kb/323308 * - * @final since version 3.3 + * @final */ protected function ensureIEOverSSLCompatibility(Request $request) { diff --git a/src/Symfony/Component/HttpKernel/CacheClearer/ChainCacheClearer.php b/src/Symfony/Component/HttpKernel/CacheClearer/ChainCacheClearer.php index 6aabdc0917efa..a646119d9904d 100644 --- a/src/Symfony/Component/HttpKernel/CacheClearer/ChainCacheClearer.php +++ b/src/Symfony/Component/HttpKernel/CacheClearer/ChainCacheClearer.php @@ -16,7 +16,7 @@ * * @author Dustin Dobervich * - * @final since version 3.4 + * @final */ class ChainCacheClearer implements CacheClearerInterface { diff --git a/src/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerAggregate.php b/src/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerAggregate.php index b188fc5860b2b..66dbe6c4eb610 100644 --- a/src/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerAggregate.php +++ b/src/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerAggregate.php @@ -16,7 +16,7 @@ * * @author Fabien Potencier * - * @final since version 3.4 + * @final */ class CacheWarmerAggregate implements CacheWarmerInterface { diff --git a/src/Symfony/Component/HttpKernel/EventListener/SessionListener.php b/src/Symfony/Component/HttpKernel/EventListener/SessionListener.php index 39ebfd922fac6..97eca1c0b10cf 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/SessionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/SessionListener.php @@ -18,7 +18,7 @@ * * @author Fabien Potencier * - * @final since version 3.3 + * @final */ class SessionListener extends AbstractSessionListener { diff --git a/src/Symfony/Component/HttpKernel/EventListener/TestSessionListener.php b/src/Symfony/Component/HttpKernel/EventListener/TestSessionListener.php index 36abb422f4f6d..f859d09769671 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/TestSessionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/TestSessionListener.php @@ -18,7 +18,7 @@ * * @author Fabien Potencier * - * @final since version 3.3 + * @final */ class TestSessionListener extends AbstractTestSessionListener { diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 0952b804b3323..83c8a0726de35 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -192,7 +192,7 @@ public function __clone() * @throws RuntimeException When process stopped after receiving signal * @throws LogicException In case a callback is provided and output has been disabled * - * @final since version 3.3 + * @final */ public function run(callable $callback = null, array $env = array()): int { @@ -214,7 +214,7 @@ public function run(callable $callback = null, array $env = array()): int * * @throws ProcessFailedException if the process didn't terminate successfully * - * @final since version 3.3 + * @final */ public function mustRun(callable $callback = null, array $env = array()) { @@ -335,7 +335,7 @@ public function start(callable $callback = null, array $env = array()) * * @see start() * - * @final since version 3.3 + * @final */ public function restart(callable $callback = null, array $env = array()) { diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php index ca4f71d8ea10a..b5b99db0ac241 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php @@ -25,7 +25,7 @@ * * @author Kévin Dunglas * - * @final since version 3.3 + * @final */ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, PropertyTypeExtractorInterface { diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 07e192fdc75ce..d00f8a7fcb702 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -22,7 +22,7 @@ * * @author Kévin Dunglas * - * @final since version 3.3 + * @final */ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface { diff --git a/src/Symfony/Component/PropertyInfo/Extractor/SerializerExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/SerializerExtractor.php index 93ebb4364afed..6afbb542e18d9 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/SerializerExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/SerializerExtractor.php @@ -19,7 +19,7 @@ * * @author Kévin Dunglas * - * @final since version 3.3 + * @final */ class SerializerExtractor implements PropertyListExtractorInterface { diff --git a/src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php b/src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php index 71edb47e5b4eb..ecb6adde2a980 100644 --- a/src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php +++ b/src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php @@ -18,7 +18,7 @@ * * @author Kévin Dunglas * - * @final since version 3.3 + * @final */ class PropertyInfoCacheExtractor implements PropertyInfoExtractorInterface { diff --git a/src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php b/src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php index f2d3a82964dc0..5902d38621229 100644 --- a/src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php +++ b/src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php @@ -16,7 +16,7 @@ * * @author Kévin Dunglas * - * @final since version 3.3 + * @final */ class PropertyInfoExtractor implements PropertyInfoExtractorInterface { diff --git a/src/Symfony/Component/PropertyInfo/Type.php b/src/Symfony/Component/PropertyInfo/Type.php index 51c9a2d8684cc..71aa162f70b79 100644 --- a/src/Symfony/Component/PropertyInfo/Type.php +++ b/src/Symfony/Component/PropertyInfo/Type.php @@ -16,7 +16,7 @@ * * @author Kévin Dunglas * - * @final since version 3.3 + * @final */ class Type { diff --git a/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php b/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php index 2a116e375d8a2..4346754cbc55a 100644 --- a/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php +++ b/src/Symfony/Component/Security/Guard/GuardAuthenticatorHandler.php @@ -30,7 +30,7 @@ * * @author Ryan Weaver * - * @final since version 3.4 + * @final */ class GuardAuthenticatorHandler { diff --git a/src/Symfony/Component/Serializer/Encoder/ChainDecoder.php b/src/Symfony/Component/Serializer/Encoder/ChainDecoder.php index 545841fffd48b..d4cfa4b11c9fa 100644 --- a/src/Symfony/Component/Serializer/Encoder/ChainDecoder.php +++ b/src/Symfony/Component/Serializer/Encoder/ChainDecoder.php @@ -20,7 +20,7 @@ * @author Johannes M. Schmitt * @author Lukas Kahwe Smith * - * @final since version 3.3. + * @final */ class ChainDecoder implements ContextAwareDecoderInterface { diff --git a/src/Symfony/Component/Serializer/Encoder/ChainEncoder.php b/src/Symfony/Component/Serializer/Encoder/ChainEncoder.php index 2737f6eba695f..9745587c95802 100644 --- a/src/Symfony/Component/Serializer/Encoder/ChainEncoder.php +++ b/src/Symfony/Component/Serializer/Encoder/ChainEncoder.php @@ -20,7 +20,7 @@ * @author Johannes M. Schmitt * @author Lukas Kahwe Smith * - * @final since version 3.3. + * @final */ class ChainEncoder implements ContextAwareEncoderInterface { diff --git a/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php index af4771348193c..88424134466ca 100644 --- a/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php @@ -22,7 +22,7 @@ * * @author Alexander M. Turek * - * @final since version 3.3. + * @final */ class ArrayDenormalizer implements ContextAwareDenormalizerInterface, SerializerAwareInterface { diff --git a/src/Symfony/Component/Yaml/Dumper.php b/src/Symfony/Component/Yaml/Dumper.php index 6681379816c0c..d47daa49c7b98 100644 --- a/src/Symfony/Component/Yaml/Dumper.php +++ b/src/Symfony/Component/Yaml/Dumper.php @@ -16,7 +16,7 @@ * * @author Fabien Potencier * - * @final since version 3.4 + * @final */ class Dumper { diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 195d3185e4d76..b1224026f23b4 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -19,7 +19,7 @@ * * @author Fabien Potencier * - * @final since version 3.4 + * @final */ class Parser { diff --git a/src/Symfony/Component/Yaml/Yaml.php b/src/Symfony/Component/Yaml/Yaml.php index 0a97c2198a3fc..80de7e877723c 100644 --- a/src/Symfony/Component/Yaml/Yaml.php +++ b/src/Symfony/Component/Yaml/Yaml.php @@ -18,7 +18,7 @@ * * @author Fabien Potencier * - * @final since version 3.4 + * @final */ class Yaml { From 14c35ad13cc3f7ad59284beb208c89c61f72c290 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Mon, 19 Feb 2018 12:14:59 +0100 Subject: [PATCH 117/166] Add support for URL-like DSNs for the PdoSessionHandler This allows migrating away from the deprecated DbalSessionHandler when DBAL was used for its ability to be configured through a URL (which is what is provided on Heroku and some other PaaS). --- .../Storage/Handler/PdoSessionHandler.php | 100 +++++++++++++++++- .../Storage/Handler/PdoSessionHandlerTest.php | 35 ++++++ 2 files changed, 134 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php index 2e1692b6f0c99..c8737be18e110 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php @@ -164,7 +164,7 @@ class PdoSessionHandler extends AbstractSessionHandler * * db_connection_options: An array of driver-specific connection options [default: array()] * * lock_mode: The strategy for locking, see constants [default: LOCK_TRANSACTIONAL] * - * @param \PDO|string|null $pdoOrDsn A \PDO instance or DSN string or null + * @param \PDO|string|null $pdoOrDsn A \PDO instance or DSN string or URL string or null * @param array $options An associative array of options * * @throws \InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION @@ -178,6 +178,8 @@ public function __construct($pdoOrDsn = null, array $options = array()) $this->pdo = $pdoOrDsn; $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME); + } elseif (is_string($pdoOrDsn) && false !== strpos($pdoOrDsn, '://')) { + $this->dsn = $this->buildDsnFromUrl($pdoOrDsn); } else { $this->dsn = $pdoOrDsn; } @@ -431,6 +433,102 @@ private function connect($dsn) $this->driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME); } + /** + * Builds a PDO DSN from a URL-like connection string. + * + * @param string $dsnOrUrl + * + * @return string + * + * @todo implement missing support for oci DSN (which look totally different from other PDO ones) + */ + private function buildDsnFromUrl($dsnOrUrl) + { + // (pdo_)?sqlite3?:///... => (pdo_)?sqlite3?://localhost/... or else the URL will be invalid + $url = preg_replace('#^((?:pdo_)?sqlite3?):///#', '$1://localhost/', $dsnOrUrl); + + $params = parse_url($url); + + if (false === $params) { + return $dsnOrUrl; // If the URL is not valid, let's assume it might be a DSN already. + } + + $params = array_map('rawurldecode', $params); + + // Override the default username and password. Values passed through options will still win over these in the constructor. + if (isset($params['user'])) { + $this->username = $params['user']; + } + + if (isset($params['pass'])) { + $this->password = $params['pass']; + } + + if (!isset($params['scheme'])) { + throw new \InvalidArgumentException('URLs without scheme are not supported to configure the PdoSessionHandler'); + } + + $driverAliasMap = array( + 'mssql' => 'sqlsrv', + 'mysql2' => 'mysql', // Amazon RDS, for some weird reason + 'postgres' => 'pgsql', + 'postgresql' => 'pgsql', + 'sqlite3' => 'sqlite', + ); + + $driver = isset($driverAliasMap[$params['scheme']]) ? $driverAliasMap[$params['scheme']] : $params['scheme']; + + // Doctrine DBAL supports passing its internal pdo_* driver names directly too (allowing both dashes and underscores). This allows supporting the same here. + if (0 === strpos($driver, 'pdo_') || 0 === strpos($driver, 'pdo-')) { + $driver = substr($driver, 4); + } + + switch ($driver) { + case 'mysql': + case 'pgsql': + $dsn = $driver.':'; + + if (isset($params['host']) && '' !== $params['host']) { + $dsn .= 'host='.$params['host'].';'; + } + + if (isset($params['port']) && '' !== $params['port']) { + $dsn .= 'port='.$params['port'].';'; + } + + if (isset($params['path'])) { + $dbName = substr($params['path'], 1); // Remove the leading slash + $dsn .= 'dbname='.$dbName.';'; + } + + return $dsn; + + case 'sqlite': + return 'sqlite:'.substr($params['path'], 1); + + case 'sqlsrv': + $dsn = 'sqlsrv:server='; + + if (isset($params['host'])) { + $dsn .= $params['host']; + } + + if (isset($params['port']) && '' !== $params['port']) { + $dsn .= ','.$params['port']; + } + + if (isset($params['path'])) { + $dbName = substr($params['path'], 1); // Remove the leading slash + $dsn .= ';Database='.$dbName; + } + + return $dsn; + + default: + throw new \InvalidArgumentException(sprintf('The scheme "%s" is not supported by the PdoSessionHandler URL configuration. Pass a PDO DSN directly.', $params['scheme'])); + } + } + /** * Helper method to begin a transaction. * diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php index a0d7529f06a86..0a0e449051a73 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php @@ -324,6 +324,41 @@ public function testGetConnectionConnectsIfNeeded() $this->assertInstanceOf('\PDO', $method->invoke($storage)); } + /** + * @dataProvider provideUrlDsnPairs + */ + public function testUrlDsn($url, $expectedDsn, $expectedUser = null, $expectedPassword = null) + { + $storage = new PdoSessionHandler($url); + + $this->assertAttributeEquals($expectedDsn, 'dsn', $storage); + + if (null !== $expectedUser) { + $this->assertAttributeEquals($expectedUser, 'username', $storage); + } + + if (null !== $expectedPassword) { + $this->assertAttributeEquals($expectedPassword, 'password', $storage); + } + } + + public function provideUrlDsnPairs() + { + yield array('mysql://localhost/test', 'mysql:host=localhost;dbname=test;'); + yield array('mysql://localhost:56/test', 'mysql:host=localhost;port=56;dbname=test;'); + yield array('mysql2://root:pwd@localhost/test', 'mysql:host=localhost;dbname=test;', 'root', 'pwd'); + yield array('postgres://localhost/test', 'pgsql:host=localhost;dbname=test;'); + yield array('postgresql://localhost:5634/test', 'pgsql:host=localhost;port=5634;dbname=test;'); + yield array('postgres://root:pwd@localhost/test', 'pgsql:host=localhost;dbname=test;', 'root', 'pwd'); + yield 'sqlite relative path' => array('sqlite://localhost/tmp/test', 'sqlite:tmp/test'); + yield 'sqlite absolute path' => array('sqlite://localhost//tmp/test', 'sqlite:/tmp/test'); + yield 'sqlite relative path without host' => array('sqlite:///tmp/test', 'sqlite:tmp/test'); + yield 'sqlite absolute path without host' => array('sqlite3:////tmp/test', 'sqlite:/tmp/test'); + yield array('sqlite://localhost/:memory:', 'sqlite::memory:'); + yield array('mssql://localhost/test', 'sqlsrv:server=localhost;Database=test'); + yield array('mssql://localhost:56/test', 'sqlsrv:server=localhost,56;Database=test'); + } + private function createStream($content) { $stream = tmpfile(); From 9ff86d61810a62fe69fd1671f8a8bb325d95468e Mon Sep 17 00:00:00 2001 From: Amrouche Hamza Date: Sat, 16 Dec 2017 16:19:00 +0100 Subject: [PATCH 118/166] [WebProfilerBundle] limit ajax request to 100 and remove the last one --- .../Resources/views/Profiler/base_js.html.twig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig index cde7a4c685832..7aae3eef5bbcf 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig @@ -108,6 +108,11 @@ var rows = document.createDocumentFragment(); if (requestStack.length) { + var nbOfAjaxRequest = tbodies.rows.count(); + if (nbOfAjaxRequest >= 100) { + tbodies.deleteRow(nbOfAjaxRequest - 1); + } + for (var i = 0; i < requestStack.length; i++) { var request = requestStack[i]; From 4055224373e321b63879873376257fe0efe07f26 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 19 Feb 2018 15:59:04 +0100 Subject: [PATCH 119/166] Clean calls to http_build_query() --- src/Symfony/Component/DomCrawler/Form.php | 2 +- src/Symfony/Component/HttpFoundation/Request.php | 2 +- src/Symfony/Component/HttpFoundation/Tests/RequestTest.php | 2 +- .../Component/Security/Http/Firewall/SwitchUserListener.php | 2 +- .../Component/Security/Http/Logout/LogoutUrlGenerator.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/DomCrawler/Form.php b/src/Symfony/Component/DomCrawler/Form.php index 54e5fc2b84a3a..258be960a707d 100644 --- a/src/Symfony/Component/DomCrawler/Form.php +++ b/src/Symfony/Component/DomCrawler/Form.php @@ -209,7 +209,7 @@ public function getUri() parse_str($query, $currentParameters); } - $queryString = http_build_query(array_merge($currentParameters, $this->getValues()), null, '&'); + $queryString = http_build_query(array_merge($currentParameters, $this->getValues()), '', '&'); $pos = strpos($uri, '?'); $base = false === $pos ? $uri : substr($uri, 0, $pos); diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index fe7080ab86321..ecdcdbc25acc2 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -522,7 +522,7 @@ public function __toString() */ public function overrideGlobals() { - $this->server->set('QUERY_STRING', static::normalizeQueryString(http_build_query($this->query->all(), null, '&'))); + $this->server->set('QUERY_STRING', static::normalizeQueryString(http_build_query($this->query->all(), '', '&'))); $_GET = $this->query->all(); $_POST = $this->request->all(); diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index 96f87958ed9c5..0c5451dfd6ccc 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -2065,7 +2065,7 @@ class RequestContentProxy extends Request { public function getContent($asResource = false) { - return http_build_query(array('_method' => 'PUT', 'content' => 'mycontent')); + return http_build_query(array('_method' => 'PUT', 'content' => 'mycontent'), '', '&'); } } diff --git a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php index f5113aa0c90ad..05531d8837ba0 100644 --- a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php @@ -89,7 +89,7 @@ public function handle(GetResponseEvent $event) } $request->query->remove($this->usernameParameter); - $request->server->set('QUERY_STRING', http_build_query($request->query->all())); + $request->server->set('QUERY_STRING', http_build_query($request->query->all(), '', '&')); $response = new RedirectResponse($request->getUri(), 302); diff --git a/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php b/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php index 1499d7e5ea33f..28ff315505796 100644 --- a/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php +++ b/src/Symfony/Component/Security/Http/Logout/LogoutUrlGenerator.php @@ -128,7 +128,7 @@ private function generateLogoutUrl($key, $referenceType) $url = UrlGeneratorInterface::ABSOLUTE_URL === $referenceType ? $request->getUriForPath($logoutPath) : $request->getBaseUrl().$logoutPath; if (!empty($parameters)) { - $url .= '?'.http_build_query($parameters); + $url .= '?'.http_build_query($parameters, '', '&'); } } else { if (!$this->router) { From 270147b04fbf54a688f4532c4d552d4d2041ee22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 19 Feb 2018 17:05:09 +0100 Subject: [PATCH 120/166] [PropertyInfo] ReflectionExtractor: give a chance to other extractors if no properties --- .../Extractor/ReflectionExtractor.php | 2 +- .../Extractors/ReflectionExtractorTest.php | 2 ++ .../Tests/Fixtures/NoProperties.php | 21 +++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/PropertyInfo/Tests/Fixtures/NoProperties.php diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 3ec1d8d6eab08..b29d78d070108 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -76,7 +76,7 @@ public function getProperties($class, array $context = array()) $properties[$propertyName] = $propertyName; } - return array_values($properties); + return $properties ? array_values($properties) : null; } /** diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php index cc2ecbe6f56d2..2828878ce6cf0 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php @@ -57,6 +57,8 @@ public function testGetProperties() ), $this->extractor->getProperties('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy') ); + + $this->assertNull($this->extractor->getProperties('Symfony\Component\PropertyInfo\Tests\Fixtures\NoProperties')); } /** diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/NoProperties.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/NoProperties.php new file mode 100644 index 0000000000000..177bbe4df0f03 --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/NoProperties.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\PropertyInfo\Tests\Fixtures; + +/** + * @author Kévin Dunglas + */ +class NoProperties +{ +} From ee4599284fba06ea58bc616fecd27e41e1aa9b52 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Mon, 19 Feb 2018 13:09:45 +0100 Subject: [PATCH 121/166] [WebProfilerBundle] Fix anchor CSS --- src/Symfony/Bridge/Twig/Extension/CodeExtension.php | 2 +- .../WebProfilerBundle/Resources/views/Profiler/open.css.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php index e47772481bdb7..f37d8100fbb44 100644 --- a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php @@ -259,6 +259,6 @@ protected static function fixCodeMarkup($line) $line .= ''; } - return $line; + return trim($line); } } 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 d0f5cda02dccc..f69406475a2af 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig @@ -68,7 +68,7 @@ a.doc:hover { .anchor { position: relative; - display: block; + display: inline-block; top: -7em; visibility: hidden; } From dfd93da23650cde6130f396d2876c5ba2475f3bb Mon Sep 17 00:00:00 2001 From: Dmitri Petmanson Date: Thu, 8 Feb 2018 11:42:56 +0200 Subject: [PATCH 122/166] bug #26086 [FrameworkBundle] Fix using annotation_reader in compiler pass to inject configured cache provider --- .../AddAnnotationsCachedReaderPass.php | 8 ++--- .../Compiler/UnusedTagsPass.php | 1 + .../FrameworkExtension.php | 2 ++ .../FrameworkExtensionTest.php | 30 +++++++++++++++---- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php index 35ea20a89accd..4f09e52bdcbd1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php @@ -26,16 +26,16 @@ public function process(ContainerBuilder $container) { // "annotations.cached_reader" is wired late so that any passes using // "annotation_reader" at build time don't get any cache - if ($container->hasDefinition('annotations.cached_reader')) { - $reader = $container->getDefinition('annotations.cached_reader'); + foreach ($container->findTaggedServiceIds('annotations.cached_reader') as $id => $tags) { + $reader = $container->getDefinition($id); $properties = $reader->getProperties(); if (isset($properties['cacheProviderBackup'])) { $provider = $properties['cacheProviderBackup']->getValues()[0]; unset($properties['cacheProviderBackup']); $reader->setProperties($properties); - $container->set('annotations.cached_reader', null); - $container->setDefinition('annotations.cached_reader', $reader->replaceArgument(1, $provider)); + $container->set($id, null); + $container->setDefinition($id, $reader->replaceArgument(1, $provider)); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php index ecc4d9e56356a..cb3366a499425 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php @@ -22,6 +22,7 @@ class UnusedTagsPass implements CompilerPassInterface { private $whitelist = array( + 'annotations.cached_reader', 'cache.pool.clearer', 'console.command', 'container.hot_path', diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 3c783f9443d0e..c36b85cc9a498 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1395,7 +1395,9 @@ private function registerAnnotationsConfiguration(array $config, ContainerBuilde ->replaceArgument(2, $config['debug']) // temporary property to lazy-reference the cache provider without using it until AddAnnotationsCachedReaderPass runs ->setProperty('cacheProviderBackup', new ServiceClosureArgument(new Reference($cacheService))) + ->addTag('annotations.cached_reader') ; + $container->setAlias('annotation_reader', 'annotations.cached_reader')->setPrivate(true); $container->setAlias(Reader::class, new Alias('annotations.cached_reader', false)); } else { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index b40e735c98b73..576b885560d7e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -25,6 +25,7 @@ use Symfony\Component\Cache\Adapter\ProxyAdapter; use Symfony\Component\Cache\Adapter\RedisAdapter; use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Loader\ClosureLoader; @@ -589,10 +590,12 @@ public function testValidationService() public function testAnnotations() { - $container = $this->createContainerFromFile('full'); + $container = $this->createContainerFromFile('full', array(), true, false); + $container->addCompilerPass(new TestAnnotationsPass()); + $container->compile(); $this->assertEquals($container->getParameter('kernel.cache_dir').'/annotations', $container->getDefinition('annotations.filesystem_cache')->getArgument(0)); - $this->assertSame('annotations.filesystem_cache', (string) $container->getDefinition('annotations.cached_reader')->getArgument(1)); + $this->assertSame('annotations.filesystem_cache', (string) $container->getDefinition('annotation_reader')->getArgument(1)); } public function testFileLinkFormat() @@ -1051,10 +1054,10 @@ protected function createContainer(array $data = array()) ), $data))); } - protected function createContainerFromFile($file, $data = array(), $resetCompilerPasses = true) + protected function createContainerFromFile($file, $data = array(), $resetCompilerPasses = true, $compile = true) { $cacheKey = md5(get_class($this).$file.serialize($data)); - if (isset(self::$containerCache[$cacheKey])) { + if ($compile && isset(self::$containerCache[$cacheKey])) { return self::$containerCache[$cacheKey]; } $container = $this->createContainer($data); @@ -1065,7 +1068,12 @@ protected function createContainerFromFile($file, $data = array(), $resetCompile $container->getCompilerPassConfig()->setOptimizationPasses(array()); $container->getCompilerPassConfig()->setRemovingPasses(array()); } - $container->getCompilerPassConfig()->setBeforeRemovingPasses(array(new AddAnnotationsCachedReaderPass(), new AddConstraintValidatorsPass(), new TranslatorPass('translator.default', 'translation.reader'))); + $container->getCompilerPassConfig()->setBeforeRemovingPasses(array(new AddConstraintValidatorsPass(), new TranslatorPass('translator.default', 'translation.reader'))); + $container->getCompilerPassConfig()->setAfterRemovingPasses(array(new AddAnnotationsCachedReaderPass())); + + if (!$compile) { + return $container; + } $container->compile(); return self::$containerCache[$cacheKey] = $container; @@ -1158,3 +1166,15 @@ private function assertCachePoolServiceDefinitionIsCreated(ContainerBuilder $con } } } + +/** + * Simulates ReplaceAliasByActualDefinitionPass. + */ +class TestAnnotationsPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + $container->setDefinition('annotation_reader', $container->getDefinition('annotations.cached_reader')); + $container->removeDefinition('annotations.cached_reader'); + } +} From b9c071015b90793d709cbce23bdc50090858591d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 19 Feb 2018 17:46:01 +0100 Subject: [PATCH 123/166] [Bridge/Twig] fix composer.json --- src/Symfony/Bridge/Twig/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index ffec118f502c8..8a531dcc62f30 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -41,7 +41,7 @@ "symfony/workflow": "~3.3|~4.0" }, "conflict": { - "symfony/form": "<3.4.5", + "symfony/form": "<3.4.5|<4.0.5,>=4.0", "symfony/console": "<3.4" }, "suggest": { From 4be63f9f4ab3d9dbd6664cbe5e0a1b2f2203bba8 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 19 Feb 2018 17:55:06 +0100 Subject: [PATCH 124/166] fix CS --- .../Component/Form/Tests/AbstractBootstrap4LayoutTest.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php index 197f3ab8d6854..89a95fca8d130 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php @@ -547,7 +547,7 @@ public function testSingleChoiceExpandedWithPlaceholderWithoutTranslation() ] /following-sibling::div [@class="form-check"] - [ + [ ./input[@type="radio"][@name="name"][@id="name_0"][@checked] /following-sibling::label [.="Choice&A"] @@ -959,8 +959,7 @@ public function testPercent() ./span [@class="input-group-text"] [contains(.., "%")] - ] - + ] ] ' ); From 611ff59c3efa9b57b8e7af5d551f04c89c296507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 19 Feb 2018 16:01:42 +0100 Subject: [PATCH 125/166] [FrameworkBundle] Add missing XML config for circular_reference_handler. Add tests. --- .../Resources/config/schema/symfony-1.0.xsd | 1 + .../Tests/DependencyInjection/Fixtures/php/full.php | 1 + .../Tests/DependencyInjection/Fixtures/xml/full.xml | 2 +- .../Tests/DependencyInjection/Fixtures/yml/full.yml | 7 ++++--- .../Tests/DependencyInjection/FrameworkExtensionTest.php | 1 + 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index cca86f8c61dde..f81b7d225cbca 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -230,6 +230,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php index a97daeef1d131..64de9309e80c0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php @@ -68,6 +68,7 @@ 'enabled' => true, 'enable_annotations' => true, 'name_converter' => 'serializer.name_converter.camel_case_to_snake_case', + 'circular_reference_handler' => 'my.circular.reference.handler', ), 'property_info' => true, 'ide' => 'file%%link%%format', diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml index 6920efebed320..f083b9cb1a221 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml @@ -41,7 +41,7 @@ - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml index 3194a0fab2e1a..f54c3e6eb18d0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml @@ -51,9 +51,10 @@ framework: debug: true file_cache_dir: '%kernel.cache_dir%/annotations' serializer: - enabled: true - enable_annotations: true - name_converter: serializer.name_converter.camel_case_to_snake_case + enabled: true + enable_annotations: true + name_converter: serializer.name_converter.camel_case_to_snake_case + circular_reference_handler: my.circular.reference.handler property_info: ~ ide: file%%link%%format request: diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 576b885560d7e..c78354ed08952 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -781,6 +781,7 @@ public function testSerializerEnabled() $this->assertNull($container->getDefinition('serializer.mapping.class_metadata_factory')->getArgument(1)); $this->assertEquals(new Reference('serializer.name_converter.camel_case_to_snake_case'), $container->getDefinition('serializer.normalizer.object')->getArgument(1)); $this->assertEquals(new Reference('property_info', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE), $container->getDefinition('serializer.normalizer.object')->getArgument(3)); + $this->assertEquals(array('setCircularReferenceHandler', array(new Reference('my.circular.reference.handler'))), $container->getDefinition('serializer.normalizer.object')->getMethodCalls()[0]); } public function testRegisterSerializerExtractor() From c338d85514a1fb84a616c8af259fdfb13c4fb54f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 20 Feb 2018 13:42:18 +0100 Subject: [PATCH 126/166] Another PR template tweak --- .github/PULL_REQUEST_TEMPLATE.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f52d3571ceb93..2d64894f413fe 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,15 +3,15 @@ | Branch? | master for features / 2.7 up to 4.0 for bug fixes | Bug fix? | yes/no | New feature? | yes/no -| BC breaks? | yes/no +| BC breaks? | no | Deprecations? | yes/no -| Tests pass? | yes/no -| Fixed tickets | #... +| Tests pass? | yes +| Fixed tickets | #... | License | MIT -| Doc PR | symfony/symfony-docs#... +| Doc PR | symfony/symfony-docs#...