From f0635877cd48b18a2fb7efee21c52a6b4231e2a2 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Sat, 1 Dec 2018 12:13:07 +0100 Subject: [PATCH 1/9] Minor tweak for c3ad8a5 --- .../DependencyInjection/Fixtures/php/messenger_transports.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transports.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transports.php index b7a6e408c3..4edc0d880a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transports.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transports.php @@ -3,7 +3,7 @@ $container->loadFromExtension('framework', array( 'serializer' => true, 'messenger' => array( - 'serializer' => 'serializer: messenger.transport.symfony_serializer', + 'serializer' => 'messenger.transport.symfony_serializer', 'transports' => array( 'default' => 'amqp://localhost/%2f/messages', 'customised' => array( From 3855d5af0139c6069016cc21526e54414779b1a8 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Sat, 1 Dec 2018 20:35:42 +0100 Subject: [PATCH 2/9] [WebProfilerBundle] Split form field heading --- .../Resources/views/Collector/form.html.twig | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig index 02b77319ac..720da85750 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig @@ -177,6 +177,12 @@ color: inherit; text-decoration: inherit; } + h2 + h3.form-data-type { + margin-top: 0; + } + h3.form-data-type + h3 { + margin-top: 1em; + } {% endblock %} @@ -455,9 +461,10 @@ {% macro form_tree_details(name, data, forms_by_hash, show) %} {% import _self as tree %}
-

- {{ name|default('(no name)') }} {% if data.type_class is defined %}({{ profiler_dump(data.type_class) }}){% endif %} -

+

{{ name|default('(no name)') }}

+ {% if data.type_class is defined %} +

{{ profiler_dump(data.type_class) }}

+ {% endif %} {% if data.errors is defined and data.errors|length > 0 %}
From 0132ba9dc5554a6227480cb8b755d557b8143ba9 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 2 Dec 2018 00:05:18 +0100 Subject: [PATCH 3/9] [VarExporter] fix dumping protected property from abstract classes --- .../Component/VarExporter/Internal/Exporter.php | 3 +-- .../Tests/Fixtures/abstract-parent.php | 17 +++++++++++++++++ .../VarExporter/Tests/Fixtures/final-error.php | 2 +- .../VarExporter/Tests/Fixtures/private.php | 6 +++++- .../VarExporter/Tests/VarExporterTest.php | 15 +++++++++++++++ 5 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 src/Symfony/Component/VarExporter/Tests/Fixtures/abstract-parent.php diff --git a/src/Symfony/Component/VarExporter/Internal/Exporter.php b/src/Symfony/Component/VarExporter/Internal/Exporter.php index bbb409e194..563eadc8c4 100644 --- a/src/Symfony/Component/VarExporter/Internal/Exporter.php +++ b/src/Symfony/Component/VarExporter/Internal/Exporter.php @@ -125,8 +125,7 @@ class Exporter $c = 'stdClass'; } elseif ('*' === $n[1]) { $n = substr($n, 3); - $c = $reflector->getProperty($n)->class; - if ('Error' === $c) { + if ('Error' === $c = $class) { $c = 'TypeError'; } elseif ('Exception' === $c) { $c = 'ErrorException'; diff --git a/src/Symfony/Component/VarExporter/Tests/Fixtures/abstract-parent.php b/src/Symfony/Component/VarExporter/Tests/Fixtures/abstract-parent.php new file mode 100644 index 0000000000..5548b9f8c8 --- /dev/null +++ b/src/Symfony/Component/VarExporter/Tests/Fixtures/abstract-parent.php @@ -0,0 +1,17 @@ + [ + 'foo' => [ + 123, + ], + ], + ], + $o[0], + [] +); diff --git a/src/Symfony/Component/VarExporter/Tests/Fixtures/final-error.php b/src/Symfony/Component/VarExporter/Tests/Fixtures/final-error.php index dc260dc024..78da251141 100644 --- a/src/Symfony/Component/VarExporter/Tests/Fixtures/final-error.php +++ b/src/Symfony/Component/VarExporter/Tests/Fixtures/final-error.php @@ -6,7 +6,7 @@ return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate( ]), null, [ - 'TypeError' => [ + 'Symfony\\Component\\VarExporter\\Tests\\FinalError' => [ 'file' => [ \dirname(__DIR__).\DIRECTORY_SEPARATOR.'VarExporterTest.php', ], diff --git a/src/Symfony/Component/VarExporter/Tests/Fixtures/private.php b/src/Symfony/Component/VarExporter/Tests/Fixtures/private.php index a9e28416e5..a901afe6ea 100644 --- a/src/Symfony/Component/VarExporter/Tests/Fixtures/private.php +++ b/src/Symfony/Component/VarExporter/Tests/Fixtures/private.php @@ -10,13 +10,17 @@ return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate( 'Symfony\\Component\\VarExporter\\Tests\\MyPrivateValue' => [ 'prot' => [ 123, - 123, ], 'priv' => [ 234, 234, ], ], + 'Symfony\\Component\\VarExporter\\Tests\\MyPrivateChildValue' => [ + 'prot' => [ + 1 => 123, + ], + ], ], [ $o[0], diff --git a/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php b/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php index f509617686..c88f445b76 100644 --- a/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php +++ b/src/Symfony/Component/VarExporter/Tests/VarExporterTest.php @@ -192,6 +192,8 @@ class VarExporterTest extends TestCase $value->bis = new \ReflectionClass($value); yield array('wakeup-refl', $value); + + yield array('abstract-parent', new ConcreteClass()); } } @@ -320,3 +322,16 @@ final class FinalStdClass extends \stdClass throw new \BadMethodCallException('Should not be called.'); } } + +abstract class AbstractClass +{ + protected $foo; +} + +class ConcreteClass extends AbstractClass +{ + public function __construct() + { + $this->foo = 123; + } +} From d1e84aa137c29da532baff930a64ad5b8c31b018 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Sat, 1 Dec 2018 20:08:25 +0100 Subject: [PATCH 4/9] [DI] Fix dumping expressions accessing single-use private services --- .../DependencyInjection/Dumper/PhpDumper.php | 5 ++--- .../Tests/Dumper/PhpDumperTest.php | 2 +- .../Tests/Fixtures/php/services9.php | 2 +- .../Tests/Fixtures/php/services9_as_files.txt | 2 +- .../Tests/Fixtures/php/services9_compiled.php | 2 +- .../php/services_almost_circular_private.php | 4 ++-- .../php/services_almost_circular_public.php | 6 +++--- .../Tests/Fixtures/php/services_env_in_id.php | 4 ++-- .../Fixtures/php/services_inline_requires.php | 2 +- .../Fixtures/php/services_legacy_privates.php | 2 +- .../Tests/Fixtures/php/services_locator.php | 14 +++++++------- .../Tests/Fixtures/php/services_private_frozen.php | 4 ++-- .../php/services_private_in_expression.php | 2 +- .../Tests/Fixtures/php/services_rot13_env.php | 2 +- .../Tests/Fixtures/php/services_subscriber.php | 8 ++++---- .../Fixtures/php/services_uninitialized_ref.php | 2 +- 16 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 95a98c6aaa..3a3c24d044 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -594,9 +594,7 @@ EOF; if ($callable[0] instanceof Reference || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0])) ) { - $callable[0] = $this->dumpValue($callable[0]); - - return sprintf(' '.('$' === $callable[0][0] ? '%s' : '(%s)')."->%s(\$%s);\n", $callable[0], $callable[1], $variableName); + return sprintf(" %s->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); } $class = $this->dumpValue($callable[0]); @@ -1824,6 +1822,7 @@ EOF; if ($definition->isShared()) { $code = sprintf('$this->services[\'%s\'] = %s', $id, $code); } + $code = "($code)"; } elseif ($this->asFiles && $definition->isShared() && !$this->isHotPath($definition)) { $code = sprintf("\$this->load('%s.php')", $this->generateMethodName($id)); } else { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 51c5fd21f6..60fa55c3b5 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -752,7 +752,7 @@ class PhpDumperTest extends TestCase ->setPublic(false); $container->register('public_foo', 'stdClass') ->setPublic(true) - ->addArgument(new Expression('service("private_foo")')); + ->addArgument(new Expression('service("private_foo").bar')); $container->compile(); $dumper = new PhpDumper($container); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php index ad316b23c6..fc04f5faee 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php @@ -126,7 +126,7 @@ class ProjectServiceContainer extends Container { $this->services['configured_service_simple'] = $instance = new \stdClass(); - ${($_ = isset($this->services['configurator_service_simple']) ? $this->services['configurator_service_simple'] : $this->services['configurator_service_simple'] = new \ConfClass('bar')) && false ?: '_'}->configureStdClass($instance); + ${($_ = isset($this->services['configurator_service_simple']) ? $this->services['configurator_service_simple'] : ($this->services['configurator_service_simple'] = new \ConfClass('bar'))) && false ?: '_'}->configureStdClass($instance); return $instance; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt index 4b6e2f59e6..fa032cbc1f 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt @@ -243,7 +243,7 @@ use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; return $this->services['tagged_iterator'] = new \Bar(new RewindableGenerator(function () { yield 0 => ${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->load('getFooService.php')) && false ?: '_'}; - yield 1 => ${($_ = isset($this->services['tagged_iterator_foo']) ? $this->services['tagged_iterator_foo'] : $this->services['tagged_iterator_foo'] = new \Bar()) && false ?: '_'}; + yield 1 => ${($_ = isset($this->services['tagged_iterator_foo']) ? $this->services['tagged_iterator_foo'] : ($this->services['tagged_iterator_foo'] = new \Bar())) && false ?: '_'}; }, 2)); [Container%s/getTaggedIteratorFooService.php] => services['tagged_iterator'] = new \Bar(new RewindableGenerator(function () { yield 0 => ${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->getFooService()) && false ?: '_'}; - yield 1 => ${($_ = isset($this->services['tagged_iterator_foo']) ? $this->services['tagged_iterator_foo'] : $this->services['tagged_iterator_foo'] = new \Bar()) && false ?: '_'}; + yield 1 => ${($_ = isset($this->services['tagged_iterator_foo']) ? $this->services['tagged_iterator_foo'] : ($this->services['tagged_iterator_foo'] = new \Bar())) && false ?: '_'}; }, 2)); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php index 9c54acc6be..8aa4a2c406 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_private.php @@ -331,7 +331,7 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container */ protected function getRootService() { - return $this->services['root'] = new \stdClass(${($_ = isset($this->services['level2']) ? $this->services['level2'] : $this->getLevel2Service()) && false ?: '_'}, ${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : $this->services['multiuse1'] = new \stdClass()) && false ?: '_'}); + return $this->services['root'] = new \stdClass(${($_ = isset($this->services['level2']) ? $this->services['level2'] : $this->getLevel2Service()) && false ?: '_'}, ${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : ($this->services['multiuse1'] = new \stdClass())) && false ?: '_'}); } /** @@ -397,7 +397,7 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container */ protected function getLevel4Service() { - return $this->services['level4'] = new \stdClass(${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : $this->services['multiuse1'] = new \stdClass()) && false ?: '_'}, ${($_ = isset($this->services['level5']) ? $this->services['level5'] : $this->getLevel5Service()) && false ?: '_'}); + return $this->services['level4'] = new \stdClass(${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : ($this->services['multiuse1'] = new \stdClass())) && false ?: '_'}, ${($_ = isset($this->services['level5']) ? $this->services['level5'] : $this->getLevel5Service()) && false ?: '_'}); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php index bd08c4d15f..a5de37f12c 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_almost_circular_public.php @@ -126,7 +126,7 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container { $this->services['bar3'] = $instance = new \BarCircular(); - $a = ${($_ = isset($this->services['foobar3']) ? $this->services['foobar3'] : $this->services['foobar3'] = new \FoobarCircular()) && false ?: '_'}; + $a = ${($_ = isset($this->services['foobar3']) ? $this->services['foobar3'] : ($this->services['foobar3'] = new \FoobarCircular())) && false ?: '_'}; $instance->addFoobar($a, $a); @@ -431,7 +431,7 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container */ protected function getRootService() { - return $this->services['root'] = new \stdClass(${($_ = isset($this->services['level2']) ? $this->services['level2'] : $this->getLevel2Service()) && false ?: '_'}, ${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : $this->services['multiuse1'] = new \stdClass()) && false ?: '_'}); + return $this->services['root'] = new \stdClass(${($_ = isset($this->services['level2']) ? $this->services['level2'] : $this->getLevel2Service()) && false ?: '_'}, ${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : ($this->services['multiuse1'] = new \stdClass())) && false ?: '_'}); } /** @@ -497,7 +497,7 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container */ protected function getLevel4Service() { - return $this->services['level4'] = new \stdClass(${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : $this->services['multiuse1'] = new \stdClass()) && false ?: '_'}, ${($_ = isset($this->services['level5']) ? $this->services['level5'] : $this->getLevel5Service()) && false ?: '_'}); + return $this->services['level4'] = new \stdClass(${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : ($this->services['multiuse1'] = new \stdClass())) && false ?: '_'}, ${($_ = isset($this->services['level5']) ? $this->services['level5'] : $this->getLevel5Service()) && false ?: '_'}); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_env_in_id.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_env_in_id.php index 91114fd978..dab23e1dbc 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_env_in_id.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_env_in_id.php @@ -73,7 +73,7 @@ class ProjectServiceContainer extends Container */ protected function getBarService() { - return $this->services['bar'] = new \stdClass(${($_ = isset($this->services['bar_%env(BAR)%']) ? $this->services['bar_%env(BAR)%'] : $this->services['bar_%env(BAR)%'] = new \stdClass()) && false ?: '_'}); + return $this->services['bar'] = new \stdClass(${($_ = isset($this->services['bar_%env(BAR)%']) ? $this->services['bar_%env(BAR)%'] : ($this->services['bar_%env(BAR)%'] = new \stdClass())) && false ?: '_'}); } /** @@ -83,7 +83,7 @@ class ProjectServiceContainer extends Container */ protected function getFooService() { - return $this->services['foo'] = new \stdClass(${($_ = isset($this->services['bar_%env(BAR)%']) ? $this->services['bar_%env(BAR)%'] : $this->services['bar_%env(BAR)%'] = new \stdClass()) && false ?: '_'}, array('baz_'.$this->getEnv('string:BAR') => new \stdClass())); + return $this->services['foo'] = new \stdClass(${($_ = isset($this->services['bar_%env(BAR)%']) ? $this->services['bar_%env(BAR)%'] : ($this->services['bar_%env(BAR)%'] = new \stdClass())) && false ?: '_'}, array('baz_'.$this->getEnv('string:BAR') => new \stdClass())); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_requires.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_requires.php index 08a474eea3..c6927eb95d 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_requires.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_inline_requires.php @@ -110,7 +110,7 @@ class ProjectServiceContainer extends Container include_once $this->targetDirs[1].'/includes/HotPath/C2.php'; include_once $this->targetDirs[1].'/includes/HotPath/C3.php'; - return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3()) && false ?: '_'}); + return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3'] : ($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3())) && false ?: '_'}); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_legacy_privates.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_legacy_privates.php index 7aa1bff870..d720ae396f 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_legacy_privates.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_legacy_privates.php @@ -98,7 +98,7 @@ class Symfony_DI_PhpDumper_Test_Legacy_Privates extends Container */ protected function getBarService() { - return $this->services['bar'] = new \stdClass(${($_ = isset($this->services['private_not_inlined']) ? $this->services['private_not_inlined'] : $this->services['private_not_inlined'] = new \stdClass()) && false ?: '_'}); + return $this->services['bar'] = new \stdClass(${($_ = isset($this->services['private_not_inlined']) ? $this->services['private_not_inlined'] : ($this->services['private_not_inlined'] = new \stdClass())) && false ?: '_'}); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_locator.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_locator.php index 496f6aa77d..c436aea407 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_locator.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_locator.php @@ -76,7 +76,7 @@ class ProjectServiceContainer extends Container */ protected function getBarServiceService() { - return $this->services['bar_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : $this->services['baz_service'] = new \stdClass()) && false ?: '_'}); + return $this->services['bar_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : ($this->services['baz_service'] = new \stdClass())) && false ?: '_'}); } /** @@ -89,7 +89,7 @@ class ProjectServiceContainer extends Container return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\ServiceLocator(array('bar' => function () { return ${($_ = isset($this->services['bar_service']) ? $this->services['bar_service'] : $this->getBarServiceService()) && false ?: '_'}; }, 'baz' => function () { - $f = function (\stdClass $v) { return $v; }; return $f(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : $this->services['baz_service'] = new \stdClass()) && false ?: '_'}); + $f = function (\stdClass $v) { return $v; }; return $f(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : ($this->services['baz_service'] = new \stdClass())) && false ?: '_'}); }, 'nil' => function () { return NULL; })); @@ -133,7 +133,7 @@ class ProjectServiceContainer extends Container protected function getTranslator1Service() { return $this->services['translator_1'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator(new \Symfony\Component\DependencyInjection\ServiceLocator(array('translator.loader_1' => function () { - return ${($_ = isset($this->services['translator.loader_1']) ? $this->services['translator.loader_1'] : $this->services['translator.loader_1'] = new \stdClass()) && false ?: '_'}; + return ${($_ = isset($this->services['translator.loader_1']) ? $this->services['translator.loader_1'] : ($this->services['translator.loader_1'] = new \stdClass())) && false ?: '_'}; }))); } @@ -145,10 +145,10 @@ class ProjectServiceContainer extends Container protected function getTranslator2Service() { $this->services['translator_2'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator(new \Symfony\Component\DependencyInjection\ServiceLocator(array('translator.loader_2' => function () { - return ${($_ = isset($this->services['translator.loader_2']) ? $this->services['translator.loader_2'] : $this->services['translator.loader_2'] = new \stdClass()) && false ?: '_'}; + return ${($_ = isset($this->services['translator.loader_2']) ? $this->services['translator.loader_2'] : ($this->services['translator.loader_2'] = new \stdClass())) && false ?: '_'}; }))); - $instance->addResource('db', ${($_ = isset($this->services['translator.loader_2']) ? $this->services['translator.loader_2'] : $this->services['translator.loader_2'] = new \stdClass()) && false ?: '_'}, 'nl'); + $instance->addResource('db', ${($_ = isset($this->services['translator.loader_2']) ? $this->services['translator.loader_2'] : ($this->services['translator.loader_2'] = new \stdClass())) && false ?: '_'}, 'nl'); return $instance; } @@ -161,10 +161,10 @@ class ProjectServiceContainer extends Container protected function getTranslator3Service() { $this->services['translator_3'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator(new \Symfony\Component\DependencyInjection\ServiceLocator(array('translator.loader_3' => function () { - return ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : $this->services['translator.loader_3'] = new \stdClass()) && false ?: '_'}; + return ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : ($this->services['translator.loader_3'] = new \stdClass())) && false ?: '_'}; }))); - $a = ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : $this->services['translator.loader_3'] = new \stdClass()) && false ?: '_'}; + $a = ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : ($this->services['translator.loader_3'] = new \stdClass())) && false ?: '_'}; $instance->addResource('db', $a, 'nl'); $instance->addResource('db', $a, 'en'); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_frozen.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_frozen.php index 1275e9f264..8ef589c127 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_frozen.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_frozen.php @@ -67,7 +67,7 @@ class ProjectServiceContainer extends Container */ protected function getBarServiceService() { - return $this->services['bar_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : $this->services['baz_service'] = new \stdClass()) && false ?: '_'}); + return $this->services['bar_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : ($this->services['baz_service'] = new \stdClass())) && false ?: '_'}); } /** @@ -77,7 +77,7 @@ class ProjectServiceContainer extends Container */ protected function getFooServiceService() { - return $this->services['foo_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : $this->services['baz_service'] = new \stdClass()) && false ?: '_'}); + return $this->services['foo_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : ($this->services['baz_service'] = new \stdClass())) && false ?: '_'}); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_in_expression.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_in_expression.php index fe84f49753..75cbc2730b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_in_expression.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_in_expression.php @@ -67,7 +67,7 @@ class ProjectServiceContainer extends Container */ protected function getPublicFooService() { - return $this->services['public_foo'] = new \stdClass(${($_ = isset($this->services['private_foo']) ? $this->services['private_foo'] : $this->services['private_foo'] = new \stdClass()) && false ?: '_'}); + return $this->services['public_foo'] = new \stdClass(${($_ = isset($this->services['private_foo']) ? $this->services['private_foo'] : ($this->services['private_foo'] = new \stdClass())) && false ?: '_'}->bar); } /** diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_rot13_env.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_rot13_env.php index 90836aa90d..efbb002316 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_rot13_env.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_rot13_env.php @@ -78,7 +78,7 @@ class Symfony_DI_PhpDumper_Test_Rot13Parameters extends Container protected function getContainer_EnvVarProcessorsLocatorService() { return $this->services['container.env_var_processors_locator'] = new \Symfony\Component\DependencyInjection\ServiceLocator(array('rot13' => function () { - return ${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor'] : $this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor()) && false ?: '_'}; + return ${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor'] : ($this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor())) && false ?: '_'}; })); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php index 9475c92306..8f198f0ba8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php @@ -84,13 +84,13 @@ class ProjectServiceContainer extends Container protected function getFooServiceService() { return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber((new \Symfony\Component\DependencyInjection\ServiceLocator(array('Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => function () { - $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition()) && false ?: '_'}); + $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : ($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition())) && false ?: '_'}); }, 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => function () { - $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber()) && false ?: '_'}); + $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] : ($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber())) && false ?: '_'}); }, 'bar' => function () { - $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber()) && false ?: '_'}); + $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] : ($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber())) && false ?: '_'}); }, 'baz' => function () { - $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition()) && false ?: '_'}); + $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : ($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition())) && false ?: '_'}); })))->withContext('foo_service', $this)); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_uninitialized_ref.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_uninitialized_ref.php index 4d0c00b289..c53e336d27 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_uninitialized_ref.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_uninitialized_ref.php @@ -107,7 +107,7 @@ class Symfony_DI_PhpDumper_Test_Uninitialized_Reference extends Container { $this->services['baz'] = $instance = new \stdClass(); - $instance->foo3 = ${($_ = isset($this->services['foo3']) ? $this->services['foo3'] : $this->services['foo3'] = new \stdClass()) && false ?: '_'}; + $instance->foo3 = ${($_ = isset($this->services['foo3']) ? $this->services['foo3'] : ($this->services['foo3'] = new \stdClass())) && false ?: '_'}; return $instance; } From b33591151220194529be8b06f74b7488c512a763 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Sun, 2 Dec 2018 10:37:20 +0100 Subject: [PATCH 5/9] [WebProfilerBundle][4.2] Deny messenger <4.2 --- src/Symfony/Bundle/WebProfilerBundle/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bundle/WebProfilerBundle/composer.json b/src/Symfony/Bundle/WebProfilerBundle/composer.json index 0f4d40879d..79f4ddb596 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/composer.json +++ b/src/Symfony/Bundle/WebProfilerBundle/composer.json @@ -32,6 +32,7 @@ "conflict": { "symfony/dependency-injection": "<3.4", "symfony/event-dispatcher": "<3.4", + "symfony/messenger": "<4.2", "symfony/var-dumper": "<3.4" }, "autoload": { From b634967d465e425f197b07da5aa0003a7d542f8d Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Sat, 1 Dec 2018 12:57:40 +0100 Subject: [PATCH 6/9] [WebProfilerBundle] Fix log filter in dark mode --- .../Bundle/TwigBundle/Resources/views/exception.css.twig | 2 +- .../Resources/views/Profiler/profiler.css.twig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig index 4556749de8..c717b70d69 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig +++ b/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig @@ -126,7 +126,7 @@ thead.sf-toggle-content.sf-toggle-visible, tbody.sf-toggle-content.sf-toggle-vis .filter-list-level li.active { cursor: n-resize; } .filter-list-level li.last-active { cursor: default; } .filter-list-level li.last-active:before { content: '\2714\00a0'; } -.filter-list-choice li:before { content: '\2714\00a0'; color: var(--tab-background); } +.filter-list-choice li:before { content: '\2714\00a0'; color: transparent; } .filter-list-choice li.active:before { color: unset; } .container { max-width: 1024px; margin: 0 auto; padding: 0 15px; } diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig index 5f6582ed38..dd5b970148 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/profiler.css.twig @@ -957,7 +957,7 @@ tr.status-warning td { .filter-list-level li.active { cursor: n-resize; } .filter-list-level li.last-active { cursor: default; } .filter-list-level li.last-active:before { content: '\2714\00a0'; } -.filter-list-choice li:before { content: '\2714\00a0'; color: var(--tab-background); } +.filter-list-choice li:before { content: '\2714\00a0'; color: transparent; } .filter-list-choice li.active:before { color: unset; } {# Twig panel From d6704bbfb0310c1d40aee6b4ec0e11c585300f97 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Sun, 2 Dec 2018 11:42:21 +0100 Subject: [PATCH 7/9] [TwigBundle] Sync tab navigation css --- .../Resources/views/exception.css.twig | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig index c717b70d69..a2091e85aa 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig +++ b/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig @@ -84,16 +84,15 @@ thead.sf-toggle-content.sf-toggle-visible, tbody.sf-toggle-content.sf-toggle-vis .sf-toggle-off .icon-open, .sf-toggle-on .icon-close { display: block; } .tab-navigation { margin: 0 0 1em 0; padding: 0; } -.tab-navigation li { background: #FFF; border: 1px solid #DDD; color: #444; cursor: pointer; display: inline-block; font-size: 16px; margin: 0 0 0 -1px; padding: .5em .75em; z-index: 1; } -.tab-navigation li:hover { background: #EEE; } -.tab-navigation li.disabled { background: #F5F5F5; color: #999; } -.tab-navigation li.active { background: #666; border-color: #666; color: #FAFAFA; z-index: 1100; } -.tab-navigation li .badge { background-color: #F5F5F5; color: #777; display: inline-block; font-size: 14px; font-weight: bold; margin-left: 8px; min-width: 10px; padding: 1px 6px; text-align: center; } -.tab-navigation li:hover .badge { background: #FAFAFA; color: #777; } -.tab-navigation li.active .badge { background-color: #444; color: #FFF; } -.tab-navigation li .badge.status-warning { background: #A46A1F; color: #FFF; } -.tab-navigation li .badge.status-error { background: #B0413E; color: #FFF; } +.tab-navigation li { background: var(--tab-background); border: 1px solid var(--table-border); color: var(--tab-color); cursor: pointer; display: inline-block; font-size: 16px; margin: 0 0 0 -1px; padding: .5em .75em; z-index: 1; } +.tab-navigation li .badge { background-color: var(--base-1); color: var(--base-4); display: inline-block; font-size: 14px; font-weight: bold; margin-left: 8px; min-width: 10px; padding: 1px 6px; text-align: center; white-space: nowrap; } +.tab-navigation li.disabled { background: var(--tab-disabled-background); color: var(--tab-disabled-color); } +.tab-navigation li.active { background: var(--tab-active-background); color: var(--tab-active-color); z-index: 1100; } +.tab-navigation li.active .badge { background-color: var(--base-5); color: var(--base-2); } .tab-content > *:first-child { margin-top: 0; } +.tab-navigation li .badge.status-warning { background: var(--color-warning); color: #FFF; } +.tab-navigation li .badge.status-error { background: var(--color-error); color: #FFF; } +.sf-tabs .tab:not(:first-child) { display: none; } [data-filters] { position: relative; } [data-filtered] { cursor: pointer; } From 6b65fac2cfaaeb980fb83feb8aed92eb39fa2ee6 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 2 Dec 2018 12:14:59 +0100 Subject: [PATCH 8/9] [Routing] fix taking verb into account when redirecting --- .../Component/Routing/Matcher/UrlMatcher.php | 14 ++++++++++---- .../Matcher/RedirectableUrlMatcherTest.php | 17 +++++++++++++++++ .../Routing/Tests/Matcher/UrlMatcherTest.php | 14 ++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php index 69d73906fe..fc4554fff5 100644 --- a/src/Symfony/Component/Routing/Matcher/UrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/UrlMatcher.php @@ -123,14 +123,15 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface foreach ($routes as $name => $route) { $compiledRoute = $route->compile(); $staticPrefix = $compiledRoute->getStaticPrefix(); + $requiredMethods = $route->getMethods(); // check the static prefix of the URL first. Only use the more expensive preg_match when it matches if ('' === $staticPrefix || 0 === strpos($pathinfo, $staticPrefix)) { // no-op - } elseif (!$supportsTrailingSlash) { + } elseif (!$supportsTrailingSlash || ($requiredMethods && !\in_array('GET', $requiredMethods))) { continue; } elseif ('/' === substr($staticPrefix, -1) && substr($staticPrefix, 0, -1) === $pathinfo) { - return; + return $this->allow = array(); } else { continue; } @@ -148,7 +149,10 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface } if ($hasTrailingSlash && '/' !== substr($pathinfo, -1)) { - return; + if (!$requiredMethods || \in_array('GET', $requiredMethods)) { + return $this->allow = array(); + } + continue; } $hostMatches = array(); @@ -163,7 +167,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface } // check HTTP method requirement - if ($requiredMethods = $route->getMethods()) { + if ($requiredMethods) { // HEAD and GET are equivalent as per RFC if ('HEAD' === $method = $this->context->getMethod()) { $method = 'GET'; @@ -180,6 +184,8 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, isset($status[1]) ? $status[1] : array())); } + + return array(); } /** diff --git a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php index a7aea0ec07..9857f05024 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/RedirectableUrlMatcherTest.php @@ -128,6 +128,23 @@ class RedirectableUrlMatcherTest extends UrlMatcherTest $this->assertSame(array('_route' => 'foo'), $matcher->match('/foo')); } + public function testSlashAndVerbPrecedenceWithRedirection() + { + $coll = new RouteCollection(); + $coll->add('a', new Route('/api/customers/{customerId}/contactpersons', array(), array(), array(), '', array(), array('post'))); + $coll->add('b', new Route('/api/customers/{customerId}/contactpersons/', array(), array(), array(), '', array(), array('get'))); + + $matcher = $this->getUrlMatcher($coll); + $expected = array( + '_route' => 'b', + 'customerId' => '123', + ); + $this->assertEquals($expected, $matcher->match('/api/customers/123/contactpersons/')); + + $matcher->expects($this->once())->method('redirect')->with('/api/customers/123/contactpersons/')->willReturn(array()); + $this->assertEquals($expected, $matcher->match('/api/customers/123/contactpersons')); + } + 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 0d4b44b090..ab682732ca 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php @@ -502,6 +502,20 @@ class UrlMatcherTest extends TestCase $matcher->match('/'); } + public function testSlashAndVerbPrecedence() + { + $coll = new RouteCollection(); + $coll->add('a', new Route('/api/customers/{customerId}/contactpersons/', array(), array(), array(), '', array(), array('post'))); + $coll->add('b', new Route('/api/customers/{customerId}/contactpersons', array(), array(), array(), '', array(), array('get'))); + + $matcher = $this->getUrlMatcher($coll); + $expected = array( + '_route' => 'b', + 'customerId' => '123', + ); + $this->assertEquals($expected, $matcher->match('/api/customers/123/contactpersons')); + } + protected function getUrlMatcher(RouteCollection $routes, RequestContext $context = null) { return new UrlMatcher($routes, $context ?: new RequestContext()); From 2bf8a1cae6d425b6a854a909ab186c0943d85ad9 Mon Sep 17 00:00:00 2001 From: Vitaliy Ryaboy Date: Sat, 1 Dec 2018 19:23:29 +0100 Subject: [PATCH 9/9] [Serializer] fixed DateTimeNormalizer to maintain microseconds when a different timezone required --- .../Normalizer/DateTimeNormalizer.php | 3 +- .../Normalizer/DateTimeNormalizerTest.php | 76 +++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php index be469a4d53..aaa4e8b940 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/DateTimeNormalizer.php @@ -59,7 +59,8 @@ class DateTimeNormalizer implements NormalizerInterface, DenormalizerInterface $timezone = $this->getTimezone($context); if (null !== $timezone) { - $object = (new \DateTimeImmutable('@'.$object->getTimestamp()))->setTimezone($timezone); + $object = clone $object; + $object = $object->setTimezone($timezone); } return $object->format($format); diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php index 178519b30e..99b224996c 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php @@ -78,6 +78,82 @@ class DateTimeNormalizerTest extends TestCase yield array('2016-12-01T09:00:00+09:00', new \DateTimeImmutable('2016/12/01', new \DateTimeZone('UTC')), new \DateTimeZone('Japan')); } + /** + * @dataProvider normalizeUsingTimeZonePassedInContextAndExpectedFormatWithMicrosecondsProvider + */ + public function testNormalizeUsingTimeZonePassedInContextAndFormattedWithMicroseconds($expected, $expectedFormat, $input, $timezone) + { + $this->assertSame( + $expected, + $this->normalizer->normalize( + $input, + null, + array( + DateTimeNormalizer::TIMEZONE_KEY => $timezone, + DateTimeNormalizer::FORMAT_KEY => $expectedFormat, + ) + ) + ); + } + + public function normalizeUsingTimeZonePassedInContextAndExpectedFormatWithMicrosecondsProvider() + { + yield array( + '2018-12-01T18:03:06.067634', + 'Y-m-d\TH:i:s.u', + \DateTime::createFromFormat( + 'Y-m-d\TH:i:s.u', + '2018-12-01T18:03:06.067634', + new \DateTimeZone('UTC') + ), + null, + ); + + yield array( + '2018-12-01T18:03:06.067634', + 'Y-m-d\TH:i:s.u', + \DateTime::createFromFormat( + 'Y-m-d\TH:i:s.u', + '2018-12-01T18:03:06.067634', + new \DateTimeZone('UTC') + ), + new \DateTimeZone('UTC'), + ); + + yield array( + '2018-12-01T19:03:06.067634+01:00', + 'Y-m-d\TH:i:s.uP', + \DateTimeImmutable::createFromFormat( + 'Y-m-d\TH:i:s.u', + '2018-12-01T18:03:06.067634', + new \DateTimeZone('UTC') + ), + new \DateTimeZone('Europe/Rome'), + ); + + yield array( + '2018-12-01T20:03:06.067634+02:00', + 'Y-m-d\TH:i:s.uP', + \DateTime::createFromFormat( + 'Y-m-d\TH:i:s.u', + '2018-12-01T18:03:06.067634', + new \DateTimeZone('UTC') + ), + new \DateTimeZone('Europe/Kiev'), + ); + + yield array( + '2018-12-01T21:03:06.067634', + 'Y-m-d\TH:i:s.u', + \DateTime::createFromFormat( + 'Y-m-d\TH:i:s.u', + '2018-12-01T18:03:06.067634', + new \DateTimeZone('UTC') + ), + new \DateTimeZone('Europe/Moscow'), + ); + } + /** * @expectedException \Symfony\Component\Serializer\Exception\InvalidArgumentException * @expectedExceptionMessage The object must implement the "\DateTimeInterface".