From c648b938b2213ab169740be5f80e09b8bcbbb020 Mon Sep 17 00:00:00 2001 From: Samuel ROZE Date: Tue, 3 Jul 2018 13:51:26 +0100 Subject: [PATCH 01/16] Fix serialization of abstract items with groups across multiple entities --- .../Serializer/Normalizer/ObjectNormalizer.php | 13 +++++++++---- .../Tests/Fixtures/DummyMessageNumberTwo.php | 6 ++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php index 6c9098528b..77c98377ee 100644 --- a/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php @@ -142,11 +142,16 @@ class ObjectNormalizer extends AbstractObjectNormalizer return false; } - if (null !== $this->classDiscriminatorResolver && null !== $discriminatorMapping = $this->classDiscriminatorResolver->getMappingForMappedObject($classOrObject)) { - $allowedAttributes[] = $attributesAsString ? $discriminatorMapping->getTypeProperty() : new AttributeMetadata($discriminatorMapping->getTypeProperty()); + if (null !== $this->classDiscriminatorResolver) { + $class = \is_object($classOrObject) ? \get_class($classOrObject) : $classOrObject; + if (null !== $discriminatorMapping = $this->classDiscriminatorResolver->getMappingForMappedObject($classOrObject)) { + $allowedAttributes[] = $attributesAsString ? $discriminatorMapping->getTypeProperty() : new AttributeMetadata($discriminatorMapping->getTypeProperty()); + } - foreach ($discriminatorMapping->getTypesMapping() as $class) { - $allowedAttributes = array_merge($allowedAttributes, parent::getAllowedAttributes($class, $context, $attributesAsString)); + if (null !== $discriminatorMapping = $this->classDiscriminatorResolver->getMappingForClass($class)) { + foreach ($discriminatorMapping->getTypesMapping() as $mappedClass) { + $allowedAttributes = array_merge($allowedAttributes, parent::getAllowedAttributes($mappedClass, $context, $attributesAsString)); + } } } diff --git a/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageNumberTwo.php b/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageNumberTwo.php index 060c10dd79..3b828e50bf 100644 --- a/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageNumberTwo.php +++ b/src/Symfony/Component/Serializer/Tests/Fixtures/DummyMessageNumberTwo.php @@ -11,9 +11,15 @@ namespace Symfony\Component\Serializer\Tests\Fixtures; +use Symfony\Component\Serializer\Annotation\Groups; + /** * @author Samuel Roze */ class DummyMessageNumberTwo implements DummyMessageInterface { + /** + * @Groups({"two"}) + */ + public $three; } From d3260dfdcd2cb365788ea3bc41e91739a8acb81d Mon Sep 17 00:00:00 2001 From: Albert Casdemont Date: Tue, 10 Jul 2018 13:02:47 +0200 Subject: [PATCH 02/16] [EventDispatcher] Clear orphaned events on TraceableEventDispatcher::reset --- .../Debug/TraceableEventDispatcher.php | 1 + .../Tests/Debug/TraceableEventDispatcherTest.php | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php index 3b6e7cc393..8d851623fb 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php @@ -217,6 +217,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface public function reset() { $this->called = array(); + $this->orphanedEvents = array(); } /** diff --git a/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php b/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php index 2521f741ea..ab3b33e377 100644 --- a/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php +++ b/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php @@ -271,6 +271,17 @@ class TraceableEventDispatcherTest extends TestCase $this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed'); } + + public function testClearOrphanedEvents() + { + $tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch()); + $tdispatcher->dispatch('foo'); + $events = $tdispatcher->getOrphanedEvents(); + $this->assertCount(1, $events); + $tdispatcher->reset(); + $events = $tdispatcher->getOrphanedEvents(); + $this->assertCount(0, $events); + } } class EventSubscriber implements EventSubscriberInterface From a265caf041aa56d2f3212dd587518ac66bd08a5b Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 10 Jul 2018 15:15:49 +0200 Subject: [PATCH 03/16] [DependencyInjection] add missing test for #27710 --- .../ValidateEnvPlaceholdersPassTest.php | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php index b5841f343a..cbec6bf778 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php @@ -234,6 +234,18 @@ class ValidateEnvPlaceholdersPassTest extends TestCase $this->addToAssertionCount(1); } + public function testEmptyConfigFromMoreThanOneSource() + { + $container = new ContainerBuilder(); + $container->registerExtension(new EnvExtension(new ConfigurationWithArrayNodeRequiringOneElement())); + $container->loadFromExtension('env_extension', array()); + $container->loadFromExtension('env_extension', array()); + + $this->doProcess($container); + + $this->addToAssertionCount(1); + } + public function testDiscardedEnvInConfig(): void { $container = new ContainerBuilder(); @@ -313,6 +325,24 @@ class EnvConfigurationWithoutRootNode implements ConfigurationInterface } } +class ConfigurationWithArrayNodeRequiringOneElement implements ConfigurationInterface +{ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $treeBuilder->root('env_extension') + ->children() + ->arrayNode('nodes') + ->isRequired() + ->requiresAtLeastOneElement() + ->scalarPrototype()->end() + ->end() + ->end(); + + return $treeBuilder; + } +} + class EnvExtension extends Extension { private $configuration; @@ -335,6 +365,10 @@ class EnvExtension extends Extension public function load(array $configs, ContainerBuilder $container) { + if (!array_filter($configs)) { + return; + } + try { $this->config = $this->processConfiguration($this->getConfiguration($configs, $container), $configs); } catch (TreeWithoutRootNodeException $e) { From d78dcc06154efe292a8511eb2b67f4866b9edf68 Mon Sep 17 00:00:00 2001 From: Sebastian Schwarz Date: Tue, 10 Jul 2018 15:15:57 +0200 Subject: [PATCH 04/16] [Console] correctly return parameter's default value on "--" Fixes #27916 --- .../Component/Console/Input/ArgvInput.php | 2 +- .../Component/Console/Input/ArrayInput.php | 2 +- .../Console/Tests/Input/ArgvInputTest.php | 25 ++++++++++--------- .../Console/Tests/Input/ArrayInputTest.php | 4 +-- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/Console/Input/ArgvInput.php b/src/Symfony/Component/Console/Input/ArgvInput.php index fd81981070..087974ab73 100644 --- a/src/Symfony/Component/Console/Input/ArgvInput.php +++ b/src/Symfony/Component/Console/Input/ArgvInput.php @@ -306,7 +306,7 @@ class ArgvInput extends Input while (0 < count($tokens)) { $token = array_shift($tokens); if ($onlyParams && '--' === $token) { - return false; + return $default; } foreach ($values as $value) { diff --git a/src/Symfony/Component/Console/Input/ArrayInput.php b/src/Symfony/Component/Console/Input/ArrayInput.php index 4d9797ba1a..595a8a0e8c 100644 --- a/src/Symfony/Component/Console/Input/ArrayInput.php +++ b/src/Symfony/Component/Console/Input/ArrayInput.php @@ -81,7 +81,7 @@ class ArrayInput extends Input foreach ($this->parameters as $k => $v) { if ($onlyParams && ('--' === $k || (is_int($k) && '--' === $v))) { - return false; + return $default; } if (is_int($k)) { diff --git a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php index 61d1723e08..4cd7ab478f 100644 --- a/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php +++ b/src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php @@ -395,25 +395,26 @@ class ArgvInputTest extends TestCase /** * @dataProvider provideGetParameterOptionValues */ - public function testGetParameterOptionEqualSign($argv, $key, $onlyParams, $expected) + public function testGetParameterOptionEqualSign($argv, $key, $default, $onlyParams, $expected) { $input = new ArgvInput($argv); - $this->assertEquals($expected, $input->getParameterOption($key, false, $onlyParams), '->getParameterOption() returns the expected value'); + $this->assertEquals($expected, $input->getParameterOption($key, $default, $onlyParams), '->getParameterOption() returns the expected value'); } public function provideGetParameterOptionValues() { return array( - array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', false, 'dev'), - array(array('app/console', 'foo:bar', '--env=dev'), '--env', false, 'dev'), - array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), false, 'dev'), - array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), false, 'dev'), - array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), false, '1'), - array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), false, '1'), - array(array('app/console', 'foo:bar', '--env', 'val'), '--env', false, 'val'), - array(array('app/console', 'foo:bar', '--env', 'val', '--dummy'), '--env', false, 'val'), - array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', false, 'dev'), - array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', true, false), + array(array('app/console', 'foo:bar'), '-e', 'default', false, 'default'), + array(array('app/console', 'foo:bar', '-e', 'dev'), '-e', 'default', false, 'dev'), + array(array('app/console', 'foo:bar', '--env=dev'), '--env', 'default', false, 'dev'), + array(array('app/console', 'foo:bar', '-e', 'dev'), array('-e', '--env'), 'default', false, 'dev'), + array(array('app/console', 'foo:bar', '--env=dev'), array('-e', '--env'), 'default', false, 'dev'), + array(array('app/console', 'foo:bar', '--env=dev', '--en=1'), array('--en'), 'default', false, '1'), + array(array('app/console', 'foo:bar', '--env=dev', '', '--en=1'), array('--en'), 'default', false, '1'), + array(array('app/console', 'foo:bar', '--env', 'val'), '--env', 'default', false, 'val'), + array(array('app/console', 'foo:bar', '--env', 'val', '--dummy'), '--env', 'default', false, 'val'), + array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', 'default', false, 'dev'), + array(array('app/console', 'foo:bar', '--', '--env=dev'), '--env', 'default', true, 'default'), ); } diff --git a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php index 6b443e0b2a..34b67ac7f5 100644 --- a/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php +++ b/src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php @@ -47,14 +47,14 @@ class ArrayInputTest extends TestCase { $input = new ArrayInput(array('name' => 'Fabien', '--foo' => 'bar')); $this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name'); - $this->assertFalse($input->getParameterOption('--bar'), '->getParameterOption() returns the default if an option is not present in the passed parameters'); + $this->assertEquals('default', $input->getParameterOption('--bar', 'default'), '->getParameterOption() returns the default value if an option is not present in the passed parameters'); $input = new ArrayInput(array('Fabien', '--foo' => 'bar')); $this->assertEquals('bar', $input->getParameterOption('--foo'), '->getParameterOption() returns the option of specified name'); $input = new ArrayInput(array('--foo', '--', '--bar' => 'woop')); $this->assertEquals('woop', $input->getParameterOption('--bar'), '->getParameterOption() returns the correct value if an option is present in the passed parameters'); - $this->assertFalse($input->getParameterOption('--bar', false, true), '->getParameterOption() returns false if an option is present in the passed parameters after an end of options signal'); + $this->assertEquals('default', $input->getParameterOption('--bar', 'default', true), '->getParameterOption() returns the default value if an option is present in the passed parameters after an end of options signal'); } public function testParseArguments() From 5f5077f4fceb69347bfca62e2a7723e45b6a55d0 Mon Sep 17 00:00:00 2001 From: Vincent Chalnot Date: Wed, 11 Jul 2018 11:08:35 +0200 Subject: [PATCH 05/16] [Form/Profiler] Massively reducing memory footprint of form profiling pages by removing redundant 'form' variable from view variables. --- .../Form/Extension/DataCollector/FormDataExtractor.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php index 490a4ad711..d907aa2707 100644 --- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php +++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataExtractor.php @@ -15,6 +15,7 @@ use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; use Symfony\Component\HttpKernel\DataCollector\Util\ValueExporter; use Symfony\Component\Validator\ConstraintViolationInterface; +use Symfony\Component\VarDumper\Caster\CutStub; /** * Default implementation of {@link FormDataExtractorInterface}. @@ -155,6 +156,10 @@ class FormDataExtractor implements FormDataExtractorInterface ); foreach ($view->vars as $varName => $value) { + // Removing redundant variable from view variables + if ('form' === $varName) { + $value = new CutStub($value); + } $data['view_vars'][$varName] = $value; } From 559cdb01bd871f2866b0e0f5bbd04dd9dbbc2dd9 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 11 Jul 2018 10:13:25 +0200 Subject: [PATCH 06/16] fix typo in ContainerBuilder docblock --- .../Component/DependencyInjection/ContainerBuilder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 2aa30026dc..1960bf9d89 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -493,10 +493,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface * the parameters passed to the container constructor to have precedence * over the loaded ones. * - * $container = new ContainerBuilder(array('foo' => 'bar')); + * $container = new ContainerBuilder(new ParameterBag(array('foo' => 'bar'))); * $loader = new LoaderXXX($container); * $loader->load('resource_name'); - * $container->register('foo', new stdClass()); + * $container->register('foo', 'stdClass'); * * In the above example, even if the loaded resource defines a foo * parameter, the value will still be 'bar' as defined in the ContainerBuilder From a72f4ecb3ac2cca30531607d3ce591e7157d7eea Mon Sep 17 00:00:00 2001 From: Jan Hort Date: Wed, 11 Jul 2018 16:52:26 +0200 Subject: [PATCH 07/16] [HttpFoundation] Fixed phpdoc for get method of HeaderBag --- src/Symfony/Component/HttpFoundation/HeaderBag.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/HeaderBag.php b/src/Symfony/Component/HttpFoundation/HeaderBag.php index d1065e7977..890dabd130 100644 --- a/src/Symfony/Component/HttpFoundation/HeaderBag.php +++ b/src/Symfony/Component/HttpFoundation/HeaderBag.php @@ -101,11 +101,11 @@ class HeaderBag implements \IteratorAggregate, \Countable /** * Returns a header value by name. * - * @param string $key The header name - * @param string|string[] $default The default value - * @param bool $first Whether to return the first value or all header values + * @param string $key The header name + * @param string|string[]|null $default The default value + * @param bool $first Whether to return the first value or all header values * - * @return string|string[] The first header value or default value if $first is true, an array of values otherwise + * @return string|string[]|null The first header value or default value if $first is true, an array of values otherwise */ public function get($key, $default = null, $first = true) { From 51a49c7f78557a847d512cac6224fc10f6706327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Calvo?= Date: Fri, 13 Jul 2018 08:54:27 +0200 Subject: [PATCH 08/16] [HttpFoundation] reset callback on StreamedResponse when setNotModified() is called --- .../HttpFoundation/StreamedResponse.php | 12 ++++++++++++ .../HttpFoundation/Tests/ResponseTest.php | 7 ++++++- .../Tests/StreamedResponseTest.php | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/StreamedResponse.php b/src/Symfony/Component/HttpFoundation/StreamedResponse.php index 01e8cf8c36..41ba4dc4e7 100644 --- a/src/Symfony/Component/HttpFoundation/StreamedResponse.php +++ b/src/Symfony/Component/HttpFoundation/StreamedResponse.php @@ -134,4 +134,16 @@ class StreamedResponse extends Response { return false; } + + /** + * {@inheritdoc} + * + * @return $this + */ + public function setNotModified() + { + $this->setCallback(function () {}); + + return parent::setNotModified(); + } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php index 46fcc5f3eb..ffd8eb354f 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php @@ -126,7 +126,7 @@ class ResponseTest extends ResponseTestCase public function testSetNotModified() { - $response = new Response(); + $response = new Response('foo'); $modified = $response->setNotModified(); $this->assertObjectHasAttribute('headers', $modified); $this->assertObjectHasAttribute('content', $modified); @@ -135,6 +135,11 @@ class ResponseTest extends ResponseTestCase $this->assertObjectHasAttribute('statusText', $modified); $this->assertObjectHasAttribute('charset', $modified); $this->assertEquals(304, $modified->getStatusCode()); + + ob_start(); + $modified->sendContent(); + $string = ob_get_clean(); + $this->assertEmpty($string); } public function testIsSuccessful() diff --git a/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php index 2ccb6841ad..66effe595d 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/StreamedResponseTest.php @@ -132,4 +132,22 @@ class StreamedResponseTest extends TestCase $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response->sendHeaders()); $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response->sendHeaders()); } + + public function testSetNotModified() + { + $response = new StreamedResponse(function () { echo 'foo'; }); + $modified = $response->setNotModified(); + $this->assertObjectHasAttribute('headers', $modified); + $this->assertObjectHasAttribute('content', $modified); + $this->assertObjectHasAttribute('version', $modified); + $this->assertObjectHasAttribute('statusCode', $modified); + $this->assertObjectHasAttribute('statusText', $modified); + $this->assertObjectHasAttribute('charset', $modified); + $this->assertEquals(304, $modified->getStatusCode()); + + ob_start(); + $modified->sendContent(); + $string = ob_get_clean(); + $this->assertEmpty($string); + } } From 5f59ad4600bf93c2f5e2a2524ef5f2e0a081a93e Mon Sep 17 00:00:00 2001 From: Webnet team Date: Wed, 11 Jul 2018 15:26:07 +0200 Subject: [PATCH 09/16] suppress side effects in 'get' or 'has' methods of NamespacedAttributeBag --- .../Attribute/NamespacedAttributeBag.php | 8 ++++++- .../Attribute/NamespacedAttributeBagTest.php | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php b/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php index abbf37ee7c..f9df69e907 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php +++ b/src/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php @@ -124,7 +124,13 @@ class NamespacedAttributeBag extends AttributeBag foreach ($parts as $part) { if (null !== $array && !array_key_exists($part, $array)) { - $array[$part] = $writeContext ? array() : null; + if (!$writeContext) { + $null = null; + + return $null; + } + + $array[$part] = array(); } $array = &$array[$part]; diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php index f074ce1b26..ec4cd5ad1a 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Attribute/NamespacedAttributeBagTest.php @@ -82,6 +82,17 @@ class NamespacedAttributeBagTest extends TestCase $this->assertEquals($exists, $this->bag->has($key)); } + /** + * @dataProvider attributesProvider + */ + public function testHasNoSideEffect($key, $value, $expected) + { + $expected = json_encode($this->bag->all()); + $this->bag->has($key); + + $this->assertEquals($expected, json_encode($this->bag->all())); + } + /** * @dataProvider attributesProvider */ @@ -96,6 +107,17 @@ class NamespacedAttributeBagTest extends TestCase $this->assertEquals('default', $this->bag->get('user2.login', 'default')); } + /** + * @dataProvider attributesProvider + */ + public function testGetNoSideEffect($key, $value, $expected) + { + $expected = json_encode($this->bag->all()); + $this->bag->get($key); + + $this->assertEquals($expected, json_encode($this->bag->all())); + } + /** * @dataProvider attributesProvider */ From ecef6f1b9b170acd0b47f3c1d31b95685f576ee2 Mon Sep 17 00:00:00 2001 From: jmsche Date: Fri, 13 Jul 2018 16:00:59 +0200 Subject: [PATCH 10/16] [WebProfilerBundle] Fixed icon alignment issue using Bootstrap 4.1.2 --- .../WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig index 91764e30de..00ab74ad9f 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig @@ -263,6 +263,7 @@ div.sf-toolbar .sf-toolbar-block a:hover { border-width: 0; position: relative; top: 8px; + vertical-align: baseline; } .sf-toolbar-block .sf-toolbar-icon img + span, From 7306018a30182e60ad039742ec580df5eed14c9f Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Fri, 13 Jul 2018 15:34:18 +0200 Subject: [PATCH 11/16] [Security] Update user phpdoc on tokens --- .../Core/Authentication/Token/AbstractToken.php | 9 +-------- .../Core/Authentication/Token/TokenInterface.php | 13 +++++++++---- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php index 8a9f2477b2..fc02e5feb9 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php @@ -77,14 +77,7 @@ abstract class AbstractToken implements TokenInterface } /** - * Sets the user in the token. - * - * The user can be a UserInterface instance, or an object implementing - * a __toString method or the username as a regular string. - * - * @param string|object $user The user - * - * @throws \InvalidArgumentException + * {@inheritdoc} */ public function setUser($user) { diff --git a/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php b/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php index 4e1dd7b2fc..583700c178 100644 --- a/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php +++ b/src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php @@ -47,17 +47,22 @@ interface TokenInterface extends \Serializable /** * Returns a user representation. * - * @return mixed Can be a UserInterface instance, an object implementing a __toString method, - * or the username as a regular string + * @return string|object Can be a UserInterface instance, an object implementing a __toString method, + * or the username as a regular string * * @see AbstractToken::setUser() */ public function getUser(); /** - * Sets a user. + * Sets the user in the token. * - * @param mixed $user + * The user can be a UserInterface instance, or an object implementing + * a __toString method or the username as a regular string. + * + * @param string|object $user The user + * + * @throws \InvalidArgumentException */ public function setUser($user); From 9854a269813a0ab2a7dc13a3cb7a5bb3e487c956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edi=20Modri=C4=87?= Date: Sat, 14 Jul 2018 16:36:53 +0200 Subject: [PATCH 12/16] [Form] Fix PHPDoc for FormConfigBuilder $dataClass argument --- src/Symfony/Component/Form/FormConfigBuilder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Form/FormConfigBuilder.php b/src/Symfony/Component/Form/FormConfigBuilder.php index 4ec16782c6..14150179d8 100644 --- a/src/Symfony/Component/Form/FormConfigBuilder.php +++ b/src/Symfony/Component/Form/FormConfigBuilder.php @@ -138,7 +138,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface private $data; /** - * @var string + * @var string|null */ private $dataClass; @@ -181,7 +181,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface * Creates an empty form configuration. * * @param string|int $name The form name - * @param string $dataClass The class of the form's data + * @param string|null $dataClass The class of the form's data * @param EventDispatcherInterface $dispatcher The event dispatcher * @param array $options The form options * From 32ad5d9f9cdbc8f175953981ba7df08caf2c07b1 Mon Sep 17 00:00:00 2001 From: Jannik Zschiesche Date: Tue, 10 Jul 2018 21:33:14 +0200 Subject: [PATCH 13/16] [Form] Improve rendering of `file` field in bootstrap 4 --- .../views/Form/bootstrap_4_layout.html.twig | 21 +++++++++---------- .../Tests/AbstractBootstrap4LayoutTest.php | 17 ++++++++++++--- 2 files changed, 24 insertions(+), 14 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 952ef3aec1..e821ac9c5a 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 @@ -114,6 +114,16 @@ {%- endblock percent_widget %} +{% block file_widget -%} +
+ <{{ element|default('div') }} class="custom-file"> + {%- set type = type|default('file') -%} + {{- block('form_widget_simple') -}} + + +
+{% endblock %} + {% block form_widget_simple -%} {% if type is not defined or type != 'hidden' %} {%- set attr = attr|merge({class: (attr.class|default('') ~ (type|default('') == 'file' ? ' custom-file-input' : ' form-control'))|trim}) -%} @@ -186,8 +196,6 @@ {%- if compound is defined and compound -%} {%- set element = 'legend' -%} {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-label')|trim}) -%} - {% elseif type is defined and type == 'file' %} - {%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' custom-file-label')|trim}) -%} {%- else -%} {%- set label_attr = label_attr|merge({for: id}) -%} {%- endif -%} @@ -269,15 +277,6 @@ {%- endblock form_row %} -{% block file_row -%} -
- <{{ element|default('div') }} class="custom-file"> - {{- form_widget(form) -}} - {{- form_label(form) -}} - -
-{% endblock %} - {# Errors #} {% block form_errors -%} diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php index 28b3111c4a..a3fc43a49f 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php @@ -940,9 +940,20 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest { $form = $this->factory->createNamed('name', FileType::class); - $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class form-control-file')), -'/input - [@type="file"] + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'nope', 'attr' => array('class' => 'my&class form-control-file')), +'/div + [@class="form-group"] + [ + ./div + [@class="custom-file"] + [ + ./input + [@type="file"] + [@name="name"] + /following-sibling::label + [@for="name"] + ] + ] ' ); } From 3cd2eef6e680c60d4d1d1e8ecd759f5806513698 Mon Sep 17 00:00:00 2001 From: Jannik Zschiesche Date: Sun, 15 Jul 2018 17:41:19 +0200 Subject: [PATCH 14/16] Add placeholder support in bootstrap 4 file fields --- .../views/Form/bootstrap_4_layout.html.twig | 6 ++++- .../Tests/AbstractBootstrap4LayoutTest.php | 24 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 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 e821ac9c5a..8f790fdd19 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 @@ -119,7 +119,11 @@ <{{ element|default('div') }} class="custom-file"> {%- set type = type|default('file') -%} {{- block('form_widget_simple') -}} - + {% endblock %} diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php index a3fc43a49f..283757080b 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php @@ -940,7 +940,7 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest { $form = $this->factory->createNamed('name', FileType::class); - $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'nope', 'attr' => array('class' => 'my&class form-control-file')), + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'n/a', 'attr' => array('class' => 'my&class form-control-file')), '/div [@class="form-group"] [ @@ -958,6 +958,28 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest ); } + public function testFileWithPlaceholder() + { + $form = $this->factory->createNamed('name', FileType::class); + + $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'n/a', 'attr' => array('class' => 'my&class form-control-file', 'placeholder' => 'Custom Placeholder')), +'/div + [@class="form-group"] + [ + ./div + [@class="custom-file"] + [ + ./input + [@type="file"] + [@name="name"] + /following-sibling::label + [@for="name" and text() = "[trans]Custom Placeholder[/trans]"] + ] + ] +' + ); + } + public function testMoney() { $form = $this->factory->createNamed('name', MoneyType::class, 1234.56, array( From b5863bc7e8620205b7d8f6c4ba92682187db4747 Mon Sep 17 00:00:00 2001 From: Ivan Nikolaev Date: Mon, 16 Jul 2018 15:56:07 +0300 Subject: [PATCH 15/16] [FrameworkBundle] fixed brackets position in method calls --- .../DependencyInjection/FrameworkExtensionTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 3a81958b11..11b0c95959 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -191,8 +191,8 @@ abstract class FrameworkExtensionTest extends TestCase { $container = $this->createContainerFromFile('workflows'); - $this->assertTrue($container->hasDefinition('workflow.article', 'Workflow is registered as a service')); - $this->assertTrue($container->hasDefinition('workflow.article.definition', 'Workflow definition is registered as a service')); + $this->assertTrue($container->hasDefinition('workflow.article'), 'Workflow is registered as a service'); + $this->assertTrue($container->hasDefinition('workflow.article.definition'), 'Workflow definition is registered as a service'); $workflowDefinition = $container->getDefinition('workflow.article.definition'); @@ -210,8 +210,8 @@ abstract class FrameworkExtensionTest extends TestCase ); $this->assertSame(array('workflow.definition' => array(array('name' => 'article', 'type' => 'workflow', 'marking_store' => 'multiple_state'))), $workflowDefinition->getTags()); - $this->assertTrue($container->hasDefinition('state_machine.pull_request', 'State machine is registered as a service')); - $this->assertTrue($container->hasDefinition('state_machine.pull_request.definition', 'State machine definition is registered as a service')); + $this->assertTrue($container->hasDefinition('state_machine.pull_request'), 'State machine is registered as a service'); + $this->assertTrue($container->hasDefinition('state_machine.pull_request.definition'), 'State machine definition is registered as a service'); $this->assertCount(4, $workflowDefinition->getArgument(1)); $this->assertSame('draft', $workflowDefinition->getArgument(2)); @@ -293,8 +293,8 @@ abstract class FrameworkExtensionTest extends TestCase { $container = $this->createContainerFromFile('workflow_with_multiple_transitions_with_same_name'); - $this->assertTrue($container->hasDefinition('workflow.article', 'Workflow is registered as a service')); - $this->assertTrue($container->hasDefinition('workflow.article.definition', 'Workflow definition is registered as a service')); + $this->assertTrue($container->hasDefinition('workflow.article'), 'Workflow is registered as a service'); + $this->assertTrue($container->hasDefinition('workflow.article.definition'), 'Workflow definition is registered as a service'); $workflowDefinition = $container->getDefinition('workflow.article.definition'); From 2afd49ff17cc645843a0c3d09534689b439c2284 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 16 Jul 2018 16:05:32 +0200 Subject: [PATCH 16/16] fixed typo --- .../Tests/DependencyInjection/FrameworkExtensionTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 955f3cad44..8f0bd34f5b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -241,7 +241,7 @@ abstract class FrameworkExtensionTest extends TestCase $this->assertInstanceOf(Reference::class, $markingStoreRef); $this->assertEquals('workflow_service', (string) $markingStoreRef); - $this->assertTrue($container->hasDefinition('workflow.registry', 'Workflow registry is registered as a service')); + $this->assertTrue($container->hasDefinition('workflow.registry'), 'Workflow registry is registered as a service'); $registryDefinition = $container->getDefinition('workflow.registry'); $this->assertGreaterThan(0, count($registryDefinition->getMethodCalls())); }