From f94b7aadd3b4f9cbd393feaa5dd24b248fd73d3a Mon Sep 17 00:00:00 2001 From: Sergey Yastrebov Date: Fri, 20 Apr 2018 13:19:35 +0300 Subject: [PATCH 01/59] fix rounding from string --- .../MoneyToLocalizedStringTransformerTest.php | 10 ++++++++++ .../Component/Intl/NumberFormatter/NumberFormatter.php | 1 + .../NumberFormatter/AbstractNumberFormatterTest.php | 7 +++++++ 3 files changed, 18 insertions(+) diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php index 1ad3aa1615c98..d9fafdff13a35 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php @@ -78,6 +78,16 @@ public function testFloatToIntConversionMismatchOnReversTransform() $transformer = new MoneyToLocalizedStringTransformer(null, null, null, 100); IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); + $this->assertSame(3655, (int) $transformer->reverseTransform('36,55')); } + + public function testFloatToIntConversionMismatchOnTransform() + { + $transformer = new MoneyToLocalizedStringTransformer(null, null, MoneyToLocalizedStringTransformer::ROUND_DOWN, 100); + IntlTestHelper::requireFullIntl($this, false); + \Locale::setDefault('de_AT'); + + $this->assertSame('10,20', $transformer->transform(1020)); + } } diff --git a/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php b/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php index f68a60143a747..4a9acb5be9ac9 100644 --- a/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php +++ b/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php @@ -708,6 +708,7 @@ private function round($value, $precision) } elseif (isset(self::$customRoundingList[$roundingModeAttribute])) { $roundingCoef = pow(10, $precision); $value *= $roundingCoef; + $value = (float) (string) $value; switch ($roundingModeAttribute) { case self::ROUND_CEILING: diff --git a/src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php b/src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php index 6c1cc569a3297..6d681f32248bc 100644 --- a/src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php +++ b/src/Symfony/Component/Intl/Tests/NumberFormatter/AbstractNumberFormatterTest.php @@ -428,6 +428,7 @@ public function formatRoundingModeRoundHalfUpProvider() // array(1.125, '1.13'), array(1.127, '1.13'), array(1.129, '1.13'), + array(1020 / 100, '10.20'), ); } @@ -451,6 +452,7 @@ public function formatRoundingModeRoundHalfDownProvider() array(1.125, '1.12'), array(1.127, '1.13'), array(1.129, '1.13'), + array(1020 / 100, '10.20'), ); } @@ -474,6 +476,7 @@ public function formatRoundingModeRoundHalfEvenProvider() array(1.125, '1.12'), array(1.127, '1.13'), array(1.129, '1.13'), + array(1020 / 100, '10.20'), ); } @@ -498,6 +501,7 @@ public function formatRoundingModeRoundCeilingProvider() array(-1.123, '-1.12'), array(-1.125, '-1.12'), array(-1.127, '-1.12'), + array(1020 / 100, '10.20'), ); } @@ -522,6 +526,7 @@ public function formatRoundingModeRoundFloorProvider() array(-1.123, '-1.13'), array(-1.125, '-1.13'), array(-1.127, '-1.13'), + array(1020 / 100, '10.20'), ); } @@ -546,6 +551,7 @@ public function formatRoundingModeRoundDownProvider() array(-1.123, '-1.12'), array(-1.125, '-1.12'), array(-1.127, '-1.12'), + array(1020 / 100, '10.20'), ); } @@ -570,6 +576,7 @@ public function formatRoundingModeRoundUpProvider() array(-1.123, '-1.13'), array(-1.125, '-1.13'), array(-1.127, '-1.13'), + array(1020 / 100, '10.20'), ); } From c121f7c6feb028eb112b4bef2bff0dcbca3b935b Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 30 Apr 2018 07:52:37 +0200 Subject: [PATCH 02/59] updated CHANGELOG for 2.8.39 --- CHANGELOG-2.8.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG-2.8.md b/CHANGELOG-2.8.md index e53256bdc8327..9b7d325c0e9dc 100644 --- a/CHANGELOG-2.8.md +++ b/CHANGELOG-2.8.md @@ -7,6 +7,23 @@ 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.39 (2018-04-30) + + * bug #27067 [HttpFoundation] Fix setting session-related ini settings (e-moe) + * bug #27016 [Security][Guard] GuardAuthenticationProvider::authenticate cannot return null (biomedia-thomas) + * bug #26831 [Bridge/Doctrine] count(): Parameter must be an array or an object that implements Countable (gpenverne) + * bug #27044 [Security] Skip user checks if not implementing UserInterface (chalasr) + * bug #26014 [Security] Fixed being logged out on failed attempt in guard (iltar) + * bug #26910 Use new PHP7.2 functions in hasColorSupport (johnstevenson) + * bug #26999 [VarDumper] Fix dumping of SplObjectStorage (corphi) + * bug #25841 [DoctrineBridge] Fix bug when indexBy is meta key in PropertyInfo\DoctrineExtractor (insekticid) + * bug #26886 Don't assume that file binary exists on *nix OS (teohhanhui) + * bug #26643 Fix that ESI/SSI processing can turn a "private" response "public" (mpdude) + * bug #26932 [Form] Fixed trimming choice values (HeahDude) + * bug #26875 [Console] Don't go past exact matches when autocompleting (nicolas-grekas) + * bug #26823 [Validator] Fix LazyLoadingMetadataFactory with PSR6Cache for non classname if tested values isn't existing class (Pascal Montoya, pmontoya) + * bug #26834 [Yaml] Throw parse error on unfinished inline map (nicolas-grekas) + * 2.8.38 (2018-04-06) * bug #26788 [Security] Load the user before pre/post auth checks when needed (chalasr) From 47bba5b935ad1794bc8f54b8e5255957c558c6e7 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 30 Apr 2018 07:52:51 +0200 Subject: [PATCH 03/59] updated VERSION for 2.8.39 --- 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 3193b61e8b18e..06f80811b05bb 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.39-DEV'; + const VERSION = '2.8.39'; const VERSION_ID = 20839; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; const RELEASE_VERSION = 39; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From 186353cb8b10f08febe904d85d0389a8c50a0212 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 30 Apr 2018 08:11:59 +0200 Subject: [PATCH 04/59] bumped Symfony version to 2.8.40 --- 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 06f80811b05bb..baeb200a6dd28 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.39'; - const VERSION_ID = 20839; + const VERSION = '2.8.40-DEV'; + const VERSION_ID = 20840; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; - const RELEASE_VERSION = 39; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 40; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From ffe9aaa166d686a38abccfe96b5279219ec81c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Fri, 27 Apr 2018 17:59:14 +0200 Subject: [PATCH 05/59] Added .github/CODEOWNERS refs https://help.github.com/articles/about-codeowners/ --- .github/CODEOWNERS | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000000..db1c2a8a6ff44 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,14 @@ +# LDAP +/src/Symfony/Component/Ldap/* @csarrazi +# Lock +/src/Symfony/Component/Lock/* @jderusse +# Messenger +/src/Symfony/Bridge/Doctrine/Messenger/* @sroze +/src/Symfony/Component/Messenger/* @sroze +# Workflow +/src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php @lyrixx +/src/Symfony/Bridge/Twig/Tests/Extension/WorkflowExtensionTest.php @lyrixx +/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php @lyrixx +/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ValidateWorkflowsPass.php @lyrixx +/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php @lyrixx +/src/Symfony/Component/Workflow/* @lyrixx From bbbafbad5cfaa8ddf3b39f31a3265d54cfdc554c Mon Sep 17 00:00:00 2001 From: Egidijus Gircys Date: Fri, 20 Apr 2018 15:16:14 +0200 Subject: [PATCH 06/59] Add CODE_OF_CONDUCT.md --- .github/CODE_OF_CONDUCT.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .github/CODE_OF_CONDUCT.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000000..16e2603b76a1d --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,8 @@ +# Code of Conduct + +This project follows a [Code of Conduct][code_of_conduct] in order to ensure an open and welcoming environment. +Please read the full text for understanding the accepted and unaccepted behavior. +Please read also the [reporting guidelines][guidelines], in case you encountered or witnessed any misbehavior. + +[code_of_conduct]: https://symfony.com/doc/current/contributing/code_of_conduct/index.html +[guidelines]: https://symfony.com/doc/current/contributing/code_of_conduct/reporting_guidelines.html From 21520b8a4a8187369c7f42fd07e374db88450550 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 30 Apr 2018 21:27:00 +0200 Subject: [PATCH 07/59] updated CHANGELOG for 3.4.9 --- CHANGELOG-3.4.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/CHANGELOG-3.4.md b/CHANGELOG-3.4.md index abc5e0a9f4da1..394f0eb4471f1 100644 --- a/CHANGELOG-3.4.md +++ b/CHANGELOG-3.4.md @@ -7,6 +7,42 @@ 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.9 (2018-04-30) + + * feature #24896 Add CODE_OF_CONDUCT.md (egircys) + * bug #27074 [Debug][WebProfilerBundle] Fix setting file link format (lyrixx, nicolas-grekas) + * bug #27088 ResolveBindingsPass: Don't throw error for unused service, missing parent class (weaverryan) + * bug #27086 [PHPUnitBridge] Add an implementation just for php 7.0 (greg0ire) + * bug #26138 [HttpKernel] Catch HttpExceptions when templating is not installed (cilefen) + * bug #27007 [Cache] TagAwareAdapterInterface::invalidateTags() should commit deferred items (nicolas-grekas) + * bug #27067 [HttpFoundation] Fix setting session-related ini settings (e-moe) + * bug #27061 [HttpKernel] Don't clean legacy containers that are still loaded (nicolas-grekas) + * bug #27064 [VarDumper] Fix HtmlDumper classes match (ogizanagi) + * bug #27016 [Security][Guard] GuardAuthenticationProvider::authenticate cannot return null (biomedia-thomas) + * bug #26831 [Bridge/Doctrine] count(): Parameter must be an array or an object that implements Countable (gpenverne) + * bug #27044 [Security] Skip user checks if not implementing UserInterface (chalasr) + * bug #27025 [DI] Add check of internal type to ContainerBuilder::getReflectionClass (upyx) + * bug #26994 [PhpUnitBridge] Add type hints (greg0ire) + * bug #26014 [Security] Fixed being logged out on failed attempt in guard (iltar) + * bug #25348 [HttpFoundation] Send cookies using header() to fix "SameSite" ones (nicolas-grekas, cvilleger) + * bug #26910 Use new PHP7.2 functions in hasColorSupport (johnstevenson) + * bug #26999 [VarDumper] Fix dumping of SplObjectStorage (corphi) + * bug #25841 [DoctrineBridge] Fix bug when indexBy is meta key in PropertyInfo\DoctrineExtractor (insekticid) + * bug #26983 [TwigBridge] [Bootstrap 4] Fix PercentType error rendering. (alexismarquis) + * bug #26980 [TwigBundle] fix formatting arguments in plaintext format (xabbuh) + * bug #26886 Don't assume that file binary exists on *nix OS (teohhanhui) + * bug #26959 [Console] Fix PSR exception context key (scaytrase) + * bug #26899 [Routing] Fix loading multiple class annotations for invokable classes (1ed) + * bug #26643 Fix that ESI/SSI processing can turn a "private" response "public" (mpdude) + * bug #26932 [Form] Fixed trimming choice values (HeahDude) + * bug #26922 [TwigBundle] fix rendering exception stack traces (xabbuh) + * bug #26773 [HttpKernel] Make ServiceValueResolver work if controller namespace starts with a backslash in routing (mathieutu) + * bug #26870 Add d-block to bootstrap 4 alerts (Normunds) + * bug #26857 [HttpKernel] Dont create mock cookie for new sessions in tests (nicolas-grekas) + * bug #26875 [Console] Don't go past exact matches when autocompleting (nicolas-grekas) + * bug #26823 [Validator] Fix LazyLoadingMetadataFactory with PSR6Cache for non classname if tested values isn't existing class (Pascal Montoya, pmontoya) + * bug #26834 [Yaml] Throw parse error on unfinished inline map (nicolas-grekas) + * 3.4.8 (2018-04-06) * bug #26802 [Security] register custom providers on ExpressionLanguage directly (dmaicher) From c7d277e64f4682470d018ec6cd1e8cfaaac83424 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 30 Apr 2018 21:27:02 +0200 Subject: [PATCH 08/59] updated VERSION for 3.4.9 --- 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 247bea208af8e..f584242a16f1e 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.9-DEV'; + const VERSION = '3.4.9'; const VERSION_ID = 30409; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; const RELEASE_VERSION = 9; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From 1f98e31da2e96eb2363031565334b8fbf43a3d0a Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 30 Apr 2018 21:44:07 +0200 Subject: [PATCH 09/59] bumped Symfony version to 3.4.10 --- 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 f584242a16f1e..f54d3589f7dfb 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.9'; - const VERSION_ID = 30409; + const VERSION = '3.4.10-DEV'; + const VERSION_ID = 30410; const MAJOR_VERSION = 3; const MINOR_VERSION = 4; - const RELEASE_VERSION = 9; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 10; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2020'; const END_OF_LIFE = '11/2021'; From 7ab4e4b78261493019b1d8075857470980c7f3b3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 30 Apr 2018 22:02:13 +0200 Subject: [PATCH 10/59] bumped Symfony version to 4.0.10 --- 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 24cce648ef443..7a8b3cdf4b199 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.9'; - const VERSION_ID = 40009; + const VERSION = '4.0.10-DEV'; + const VERSION_ID = 40010; const MAJOR_VERSION = 4; const MINOR_VERSION = 0; - const RELEASE_VERSION = 9; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 10; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '07/2018'; const END_OF_LIFE = '01/2019'; From 27fddf5927ae59bac89ee4522ba5d795cfc4c627 Mon Sep 17 00:00:00 2001 From: Hugo Hamon Date: Tue, 1 May 2018 14:10:15 +0200 Subject: [PATCH 11/59] [Form] fixes instance variable phpdoc in FormRegistry class --- src/Symfony/Component/Form/FormRegistry.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/FormRegistry.php b/src/Symfony/Component/Form/FormRegistry.php index 70b0c78e6cfa5..c4bfb0e303c53 100644 --- a/src/Symfony/Component/Form/FormRegistry.php +++ b/src/Symfony/Component/Form/FormRegistry.php @@ -30,7 +30,7 @@ class FormRegistry implements FormRegistryInterface private $extensions = array(); /** - * @var FormTypeInterface[] + * @var ResolvedFormTypeInterface[] */ private $types = array(); From afc09cc8a797b6ad2f1f729a9523b0e6583b42da Mon Sep 17 00:00:00 2001 From: Gert de Pagter Date: Tue, 1 May 2018 20:24:18 +0200 Subject: [PATCH 12/59] Use symfony/polyfill-ctype Use the polyfill for every package that uses cytpe functions. --- composer.json | 1 + src/Symfony/Bridge/Doctrine/composer.json | 3 ++- src/Symfony/Bundle/TwigBundle/composer.json | 3 ++- src/Symfony/Component/Config/composer.json | 3 ++- src/Symfony/Component/DomCrawler/composer.json | 3 ++- src/Symfony/Component/ExpressionLanguage/composer.json | 3 ++- src/Symfony/Component/Filesystem/composer.json | 3 ++- src/Symfony/Component/Form/composer.json | 1 + src/Symfony/Component/HttpKernel/composer.json | 1 + src/Symfony/Component/Intl/composer.json | 3 ++- src/Symfony/Component/PropertyAccess/composer.json | 3 ++- src/Symfony/Component/Security/Csrf/composer.json | 3 ++- src/Symfony/Component/Serializer/composer.json | 3 ++- src/Symfony/Component/Templating/composer.json | 3 ++- src/Symfony/Component/Validator/composer.json | 1 + src/Symfony/Component/Yaml/composer.json | 3 ++- 16 files changed, 28 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index f263c15d45324..350ea8cce2185 100644 --- a/composer.json +++ b/composer.json @@ -21,6 +21,7 @@ "doctrine/common": "~2.4", "paragonie/random_compat": "~1.0", "symfony/polyfill-apcu": "~1.1", + "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.1", "twig/twig": "~1.34|~2.4", "psr/log": "~1.0" diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index e9dda5f59ae43..cd0794f3e4fbc 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": ">=5.3.9", - "doctrine/common": "~2.4" + "doctrine/common": "~2.4", + "symfony/polyfill-ctype": "~1.8" }, "require-dev": { "symfony/stopwatch": "~2.2", diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index cd2f229e4ff88..d5b85177bcc56 100644 --- a/src/Symfony/Bundle/TwigBundle/composer.json +++ b/src/Symfony/Bundle/TwigBundle/composer.json @@ -21,7 +21,8 @@ "symfony/twig-bridge": "~2.7", "twig/twig": "~1.34|~2.4", "symfony/http-foundation": "~2.5", - "symfony/http-kernel": "~2.7.23|^2.8.16" + "symfony/http-kernel": "~2.7.23|^2.8.16", + "symfony/polyfill-ctype": "~1.8" }, "require-dev": { "symfony/stopwatch": "~2.2", diff --git a/src/Symfony/Component/Config/composer.json b/src/Symfony/Component/Config/composer.json index 47f8642ae6dbc..2027e190c8d44 100644 --- a/src/Symfony/Component/Config/composer.json +++ b/src/Symfony/Component/Config/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": ">=5.3.9", - "symfony/filesystem": "~2.3" + "symfony/filesystem": "~2.3", + "symfony/polyfill-ctype": "~1.8" }, "require-dev": { "symfony/yaml": "~2.7" diff --git a/src/Symfony/Component/DomCrawler/composer.json b/src/Symfony/Component/DomCrawler/composer.json index 5ea57b2657041..068f8390ed922 100644 --- a/src/Symfony/Component/DomCrawler/composer.json +++ b/src/Symfony/Component/DomCrawler/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" }, "require-dev": { "symfony/css-selector": "~2.3" diff --git a/src/Symfony/Component/ExpressionLanguage/composer.json b/src/Symfony/Component/ExpressionLanguage/composer.json index 5bff703b0ebec..9d4d693812566 100644 --- a/src/Symfony/Component/ExpressionLanguage/composer.json +++ b/src/Symfony/Component/ExpressionLanguage/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" }, "autoload": { "psr-4": { "Symfony\\Component\\ExpressionLanguage\\": "" }, diff --git a/src/Symfony/Component/Filesystem/composer.json b/src/Symfony/Component/Filesystem/composer.json index 20a13bbd92b0d..e1783a7f10247 100644 --- a/src/Symfony/Component/Filesystem/composer.json +++ b/src/Symfony/Component/Filesystem/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" }, "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" }, diff --git a/src/Symfony/Component/Form/composer.json b/src/Symfony/Component/Form/composer.json index 5b3af06994b82..67441c9ec9804 100644 --- a/src/Symfony/Component/Form/composer.json +++ b/src/Symfony/Component/Form/composer.json @@ -20,6 +20,7 @@ "symfony/event-dispatcher": "~2.1", "symfony/intl": "~2.7.25|^2.8.18", "symfony/options-resolver": "~2.6", + "symfony/polyfill-ctype": "~1.8", "symfony/property-access": "~2.3" }, "require-dev": { diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index 1b6b096a8a61f..6986945497ebf 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -20,6 +20,7 @@ "symfony/event-dispatcher": "^2.6.7", "symfony/http-foundation": "~2.7.36|^2.8.29", "symfony/debug": "^2.6.2", + "symfony/polyfill-ctype": "~1.8", "psr/log": "~1.0" }, "require-dev": { diff --git a/src/Symfony/Component/Intl/composer.json b/src/Symfony/Component/Intl/composer.json index 2310fbb396c00..cc9ac80f55a1d 100644 --- a/src/Symfony/Component/Intl/composer.json +++ b/src/Symfony/Component/Intl/composer.json @@ -24,7 +24,8 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" }, "require-dev": { "symfony/filesystem": "~2.1" diff --git a/src/Symfony/Component/PropertyAccess/composer.json b/src/Symfony/Component/PropertyAccess/composer.json index c02990a198a15..8e881763efcf8 100644 --- a/src/Symfony/Component/PropertyAccess/composer.json +++ b/src/Symfony/Component/PropertyAccess/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" }, "autoload": { "psr-4": { "Symfony\\Component\\PropertyAccess\\": "" }, diff --git a/src/Symfony/Component/Security/Csrf/composer.json b/src/Symfony/Component/Security/Csrf/composer.json index 4f6ee250c0d38..1fb4bcbf6819a 100644 --- a/src/Symfony/Component/Security/Csrf/composer.json +++ b/src/Symfony/Component/Security/Csrf/composer.json @@ -20,7 +20,8 @@ "symfony/security-core": "~2.4" }, "require-dev": { - "symfony/http-foundation": "~2.7" + "symfony/http-foundation": "~2.7", + "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/http-foundation": "<2.7.38|~2.8,<2.8.31" diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json index bcacfbc7549e9..e1bde54956281 100644 --- a/src/Symfony/Component/Serializer/composer.json +++ b/src/Symfony/Component/Serializer/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" }, "require-dev": { "symfony/yaml": "^2.0.5", diff --git a/src/Symfony/Component/Templating/composer.json b/src/Symfony/Component/Templating/composer.json index 334909c1a3a67..5ccb27c1028b4 100644 --- a/src/Symfony/Component/Templating/composer.json +++ b/src/Symfony/Component/Templating/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" }, "require-dev": { "psr/log": "~1.0" diff --git a/src/Symfony/Component/Validator/composer.json b/src/Symfony/Component/Validator/composer.json index e6db2e6907f0e..7fe92bae77c71 100644 --- a/src/Symfony/Component/Validator/composer.json +++ b/src/Symfony/Component/Validator/composer.json @@ -17,6 +17,7 @@ ], "require": { "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8", "symfony/translation": "~2.4" }, "require-dev": { diff --git a/src/Symfony/Component/Yaml/composer.json b/src/Symfony/Component/Yaml/composer.json index 03eb421d294fc..eeab73c355d15 100644 --- a/src/Symfony/Component/Yaml/composer.json +++ b/src/Symfony/Component/Yaml/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" }, "autoload": { "psr-4": { "Symfony\\Component\\Yaml\\": "" }, From d2c58132395d2e0aa33dfbbc45dd96324df26fd0 Mon Sep 17 00:00:00 2001 From: Hugo Hamon Date: Wed, 2 May 2018 00:36:56 +0200 Subject: [PATCH 13/59] [Validator] fixes phpdoc reference to an interface that was removed in Symfony 3.0 --- src/Symfony/Component/Validator/ObjectInitializerInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/ObjectInitializerInterface.php b/src/Symfony/Component/Validator/ObjectInitializerInterface.php index dcbc2cd11dbdd..1bd55f0cda8e7 100644 --- a/src/Symfony/Component/Validator/ObjectInitializerInterface.php +++ b/src/Symfony/Component/Validator/ObjectInitializerInterface.php @@ -14,7 +14,7 @@ /** * Prepares an object for validation. * - * Concrete implementations of this interface are used by {@link ValidationVisitorInterface} + * Concrete implementations of this interface are used by {@link Validator\ContextualValidatorInterface} * to initialize objects just before validating them. * * @author Fabien Potencier From 30970c7a9b475c888f65980347df98cbe5c3fc94 Mon Sep 17 00:00:00 2001 From: Hugo Hamon Date: Wed, 2 May 2018 00:50:12 +0200 Subject: [PATCH 14/59] [Validator] make phpdoc of ObjectInitializerInterface interface more accurate --- src/Symfony/Component/Validator/ObjectInitializerInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/ObjectInitializerInterface.php b/src/Symfony/Component/Validator/ObjectInitializerInterface.php index dcbc2cd11dbdd..5f9cdad879632 100644 --- a/src/Symfony/Component/Validator/ObjectInitializerInterface.php +++ b/src/Symfony/Component/Validator/ObjectInitializerInterface.php @@ -15,7 +15,7 @@ * Prepares an object for validation. * * Concrete implementations of this interface are used by {@link ValidationVisitorInterface} - * to initialize objects just before validating them. + * and {@link Validator\ContextualValidatorInterface} to initialize objects just before validating them. * * @author Fabien Potencier * @author Bernhard Schussek From 046f0920c08c6777df97be296bf5e0efbb08aa82 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 1 May 2018 15:50:35 -0700 Subject: [PATCH 15/59] Remove symfony/polyfill-ctype where not needed --- src/Symfony/Component/ExpressionLanguage/composer.json | 3 +-- src/Symfony/Component/Intl/composer.json | 3 +-- src/Symfony/Component/Security/Csrf/composer.json | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/ExpressionLanguage/composer.json b/src/Symfony/Component/ExpressionLanguage/composer.json index 9d4d693812566..5bff703b0ebec 100644 --- a/src/Symfony/Component/ExpressionLanguage/composer.json +++ b/src/Symfony/Component/ExpressionLanguage/composer.json @@ -16,8 +16,7 @@ } ], "require": { - "php": ">=5.3.9", - "symfony/polyfill-ctype": "~1.8" + "php": ">=5.3.9" }, "autoload": { "psr-4": { "Symfony\\Component\\ExpressionLanguage\\": "" }, diff --git a/src/Symfony/Component/Intl/composer.json b/src/Symfony/Component/Intl/composer.json index cc9ac80f55a1d..2310fbb396c00 100644 --- a/src/Symfony/Component/Intl/composer.json +++ b/src/Symfony/Component/Intl/composer.json @@ -24,8 +24,7 @@ } ], "require": { - "php": ">=5.3.9", - "symfony/polyfill-ctype": "~1.8" + "php": ">=5.3.9" }, "require-dev": { "symfony/filesystem": "~2.1" diff --git a/src/Symfony/Component/Security/Csrf/composer.json b/src/Symfony/Component/Security/Csrf/composer.json index 1fb4bcbf6819a..4f6ee250c0d38 100644 --- a/src/Symfony/Component/Security/Csrf/composer.json +++ b/src/Symfony/Component/Security/Csrf/composer.json @@ -20,8 +20,7 @@ "symfony/security-core": "~2.4" }, "require-dev": { - "symfony/http-foundation": "~2.7", - "symfony/polyfill-ctype": "~1.8" + "symfony/http-foundation": "~2.7" }, "conflict": { "symfony/http-foundation": "<2.7.38|~2.8,<2.8.31" From b3ac93829a12032c8deb2175f05decfd627762ed Mon Sep 17 00:00:00 2001 From: David Maicher Date: Thu, 3 May 2018 09:30:44 +0200 Subject: [PATCH 16/59] [Doctrine Bridge] fix priority for doctrine event listeners --- ...gisterEventListenersAndSubscribersPass.php | 146 ++++++++--------- ...erEventListenersAndSubscribersPassTest.php | 155 ++++++++++++++---- 2 files changed, 194 insertions(+), 107 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php index e7015fd1e4119..3ffd924e519e3 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php @@ -11,22 +11,22 @@ namespace Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Reference; /** * Registers event listeners and subscribers to the available doctrine connections. * * @author Jeremy Mikola * @author Alexander + * @author David Maicher */ class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface { private $connections; - private $container; private $eventManagers; private $managerTemplate; private $tagPrefix; @@ -53,97 +53,97 @@ public function process(ContainerBuilder $container) return; } - $taggedSubscribers = $container->findTaggedServiceIds($this->tagPrefix.'.event_subscriber', true); - $taggedListeners = $container->findTaggedServiceIds($this->tagPrefix.'.event_listener', true); - - if (empty($taggedSubscribers) && empty($taggedListeners)) { - return; - } - - $this->container = $container; $this->connections = $container->getParameter($this->connections); - $sortFunc = function ($a, $b) { - $a = isset($a['priority']) ? $a['priority'] : 0; - $b = isset($b['priority']) ? $b['priority'] : 0; - - return $a > $b ? -1 : 1; - }; - - if (!empty($taggedSubscribers)) { - $subscribersPerCon = $this->groupByConnection($taggedSubscribers); - foreach ($subscribersPerCon as $con => $subscribers) { - $em = $this->getEventManager($con); + $this->addTaggedSubscribers($container); + $this->addTaggedListeners($container); + } - uasort($subscribers, $sortFunc); - foreach ($subscribers as $id => $instance) { - $em->addMethodCall('addEventSubscriber', array(new Reference($id))); + private function addTaggedSubscribers(ContainerBuilder $container) + { + $subscriberTag = $this->tagPrefix.'.event_subscriber'; + $taggedSubscribers = $this->findAndSortTags($subscriberTag, $container); + + foreach ($taggedSubscribers as $taggedSubscriber) { + list($id, $tag) = $taggedSubscriber; + $connections = isset($tag['connection']) ? array($tag['connection']) : array_keys($this->connections); + foreach ($connections as $con) { + if (!isset($this->connections[$con])) { + throw new RuntimeException(sprintf('The Doctrine connection "%s" referenced in service "%s" does not exist. Available connections names: %s', $con, $taggedSubscriber, implode(', ', array_keys($this->connections)))); } - } - } - if (!empty($taggedListeners)) { - $listenersPerCon = $this->groupByConnection($taggedListeners, true); - foreach ($listenersPerCon as $con => $listeners) { - $em = $this->getEventManager($con); - - uasort($listeners, $sortFunc); - foreach ($listeners as $id => $instance) { - $em->addMethodCall('addEventListener', array( - array_unique($instance['event']), - isset($instance['lazy']) && $instance['lazy'] ? $id : new Reference($id), - )); - } + $this->getEventManagerDef($container, $con)->addMethodCall('addEventSubscriber', array(new Reference($id))); } } } - private function groupByConnection(array $services, $isListener = false) + private function addTaggedListeners(ContainerBuilder $container) { - $grouped = array(); - foreach ($allCons = array_keys($this->connections) as $con) { - $grouped[$con] = array(); - } + $listenerTag = $this->tagPrefix.'.event_listener'; + $taggedListeners = $this->findAndSortTags($listenerTag, $container); + + foreach ($taggedListeners as $taggedListener) { + list($id, $tag) = $taggedListener; + $taggedListenerDef = $container->getDefinition($id); + if (!isset($tag['event'])) { + throw new InvalidArgumentException(sprintf('Doctrine event listener "%s" must specify the "event" attribute.', $id)); + } - foreach ($services as $id => $instances) { - foreach ($instances as $instance) { - if ($isListener) { - if (!isset($instance['event'])) { - throw new InvalidArgumentException(sprintf('Doctrine event listener "%s" must specify the "event" attribute.', $id)); - } - $instance['event'] = array($instance['event']); - - if (!empty($instance['lazy'])) { - $this->container->getDefinition($id)->setPublic(true); - } + $connections = isset($tag['connection']) ? array($tag['connection']) : array_keys($this->connections); + foreach ($connections as $con) { + if (!isset($this->connections[$con])) { + throw new RuntimeException(sprintf('The Doctrine connection "%s" referenced in service "%s" does not exist. Available connections names: %s', $con, $id, implode(', ', array_keys($this->connections)))); } - $cons = isset($instance['connection']) ? array($instance['connection']) : $allCons; - foreach ($cons as $con) { - if (!isset($grouped[$con])) { - throw new RuntimeException(sprintf('The Doctrine connection "%s" referenced in service "%s" does not exist. Available connections names: %s', $con, $id, implode(', ', array_keys($this->connections)))); - } - - if ($isListener && isset($grouped[$con][$id])) { - $grouped[$con][$id]['event'] = array_merge($grouped[$con][$id]['event'], $instance['event']); - } else { - $grouped[$con][$id] = $instance; - } + if ($lazy = !empty($tag['lazy'])) { + $taggedListenerDef->setPublic(true); } + + // we add one call per event per service so we have the correct order + $this->getEventManagerDef($container, $con)->addMethodCall('addEventListener', array(array($tag['event']), $lazy ? $id : new Reference($id))); } } + } + + private function getEventManagerDef(ContainerBuilder $container, $name) + { + if (!isset($this->eventManagers[$name])) { + $this->eventManagers[$name] = $container->getDefinition(sprintf($this->managerTemplate, $name)); + } - return $grouped; + return $this->eventManagers[$name]; } - private function getEventManager($name) + /** + * Finds and orders all service tags with the given name by their priority. + * + * The order of additions must be respected for services having the same priority, + * and knowing that the \SplPriorityQueue class does not respect the FIFO method, + * we should not use this class. + * + * @see https://bugs.php.net/bug.php?id=53710 + * @see https://bugs.php.net/bug.php?id=60926 + * + * @param string $tagName + * @param ContainerBuilder $container + * + * @return array + */ + private function findAndSortTags($tagName, ContainerBuilder $container) { - if (null === $this->eventManagers) { - $this->eventManagers = array(); - foreach ($this->connections as $n => $id) { - $this->eventManagers[$n] = $this->container->getDefinition(sprintf($this->managerTemplate, $n)); + $sortedTags = array(); + + foreach ($container->findTaggedServiceIds($tagName, true) as $serviceId => $tags) { + foreach ($tags as $attributes) { + $priority = isset($attributes['priority']) ? $attributes['priority'] : 0; + $sortedTags[$priority][] = array($serviceId, $attributes); } } - return $this->eventManagers[$name]; + if ($sortedTags) { + krsort($sortedTags); + $sortedTags = call_user_func_array('array_merge', $sortedTags); + } + + return $sortedTags; } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPassTest.php b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPassTest.php index 25776f86695af..7e99a7d9356c2 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPassTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPassTest.php @@ -15,6 +15,7 @@ use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; class RegisterEventListenersAndSubscribersPassTest extends TestCase { @@ -56,12 +57,18 @@ public function testProcessEventListenersWithPriorities() $container ->register('a', 'stdClass') + ->setPublic(false) + ->addTag('doctrine.event_listener', array( + 'event' => 'bar', + )) ->addTag('doctrine.event_listener', array( 'event' => 'foo', 'priority' => -5, )) ->addTag('doctrine.event_listener', array( - 'event' => 'bar', + 'event' => 'foo_bar', + 'priority' => 3, + 'lazy' => true, )) ; $container @@ -70,12 +77,34 @@ public function testProcessEventListenersWithPriorities() 'event' => 'foo', )) ; + $container + ->register('c', 'stdClass') + ->addTag('doctrine.event_listener', array( + 'event' => 'foo_bar', + 'priority' => 4, + )) + ; $this->process($container); - $this->assertEquals(array('b', 'a'), $this->getServiceOrder($container, 'addEventListener')); - - $calls = $container->getDefinition('doctrine.dbal.default_connection.event_manager')->getMethodCalls(); - $this->assertEquals(array('foo', 'bar'), $calls[1][1][0]); + $methodCalls = $container->getDefinition('doctrine.dbal.default_connection.event_manager')->getMethodCalls(); + + $this->assertEquals( + array( + array('addEventListener', array(array('foo_bar'), new Reference('c'))), + array('addEventListener', array(array('foo_bar'), new Reference('a'))), + array('addEventListener', array(array('bar'), new Reference('a'))), + array('addEventListener', array(array('foo'), new Reference('b'))), + array('addEventListener', array(array('foo'), new Reference('a'))), + ), + $methodCalls + ); + + // not lazy so must be reference + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Reference', $methodCalls[0][1][1]); + + // lazy so id instead of reference and must mark service public + $this->assertSame('a', $methodCalls[1][1][1]); + $this->assertTrue($container->getDefinition('a')->isPublic()); } public function testProcessEventListenersWithMultipleConnections() @@ -88,15 +117,86 @@ public function testProcessEventListenersWithMultipleConnections() 'event' => 'onFlush', )) ; + + $container + ->register('b', 'stdClass') + ->addTag('doctrine.event_listener', array( + 'event' => 'onFlush', + 'connection' => 'default', + )) + ; + + $container + ->register('c', 'stdClass') + ->addTag('doctrine.event_listener', array( + 'event' => 'onFlush', + 'connection' => 'second', + )) + ; + $this->process($container); - $callsDefault = $container->getDefinition('doctrine.dbal.default_connection.event_manager')->getMethodCalls(); + $this->assertEquals( + array( + array('addEventListener', array(array('onFlush'), new Reference('a'))), + array('addEventListener', array(array('onFlush'), new Reference('b'))), + ), + $container->getDefinition('doctrine.dbal.default_connection.event_manager')->getMethodCalls() + ); + + $this->assertEquals( + array( + array('addEventListener', array(array('onFlush'), new Reference('a'))), + array('addEventListener', array(array('onFlush'), new Reference('c'))), + ), + $container->getDefinition('doctrine.dbal.second_connection.event_manager')->getMethodCalls() + ); + } - $this->assertEquals('addEventListener', $callsDefault[0][0]); - $this->assertEquals(array('onFlush'), $callsDefault[0][1][0]); + public function testProcessEventSubscribersWithMultipleConnections() + { + $container = $this->createBuilder(true); - $callsSecond = $container->getDefinition('doctrine.dbal.second_connection.event_manager')->getMethodCalls(); - $this->assertEquals($callsDefault, $callsSecond); + $container + ->register('a', 'stdClass') + ->addTag('doctrine.event_subscriber', array( + 'event' => 'onFlush', + )) + ; + + $container + ->register('b', 'stdClass') + ->addTag('doctrine.event_subscriber', array( + 'event' => 'onFlush', + 'connection' => 'default', + )) + ; + + $container + ->register('c', 'stdClass') + ->addTag('doctrine.event_subscriber', array( + 'event' => 'onFlush', + 'connection' => 'second', + )) + ; + + $this->process($container); + + $this->assertEquals( + array( + array('addEventSubscriber', array(new Reference('a'))), + array('addEventSubscriber', array(new Reference('b'))), + ), + $container->getDefinition('doctrine.dbal.default_connection.event_manager')->getMethodCalls() + ); + + $this->assertEquals( + array( + array('addEventSubscriber', array(new Reference('a'))), + array('addEventSubscriber', array(new Reference('c'))), + ), + $container->getDefinition('doctrine.dbal.second_connection.event_manager')->getMethodCalls() + ); } public function testProcessEventSubscribersWithPriorities() @@ -133,11 +233,17 @@ public function testProcessEventSubscribersWithPriorities() ; $this->process($container); - $serviceOrder = $this->getServiceOrder($container, 'addEventSubscriber'); - $unordered = array_splice($serviceOrder, 0, 3); - sort($unordered); - $this->assertEquals(array('c', 'd', 'e'), $unordered); - $this->assertEquals(array('b', 'a'), $serviceOrder); + + $this->assertEquals( + array( + array('addEventSubscriber', array(new Reference('c'))), + array('addEventSubscriber', array(new Reference('d'))), + array('addEventSubscriber', array(new Reference('e'))), + array('addEventSubscriber', array(new Reference('b'))), + array('addEventSubscriber', array(new Reference('a'))), + ), + $container->getDefinition('doctrine.dbal.default_connection.event_manager')->getMethodCalls() + ); } public function testProcessNoTaggedServices() @@ -157,25 +263,6 @@ private function process(ContainerBuilder $container) $pass->process($container); } - private function getServiceOrder(ContainerBuilder $container, $method) - { - $order = array(); - foreach ($container->getDefinition('doctrine.dbal.default_connection.event_manager')->getMethodCalls() as list($name, $arguments)) { - if ($method !== $name) { - continue; - } - - if ('addEventListener' === $name) { - $order[] = (string) $arguments[1]; - continue; - } - - $order[] = (string) $arguments[0]; - } - - return $order; - } - private function createBuilder($multipleConnections = false) { $container = new ContainerBuilder(); From 34f136e01b9f3246f4d8debca0153d9df143761c Mon Sep 17 00:00:00 2001 From: Ben Johnson Date: Thu, 3 May 2018 12:50:56 -0400 Subject: [PATCH 17/59] Suppress warnings when open_basedir is non-empty If PHP is configured *with a non-empty open_basedir* value that does not permit access to the target location, these calls to is_executable() throw warnings. While Symfony may not raise exceptions for warnings in production environments, other frameworks (such as Laravel) do, in which case any of these checks causes a show-stopping 500 error. We fixed a similar issue in the ExecutableFinder class via symfony/symfony#16182 . This has always been an issue, but 709e15e7a37cb7ed6199548dc70dc33168e6cb2d made it more likely that a warning is triggered. --- src/Symfony/Component/Process/PhpExecutableFinder.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Process/PhpExecutableFinder.php b/src/Symfony/Component/Process/PhpExecutableFinder.php index f5c97d6bb9f8f..2a0b7a0268d7f 100644 --- a/src/Symfony/Component/Process/PhpExecutableFinder.php +++ b/src/Symfony/Component/Process/PhpExecutableFinder.php @@ -49,7 +49,7 @@ public function find($includeArgs = true) } if ($php = getenv('PHP_PATH')) { - if (!is_executable($php)) { + if (@!is_executable($php)) { return false; } @@ -57,12 +57,12 @@ public function find($includeArgs = true) } if ($php = getenv('PHP_PEAR_PHP_BIN')) { - if (is_executable($php)) { + if (@is_executable($php)) { return $php; } } - if (is_executable($php = PHP_BINDIR.('\\' === DIRECTORY_SEPARATOR ? '\\php.exe' : '/php'))) { + if (@is_executable($php = PHP_BINDIR.('\\' === DIRECTORY_SEPARATOR ? '\\php.exe' : '/php'))) { return $php; } From 11f3c455d4b2949c4a04f4e34e709a9adaf01b64 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Thu, 3 May 2018 19:18:14 -0400 Subject: [PATCH 18/59] Hide short exception trace by default --- src/Symfony/Bridge/Twig/Command/LintCommand.php | 8 +++++--- .../FrameworkBundle/Command/AbstractConfigCommand.php | 3 ++- .../FrameworkBundle/Command/AssetsInstallCommand.php | 3 ++- .../Bundle/FrameworkBundle/Command/CacheClearCommand.php | 3 ++- .../FrameworkBundle/Command/CachePoolClearCommand.php | 3 ++- .../Command/ConfigDumpReferenceCommand.php | 3 ++- .../FrameworkBundle/Command/ContainerDebugCommand.php | 7 ++++--- .../Bundle/FrameworkBundle/Command/RouterDebugCommand.php | 3 ++- .../FrameworkBundle/Command/TranslationDebugCommand.php | 3 ++- .../FrameworkBundle/Command/TranslationUpdateCommand.php | 3 ++- .../FrameworkBundle/Command/WorkflowDumpCommand.php | 3 ++- .../Bundle/SecurityBundle/Command/SetAclCommand.php | 5 +++-- .../SecurityBundle/Command/UserPasswordEncoderCommand.php | 6 ++++-- .../Bundle/WebServerBundle/Command/ServerLogCommand.php | 6 ++++-- .../WebServerBundle/Command/ServerStatusCommand.php | 3 ++- .../Component/Translation/Command/XliffLintCommand.php | 7 ++++--- src/Symfony/Component/Yaml/Command/LintCommand.php | 8 +++++--- 17 files changed, 49 insertions(+), 28 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Command/LintCommand.php b/src/Symfony/Bridge/Twig/Command/LintCommand.php index afb1d1bf31cf2..24630012188b1 100644 --- a/src/Symfony/Bridge/Twig/Command/LintCommand.php +++ b/src/Symfony/Bridge/Twig/Command/LintCommand.php @@ -12,6 +12,8 @@ namespace Symfony\Bridge\Twig\Command; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -119,7 +121,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if (0 === count($filenames)) { if (0 !== ftell(STDIN)) { - throw new \RuntimeException('Please provide a filename or pipe template content to STDIN.'); + throw new RuntimeException('Please provide a filename or pipe template content to STDIN.'); } $template = ''; @@ -155,7 +157,7 @@ protected function findFiles($filename) return Finder::create()->files()->in($filename)->name('*.twig'); } - throw new \RuntimeException(sprintf('File or directory "%s" is not readable', $filename)); + throw new RuntimeException(sprintf('File or directory "%s" is not readable', $filename)); } private function validate($template, $file) @@ -184,7 +186,7 @@ private function display(InputInterface $input, OutputInterface $output, Symfony case 'json': return $this->displayJson($output, $files); default: - throw new \InvalidArgumentException(sprintf('The format "%s" is not supported.', $input->getOption('format'))); + throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $input->getOption('format'))); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AbstractConfigCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AbstractConfigCommand.php index 5244b7ef331e5..edd3e64556622 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AbstractConfigCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AbstractConfigCommand.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\FrameworkBundle\Command; use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\Console\Exception\LogicException; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Style\StyleInterface; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; @@ -98,7 +99,7 @@ protected function findExtension($name) $message .= sprintf("\n\nDid you mean \"%s\"?", $guess); } - throw new \LogicException($message); + throw new LogicException($message); } public function validateConfiguration(ExtensionInterface $extension, $configuration) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php index 4aaf847ff453a..81477bab1c3cc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\Command; +use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -115,7 +116,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if (is_dir(dirname($targetArg).'/web')) { $targetArg = dirname($targetArg).'/web'; } else { - throw new \InvalidArgumentException(sprintf('The target directory "%s" does not exist.', $input->getArgument('target'))); + throw new InvalidArgumentException(sprintf('The target directory "%s" does not exist.', $input->getArgument('target'))); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php index 9c77853101534..bbb71c15dd92a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\Command; +use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -104,7 +105,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $fs->remove($oldCacheDir); if (!is_writable($realCacheDir)) { - throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $realCacheDir)); + throw new RuntimeException(sprintf('Unable to write in the "%s" directory', $realCacheDir)); } $io->comment(sprintf('Clearing the cache for the %s environment with debug %s', $kernel->getEnvironment(), var_export($kernel->isDebug(), true))); diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolClearCommand.php index 24ab64cc9c696..93a41f14bd047 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolClearCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CachePoolClearCommand.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\FrameworkBundle\Command; use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Output\OutputInterface; @@ -93,7 +94,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } elseif ($pool instanceof Psr6CacheClearer) { $clearers[$id] = $pool; } else { - throw new \InvalidArgumentException(sprintf('"%s" is not a cache pool nor a cache clearer.', $id)); + throw new InvalidArgumentException(sprintf('"%s" is not a cache pool nor a cache clearer.', $id)); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php index 06900cc2c40e5..47b04409bee27 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php @@ -13,6 +13,7 @@ use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper; use Symfony\Component\Config\Definition\Dumper\XmlReferenceDumper; +use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; @@ -124,7 +125,7 @@ protected function execute(InputInterface $input, OutputInterface $output) break; default: $io->writeln($message); - throw new \InvalidArgumentException('Only the yaml and xml formats are supported.'); + throw new InvalidArgumentException('Only the yaml and xml formats are supported.'); } $io->writeln(null === $path ? $dumper->dump($configuration, $extension->getNamespace()) : $dumper->dumpAtPath($configuration, $path)); diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php index ccc6b38d92e65..085b5a1203f52 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerDebugCommand.php @@ -13,6 +13,7 @@ use Symfony\Bundle\FrameworkBundle\Console\Helper\DescriptorHelper; use Symfony\Component\Config\ConfigCache; +use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; @@ -167,9 +168,9 @@ protected function validateInput(InputInterface $input) $name = $input->getArgument('name'); if ((null !== $name) && ($optionsCount > 0)) { - throw new \InvalidArgumentException('The options tags, tag, parameters & parameter can not be combined with the service name argument.'); + throw new InvalidArgumentException('The options tags, tag, parameters & parameter can not be combined with the service name argument.'); } elseif ((null === $name) && $optionsCount > 1) { - throw new \InvalidArgumentException('The options tags, tag, parameters & parameter can not be combined together.'); + throw new InvalidArgumentException('The options tags, tag, parameters & parameter can not be combined together.'); } } @@ -208,7 +209,7 @@ private function findProperServiceName(InputInterface $input, SymfonyStyle $io, $matchingServices = $this->findServiceIdsContaining($builder, $name); if (empty($matchingServices)) { - throw new \InvalidArgumentException(sprintf('No services found that match "%s".', $name)); + throw new InvalidArgumentException(sprintf('No services found that match "%s".', $name)); } $default = 1 === count($matchingServices) ? $matchingServices[0] : null; diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php index 5533fae74b76f..ca4a63dd0c5bd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/RouterDebugCommand.php @@ -13,6 +13,7 @@ use Symfony\Bundle\FrameworkBundle\Console\Helper\DescriptorHelper; use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser; +use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -116,7 +117,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($name) { if (!$route = $routes->get($name)) { - throw new \InvalidArgumentException(sprintf('The route "%s" does not exist.', $name)); + throw new InvalidArgumentException(sprintf('The route "%s" does not exist.', $name)); } $callable = $this->extractCallable($route); diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php index 22d154872cf39..c84a4363df00b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\Command; +use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; @@ -182,7 +183,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $viewsPaths = array($input->getArgument('bundle').'/Resources/views'); if (!is_dir($transPaths[0])) { - throw new \InvalidArgumentException(sprintf('"%s" is neither an enabled bundle nor a directory.', $transPaths[0])); + throw new InvalidArgumentException(sprintf('"%s" is neither an enabled bundle nor a directory.', $transPaths[0])); } } } elseif ($input->getOption('all')) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php index d2c88d9c9fd0d..f35199479843e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\Command; +use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\Translation\Catalogue\TargetOperation; @@ -192,7 +193,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $currentName = $transPaths[0]; if (!is_dir($transPaths[0])) { - throw new \InvalidArgumentException(sprintf('"%s" is neither an enabled bundle nor a directory.', $transPaths[0])); + throw new InvalidArgumentException(sprintf('"%s" is neither an enabled bundle nor a directory.', $transPaths[0])); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php index 3d72226c677c3..bdc5690d72992 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\Command; +use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -63,7 +64,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $workflow = $container->get('state_machine.'.$serviceId); $dumper = new StateMachineGraphvizDumper(); } else { - throw new \InvalidArgumentException(sprintf('No service found for "workflow.%1$s" nor "state_machine.%1$s".', $serviceId)); + throw new InvalidArgumentException(sprintf('No service found for "workflow.%1$s" nor "state_machine.%1$s".', $serviceId)); } $marking = new Marking(); diff --git a/src/Symfony/Bundle/SecurityBundle/Command/SetAclCommand.php b/src/Symfony/Bundle/SecurityBundle/Command/SetAclCommand.php index 46aacfc266142..b27fc91021ad7 100644 --- a/src/Symfony/Bundle/SecurityBundle/Command/SetAclCommand.php +++ b/src/Symfony/Bundle/SecurityBundle/Command/SetAclCommand.php @@ -14,6 +14,7 @@ @trigger_error(sprintf('Class "%s" is deprecated since Symfony 3.4 and will be removed in 4.0. Use Symfony\Bundle\AclBundle\Command\SetAclCommand instead.', SetAclCommand::class), E_USER_DEPRECATED); use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -144,7 +145,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $classScopeOption = $input->getOption('class-scope'); if (empty($userOption) && empty($roleOption)) { - throw new \InvalidArgumentException('A Role or a User must be specified.'); + throw new InvalidArgumentException('A Role or a User must be specified.'); } // Create security identities @@ -155,7 +156,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $data = explode(':', $user, 2); if (1 === count($data)) { - throw new \InvalidArgumentException('The user must follow the format "Acme/MyUser:username".'); + throw new InvalidArgumentException('The user must follow the format "Acme/MyUser:username".'); } $securityIdentities[] = new UserSecurityIdentity($data[1], strtr($data[0], '/', '\\')); diff --git a/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php b/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php index 0f6eb839a18e9..cea8bd2e1541d 100644 --- a/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php +++ b/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php @@ -12,6 +12,8 @@ namespace Symfony\Bundle\SecurityBundle\Command; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -179,7 +181,7 @@ private function createPasswordQuestion() return $passwordQuestion->setValidator(function ($value) { if ('' === trim($value)) { - throw new \Exception('The password must not be empty.'); + throw new InvalidArgumentException('The password must not be empty.'); } return $value; @@ -203,7 +205,7 @@ private function getUserClass(InputInterface $input, SymfonyStyle $io) return User::class; } - throw new \RuntimeException('There are no configured encoders for the "security" extension.'); + throw new RuntimeException('There are no configured encoders for the "security" extension.'); } if (!$input->isInteractive() || 1 === count($this->userClasses)) { diff --git a/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php b/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php index 6a31b596f67ae..a9c62c99c61d2 100644 --- a/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php +++ b/src/Symfony/Bundle/WebServerBundle/Command/ServerLogCommand.php @@ -15,6 +15,8 @@ use Symfony\Bridge\Monolog\Formatter\ConsoleFormatter; use Symfony\Bridge\Monolog\Handler\ConsoleHandler; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Exception\LogicException; +use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -78,7 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $filter = $input->getOption('filter'); if ($filter) { if (!class_exists(ExpressionLanguage::class)) { - throw new \LogicException('Package "symfony/expression-language" is required to use the "filter" option.'); + throw new LogicException('Package "symfony/expression-language" is required to use the "filter" option.'); } $this->el = new ExpressionLanguage(); } @@ -97,7 +99,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } if (!$socket = stream_socket_server($host, $errno, $errstr)) { - throw new \RuntimeException(sprintf('Server start failed on "%s": %s %s.', $host, $errstr, $errno)); + throw new RuntimeException(sprintf('Server start failed on "%s": %s %s.', $host, $errstr, $errno)); } foreach ($this->getLogs($socket) as $clientId => $message) { diff --git a/src/Symfony/Bundle/WebServerBundle/Command/ServerStatusCommand.php b/src/Symfony/Bundle/WebServerBundle/Command/ServerStatusCommand.php index 6a01ebed79a3d..dd4f72af226ce 100644 --- a/src/Symfony/Bundle/WebServerBundle/Command/ServerStatusCommand.php +++ b/src/Symfony/Bundle/WebServerBundle/Command/ServerStatusCommand.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\WebServerBundle\Command; use Symfony\Bundle\WebServerBundle\WebServer; +use Symfony\Component\Console\Exception\InvalidArgumentException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -73,7 +74,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } elseif ('port' === $filter) { $output->write($port); } else { - throw new \InvalidArgumentException(sprintf('"%s" is not a valid filter.', $filter)); + throw new InvalidArgumentException(sprintf('"%s" is not a valid filter.', $filter)); } } else { return 1; diff --git a/src/Symfony/Component/Translation/Command/XliffLintCommand.php b/src/Symfony/Component/Translation/Command/XliffLintCommand.php index fead5edcb18bb..e868a57e8308f 100644 --- a/src/Symfony/Component/Translation/Command/XliffLintCommand.php +++ b/src/Symfony/Component/Translation/Command/XliffLintCommand.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Translation\Command; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -81,14 +82,14 @@ protected function execute(InputInterface $input, OutputInterface $output) if (!$filename) { if (!$stdin = $this->getStdin()) { - throw new \RuntimeException('Please provide a filename or pipe file content to STDIN.'); + throw new RuntimeException('Please provide a filename or pipe file content to STDIN.'); } return $this->display($io, array($this->validate($stdin))); } if (!$this->isReadable($filename)) { - throw new \RuntimeException(sprintf('File or directory "%s" is not readable.', $filename)); + throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename)); } $filesInfo = array(); @@ -136,7 +137,7 @@ private function display(SymfonyStyle $io, array $files) case 'json': return $this->displayJson($io, $files); default: - throw new \InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format)); + throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format)); } } diff --git a/src/Symfony/Component/Yaml/Command/LintCommand.php b/src/Symfony/Component/Yaml/Command/LintCommand.php index 4f2dc637df03a..04163a1ef40b9 100644 --- a/src/Symfony/Component/Yaml/Command/LintCommand.php +++ b/src/Symfony/Component/Yaml/Command/LintCommand.php @@ -12,6 +12,8 @@ namespace Symfony\Component\Yaml\Command; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -86,14 +88,14 @@ protected function execute(InputInterface $input, OutputInterface $output) if (!$filename) { if (!$stdin = $this->getStdin()) { - throw new \RuntimeException('Please provide a filename or pipe file content to STDIN.'); + throw new RuntimeException('Please provide a filename or pipe file content to STDIN.'); } return $this->display($io, array($this->validate($stdin, $flags))); } if (!$this->isReadable($filename)) { - throw new \RuntimeException(sprintf('File or directory "%s" is not readable.', $filename)); + throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename)); } $filesInfo = array(); @@ -133,7 +135,7 @@ private function display(SymfonyStyle $io, array $files) case 'json': return $this->displayJson($io, $files); default: - throw new \InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format)); + throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format)); } } From 32c7ee35be36270cdf8e226f7251c26f46a3b790 Mon Sep 17 00:00:00 2001 From: Bert Hekman Date: Thu, 3 May 2018 11:00:23 +0200 Subject: [PATCH 19/59] [FrameworkBundle] Use the correct service id for CachePoolPruneCommand in its compiler pass --- .../DependencyInjection/Compiler/CachePoolPrunerPass.php | 3 +-- .../Compiler/CachePoolPrunerPassTest.php | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPrunerPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPrunerPass.php index d02e2c372c3d4..9ffe548fa3d08 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPrunerPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPrunerPass.php @@ -11,7 +11,6 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; -use Symfony\Bundle\FrameworkBundle\Command\CachePoolPruneCommand; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -27,7 +26,7 @@ class CachePoolPrunerPass implements CompilerPassInterface private $cacheCommandServiceId; private $cachePoolTag; - public function __construct($cacheCommandServiceId = CachePoolPruneCommand::class, $cachePoolTag = 'cache.pool') + public function __construct($cacheCommandServiceId = 'console.command.cache_pool_prune', $cachePoolTag = 'cache.pool') { $this->cacheCommandServiceId = $cacheCommandServiceId; $this->cachePoolTag = $cachePoolTag; diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPrunerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPrunerPassTest.php index 105760641c34f..ec7e6200649de 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPrunerPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPrunerPassTest.php @@ -12,7 +12,6 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; use PHPUnit\Framework\TestCase; -use Symfony\Bundle\FrameworkBundle\Command\CachePoolPruneCommand; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolPrunerPass; use Symfony\Component\Cache\Adapter\FilesystemAdapter; use Symfony\Component\Cache\Adapter\PhpFilesAdapter; @@ -25,7 +24,7 @@ class CachePoolPrunerPassTest extends TestCase public function testCompilerPassReplacesCommandArgument() { $container = new ContainerBuilder(); - $container->register(CachePoolPruneCommand::class)->addArgument(array()); + $container->register('console.command.cache_pool_prune')->addArgument(array()); $container->register('pool.foo', FilesystemAdapter::class)->addTag('cache.pool'); $container->register('pool.bar', PhpFilesAdapter::class)->addTag('cache.pool'); @@ -36,7 +35,7 @@ public function testCompilerPassReplacesCommandArgument() 'pool.foo' => new Reference('pool.foo'), 'pool.bar' => new Reference('pool.bar'), ); - $argument = $container->getDefinition(CachePoolPruneCommand::class)->getArgument(0); + $argument = $container->getDefinition('console.command.cache_pool_prune')->getArgument(0); $this->assertInstanceOf(IteratorArgument::class, $argument); $this->assertEquals($expected, $argument->getValues()); @@ -64,7 +63,7 @@ public function testCompilePassIsIgnoredIfCommandDoesNotExist() public function testCompilerPassThrowsOnInvalidDefinitionClass() { $container = new ContainerBuilder(); - $container->register(CachePoolPruneCommand::class)->addArgument(array()); + $container->register('console.command.cache_pool_prune')->addArgument(array()); $container->register('pool.not-found', NotFound::class)->addTag('cache.pool'); $pass = new CachePoolPrunerPass(); From 29b3e31382ee75d112eae8f8fefd09fa71e716ca Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Fri, 4 May 2018 16:54:39 +0200 Subject: [PATCH 20/59] [FrameworkBundle] Remove dead code --- .../FrameworkExtension.php | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index f9f3ddf0406c9..43e75ceef2f44 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -97,11 +97,6 @@ class FrameworkExtension extends Extension private $annotationsConfigEnabled = false; private $validatorConfigEnabled = false; - /** - * @var string|null - */ - private $kernelRootHash; - /** * Responds to the app.config configuration parameter. * @@ -1391,20 +1386,6 @@ private function registerCacheConfiguration(array $config, ContainerBuilder $con } } - /** - * Gets a hash of the kernel root directory. - * - * @return string - */ - private function getKernelRootHash(ContainerBuilder $container) - { - if (!$this->kernelRootHash) { - $this->kernelRootHash = hash('sha256', $container->getParameter('kernel.root_dir')); - } - - return $this->kernelRootHash; - } - /** * Returns the base path for the XSD files. * From d3790cadcd35d952815826144e2d7092dd0a6add Mon Sep 17 00:00:00 2001 From: David Maicher Date: Fri, 4 May 2018 21:08:14 +0200 Subject: [PATCH 21/59] [Cache] fix logic for fetching tag versions on TagAwareAdapter --- src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php | 1 + .../Component/Cache/Tests/Adapter/TagAwareAdapterTest.php | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php index 67f9477ae3632..62f815e0171ad 100644 --- a/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php @@ -345,6 +345,7 @@ private function getTagVersions(array $tagsByKey, array &$invalidatedTags = arra foreach ($tagVersions as $tag => $version) { $tags[$tag.static::TAGS_PREFIX] = $tag; if ($fetchTagVersions || !isset($this->knownTagVersions[$tag])) { + $fetchTagVersions = true; continue; } $version -= $this->knownTagVersions[$tag][1]; diff --git a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php index 094fa9558bfd5..7074299e7ac34 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php @@ -69,6 +69,12 @@ public function testInvalidateTags() $this->assertFalse($pool->getItem('i1')->isHit()); $this->assertFalse($pool->getItem('i3')->isHit()); $this->assertTrue($pool->getItem('foo')->isHit()); + + $anotherPoolInstance = $this->createCachePool(); + + $this->assertFalse($anotherPoolInstance->getItem('i1')->isHit()); + $this->assertFalse($anotherPoolInstance->getItem('i3')->isHit()); + $this->assertTrue($anotherPoolInstance->getItem('foo')->isHit()); } public function testInvalidateCommits() From b11dccebd2781447ba0e9c852aa3e4549d82ec9b Mon Sep 17 00:00:00 2001 From: Valentin Udaltsov Date: Sun, 6 May 2018 17:23:59 +0300 Subject: [PATCH 22/59] Fixed typo RecursiveIterator -> RecursiveIteratorIterator --- src/Symfony/Component/Form/Util/InheritDataAwareIterator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/Util/InheritDataAwareIterator.php b/src/Symfony/Component/Form/Util/InheritDataAwareIterator.php index ba157b7d182f4..a400c16f0b294 100644 --- a/src/Symfony/Component/Form/Util/InheritDataAwareIterator.php +++ b/src/Symfony/Component/Form/Util/InheritDataAwareIterator.php @@ -17,7 +17,7 @@ * Contrary to \ArrayIterator, this iterator recognizes changes in the original * array during iteration. * - * You can wrap the iterator into a {@link \RecursiveIterator} in order to + * You can wrap the iterator into a {@link \RecursiveIteratorIterator} in order to * enter any child form that inherits its parent's data and iterate the children * of that form as well. * From ae62d9bc811b011d68ef8a6e88b2df21d8a7a4a5 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 3 May 2018 14:15:36 +0200 Subject: [PATCH 23/59] use brace-style regex delimiters --- src/Symfony/Component/HttpFoundation/Request.php | 2 +- .../HttpFoundation/Tests/RequestTest.php | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index ecdcdbc25acc2..e1309d477bd2d 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -581,7 +581,7 @@ public static function getTrustedProxies() public static function setTrustedHosts(array $hostPatterns) { self::$trustedHostPatterns = array_map(function ($hostPattern) { - return sprintf('#%s#i', $hostPattern); + return sprintf('{%s}i', $hostPattern); }, $hostPatterns); // we need to reset trusted hosts on trusted host patterns change self::$trustedHosts = array(); diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index 0c5451dfd6ccc..688a7c714a1d7 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -18,6 +18,11 @@ class RequestTest extends TestCase { + protected function tearDown() + { + Request::setTrustedHosts(array()); + } + public function testInitialize() { $request = new Request(); @@ -1871,9 +1876,15 @@ public function testTrustedHosts() $request->headers->set('host', 'subdomain.trusted.com'); $this->assertEquals('subdomain.trusted.com', $request->getHost()); + } - // reset request for following tests - Request::setTrustedHosts(array()); + public function testSetTrustedHostsDoesNotBreakOnSpecialCharacters() + { + Request::setTrustedHosts(array('localhost(\.local){0,1}#,example.com', 'localhost')); + + $request = Request::create('/'); + $request->headers->set('host', 'localhost'); + $this->assertSame('localhost', $request->getHost()); } public function testFactory() From cb06e2a6fb935da690e8d6fc9f96a531fd6ac619 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 7 May 2018 10:32:11 +0200 Subject: [PATCH 24/59] fixed bad merge --- .../FrameworkBundle/Command/AssetsInstallCommand.php | 12 +----------- .../Command/UserPasswordEncoderCommand.php | 9 --------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php index b018ea292be3e..9bd9d03c95713 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/AssetsInstallCommand.php @@ -95,17 +95,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $targetArg = $kernel->getContainer()->getParameter('kernel.project_dir').'/'.$targetArg; if (!is_dir($targetArg)) { -<<<<<<< HEAD - throw new \InvalidArgumentException(sprintf('The target directory "%s" does not exist.', $input->getArgument('target'))); -======= - // deprecated, logic to be removed in 4.0 - // this allows the commands to work out of the box with web/ and public/ - if (is_dir(dirname($targetArg).'/web')) { - $targetArg = dirname($targetArg).'/web'; - } else { - throw new InvalidArgumentException(sprintf('The target directory "%s" does not exist.', $input->getArgument('target'))); - } ->>>>>>> 3.4 + throw new InvalidArgumentException(sprintf('The target directory "%s" does not exist.', $input->getArgument('target'))); } } diff --git a/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php b/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php index 64219ad336424..84227cf47e72e 100644 --- a/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php +++ b/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php @@ -192,16 +192,7 @@ private function getUserClass(InputInterface $input, SymfonyStyle $io) } if (empty($this->userClasses)) { -<<<<<<< HEAD - throw new \RuntimeException('There are no configured encoders for the "security" extension.'); -======= - if (null === $this->encoderFactory) { - // BC to be removed and simply keep the exception whenever there is no configured user classes in 4.0 - return User::class; - } - throw new RuntimeException('There are no configured encoders for the "security" extension.'); ->>>>>>> 3.4 } if (!$input->isInteractive() || 1 === count($this->userClasses)) { From 5539f9d6c815d4bc1ec7f8191af37f2c8bf0cfae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarmo=20Lepp=C3=A4nen?= Date: Mon, 7 May 2018 19:50:17 +0300 Subject: [PATCH 25/59] Fixed return type --- src/Symfony/Component/HttpFoundation/Request.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index e1309d477bd2d..7e8e075a833f3 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1322,7 +1322,7 @@ public function getRealMethod() * * @param string $format The format * - * @return string The associated mime type (null if not found) + * @return string|null The associated mime type (null if not found) */ public function getMimeType($format) { From f2231b584ebbfdbf42db4aab4ca93ce28db67530 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 May 2018 15:24:01 -0700 Subject: [PATCH 26/59] [DI] Display previous error messages when throwing unused bindings --- .../Compiler/AbstractRecursivePass.php | 8 ++++++-- .../Compiler/ResolveBindingsPass.php | 12 +++++++++++- .../Tests/Compiler/ResolveBindingsPassTest.php | 16 ++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php index 5d2d4429e4a97..901dc06ffaee5 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php @@ -118,8 +118,12 @@ protected function getConstructor(Definition $definition, $required) $class = $definition->getClass(); - if (!$r = $this->container->getReflectionClass($class)) { - throw new RuntimeException(sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class)); + try { + if (!$r = $this->container->getReflectionClass($class)) { + throw new RuntimeException(sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class)); + } + } catch (\ReflectionException $e) { + throw new RuntimeException(sprintf('Invalid service "%s": %s.', $this->currentId, lcfirst(rtrim($e->getMessage(), '.')))); } if (!$r = $r->getConstructor()) { if ($required) { diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php index 024523e15585c..9a895cb523258 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php @@ -27,6 +27,7 @@ class ResolveBindingsPass extends AbstractRecursivePass { private $usedBindings = array(); private $unusedBindings = array(); + private $errorMessages = array(); /** * {@inheritdoc} @@ -37,11 +38,19 @@ public function process(ContainerBuilder $container) parent::process($container); foreach ($this->unusedBindings as list($key, $serviceId)) { - throw new InvalidArgumentException(sprintf('Unused binding "%s" in service "%s".', $key, $serviceId)); + $message = sprintf('Unused binding "%s" in service "%s".', $key, $serviceId); + if ($this->errorMessages) { + $message .= sprintf("\nCould be related to%s:", 1 < \count($this->errorMessages) ? ' one of' : ''); + } + foreach ($this->errorMessages as $m) { + $message .= "\n - ".$m; + } + throw new InvalidArgumentException($message); } } finally { $this->usedBindings = array(); $this->unusedBindings = array(); + $this->errorMessages = array(); } } @@ -94,6 +103,7 @@ protected function processValue($value, $isRoot = false) $calls[] = array($constructor, $value->getArguments()); } } catch (RuntimeException $e) { + $this->errorMessages[] = $e->getMessage(); $this->container->getDefinition($this->currentId)->addError($e->getMessage()); return parent::processValue($value, $isRoot); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php index 16e486afafe2e..65f5ceb80fd0c 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php @@ -18,6 +18,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy; +use Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists; use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass; use Symfony\Component\DependencyInjection\TypedReference; @@ -61,6 +62,21 @@ public function testUnusedBinding() $pass->process($container); } + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException + * @expectedExceptionMessageRegexp Unused binding "$quz" in service [\s\S]+ Invalid service ".*\\ParentNotExists": class NotExists not found\. + */ + public function testMissingParent() + { + $container = new ContainerBuilder(); + + $definition = $container->register(ParentNotExists::class, ParentNotExists::class); + $definition->setBindings(array('$quz' => '123')); + + $pass = new ResolveBindingsPass(); + $pass->process($container); + } + public function testTypedReferenceSupport() { $container = new ContainerBuilder(); From 3d1ab6df13f04f29458b9bb8f1a5c77e6a98bab9 Mon Sep 17 00:00:00 2001 From: fsevestre Date: Thu, 10 May 2018 16:33:41 +0200 Subject: [PATCH 27/59] Fix misses calculation when calling getItems --- .../Component/Cache/DataCollector/CacheDataCollector.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php b/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php index ceef45aa0b185..962fb25cb94cb 100644 --- a/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php +++ b/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php @@ -132,10 +132,9 @@ private function calculateStatistics() $statistics[$name]['misses'] += 1; } } elseif ('getItems' === $call->name) { - $count = $call->hits + $call->misses; - $statistics[$name]['reads'] += $count; + $statistics[$name]['reads'] += $call->hits + $call->misses; $statistics[$name]['hits'] += $call->hits; - $statistics[$name]['misses'] += $count - $call->misses; + $statistics[$name]['misses'] += $call->misses; } elseif ('hasItem' === $call->name) { $statistics[$name]['reads'] += 1; if (false === $call->result) { From db6ef38ea9a5ff1c7198159984a9a714de55c917 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 10 May 2018 11:44:29 -0700 Subject: [PATCH 28/59] [HttpKernel] Handle NoConfigurationException "onKernelException()" --- .../EventListener/RouterListener.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php index caaf80f86b892..959f2ba0d1135 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php @@ -14,6 +14,7 @@ use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\HttpKernel\KernelEvents; @@ -129,12 +130,6 @@ public function onKernelRequest(GetResponseEvent $event) unset($parameters['_route'], $parameters['_controller']); $request->attributes->set('_route_params', $parameters); } catch (ResourceNotFoundException $e) { - if ($this->debug && $e instanceof NoConfigurationException) { - $event->setResponse($this->createWelcomeResponse()); - - return; - } - $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo()); if ($referer = $request->headers->get('referer')) { @@ -149,11 +144,23 @@ public function onKernelRequest(GetResponseEvent $event) } } + public function onKernelException(GetResponseForExceptionEvent $event) + { + if (!$this->debug || !($e = $event->getException()) instanceof NotFoundHttpException) { + return; + } + + if ($e->getPrevious() instanceof NoConfigurationException) { + $event->setResponse($this->createWelcomeResponse()); + } + } + public static function getSubscribedEvents() { return array( KernelEvents::REQUEST => array(array('onKernelRequest', 32)), KernelEvents::FINISH_REQUEST => array(array('onKernelFinishRequest', 0)), + KernelEvents::EXCEPTION => array('onKernelException', -64), ); } From 3381611d86e684737c064efef0d937e08a801a63 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 10 May 2018 19:25:00 -0700 Subject: [PATCH 29/59] [FrameworkBundle] Fix cache:clear on vagrant --- .../Command/CacheClearCommand.php | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php index bbb71c15dd92a..650f36dc15b71 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php @@ -140,16 +140,34 @@ protected function execute(InputInterface $input, OutputInterface $output) } } - $containerDir = $fs->exists($warmupDir.'/'.$containerDir) ? false : $containerDir; + if (!$fs->exists($warmupDir.'/'.$containerDir)) { + $fs->rename($realCacheDir.'/'.$containerDir, $warmupDir.'/'.$containerDir); + touch($warmupDir.'/'.$containerDir.'.legacy'); + } - $fs->rename($realCacheDir, $oldCacheDir); - $fs->rename($warmupDir, $realCacheDir); + if ('/' === \DIRECTORY_SEPARATOR && $mounts = @file('/proc/mounts')) { + foreach ($mounts as $mount) { + $mount = array_slice(explode(' ', $mount), 1, -3); + if (!\in_array(array_pop($mount), array('vboxfs', 'nfs'))) { + continue; + } + $mount = implode(' ', $mount).'/'; - if ($containerDir) { - $fs->rename($oldCacheDir.'/'.$containerDir, $realCacheDir.'/'.$containerDir); - touch($realCacheDir.'/'.$containerDir.'.legacy'); + if (0 === strpos($realCacheDir, $mount)) { + $io->note('For better performances, you should move the cache and log directories to a non-shared folder of the VM.'); + $oldCacheDir = false; + break; + } + } } + if ($oldCacheDir) { + $fs->rename($realCacheDir, $oldCacheDir); + } else { + $fs->remove($realCacheDir); + } + $fs->rename($warmupDir, $realCacheDir); + if ($output->isVerbose()) { $io->comment('Removing old cache directory...'); } From 8072eed4bf6237df15f74647c793cf2e951b6ab8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 11 May 2018 17:48:19 +0200 Subject: [PATCH 30/59] fixed CS --- .../Handler/FingersCrossed/NotFoundActivationStrategy.php | 2 +- src/Symfony/Component/Finder/Shell/Command.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php index 413b476f2938d..596fcdd84d2c5 100644 --- a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php +++ b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php @@ -42,7 +42,7 @@ public function isHandlerActivated(array $record) $isActivated && isset($record['context']['exception']) && $record['context']['exception'] instanceof HttpException - && $record['context']['exception']->getStatusCode() == 404 + && 404 == $record['context']['exception']->getStatusCode() && ($request = $this->requestStack->getMasterRequest()) ) { return !preg_match($this->blacklist, $request->getPathInfo()); diff --git a/src/Symfony/Component/Finder/Shell/Command.php b/src/Symfony/Component/Finder/Shell/Command.php index 47f4b422216b9..43114dbcc07db 100644 --- a/src/Symfony/Component/Finder/Shell/Command.php +++ b/src/Symfony/Component/Finder/Shell/Command.php @@ -100,7 +100,7 @@ public function top($bit) array_unshift($this->bits, $bit); foreach ($this->labels as $label => $index) { - $this->labels[$label] += 1; + ++$this->labels[$label]; } return $this; From df43c1e99dea042c9911fd6dd640ba9fd9bea3f3 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 11 May 2018 17:51:28 +0200 Subject: [PATCH 31/59] fixed CS --- .../SecurityBundle/DependencyInjection/SecurityExtension.php | 1 - .../Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 91d2d979c16b1..7ebe982e6d0b3 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -14,7 +14,6 @@ use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; -use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\HttpKernel\DependencyInjection\Extension; 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 2c4c15f410428..44f6e45e924cf 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -2568,7 +2568,7 @@ public function testStripLeadingUnderscoresAndDigitsFromId() $this->assertEquals('_09name', $view->vars['full_name']); } - /** + /** * @dataProvider provideTrimCases */ public function testTrimIsDisabled($multiple, $expanded) From 4f3afd53a8e3c673b889eb936410291108c89d88 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 11 May 2018 17:58:37 +0200 Subject: [PATCH 32/59] fixed CS --- .../PhpUnit/Legacy/CoverageListenerTrait.php | 1 - .../weak_vendors_on_eval_d_deprecation.phpt | 2 +- src/Symfony/Bridge/Twig/NodeVisitor/Scope.php | 2 +- .../Tests/Controller/ControllerTest.php | 1 - .../Cache/DataCollector/CacheDataCollector.php | 18 +++++++++--------- .../Component/CssSelector/Node/Specificity.php | 4 ++-- .../Component/CssSelector/XPath/Translator.php | 4 ++-- .../Component/CssSelector/XPath/XPathExpr.php | 6 +++--- .../Debug/Exception/FlattenException.php | 2 +- .../Configurator/InstanceofConfigurator.php | 2 +- src/Symfony/Component/Form/FormInterface.php | 2 +- src/Symfony/Component/Form/FormView.php | 2 +- .../Tests/AbstractBootstrap4LayoutTest.php | 2 +- .../Storage/Handler/PdoSessionHandler.php | 2 +- .../HttpFoundation/Tests/ResponseTest.php | 2 +- .../Component/HttpKernel/Profiler/Profile.php | 4 ++-- .../ContainerControllerResolverTest.php | 1 - .../ArgumentMetadataFactoryTest.php | 4 ++-- .../HttpKernel/Tests/Profiler/ProfilerTest.php | 2 +- src/Symfony/Component/Ldap/Ldap.php | 2 +- .../OptionsResolver/OptionsResolver.php | 2 +- .../PropertyAccess/PropertyAccessor.php | 2 +- src/Symfony/Component/PropertyInfo/Type.php | 2 +- .../Matcher/Dumper/DumperCollection.php | 2 +- .../Routing/RouteCollectionBuilder.php | 4 ++-- .../Firewall/GuardAuthenticationListener.php | 1 - .../Security/Http/Firewall/ContextListener.php | 4 ++-- .../Mapping/AttributeMetadataInterface.php | 2 +- .../Mapping/ClassMetadataInterface.php | 2 +- .../Normalizer/AbstractObjectNormalizer.php | 4 ++-- .../Translation/MessageCatalogueInterface.php | 4 ++-- .../ConstraintViolationListInterface.php | 2 +- .../Validator/Mapping/ClassMetadata.php | 2 +- 33 files changed, 47 insertions(+), 51 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php index 1c84ff32c0b74..ab1cda6702be5 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php @@ -11,7 +11,6 @@ namespace Symfony\Bridge\PhpUnit\Legacy; -use PHPUnit\Framework\Test; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Warning; 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 8fa436e20178b..8390d16332fa1 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 @@ -15,7 +15,7 @@ while (!file_exists($vendor.'/vendor')) { define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php'); require PHPUNIT_COMPOSER_INSTALL; require_once __DIR__.'/../../bootstrap.php'; -eval("@trigger_error('who knows where I come from?', E_USER_DEPRECATED);") +eval("@trigger_error('who knows where I come from?', E_USER_DEPRECATED);"); ?> --EXPECTF-- diff --git a/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php b/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php index 1c3451bbebf46..59497dc961984 100644 --- a/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php +++ b/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php @@ -20,7 +20,7 @@ class Scope private $data = array(); private $left = false; - public function __construct(Scope $parent = null) + public function __construct(self $parent = null) { $this->parent = $parent; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php index 9fd20649289de..452845cea8e34 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php @@ -12,7 +12,6 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; -use Symfony\Component\HttpFoundation\File\File; class ControllerTest extends ControllerTraitTest { diff --git a/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php b/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php index 14c6a8d0fa584..91763e5a9f33b 100644 --- a/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php +++ b/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php @@ -119,30 +119,30 @@ private function calculateStatistics(): array ); /** @var TraceableAdapterEvent $call */ foreach ($calls as $call) { - $statistics[$name]['calls'] += 1; + ++$statistics[$name]['calls']; $statistics[$name]['time'] += $call->end - $call->start; if ('getItem' === $call->name) { - $statistics[$name]['reads'] += 1; + ++$statistics[$name]['reads']; if ($call->hits) { - $statistics[$name]['hits'] += 1; + ++$statistics[$name]['hits']; } else { - $statistics[$name]['misses'] += 1; + ++$statistics[$name]['misses']; } } elseif ('getItems' === $call->name) { $statistics[$name]['reads'] += $call->hits + $call->misses; $statistics[$name]['hits'] += $call->hits; $statistics[$name]['misses'] += $call->misses; } elseif ('hasItem' === $call->name) { - $statistics[$name]['reads'] += 1; + ++$statistics[$name]['reads']; if (false === $call->result) { - $statistics[$name]['misses'] += 1; + ++$statistics[$name]['misses']; } else { - $statistics[$name]['hits'] += 1; + ++$statistics[$name]['hits']; } } elseif ('save' === $call->name) { - $statistics[$name]['writes'] += 1; + ++$statistics[$name]['writes']; } elseif ('deleteItem' === $call->name) { - $statistics[$name]['deletes'] += 1; + ++$statistics[$name]['deletes']; } } if ($statistics[$name]['reads']) { diff --git a/src/Symfony/Component/CssSelector/Node/Specificity.php b/src/Symfony/Component/CssSelector/Node/Specificity.php index 11228f7246d3a..9b35cb411632c 100644 --- a/src/Symfony/Component/CssSelector/Node/Specificity.php +++ b/src/Symfony/Component/CssSelector/Node/Specificity.php @@ -40,7 +40,7 @@ public function __construct(int $a, int $b, int $c) $this->c = $c; } - public function plus(Specificity $specificity): Specificity + public function plus(self $specificity): self { return new self($this->a + $specificity->a, $this->b + $specificity->b, $this->c + $specificity->c); } @@ -56,7 +56,7 @@ public function getValue(): int * * @return int */ - public function compareTo(Specificity $specificity) + public function compareTo(self $specificity) { if ($this->a !== $specificity->a) { return $this->a > $specificity->a ? 1 : -1; diff --git a/src/Symfony/Component/CssSelector/XPath/Translator.php b/src/Symfony/Component/CssSelector/XPath/Translator.php index 28478b3db7e47..73b548215d671 100644 --- a/src/Symfony/Component/CssSelector/XPath/Translator.php +++ b/src/Symfony/Component/CssSelector/XPath/Translator.php @@ -114,7 +114,7 @@ public function selectorToXPath(SelectorNode $selector, string $prefix = 'descen return ($prefix ?: '').$this->nodeToXPath($selector); } - public function registerExtension(Extension\ExtensionInterface $extension): Translator + public function registerExtension(Extension\ExtensionInterface $extension): self { $this->extensions[$extension->getName()] = $extension; @@ -139,7 +139,7 @@ public function getExtension(string $name): Extension\ExtensionInterface return $this->extensions[$name]; } - public function registerParserShortcut(ParserInterface $shortcut): Translator + public function registerParserShortcut(ParserInterface $shortcut): self { $this->shortcutParsers[] = $shortcut; diff --git a/src/Symfony/Component/CssSelector/XPath/XPathExpr.php b/src/Symfony/Component/CssSelector/XPath/XPathExpr.php index 8090df99075fa..638cbd0fe0619 100644 --- a/src/Symfony/Component/CssSelector/XPath/XPathExpr.php +++ b/src/Symfony/Component/CssSelector/XPath/XPathExpr.php @@ -43,7 +43,7 @@ public function getElement(): string return $this->element; } - public function addCondition(string $condition): XPathExpr + public function addCondition(string $condition): self { $this->condition = $this->condition ? sprintf('(%s) and (%s)', $this->condition, $condition) : $condition; @@ -55,7 +55,7 @@ public function getCondition(): string return $this->condition; } - public function addNameTest(): XPathExpr + public function addNameTest(): self { if ('*' !== $this->element) { $this->addCondition('name() = '.Translator::getXpathLiteral($this->element)); @@ -65,7 +65,7 @@ public function addNameTest(): XPathExpr return $this; } - public function addStarPrefix(): XPathExpr + public function addStarPrefix(): self { $this->path .= '*/'; diff --git a/src/Symfony/Component/Debug/Exception/FlattenException.php b/src/Symfony/Component/Debug/Exception/FlattenException.php index 24679dcaab242..f491bf2ac4c92 100644 --- a/src/Symfony/Component/Debug/Exception/FlattenException.php +++ b/src/Symfony/Component/Debug/Exception/FlattenException.php @@ -157,7 +157,7 @@ public function getPrevious() return $this->previous; } - public function setPrevious(FlattenException $previous) + public function setPrevious(self $previous) { $this->previous = $previous; } diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/InstanceofConfigurator.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/InstanceofConfigurator.php index 9ecb2a21c3deb..78a8e3c327f85 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/Configurator/InstanceofConfigurator.php +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/InstanceofConfigurator.php @@ -30,7 +30,7 @@ class InstanceofConfigurator extends AbstractServiceConfigurator /** * Defines an instanceof-conditional to be applied to following service definitions. */ - final public function instanceof(string $fqcn): InstanceofConfigurator + final public function instanceof(string $fqcn): self { return $this->parent->instanceof($fqcn); } diff --git a/src/Symfony/Component/Form/FormInterface.php b/src/Symfony/Component/Form/FormInterface.php index 921ae2829c5ff..a0e9b636c5f38 100644 --- a/src/Symfony/Component/Form/FormInterface.php +++ b/src/Symfony/Component/Form/FormInterface.php @@ -29,7 +29,7 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable * @throws Exception\LogicException when trying to set a parent for a form with * an empty name */ - public function setParent(FormInterface $parent = null); + public function setParent(self $parent = null); /** * Returns the parent form. diff --git a/src/Symfony/Component/Form/FormView.php b/src/Symfony/Component/Form/FormView.php index 21a3d5036ad2b..9fbca4379688a 100644 --- a/src/Symfony/Component/Form/FormView.php +++ b/src/Symfony/Component/Form/FormView.php @@ -51,7 +51,7 @@ class FormView implements \ArrayAccess, \IteratorAggregate, \Countable private $methodRendered = false; - public function __construct(FormView $parent = null) + public function __construct(self $parent = null) { $this->parent = $parent; } diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php index 2cadba0ba9e67..a2c606c0362ab 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php @@ -178,7 +178,7 @@ public function testErrors() public function testErrorWithNoLabel() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType', array('label'=>false)); + $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType', array('label' => false)); $form->addError(new FormError('[trans]Error 1[/trans]')); $view = $form->createView(); $html = $this->renderLabel($view); diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php index 5ae3d52cc30b1..7b30aed381053 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php @@ -833,7 +833,7 @@ private function getUpdateStatement($sessionId, $sessionData, $maxlifetime) /** * Returns a merge/upsert (i.e. insert or update) statement when supported by the database for writing session data. */ - private function getMergeStatement(string $sessionId, string $data, int$maxlifetime): ?\PDOStatement + private function getMergeStatement(string $sessionId, string $data, int $maxlifetime): ?\PDOStatement { switch (true) { case 'mysql' === $this->driver: diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php index b35727962eacd..b4af82ddf68de 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseTest.php @@ -300,7 +300,7 @@ public function testGetMaxAge() $response = new Response(); $response->headers->set('Cache-Control', 'must-revalidate'); $response->headers->set('Expires', -1); - $this->assertLessThanOrEqual(time() - 2*86400, $response->getExpires()->format('U')); + $this->assertLessThanOrEqual(time() - 2 * 86400, $response->getExpires()->format('U')); $response = new Response(); $this->assertNull($response->getMaxAge(), '->getMaxAge() returns null if no freshness information available'); diff --git a/src/Symfony/Component/HttpKernel/Profiler/Profile.php b/src/Symfony/Component/HttpKernel/Profiler/Profile.php index e91a0b0c70e49..cc7efc8487475 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/Profile.php +++ b/src/Symfony/Component/HttpKernel/Profiler/Profile.php @@ -71,7 +71,7 @@ public function getToken() /** * Sets the parent token. */ - public function setParent(Profile $parent) + public function setParent(self $parent) { $this->parent = $parent; } @@ -210,7 +210,7 @@ public function setChildren(array $children) /** * Adds the child token. */ - public function addChild(Profile $child) + public function addChild(self $child) { $this->children[] = $child; $child->setParent($this); diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ContainerControllerResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ContainerControllerResolverTest.php index 6f203d3a987c3..1602de4c261f9 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ContainerControllerResolverTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ContainerControllerResolverTest.php @@ -13,7 +13,6 @@ use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; -use Symfony\Component\Debug\ErrorHandler; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Controller\ContainerControllerResolver; diff --git a/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php b/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php index 2ddc6e7a5ee10..a667705f50813 100644 --- a/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php @@ -117,11 +117,11 @@ public function testNullableTypesSignature() ), $arguments); } - private function signature1(ArgumentMetadataFactoryTest $foo, array $bar, callable $baz) + private function signature1(self $foo, array $bar, callable $baz) { } - private function signature2(ArgumentMetadataFactoryTest $foo = null, FakeClassThatDoesNotExist $bar = null, ImportedAndFake $baz = null) + private function signature2(self $foo = null, FakeClassThatDoesNotExist $bar = null, ImportedAndFake $baz = null) { } diff --git a/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php b/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php index 243c3c5c5a7cb..2d5f0ca5ad59e 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php @@ -44,7 +44,7 @@ public function testCollect() public function testReset() { $collector = $this->getMockBuilder(DataCollectorInterface::class) - ->setMethods(['collect', 'getName', 'reset']) + ->setMethods(array('collect', 'getName', 'reset')) ->getMock(); $collector->expects($this->any())->method('getName')->willReturn('mock'); $collector->expects($this->once())->method('reset'); diff --git a/src/Symfony/Component/Ldap/Ldap.php b/src/Symfony/Component/Ldap/Ldap.php index 26fd4f946ccc9..de1ab1a249eda 100644 --- a/src/Symfony/Component/Ldap/Ldap.php +++ b/src/Symfony/Component/Ldap/Ldap.php @@ -70,7 +70,7 @@ public function escape($subject, $ignore = '', $flags = 0) * * @return static */ - public static function create($adapter, array $config = array()): Ldap + public static function create($adapter, array $config = array()): self { if (!isset(self::$adapterMap[$adapter])) { throw new DriverNotFoundException(sprintf( diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php index 8edd6b5c89791..68b4154b10da2 100644 --- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php +++ b/src/Symfony/Component/OptionsResolver/OptionsResolver.php @@ -975,7 +975,7 @@ public function count() * parameters should usually not be included in messages aimed at * non-technical people. * - * @param mixed $value The value to return the type of + * @param mixed $value The value to return the type of */ private function formatTypeOf($value, ?string $type): string { diff --git a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php index 1768dda885421..40a2ae047e812 100644 --- a/src/Symfony/Component/PropertyAccess/PropertyAccessor.php +++ b/src/Symfony/Component/PropertyAccess/PropertyAccessor.php @@ -588,7 +588,7 @@ private function writeCollection($zval, $property, $collection, $addMethod, $rem /** * Guesses how to write the property value. * - * @param mixed $value + * @param mixed $value */ private function getWriteAccessInfo(string $class, string $property, $value): array { diff --git a/src/Symfony/Component/PropertyInfo/Type.php b/src/Symfony/Component/PropertyInfo/Type.php index 71aa162f70b79..461495ed510ac 100644 --- a/src/Symfony/Component/PropertyInfo/Type.php +++ b/src/Symfony/Component/PropertyInfo/Type.php @@ -59,7 +59,7 @@ class Type /** * @throws \InvalidArgumentException */ - public function __construct(string $builtinType, bool $nullable = false, string $class = null, bool $collection = false, Type $collectionKeyType = null, Type $collectionValueType = null) + public function __construct(string $builtinType, bool $nullable = false, string $class = null, bool $collection = false, self $collectionKeyType = null, self $collectionValueType = null) { if (!in_array($builtinType, self::$builtinTypes)) { throw new \InvalidArgumentException(sprintf('"%s" is not a valid PHP type.', $builtinType)); diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/DumperCollection.php b/src/Symfony/Component/Routing/Matcher/Dumper/DumperCollection.php index 6916297b8c174..dd057d2ee8301 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/DumperCollection.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/DumperCollection.php @@ -106,7 +106,7 @@ protected function getParent() /** * Sets the parent collection. */ - protected function setParent(DumperCollection $parent) + protected function setParent(self $parent) { $this->parent = $parent; } diff --git a/src/Symfony/Component/Routing/RouteCollectionBuilder.php b/src/Symfony/Component/Routing/RouteCollectionBuilder.php index d63c6138f7983..a58613cefe48f 100644 --- a/src/Symfony/Component/Routing/RouteCollectionBuilder.php +++ b/src/Symfony/Component/Routing/RouteCollectionBuilder.php @@ -118,7 +118,7 @@ public function createBuilder() * @param string $prefix * @param RouteCollectionBuilder $builder */ - public function mount($prefix, RouteCollectionBuilder $builder) + public function mount($prefix, self $builder) { $builder->prefix = trim(trim($prefix), '/'); $this->routes[] = $builder; @@ -255,7 +255,7 @@ public function setMethods($methods) * * @return $this */ - private function addResource(ResourceInterface $resource): RouteCollectionBuilder + private function addResource(ResourceInterface $resource): self { $this->resources[] = $resource; diff --git a/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php b/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php index 80ae75caa2b85..b9859452b1585 100644 --- a/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php +++ b/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php @@ -14,7 +14,6 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\GetResponseEvent; -use Symfony\Component\Security\Guard\AbstractGuardAuthenticator; use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; use Symfony\Component\Security\Guard\AuthenticatorInterface; use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; diff --git a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php index fb8c7a1761cbc..00440702279a7 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php @@ -45,8 +45,8 @@ class ContextListener implements ListenerInterface private $trustResolver; /** - * @param TokenStorageInterface $tokenStorage - * @param iterable|UserProviderInterface[] $userProviders + * @param TokenStorageInterface $tokenStorage + * @param iterable|UserProviderInterface[] $userProviders */ public function __construct(TokenStorageInterface $tokenStorage, iterable $userProviders, string $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, AuthenticationTrustResolverInterface $trustResolver = null) { diff --git a/src/Symfony/Component/Serializer/Mapping/AttributeMetadataInterface.php b/src/Symfony/Component/Serializer/Mapping/AttributeMetadataInterface.php index 944a7b3133f35..d9a15d5ac0de5 100644 --- a/src/Symfony/Component/Serializer/Mapping/AttributeMetadataInterface.php +++ b/src/Symfony/Component/Serializer/Mapping/AttributeMetadataInterface.php @@ -60,5 +60,5 @@ public function getMaxDepth(); /** * Merges an {@see AttributeMetadataInterface} with in the current one. */ - public function merge(AttributeMetadataInterface $attributeMetadata); + public function merge(self $attributeMetadata); } diff --git a/src/Symfony/Component/Serializer/Mapping/ClassMetadataInterface.php b/src/Symfony/Component/Serializer/Mapping/ClassMetadataInterface.php index 3811e56548a0c..a0765861643bb 100644 --- a/src/Symfony/Component/Serializer/Mapping/ClassMetadataInterface.php +++ b/src/Symfony/Component/Serializer/Mapping/ClassMetadataInterface.php @@ -46,7 +46,7 @@ public function getAttributesMetadata(); /** * Merges a {@link ClassMetadataInterface} in the current one. */ - public function merge(ClassMetadataInterface $classMetadata); + public function merge(self $classMetadata); /** * Returns a {@link \ReflectionClass} instance for this class. diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index ecf60dc8884a2..e2b15d1aa1c41 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -228,7 +228,7 @@ abstract protected function setAttributeValue($object, $attribute, $value, $form /** * Validates the submitted data and denormalizes it. * - * @param mixed $data + * @param mixed $data * * @return mixed * @@ -297,7 +297,7 @@ private function validateAndDenormalize(string $currentClass, string $attribute, /** * Sets an attribute and apply the name converter if necessary. * - * @param mixed $attributeValue + * @param mixed $attributeValue */ private function updateData(array $data, string $attribute, $attributeValue): array { diff --git a/src/Symfony/Component/Translation/MessageCatalogueInterface.php b/src/Symfony/Component/Translation/MessageCatalogueInterface.php index 4dad27fbf6aa3..e0dbb2bd962cb 100644 --- a/src/Symfony/Component/Translation/MessageCatalogueInterface.php +++ b/src/Symfony/Component/Translation/MessageCatalogueInterface.php @@ -105,7 +105,7 @@ public function add($messages, $domain = 'messages'); * * The two catalogues must have the same locale. */ - public function addCatalogue(MessageCatalogueInterface $catalogue); + public function addCatalogue(self $catalogue); /** * Merges translations from the given Catalogue into the current one @@ -113,7 +113,7 @@ public function addCatalogue(MessageCatalogueInterface $catalogue); * * This is used to provide default translations when they do not exist for the current locale. */ - public function addFallbackCatalogue(MessageCatalogueInterface $catalogue); + public function addFallbackCatalogue(self $catalogue); /** * Gets the fallback catalogue. diff --git a/src/Symfony/Component/Validator/ConstraintViolationListInterface.php b/src/Symfony/Component/Validator/ConstraintViolationListInterface.php index 0489ab500a1dc..47e986f51e50a 100644 --- a/src/Symfony/Component/Validator/ConstraintViolationListInterface.php +++ b/src/Symfony/Component/Validator/ConstraintViolationListInterface.php @@ -26,7 +26,7 @@ public function add(ConstraintViolationInterface $violation); /** * Merges an existing violation list into this list. */ - public function addAll(ConstraintViolationListInterface $otherList); + public function addAll(self $otherList); /** * Returns the violation at a given offset. diff --git a/src/Symfony/Component/Validator/Mapping/ClassMetadata.php b/src/Symfony/Component/Validator/Mapping/ClassMetadata.php index dd0dd1fa46a97..d7773861445fb 100644 --- a/src/Symfony/Component/Validator/Mapping/ClassMetadata.php +++ b/src/Symfony/Component/Validator/Mapping/ClassMetadata.php @@ -330,7 +330,7 @@ public function addGetterMethodConstraints($property, $method, array $constraint /** * Merges the constraints of the given metadata into this object. */ - public function mergeConstraints(ClassMetadata $source) + public function mergeConstraints(self $source) { if ($source->isGroupSequenceProvider()) { $this->setGroupSequenceProvider(true); From d7e612d2acda29f18d187167c8dbe8e260423b2e Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 11 May 2018 10:00:11 -0700 Subject: [PATCH 33/59] [Debug] Fix populating error_get_last() for handled silent errors --- src/Symfony/Component/Debug/ErrorHandler.php | 8 ++++--- .../Debug/Tests/ErrorHandlerTest.php | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index e056862b8e675..4671b85469d78 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -377,13 +377,15 @@ private function reRegister($prev) */ public function handleError($type, $message, $file, $line) { - $level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED; + $level = error_reporting(); + $silenced = 0 === ($level & $type); + $level |= E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED; $log = $this->loggedErrors & $type; $throw = $this->thrownErrors & $type & $level; $type &= $level | $this->screamedErrors; if (!$type || (!$log && !$throw)) { - return $type && $log; + return !$silenced && $type && $log; } $scope = $this->scopedErrors & $type; @@ -479,7 +481,7 @@ public function handleError($type, $message, $file, $line) } } - return $type && $log; + return !$silenced && $type && $log; } /** diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php index 4eb4aef0c0fa9..d8f4a74d86969 100644 --- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php +++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php @@ -64,6 +64,30 @@ public function testRegister() } } + public function testErrorGetLast() + { + $handler = ErrorHandler::register(); + $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); + $handler->setDefaultLogger($logger); + $handler->screamAt(E_ALL); + + try { + @trigger_error('Hello', E_USER_WARNING); + $expected = array( + 'type' => E_USER_WARNING, + 'message' => 'Hello', + 'file' => __FILE__, + 'line' => __LINE__ - 5, + ); + $this->assertSame($expected, error_get_last()); + } catch (\Exception $e) { + restore_error_handler(); + restore_exception_handler(); + + throw $e; + } + } + public function testNotice() { ErrorHandler::register(); From 7904784a94b2715eca600317f5a1c18cd3eaed4a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 10 May 2018 19:25:00 -0700 Subject: [PATCH 34/59] [Cache][Lock] Fix usages of error_get_last() --- src/Symfony/Component/Cache/Traits/RedisTrait.php | 9 ++++++--- src/Symfony/Component/Lock/Store/FlockStore.php | 6 ++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Cache/Traits/RedisTrait.php b/src/Symfony/Component/Cache/Traits/RedisTrait.php index b8e05d9e417c9..9fc6177c6bd78 100644 --- a/src/Symfony/Component/Cache/Traits/RedisTrait.php +++ b/src/Symfony/Component/Cache/Traits/RedisTrait.php @@ -126,9 +126,12 @@ public static function createConnection($dsn, array $options = array()) throw new InvalidArgumentException(sprintf('Redis connection failed (%s): %s', $e->getMessage(), $dsn)); } - if (@!$redis->isConnected()) { - $e = ($e = error_get_last()) && preg_match('/^Redis::p?connect\(\): (.*)/', $e['message'], $e) ? sprintf(' (%s)', $e[1]) : ''; - throw new InvalidArgumentException(sprintf('Redis connection failed%s: %s', $e, $dsn)); + set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; }); + $isConnected = $redis->isConnected(); + restore_error_handler(); + if (!$isConnected) { + $error = preg_match('/^Redis::p?connect\(\): (.*)/', $error, $error) ? sprintf(' (%s)', $error[1]) : ''; + throw new InvalidArgumentException(sprintf('Redis connection failed%s: %s', $error, $dsn)); } if ((null !== $auth && !$redis->auth($auth)) diff --git a/src/Symfony/Component/Lock/Store/FlockStore.php b/src/Symfony/Component/Lock/Store/FlockStore.php index 287d6fb583160..d0317358e89a5 100644 --- a/src/Symfony/Component/Lock/Store/FlockStore.php +++ b/src/Symfony/Component/Lock/Store/FlockStore.php @@ -78,8 +78,7 @@ private function lock(Key $key, $blocking) ); // Silence error reporting - set_error_handler(function () { - }); + set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; }); if (!$handle = fopen($fileName, 'r')) { if ($handle = fopen($fileName, 'x')) { chmod($fileName, 0444); @@ -91,8 +90,7 @@ private function lock(Key $key, $blocking) restore_error_handler(); if (!$handle) { - $error = error_get_last(); - throw new LockStorageException($error['message'], 0, null); + throw new LockStorageException($error, 0, null); } // On Windows, even if PHP doc says the contrary, LOCK_NB works, see From f8cde70ba19cb0ac547ea1e63f7a7aea2e07d4bd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 13 May 2018 13:51:16 +0200 Subject: [PATCH 35/59] [HttpKernel] do file_exists() check instead of silent notice --- 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 f54d3589f7dfb..b5e5a2b5ca068 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -587,7 +587,7 @@ protected function initializeContainer() $errorLevel = error_reporting(\E_ALL ^ \E_WARNING); $fresh = $oldContainer = false; try { - if (\is_object($this->container = include $cache->getPath())) { + if (file_exists($cache->getPath()) && \is_object($this->container = include $cache->getPath())) { $this->container->set('kernel', $this); $oldContainer = $this->container; $fresh = true; @@ -650,7 +650,7 @@ protected function initializeContainer() } } - if (null === $oldContainer) { + if (null === $oldContainer && file_exists($cache->getPath())) { $errorLevel = error_reporting(\E_ALL ^ \E_WARNING); try { $oldContainer = include $cache->getPath(); From 9d015c7c50cac8e954276c21025c030250174013 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 10 May 2018 19:25:00 -0700 Subject: [PATCH 36/59] [Filesystem] Fix usages of error_get_last() --- .../Component/Console/Command/Command.php | 5 +- .../Component/Filesystem/Filesystem.php | 64 ++++++++++++------- src/Symfony/Component/Finder/SplFileInfo.php | 7 +- .../Component/HttpFoundation/File/File.php | 8 ++- .../HttpFoundation/File/UploadedFile.php | 8 ++- .../Component/Process/Pipes/AbstractPipes.php | 14 +++- .../Component/Process/Pipes/UnixPipes.php | 5 +- 7 files changed, 73 insertions(+), 38 deletions(-) diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php index 4b8eaea64e666..3fe12e867a827 100644 --- a/src/Symfony/Component/Console/Command/Command.php +++ b/src/Symfony/Component/Console/Command/Command.php @@ -205,12 +205,11 @@ public function run(InputInterface $input, OutputInterface $output) if (null !== $this->processTitle) { if (function_exists('cli_set_process_title')) { - if (false === @cli_set_process_title($this->processTitle)) { + if (!@cli_set_process_title($this->processTitle)) { if ('Darwin' === PHP_OS) { $output->writeln('Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.'); } else { - $error = error_get_last(); - trigger_error($error['message'], E_USER_WARNING); + cli_set_process_title($this->processTitle); } } } elseif (function_exists('setproctitle')) { diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 5c3b2a2d9cb8e..0f6d0a269e6cb 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -21,6 +21,8 @@ */ class Filesystem { + private static $lastError; + /** * Copies a file. * @@ -95,12 +97,11 @@ public function mkdir($dirs, $mode = 0777) continue; } - if (true !== @mkdir($dir, $mode, true)) { - $error = error_get_last(); + if (!self::box('mkdir', $dir, $mode, true)) { if (!is_dir($dir)) { // The directory was not created by a concurrent process. Let's throw an exception with a developer friendly error message if we have one - if ($error) { - throw new IOException(sprintf('Failed to create "%s": %s.', $dir, $error['message']), 0, null, $dir); + if (self::$lastError) { + throw new IOException(sprintf('Failed to create "%s": %s.', $dir, self::$lastError), 0, null, $dir); } throw new IOException(sprintf('Failed to create "%s"', $dir), 0, null, $dir); } @@ -169,20 +170,17 @@ public function remove($files) foreach ($files as $file) { if (is_link($file)) { // See https://bugs.php.net/52176 - if (!@(unlink($file) || '\\' !== DIRECTORY_SEPARATOR || rmdir($file)) && file_exists($file)) { - $error = error_get_last(); - throw new IOException(sprintf('Failed to remove symlink "%s": %s.', $file, $error['message'])); + if (!(self::box('unlink', $file) || '\\' !== DIRECTORY_SEPARATOR || self::box('rmdir', $file)) && file_exists($file)) { + throw new IOException(sprintf('Failed to remove symlink "%s": %s.', $file, self::$lastError)); } } elseif (is_dir($file)) { $this->remove(new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS)); - if (!@rmdir($file) && file_exists($file)) { - $error = error_get_last(); - throw new IOException(sprintf('Failed to remove directory "%s": %s.', $file, $error['message'])); + if (!self::box('rmdir', $file) && file_exists($file)) { + throw new IOException(sprintf('Failed to remove directory "%s": %s.', $file, self::$lastError)); } - } elseif (!@unlink($file) && file_exists($file)) { - $error = error_get_last(); - throw new IOException(sprintf('Failed to remove file "%s": %s.', $file, $error['message'])); + } elseif (!self::box('unlink', $file) && file_exists($file)) { + throw new IOException(sprintf('Failed to remove file "%s": %s.', $file, self::$lastError)); } } } @@ -336,19 +334,16 @@ public function symlink($originDir, $targetDir, $copyOnWindows = false) $this->mkdir(dirname($targetDir)); - $ok = false; if (is_link($targetDir)) { - if (readlink($targetDir) != $originDir) { - $this->remove($targetDir); - } else { - $ok = true; + if (readlink($targetDir) === $originDir) { + return; } + $this->remove($targetDir); } - if (!$ok && true !== @symlink($originDir, $targetDir)) { - $report = error_get_last(); - if (is_array($report)) { - if ('\\' === DIRECTORY_SEPARATOR && false !== strpos($report['message'], 'error code(1314)')) { + if (!self::box('symlink', $originDir, $targetDir)) { + if (null !== self::$lastError) { + if ('\\' === DIRECTORY_SEPARATOR && false !== strpos(self::$lastError, 'error code(1314)')) { throw new IOException('Unable to create symlink due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', 0, null, $targetDir); } } @@ -580,4 +575,29 @@ private function toIterator($files) return $files; } + + private static function box($func) + { + self::$lastError = null; + \set_error_handler(__CLASS__.'::handleError'); + try { + $result = \call_user_func_array($func, \array_slice(\func_get_args(), 1)); + \restore_error_handler(); + + return $result; + } catch (\Throwable $e) { + } catch (\Exception $e) { + } + \restore_error_handler(); + + throw $e; + } + + /** + * @internal + */ + public static function handleError($type, $msg) + { + self::$lastError = $msg; + } } diff --git a/src/Symfony/Component/Finder/SplFileInfo.php b/src/Symfony/Component/Finder/SplFileInfo.php index 19f95e26be69a..0f4e025b22bd2 100644 --- a/src/Symfony/Component/Finder/SplFileInfo.php +++ b/src/Symfony/Component/Finder/SplFileInfo.php @@ -66,12 +66,11 @@ public function getRelativePathname() */ public function getContents() { - $level = error_reporting(0); + set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; }); $content = file_get_contents($this->getPathname()); - error_reporting($level); + restore_error_handler(); if (false === $content) { - $error = error_get_last(); - throw new \RuntimeException($error['message']); + throw new \RuntimeException($error); } return $content; diff --git a/src/Symfony/Component/HttpFoundation/File/File.php b/src/Symfony/Component/HttpFoundation/File/File.php index e2a67684fcda6..65ece98379019 100644 --- a/src/Symfony/Component/HttpFoundation/File/File.php +++ b/src/Symfony/Component/HttpFoundation/File/File.php @@ -93,9 +93,11 @@ public function move($directory, $name = null) { $target = $this->getTargetFile($directory, $name); - if (!@rename($this->getPathname(), $target)) { - $error = error_get_last(); - throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message']))); + set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; }); + $renamed = rename($this->getPathname(), $target); + restore_error_handler(); + if (!$renamed) { + throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error))); } @chmod($target, 0666 & ~umask()); diff --git a/src/Symfony/Component/HttpFoundation/File/UploadedFile.php b/src/Symfony/Component/HttpFoundation/File/UploadedFile.php index 082d8d534e17a..39b29775ccd8e 100644 --- a/src/Symfony/Component/HttpFoundation/File/UploadedFile.php +++ b/src/Symfony/Component/HttpFoundation/File/UploadedFile.php @@ -192,9 +192,11 @@ public function move($directory, $name = null) $target = $this->getTargetFile($directory, $name); - if (!@move_uploaded_file($this->getPathname(), $target)) { - $error = error_get_last(); - throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message']))); + set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; }); + $moved = move_uploaded_file($this->getPathname(), $target); + restore_error_handler(); + if (!$moved) { + throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error))); } @chmod($target, 0666 & ~umask()); diff --git a/src/Symfony/Component/Process/Pipes/AbstractPipes.php b/src/Symfony/Component/Process/Pipes/AbstractPipes.php index 9a23d93c98688..97fe728bfd70d 100644 --- a/src/Symfony/Component/Process/Pipes/AbstractPipes.php +++ b/src/Symfony/Component/Process/Pipes/AbstractPipes.php @@ -23,6 +23,7 @@ abstract class AbstractPipes implements PipesInterface private $inputBuffer = ''; private $input; private $blocked = true; + private $lastError; /** * @param resource|null $input @@ -56,10 +57,11 @@ public function close() */ protected function hasSystemCallBeenInterrupted() { - $lastError = error_get_last(); + $lastError = $this->lastError; + $this->lastError = null; // stream_select returns false when the `select` system call is interrupted by an incoming signal - return isset($lastError['message']) && false !== stripos($lastError['message'], 'interrupted system call'); + return null !== $lastError && false !== stripos($lastError, 'interrupted system call'); } /** @@ -137,4 +139,12 @@ protected function write() return array($this->pipes[0]); } } + + /** + * @internal + */ + public function handleError($type, $msg) + { + $this->lastError = $msg; + } } diff --git a/src/Symfony/Component/Process/Pipes/UnixPipes.php b/src/Symfony/Component/Process/Pipes/UnixPipes.php index 65f32ecf2735a..935c43209d9da 100644 --- a/src/Symfony/Component/Process/Pipes/UnixPipes.php +++ b/src/Symfony/Component/Process/Pipes/UnixPipes.php @@ -99,7 +99,9 @@ public function readAndWrite($blocking, $close = false) unset($r[0]); // let's have a look if something changed in streams - if (($r || $w) && false === @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) { + set_error_handler(array($this, 'handleError')); + if (($r || $w) && false === stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) { + restore_error_handler(); // if a system call has been interrupted, forget about it, let's try again // otherwise, an error occurred, let's reset pipes if (!$this->hasSystemCallBeenInterrupted()) { @@ -108,6 +110,7 @@ public function readAndWrite($blocking, $close = false) return $read; } + restore_error_handler(); foreach ($r as $pipe) { // prior PHP 5.4 the array passed to stream_select is modified and From 16ebb43bd4ff29b53cb78b9cd1d1f7d97de3cb32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Ostroluck=C3=BD?= Date: Sat, 12 May 2018 21:17:30 +0200 Subject: [PATCH 37/59] Disallow illegal characters like "." in session.name PHP saves cookie with correct name, but upon deserialization to $_COOKIE, it replaces some characters, e.g. "." becomes "_". This is probably also reason why \SessionHandler is not able to find a session. https://harrybailey.com/2009/04/dots-arent-allowed-in-php-cookie-names/ https://bugs.php.net/bug.php?id=75883 --- .../DependencyInjection/Configuration.php | 11 ++++- .../DependencyInjection/ConfigurationTest.php | 49 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index b21b3ee8df769..a29d8fada010a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -339,7 +339,16 @@ private function addSessionSection(ArrayNodeDefinition $rootNode) ->children() ->scalarNode('storage_id')->defaultValue('session.storage.native')->end() ->scalarNode('handler_id')->defaultValue('session.handler.native_file')->end() - ->scalarNode('name')->end() + ->scalarNode('name') + ->validate() + ->ifTrue(function ($v) { + parse_str($v, $parsed); + + return implode('&', array_keys($parsed)) !== (string) $v; + }) + ->thenInvalid('Session name %s contains illegal character(s)') + ->end() + ->end() ->scalarNode('cookie_lifetime')->end() ->scalarNode('cookie_path')->end() ->scalarNode('cookie_domain')->end() diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index a20a120d0710b..6505d5a034932 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -41,6 +41,55 @@ public function testDoNoDuplicateDefaultFormResources() $this->assertEquals(array('FrameworkBundle:Form'), $config['templating']['form']['resources']); } + /** + * @dataProvider getTestValidSessionName + */ + public function testValidSessionName($sessionName) + { + $processor = new Processor(); + $config = $processor->processConfiguration( + new Configuration(true), + array(array('session' => array('name' => $sessionName))) + ); + + $this->assertEquals($sessionName, $config['session']['name']); + } + + public function getTestValidSessionName() + { + return array( + array(null), + array('PHPSESSID'), + array('a&b'), + array(',_-!@#$%^*(){}:<>/?'), + ); + } + + /** + * @dataProvider getTestInvalidSessionName + * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException + */ + public function testInvalidSessionName($sessionName) + { + $processor = new Processor(); + $processor->processConfiguration( + new Configuration(true), + array(array('session' => array('name' => $sessionName))) + ); + } + + public function getTestInvalidSessionName() + { + return array( + array('a.b'), + array('a['), + array('a[]'), + array('a[b]'), + array('a=b'), + array('a+b'), + ); + } + /** * @dataProvider getTestValidTrustedProxiesData */ From d52f491bfa94d2092f9beb1e8137fc6b0f32ceab Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Mon, 14 May 2018 18:07:30 +0200 Subject: [PATCH 38/59] [Profiler] Remove propel & event_listener_loading category identifiers --- .../WebProfilerBundle/Resources/views/Collector/time.html.twig | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig index 3361be296e26b..469aee8f5fe60 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig @@ -7,10 +7,8 @@ 'default': '#aacd4e', 'section': '#666', 'event_listener': '#3dd', - 'event_listener_loading': '#add', 'template': '#dd3', 'doctrine': '#d3d', - 'propel': '#f4d', 'child_sections': '#eed', } %} {% endif %} From 6f8b8625f45f04b30bb69e227c4a2b4bc7ede528 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 13 May 2018 23:24:43 +0200 Subject: [PATCH 39/59] [DI] Shared services should not be inlined in non-shared ones --- .../Compiler/InlineServiceDefinitionsPass.php | 2 +- .../Tests/Compiler/InlineServiceDefinitionsPassTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php index c64348ed1de3b..a79e78b6b2a46 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php @@ -138,6 +138,6 @@ private function isInlineableDefinition($id, Definition $definition, ServiceRefe return false; } - return true; + return $this->container->getDefinition($ids[0])->isShared(); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php index adaa4044f453c..4abe6143152c7 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php @@ -92,7 +92,7 @@ public function testProcessDoesInlineNonSharedService() $this->assertNotSame($container->getDefinition('bar'), $arguments[2]); } - public function testProcessInlinesMixedServicesLoop() + public function testProcessDoesNotInlineMixedServicesLoop() { $container = new ContainerBuilder(); $container @@ -108,7 +108,7 @@ public function testProcessInlinesMixedServicesLoop() $this->process($container); - $this->assertEquals($container->getDefinition('foo')->getArgument(0), $container->getDefinition('bar')); + $this->assertEquals(new Reference('bar'), $container->getDefinition('foo')->getArgument(0)); } /** From b2a97ea00f8993b2efbc491ad60af1672f62ed9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Ostroluck=C3=BD?= Date: Sat, 12 May 2018 16:29:41 +0200 Subject: [PATCH 40/59] [Config] Fix tests when path contains UTF chars --- src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php b/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php index 9d61c9cd83284..10b4a7a9b4dc7 100644 --- a/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php +++ b/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php @@ -55,7 +55,7 @@ public function testLoadFile() XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate')); $this->fail(); } catch (\InvalidArgumentException $e) { - $this->assertRegExp('/The XML file "[\w:\/\\\.~+-]+" is not valid\./', $e->getMessage()); + $this->assertRegExp('/The XML file ".+" is not valid\./', $e->getMessage()); } $this->assertInstanceOf('DOMDocument', XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate'))); From 2400e719621fdc9b3f7b9254ed1f6d38bf35a84c Mon Sep 17 00:00:00 2001 From: Adam Szaraniec Date: Mon, 14 May 2018 21:15:07 +0400 Subject: [PATCH 41/59] use strict compare in url validator --- src/Symfony/Component/Validator/Constraints/UrlValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Constraints/UrlValidator.php b/src/Symfony/Component/Validator/Constraints/UrlValidator.php index 222597ed10f41..292e117d9f12d 100644 --- a/src/Symfony/Component/Validator/Constraints/UrlValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UrlValidator.php @@ -92,7 +92,7 @@ public function validate($value, Constraint $constraint) Url::CHECK_DNS_TYPE_SOA, Url::CHECK_DNS_TYPE_SRV, Url::CHECK_DNS_TYPE_TXT, - ))) { + ), true)) { throw new InvalidOptionsException(sprintf('Invalid value for option "checkDNS" in constraint %s', get_class($constraint)), array('checkDNS')); } From 9cda96b8b539e85f5be3afed406905f341f4741b Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Mon, 14 May 2018 20:26:58 +0300 Subject: [PATCH 42/59] #27250 limiting GET_LOCK key up to 64 char due to changes in MySQL 5.7.5 and later --- .../Session/Storage/Handler/PdoSessionHandler.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php index dfd66516062c3..0825ee6ea9899 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php @@ -552,14 +552,16 @@ private function doAdvisoryLock($sessionId) { switch ($this->driver) { case 'mysql': + // MySQL 5.7.5 and later enforces a maximum length on lock names of 64 characters. Previously, no limit was enforced. + $lockId = \substr($sessionId, 0, 64); // should we handle the return value? 0 on timeout, null on error // we use a timeout of 50 seconds which is also the default for innodb_lock_wait_timeout $stmt = $this->pdo->prepare('SELECT GET_LOCK(:key, 50)'); - $stmt->bindValue(':key', $sessionId, \PDO::PARAM_STR); + $stmt->bindValue(':key', $lockId, \PDO::PARAM_STR); $stmt->execute(); $releaseStmt = $this->pdo->prepare('DO RELEASE_LOCK(:key)'); - $releaseStmt->bindValue(':key', $sessionId, \PDO::PARAM_STR); + $releaseStmt->bindValue(':key', $lockId, \PDO::PARAM_STR); return $releaseStmt; case 'pgsql': From 5516b329afee4b7ed9601f39911440ad673eff80 Mon Sep 17 00:00:00 2001 From: ncou Date: Mon, 14 May 2018 10:51:37 +0200 Subject: [PATCH 43/59] Cleanup 2 tests for the HttpException classes --- .../UnprocessableEntityHttpExceptionTest.php | 15 --------------- .../UnsupportedMediaTypeHttpExceptionTest.php | 12 +----------- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Tests/Exception/UnprocessableEntityHttpExceptionTest.php b/src/Symfony/Component/HttpKernel/Tests/Exception/UnprocessableEntityHttpExceptionTest.php index 760366c6943a1..05d8d787aa5c5 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Exception/UnprocessableEntityHttpExceptionTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Exception/UnprocessableEntityHttpExceptionTest.php @@ -6,21 +6,6 @@ class UnprocessableEntityHttpExceptionTest extends HttpExceptionTest { - /** - * Test that setting the headers using the setter function - * is working as expected. - * - * @param array $headers The headers to set - * - * @dataProvider headerDataProvider - */ - public function testHeadersSetter($headers) - { - $exception = new UnprocessableEntityHttpException(10); - $exception->setHeaders($headers); - $this->assertSame($headers, $exception->getHeaders()); - } - protected function createException() { return new UnprocessableEntityHttpException(); diff --git a/src/Symfony/Component/HttpKernel/Tests/Exception/UnsupportedMediaTypeHttpExceptionTest.php b/src/Symfony/Component/HttpKernel/Tests/Exception/UnsupportedMediaTypeHttpExceptionTest.php index d47287a1fbc69..4dae039c11fc1 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Exception/UnsupportedMediaTypeHttpExceptionTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Exception/UnsupportedMediaTypeHttpExceptionTest.php @@ -6,17 +6,7 @@ class UnsupportedMediaTypeHttpExceptionTest extends HttpExceptionTest { - /** - * @dataProvider headerDataProvider - */ - public function testHeadersSetter($headers) - { - $exception = new UnsupportedMediaTypeHttpException(10); - $exception->setHeaders($headers); - $this->assertSame($headers, $exception->getHeaders()); - } - - protected function createException($headers = array()) + protected function createException() { return new UnsupportedMediaTypeHttpException(); } From 1c3b1055dfb3b8ea5318743f480715b9d40a6635 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 15 May 2018 09:06:31 +0200 Subject: [PATCH 44/59] [DI] Allow defining bindings on ChildDefinition --- .../DependencyInjection/ChildDefinition.php | 8 ------- .../Compiler/ResolveChildDefinitionsPass.php | 2 +- .../ResolveChildDefinitionsPassTest.php | 21 +++++++++++++++++++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/ChildDefinition.php b/src/Symfony/Component/DependencyInjection/ChildDefinition.php index f363a64829c24..61460ca2e0f71 100644 --- a/src/Symfony/Component/DependencyInjection/ChildDefinition.php +++ b/src/Symfony/Component/DependencyInjection/ChildDefinition.php @@ -121,14 +121,6 @@ public function setInstanceofConditionals(array $instanceof) { throw new BadMethodCallException('A ChildDefinition cannot have instanceof conditionals set on it.'); } - - /** - * @internal - */ - public function setBindings(array $bindings) - { - throw new BadMethodCallException('A ChildDefinition cannot have bindings set on it.'); - } } class_alias(ChildDefinition::class, DefinitionDecorator::class); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveChildDefinitionsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveChildDefinitionsPass.php index a124e472aca81..eefb0cefd4ff7 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveChildDefinitionsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveChildDefinitionsPass.php @@ -103,7 +103,7 @@ private function doResolveDefinition(ChildDefinition $definition) $def->setAutowired($parentDef->isAutowired()); $def->setChanges($parentDef->getChanges()); - $def->setBindings($parentDef->getBindings()); + $def->setBindings($definition->getBindings() + $parentDef->getBindings()); // overwrite with values specified in the decorator $changes = $definition->getChanges(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php index 23a1915fd777c..18c0fb7c5987f 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php @@ -382,6 +382,27 @@ public function testProcessSetsArguments() $this->assertSame(array(2, 1, 'foo' => 3), $def->getArguments()); } + public function testBindings() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass') + ->setBindings(array('a' => '1', 'b' => '2')) + ; + + $child = $container->setDefinition('child', new ChildDefinition('parent')) + ->setBindings(array('b' => 'B', 'c' => 'C')) + ; + + $this->process($container); + + $bindings = array(); + foreach ($container->getDefinition('child')->getBindings() as $k => $v) { + $bindings[$k] = $v->getValues()[0]; + } + $this->assertEquals(array('b' => 'B', 'c' => 'C', 'a' => '1'), $bindings); + } + public function testSetAutoconfiguredOnServiceIsParent() { $container = new ContainerBuilder(); From 9e88eb5aa980e09f0f9ac691ebbe08d1baac0e0a Mon Sep 17 00:00:00 2001 From: MatTheCat Date: Fri, 11 May 2018 20:46:08 +0200 Subject: [PATCH 45/59] [Security] Fix logout --- .../DependencyInjection/SecurityExtension.php | 25 +++++++------- .../Resources/config/security.xml | 1 + .../Security/FirewallContext.php | 7 ++-- .../SecurityBundle/Security/FirewallMap.php | 2 +- .../CompleteConfigurationTest.php | 1 - .../Tests/Functional/LogoutTest.php | 34 +++++++++++++++++++ .../app/RememberMeLogout/bundles.php | 18 ++++++++++ .../app/RememberMeLogout/config.yml | 25 ++++++++++++++ .../app/RememberMeLogout/routing.yml | 5 +++ .../Bundle/SecurityBundle/composer.json | 2 +- .../Component/Security/Http/Firewall.php | 13 +++++-- .../Component/Security/Http/FirewallMap.php | 9 ++--- 12 files changed, 119 insertions(+), 23 deletions(-) create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/bundles.php create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/config.yml create mode 100644 src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/routing.yml diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 3ffe2876e88d8..9c526f88daa9d 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -222,13 +222,14 @@ private function createFirewalls($config, ContainerBuilder $container) $mapDef = $container->getDefinition('security.firewall.map'); $map = $authenticationProviders = array(); foreach ($firewalls as $name => $firewall) { - list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds); + list($matcher, $listeners, $exceptionListener, $logoutListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds); $contextId = 'security.firewall.map.context.'.$name; $context = $container->setDefinition($contextId, new DefinitionDecorator('security.firewall.context')); $context ->replaceArgument(0, $listeners) ->replaceArgument(1, $exceptionListener) + ->replaceArgument(2, $logoutListener) ; $map[$contextId] = $matcher; } @@ -259,7 +260,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a // Security disabled? if (false === $firewall['security']) { - return array($matcher, array(), null); + return array($matcher, array(), null, null); } // Provider id (take the first registered provider if none defined) @@ -286,15 +287,15 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a } // Logout listener + $logoutListenerId = null; if (isset($firewall['logout'])) { - $listenerId = 'security.logout_listener.'.$id; - $listener = $container->setDefinition($listenerId, new DefinitionDecorator('security.logout_listener')); - $listener->replaceArgument(3, array( + $logoutListenerId = 'security.logout_listener.'.$id; + $logoutListener = $container->setDefinition($logoutListenerId, new DefinitionDecorator('security.logout_listener')); + $logoutListener->replaceArgument(3, array( 'csrf_parameter' => $firewall['logout']['csrf_parameter'], 'intention' => $firewall['logout']['csrf_token_id'], 'logout_path' => $firewall['logout']['path'], )); - $listeners[] = new Reference($listenerId); // add logout success handler if (isset($firewall['logout']['success_handler'])) { @@ -304,16 +305,16 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a $logoutSuccessHandler = $container->setDefinition($logoutSuccessHandlerId, new DefinitionDecorator('security.logout.success_handler')); $logoutSuccessHandler->replaceArgument(1, $firewall['logout']['target']); } - $listener->replaceArgument(2, new Reference($logoutSuccessHandlerId)); + $logoutListener->replaceArgument(2, new Reference($logoutSuccessHandlerId)); // add CSRF provider if (isset($firewall['logout']['csrf_token_generator'])) { - $listener->addArgument(new Reference($firewall['logout']['csrf_token_generator'])); + $logoutListener->addArgument(new Reference($firewall['logout']['csrf_token_generator'])); } // add session logout handler if (true === $firewall['logout']['invalidate_session'] && false === $firewall['stateless']) { - $listener->addMethodCall('addHandler', array(new Reference('security.logout.handler.session'))); + $logoutListener->addMethodCall('addHandler', array(new Reference('security.logout.handler.session'))); } // add cookie logout handler @@ -322,12 +323,12 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a $cookieHandler = $container->setDefinition($cookieHandlerId, new DefinitionDecorator('security.logout.handler.cookie_clearing')); $cookieHandler->addArgument($firewall['logout']['delete_cookies']); - $listener->addMethodCall('addHandler', array(new Reference($cookieHandlerId))); + $logoutListener->addMethodCall('addHandler', array(new Reference($cookieHandlerId))); } // add custom handlers foreach ($firewall['logout']['handlers'] as $handlerId) { - $listener->addMethodCall('addHandler', array(new Reference($handlerId))); + $logoutListener->addMethodCall('addHandler', array(new Reference($handlerId))); } // register with LogoutUrlGenerator @@ -362,7 +363,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a // Exception listener $exceptionListener = new Reference($this->createExceptionListener($container, $firewall, $id, $configuredEntryPoint ?: $defaultEntryPoint, $firewall['stateless'])); - return array($matcher, $listeners, $exceptionListener); + return array($matcher, $listeners, $exceptionListener, null !== $logoutListenerId ? new Reference($logoutListenerId) : null); } private function createContextListener($container, $contextKey) diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml index b7c1407c1cc56..b044ccba98e74 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml @@ -150,6 +150,7 @@ + diff --git a/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php b/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php index 13d096d97e951..e9f8fe66d6395 100644 --- a/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php +++ b/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\Security\Http\Firewall\ExceptionListener; +use Symfony\Component\Security\Http\Firewall\LogoutListener; /** * This is a wrapper around the actual firewall configuration which allows us @@ -23,15 +24,17 @@ class FirewallContext { private $listeners; private $exceptionListener; + private $logoutListener; - public function __construct(array $listeners, ExceptionListener $exceptionListener = null) + public function __construct(array $listeners, ExceptionListener $exceptionListener = null, LogoutListener $logoutListener = null) { $this->listeners = $listeners; $this->exceptionListener = $exceptionListener; + $this->logoutListener = $logoutListener; } public function getContext() { - return array($this->listeners, $this->exceptionListener); + return array($this->listeners, $this->exceptionListener, $this->logoutListener); } } diff --git a/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php b/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php index dc87681c37511..d45d7b87f04a6 100644 --- a/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php +++ b/src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php @@ -41,6 +41,6 @@ public function getListeners(Request $request) } } - return array(array(), null); + return array(array(), null, null); } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php index 855bed9b6899d..371baa704a835 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php @@ -76,7 +76,6 @@ public function testFirewalls() array(), array( 'security.channel_listener', - 'security.logout_listener.secure', 'security.authentication.listener.x509.secure', 'security.authentication.listener.remote_user.secure', 'security.authentication.listener.form.secure', diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php new file mode 100644 index 0000000000000..7eeb7c21171ce --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\Functional; + +class LogoutTest extends WebTestCase +{ + public function testSessionLessRememberMeLogout() + { + $client = $this->createClient(array('test_case' => 'RememberMeLogout', 'root_config' => 'config.yml')); + + $client->request('POST', '/login', array( + '_username' => 'johannes', + '_password' => 'test', + )); + + $cookieJar = $client->getCookieJar(); + $cookieJar->expire(session_name()); + + $this->assertNotNull($cookieJar->get('REMEMBERME')); + + $client->request('GET', '/logout'); + + $this->assertNull($cookieJar->get('REMEMBERME')); + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/bundles.php new file mode 100644 index 0000000000000..d90f774abde2b --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/bundles.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Bundle\SecurityBundle\SecurityBundle; +use Symfony\Bundle\FrameworkBundle\FrameworkBundle; + +return array( + new FrameworkBundle(), + new SecurityBundle(), +); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/config.yml new file mode 100644 index 0000000000000..48fd4ed6cc3cd --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/config.yml @@ -0,0 +1,25 @@ +imports: + - { resource: ./../config/framework.yml } + +security: + encoders: + Symfony\Component\Security\Core\User\User: plaintext + + providers: + in_memory: + memory: + users: + johannes: { password: test, roles: [ROLE_USER] } + + firewalls: + default: + form_login: + check_path: login + remember_me: true + require_previous_session: false + remember_me: + always_remember_me: true + key: key + logout: ~ + anonymous: ~ + stateless: true diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/routing.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/routing.yml new file mode 100644 index 0000000000000..1dddfca2f8154 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/routing.yml @@ -0,0 +1,5 @@ +login: + path: /login + +logout: + path: /logout diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index e765b16bef867..90edcf6e38cee 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=5.3.9", "ext-xml": "*", - "symfony/security": "~2.7.38|~2.8.31", + "symfony/security": "~2.7.47|~2.8.40", "symfony/security-acl": "~2.7", "symfony/http-kernel": "~2.7" }, diff --git a/src/Symfony/Component/Security/Http/Firewall.php b/src/Symfony/Component/Security/Http/Firewall.php index 62b0071212e54..376194d3a6c8c 100644 --- a/src/Symfony/Component/Security/Http/Firewall.php +++ b/src/Symfony/Component/Security/Http/Firewall.php @@ -47,20 +47,29 @@ public function onKernelRequest(GetResponseEvent $event) } // register listeners for this firewall - list($listeners, $exceptionListener) = $this->map->getListeners($event->getRequest()); + $listeners = $this->map->getListeners($event->getRequest()); + + $authenticationListeners = $listeners[0]; + $exceptionListener = $listeners[1]; + $logoutListener = isset($listeners[2]) ? $listeners[2] : null; + if (null !== $exceptionListener) { $this->exceptionListeners[$event->getRequest()] = $exceptionListener; $exceptionListener->register($this->dispatcher); } // initiate the listener chain - foreach ($listeners as $listener) { + foreach ($authenticationListeners as $listener) { $listener->handle($event); if ($event->hasResponse()) { break; } } + + if (null !== $logoutListener) { + $logoutListener->handle($event); + } } public function onKernelFinishRequest(FinishRequestEvent $event) diff --git a/src/Symfony/Component/Security/Http/FirewallMap.php b/src/Symfony/Component/Security/Http/FirewallMap.php index e767d123cb03e..fc97410d4e698 100644 --- a/src/Symfony/Component/Security/Http/FirewallMap.php +++ b/src/Symfony/Component/Security/Http/FirewallMap.php @@ -14,6 +14,7 @@ use Symfony\Component\HttpFoundation\RequestMatcherInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Http\Firewall\ExceptionListener; +use Symfony\Component\Security\Http\Firewall\LogoutListener; /** * FirewallMap allows configuration of different firewalls for specific parts @@ -25,9 +26,9 @@ class FirewallMap implements FirewallMapInterface { private $map = array(); - public function add(RequestMatcherInterface $requestMatcher = null, array $listeners = array(), ExceptionListener $exceptionListener = null) + public function add(RequestMatcherInterface $requestMatcher = null, array $listeners = array(), ExceptionListener $exceptionListener = null, LogoutListener $logoutListener = null) { - $this->map[] = array($requestMatcher, $listeners, $exceptionListener); + $this->map[] = array($requestMatcher, $listeners, $exceptionListener, $logoutListener); } /** @@ -37,10 +38,10 @@ public function getListeners(Request $request) { foreach ($this->map as $elements) { if (null === $elements[0] || $elements[0]->matches($request)) { - return array($elements[1], $elements[2]); + return array($elements[1], $elements[2], $elements[3]); } } - return array(array(), null); + return array(array(), null, null); } } From 97cbea005e6e1e5c238a8e1d6a753a54404811a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Ostroluck=C3=BD?= Date: Tue, 15 May 2018 20:17:27 +0200 Subject: [PATCH 46/59] [Lock] Skip test if posix extension is not installed This isn't installed by default on Fedora --- .../Component/Lock/Tests/Store/BlockingStoreTestTrait.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Lock/Tests/Store/BlockingStoreTestTrait.php b/src/Symfony/Component/Lock/Tests/Store/BlockingStoreTestTrait.php index 93e5a54793f31..588f0028a4944 100644 --- a/src/Symfony/Component/Lock/Tests/Store/BlockingStoreTestTrait.php +++ b/src/Symfony/Component/Lock/Tests/Store/BlockingStoreTestTrait.php @@ -31,6 +31,7 @@ abstract protected function getStore(); * This test is time sensible: the $clockDelay could be adjust. * * @requires extension pcntl + * @requires extension posix * @requires function pcntl_sigwaitinfo */ public function testBlockingLocks() From f49310b54cd3e44779819717617989843bb77325 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 16 May 2018 10:49:48 +0200 Subject: [PATCH 47/59] fix merge --- .../Tests/Functional/app/RememberMeLogout/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/config.yml b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/config.yml index 48fd4ed6cc3cd..60e9cb89a229a 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/config.yml +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/config.yml @@ -19,7 +19,7 @@ security: require_previous_session: false remember_me: always_remember_me: true - key: key + secret: key logout: ~ anonymous: ~ stateless: true From ba5cb1a24548b86835be960867687c1f3d3bec05 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 11 May 2018 17:58:37 +0200 Subject: [PATCH 48/59] fixed CS --- .../PhpUnit/Legacy/CoverageListenerTrait.php | 1 - .../weak_vendors_on_eval_d_deprecation.phpt | 2 +- src/Symfony/Bridge/Twig/NodeVisitor/Scope.php | 2 +- .../Tests/Controller/ControllerTest.php | 1 - .../DataCollector/CacheDataCollector.php | 18 ++--- .../CssSelector/Node/Specificity.php | 4 +- .../Component/CssSelector/XPath/XPathExpr.php | 2 - .../Debug/Exception/FlattenException.php | 2 +- .../Configurator/InstanceofConfigurator.php | 2 +- src/Symfony/Component/Form/FormView.php | 2 +- .../Tests/AbstractBootstrap4LayoutTest.php | 81 ++++++++++--------- .../ArgumentMetadataFactory.php | 28 +++++-- .../HttpKernel/Profiler/Profiler.php | 2 +- .../ArgumentMetadataFactoryTest.php | 4 +- .../Tests/Profiler/ProfilerTest.php | 2 +- .../Tests/Fixtures/ParentDummy.php | 2 +- src/Symfony/Component/PropertyInfo/Type.php | 4 +- .../Matcher/Dumper/DumperCollection.php | 2 +- .../Routing/RouteCollectionBuilder.php | 4 +- .../Http/Firewall/ContextListener.php | 8 +- .../Mapping/AttributeMetadataInterface.php | 2 +- .../Mapping/ClassMetadataInterface.php | 2 +- .../Normalizer/AbstractObjectNormalizer.php | 1 - .../Translation/MessageCatalogueInterface.php | 4 +- .../Validator/Mapping/ClassMetadata.php | 2 +- 25 files changed, 96 insertions(+), 88 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php index 1c84ff32c0b74..ab1cda6702be5 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/CoverageListenerTrait.php @@ -11,7 +11,6 @@ namespace Symfony\Bridge\PhpUnit\Legacy; -use PHPUnit\Framework\Test; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Warning; 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 8fa436e20178b..8390d16332fa1 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 @@ -15,7 +15,7 @@ while (!file_exists($vendor.'/vendor')) { define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php'); require PHPUNIT_COMPOSER_INSTALL; require_once __DIR__.'/../../bootstrap.php'; -eval("@trigger_error('who knows where I come from?', E_USER_DEPRECATED);") +eval("@trigger_error('who knows where I come from?', E_USER_DEPRECATED);"); ?> --EXPECTF-- diff --git a/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php b/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php index 1c3451bbebf46..59497dc961984 100644 --- a/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php +++ b/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php @@ -20,7 +20,7 @@ class Scope private $data = array(); private $left = false; - public function __construct(Scope $parent = null) + public function __construct(self $parent = null) { $this->parent = $parent; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php index 9fd20649289de..452845cea8e34 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php @@ -12,7 +12,6 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; -use Symfony\Component\HttpFoundation\File\File; class ControllerTest extends ControllerTraitTest { diff --git a/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php b/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php index 962fb25cb94cb..ac5c36d2fd83a 100644 --- a/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php +++ b/src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php @@ -122,30 +122,30 @@ private function calculateStatistics() ); /** @var TraceableAdapterEvent $call */ foreach ($calls as $call) { - $statistics[$name]['calls'] += 1; + ++$statistics[$name]['calls']; $statistics[$name]['time'] += $call->end - $call->start; if ('getItem' === $call->name) { - $statistics[$name]['reads'] += 1; + ++$statistics[$name]['reads']; if ($call->hits) { - $statistics[$name]['hits'] += 1; + ++$statistics[$name]['hits']; } else { - $statistics[$name]['misses'] += 1; + ++$statistics[$name]['misses']; } } elseif ('getItems' === $call->name) { $statistics[$name]['reads'] += $call->hits + $call->misses; $statistics[$name]['hits'] += $call->hits; $statistics[$name]['misses'] += $call->misses; } elseif ('hasItem' === $call->name) { - $statistics[$name]['reads'] += 1; + ++$statistics[$name]['reads']; if (false === $call->result) { - $statistics[$name]['misses'] += 1; + ++$statistics[$name]['misses']; } else { - $statistics[$name]['hits'] += 1; + ++$statistics[$name]['hits']; } } elseif ('save' === $call->name) { - $statistics[$name]['writes'] += 1; + ++$statistics[$name]['writes']; } elseif ('deleteItem' === $call->name) { - $statistics[$name]['deletes'] += 1; + ++$statistics[$name]['deletes']; } } if ($statistics[$name]['reads']) { diff --git a/src/Symfony/Component/CssSelector/Node/Specificity.php b/src/Symfony/Component/CssSelector/Node/Specificity.php index 6aa70d781cae2..a11b7f73d89c8 100644 --- a/src/Symfony/Component/CssSelector/Node/Specificity.php +++ b/src/Symfony/Component/CssSelector/Node/Specificity.php @@ -48,7 +48,7 @@ public function __construct($a, $b, $c) /** * @return self */ - public function plus(Specificity $specificity) + public function plus(self $specificity) { return new self($this->a + $specificity->a, $this->b + $specificity->b, $this->c + $specificity->c); } @@ -69,7 +69,7 @@ public function getValue() * * @return int */ - public function compareTo(Specificity $specificity) + public function compareTo(self $specificity) { if ($this->a !== $specificity->a) { return $this->a > $specificity->a ? 1 : -1; diff --git a/src/Symfony/Component/CssSelector/XPath/XPathExpr.php b/src/Symfony/Component/CssSelector/XPath/XPathExpr.php index 63e3ac36bf820..a1e244c9e45d8 100644 --- a/src/Symfony/Component/CssSelector/XPath/XPathExpr.php +++ b/src/Symfony/Component/CssSelector/XPath/XPathExpr.php @@ -53,8 +53,6 @@ public function getElement() } /** - * @param $condition - * * @return $this */ public function addCondition($condition) diff --git a/src/Symfony/Component/Debug/Exception/FlattenException.php b/src/Symfony/Component/Debug/Exception/FlattenException.php index 24679dcaab242..f491bf2ac4c92 100644 --- a/src/Symfony/Component/Debug/Exception/FlattenException.php +++ b/src/Symfony/Component/Debug/Exception/FlattenException.php @@ -157,7 +157,7 @@ public function getPrevious() return $this->previous; } - public function setPrevious(FlattenException $previous) + public function setPrevious(self $previous) { $this->previous = $previous; } diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/InstanceofConfigurator.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/InstanceofConfigurator.php index 1d3975bf8794e..629874d19cd14 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/Configurator/InstanceofConfigurator.php +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/InstanceofConfigurator.php @@ -34,7 +34,7 @@ class InstanceofConfigurator extends AbstractServiceConfigurator * * @param string $fqcn * - * @return InstanceofConfigurator + * @return self */ final protected function setInstanceof($fqcn) { diff --git a/src/Symfony/Component/Form/FormView.php b/src/Symfony/Component/Form/FormView.php index 21a3d5036ad2b..9fbca4379688a 100644 --- a/src/Symfony/Component/Form/FormView.php +++ b/src/Symfony/Component/Form/FormView.php @@ -51,7 +51,7 @@ class FormView implements \ArrayAccess, \IteratorAggregate, \Countable private $methodRendered = false; - public function __construct(FormView $parent = null) + public function __construct(self $parent = null) { $this->parent = $parent; } diff --git a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php index 2cadba0ba9e67..f9c4613e591c7 100644 --- a/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php @@ -11,6 +11,15 @@ namespace Symfony\Component\Form\Tests; +use Symfony\Component\Form\Extension\Core\Type\ButtonType; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; +use Symfony\Component\Form\Extension\Core\Type\DateType; +use Symfony\Component\Form\Extension\Core\Type\FileType; +use Symfony\Component\Form\Extension\Core\Type\MoneyType; +use Symfony\Component\Form\Extension\Core\Type\PercentType; +use Symfony\Component\Form\Extension\Core\Type\RadioType; +use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormError; /** @@ -22,7 +31,7 @@ abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest { public function testRow() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType'); + $form = $this->factory->createNamed('name', TextType::class); $form->addError(new FormError('[trans]Error![/trans]')); $view = $form->createView(); $html = $this->renderRow($view); @@ -47,7 +56,7 @@ public function testRow() public function testLabelOnForm() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType'); + $form = $this->factory->createNamed('name', DateType::class); $view = $form->createView(); $this->renderWidget($view, array('label' => 'foo')); $html = $this->renderLabel($view); @@ -62,7 +71,7 @@ public function testLabelOnForm() public function testLabelDoesNotRenderFieldAttributes() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType'); + $form = $this->factory->createNamed('name', TextType::class); $html = $this->renderLabel($form->createView(), null, array( 'attr' => array( 'class' => 'my&class', @@ -79,7 +88,7 @@ public function testLabelDoesNotRenderFieldAttributes() public function testLabelWithCustomAttributesPassedDirectly() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType'); + $form = $this->factory->createNamed('name', TextType::class); $html = $this->renderLabel($form->createView(), null, array( 'label_attr' => array( 'class' => 'my&class', @@ -96,7 +105,7 @@ public function testLabelWithCustomAttributesPassedDirectly() public function testLabelWithCustomTextAndCustomAttributesPassedDirectly() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType'); + $form = $this->factory->createNamed('name', TextType::class); $html = $this->renderLabel($form->createView(), 'Custom label', array( 'label_attr' => array( 'class' => 'my&class', @@ -114,7 +123,7 @@ public function testLabelWithCustomTextAndCustomAttributesPassedDirectly() public function testLabelWithCustomTextAsOptionAndCustomAttributesPassedDirectly() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType', null, array( + $form = $this->factory->createNamed('name', TextType::class, null, array( 'label' => 'Custom label', )); $html = $this->renderLabel($form->createView(), null, array( @@ -134,7 +143,7 @@ public function testLabelWithCustomTextAsOptionAndCustomAttributesPassedDirectly public function testLegendOnExpandedType() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', null, array( + $form = $this->factory->createNamed('name', ChoiceType::class, null, array( 'label' => 'Custom label', 'expanded' => true, 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b'), @@ -153,7 +162,7 @@ public function testLegendOnExpandedType() public function testErrors() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType'); + $form = $this->factory->createNamed('name', TextType::class); $form->addError(new FormError('[trans]Error 1[/trans]')); $form->addError(new FormError('[trans]Error 2[/trans]')); $view = $form->createView(); @@ -178,7 +187,7 @@ public function testErrors() public function testErrorWithNoLabel() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType', array('label'=>false)); + $form = $this->factory->createNamed('name', TextType::class, array('label' => false)); $form->addError(new FormError('[trans]Error 1[/trans]')); $view = $form->createView(); $html = $this->renderLabel($view); @@ -188,7 +197,7 @@ public function testErrorWithNoLabel() public function testCheckedCheckbox() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\CheckboxType', true); + $form = $this->factory->createNamed('name', CheckboxType::class, true); $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), '/div @@ -205,7 +214,7 @@ public function testCheckedCheckbox() public function testSingleChoiceAttributesWithMainAttributes() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', array( + $form = $this->factory->createNamed('name', ChoiceType::class, '&a', array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b'), 'multiple' => false, 'expanded' => false, @@ -228,7 +237,7 @@ public function testSingleChoiceAttributesWithMainAttributes() public function testSingleExpandedChoiceAttributesWithMainAttributes() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', array( + $form = $this->factory->createNamed('name', ChoiceType::class, '&a', array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b'), 'multiple' => false, 'expanded' => true, @@ -261,7 +270,7 @@ public function testSingleExpandedChoiceAttributesWithMainAttributes() public function testUncheckedCheckbox() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\CheckboxType', false); + $form = $this->factory->createNamed('name', CheckboxType::class, false); $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), '/div @@ -277,7 +286,7 @@ public function testUncheckedCheckbox() public function testCheckboxWithValue() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\CheckboxType', false, array( + $form = $this->factory->createNamed('name', CheckboxType::class, false, array( 'value' => 'foo&bar', )); @@ -295,7 +304,7 @@ public function testCheckboxWithValue() public function testSingleChoiceExpanded() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', array( + $form = $this->factory->createNamed('name', ChoiceType::class, '&a', array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b'), 'multiple' => false, 'expanded' => true, @@ -326,7 +335,7 @@ public function testSingleChoiceExpanded() public function testSingleChoiceExpandedWithLabelsAsFalse() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', array( + $form = $this->factory->createNamed('name', ChoiceType::class, '&a', array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b'), 'choice_label' => false, 'multiple' => false, @@ -356,7 +365,7 @@ public function testSingleChoiceExpandedWithLabelsAsFalse() public function testSingleChoiceExpandedWithLabelsSetByCallable() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', array( + $form = $this->factory->createNamed('name', ChoiceType::class, '&a', array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b', 'Choice&C' => '&c'), 'choice_label' => function ($choice, $label, $value) { if ('&b' === $choice) { @@ -400,7 +409,7 @@ public function testSingleChoiceExpandedWithLabelsSetByCallable() public function testSingleChoiceExpandedWithLabelsSetFalseByCallable() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', array( + $form = $this->factory->createNamed('name', ChoiceType::class, '&a', array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b'), 'choice_label' => function () { return false; @@ -432,7 +441,7 @@ public function testSingleChoiceExpandedWithLabelsSetFalseByCallable() public function testSingleChoiceExpandedWithoutTranslation() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', array( + $form = $this->factory->createNamed('name', ChoiceType::class, '&a', array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b'), 'multiple' => false, 'expanded' => true, @@ -464,7 +473,7 @@ public function testSingleChoiceExpandedWithoutTranslation() public function testSingleChoiceExpandedAttributes() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', array( + $form = $this->factory->createNamed('name', ChoiceType::class, '&a', array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b'), 'choice_attr' => array('Choice&B' => array('class' => 'foo&bar')), 'multiple' => false, @@ -496,7 +505,7 @@ public function testSingleChoiceExpandedAttributes() public function testSingleChoiceExpandedWithPlaceholder() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', array( + $form = $this->factory->createNamed('name', ChoiceType::class, '&a', array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b'), 'multiple' => false, 'expanded' => true, @@ -536,7 +545,7 @@ public function testSingleChoiceExpandedWithPlaceholder() public function testSingleChoiceExpandedWithPlaceholderWithoutTranslation() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', '&a', array( + $form = $this->factory->createNamed('name', ChoiceType::class, '&a', array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b'), 'multiple' => false, 'expanded' => true, @@ -577,7 +586,7 @@ public function testSingleChoiceExpandedWithPlaceholderWithoutTranslation() public function testSingleChoiceExpandedWithBooleanValue() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', true, array( + $form = $this->factory->createNamed('name', ChoiceType::class, true, array( 'choices' => array('Choice&A' => '1', 'Choice&B' => '0'), 'multiple' => false, 'expanded' => true, @@ -608,7 +617,7 @@ public function testSingleChoiceExpandedWithBooleanValue() public function testMultipleChoiceExpanded() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', array('&a', '&c'), array( + $form = $this->factory->createNamed('name', ChoiceType::class, array('&a', '&c'), array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b', 'Choice&C' => '&c'), 'multiple' => true, 'expanded' => true, @@ -647,7 +656,7 @@ public function testMultipleChoiceExpanded() public function testMultipleChoiceExpandedWithLabelsAsFalse() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', array('&a'), array( + $form = $this->factory->createNamed('name', ChoiceType::class, array('&a'), array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b'), 'choice_label' => false, 'multiple' => true, @@ -677,7 +686,7 @@ public function testMultipleChoiceExpandedWithLabelsAsFalse() public function testMultipleChoiceExpandedWithLabelsSetByCallable() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', array('&a'), array( + $form = $this->factory->createNamed('name', ChoiceType::class, array('&a'), array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b', 'Choice&C' => '&c'), 'choice_label' => function ($choice, $label, $value) { if ('&b' === $choice) { @@ -721,7 +730,7 @@ public function testMultipleChoiceExpandedWithLabelsSetByCallable() public function testMultipleChoiceExpandedWithLabelsSetFalseByCallable() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', array('&a'), array( + $form = $this->factory->createNamed('name', ChoiceType::class, array('&a'), array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b'), 'choice_label' => function () { return false; @@ -753,7 +762,7 @@ public function testMultipleChoiceExpandedWithLabelsSetFalseByCallable() public function testMultipleChoiceExpandedWithoutTranslation() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', array('&a', '&c'), array( + $form = $this->factory->createNamed('name', ChoiceType::class, array('&a', '&c'), array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b', 'Choice&C' => '&c'), 'multiple' => true, 'expanded' => true, @@ -793,7 +802,7 @@ public function testMultipleChoiceExpandedWithoutTranslation() public function testMultipleChoiceExpandedAttributes() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', array('&a', '&c'), array( + $form = $this->factory->createNamed('name', ChoiceType::class, array('&a', '&c'), array( 'choices' => array('Choice&A' => '&a', 'Choice&B' => '&b', 'Choice&C' => '&c'), 'choice_attr' => array('Choice&B' => array('class' => 'foo&bar')), 'multiple' => true, @@ -833,7 +842,7 @@ public function testMultipleChoiceExpandedAttributes() public function testCheckedRadio() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RadioType', true); + $form = $this->factory->createNamed('name', RadioType::class, true); $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), '/div @@ -855,7 +864,7 @@ public function testCheckedRadio() public function testUncheckedRadio() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RadioType', false); + $form = $this->factory->createNamed('name', RadioType::class, false); $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), '/div @@ -876,7 +885,7 @@ public function testUncheckedRadio() public function testRadioWithValue() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RadioType', false, array( + $form = $this->factory->createNamed('name', RadioType::class, false, array( 'value' => 'foo&bar', )); @@ -900,7 +909,7 @@ public function testRadioWithValue() public function testButtonAttributeNameRepeatedIfTrue() { - $form = $this->factory->createNamed('button', 'Symfony\Component\Form\Extension\Core\Type\ButtonType', null, array( + $form = $this->factory->createNamed('button', ButtonType::class, null, array( 'attr' => array('foo' => true), )); @@ -912,7 +921,7 @@ public function testButtonAttributeNameRepeatedIfTrue() public function testFile() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\FileType'); + $form = $this->factory->createNamed('name', FileType::class); $this->assertWidgetMatchesXpath($form->createView(), array('attr' => array('class' => 'my&class form-control-file')), '/input @@ -923,7 +932,7 @@ public function testFile() public function testMoney() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\MoneyType', 1234.56, array( + $form = $this->factory->createNamed('name', MoneyType::class, 1234.56, array( 'currency' => 'EUR', )); @@ -951,7 +960,7 @@ public function testMoney() public function testPercent() { - $form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PercentType', 0.1); + $form = $this->factory->createNamed('name', PercentType::class, 0.1); $this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')), '/div diff --git a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php index d1e7af206804b..0424850e144c2 100644 --- a/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php +++ b/src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php @@ -58,7 +58,7 @@ public function createArgumentMetadata($controller) } foreach ($reflection->getParameters() as $param) { - $arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param), $this->isVariadic($param), $this->hasDefaultValue($param), $this->getDefaultValue($param), $param->allowsNull()); + $arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param, $reflection), $this->isVariadic($param), $this->hasDefaultValue($param), $this->getDefaultValue($param), $param->allowsNull()); } return $arguments; @@ -107,23 +107,35 @@ private function getDefaultValue(\ReflectionParameter $parameter) * * @return null|string */ - private function getType(\ReflectionParameter $parameter) + private function getType(\ReflectionParameter $parameter, \ReflectionFunctionAbstract $function) { if ($this->supportsParameterType) { if (!$type = $parameter->getType()) { return; } - $typeName = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString(); - if ('array' === $typeName && !$type->isBuiltin()) { + $name = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString(); + if ('array' === $name && !$type->isBuiltin()) { // Special case for HHVM with variadics return; } - - return $typeName; + } elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $parameter, $name)) { + $name = $name[1]; + } else { + return; } + $lcName = strtolower($name); - if (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $parameter, $info)) { - return $info[1]; + if ('self' !== $lcName && 'parent' !== $lcName) { + return $name; + } + if (!$function instanceof \ReflectionMethod) { + return; + } + if ('self' === $lcName) { + return $function->getDeclaringClass()->name; + } + if ($parent = $function->getDeclaringClass()->getParentClass()) { + return $parent->name; } } } diff --git a/src/Symfony/Component/HttpKernel/Profiler/Profiler.php b/src/Symfony/Component/HttpKernel/Profiler/Profiler.php index 15bfbc5a07777..6245a21b5f142 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/Profiler.php +++ b/src/Symfony/Component/HttpKernel/Profiler/Profiler.php @@ -37,7 +37,7 @@ class Profiler private $enabled = true; /** - * @param bool $enable The initial enabled state + * @param bool $enable The initial enabled state */ public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null, $enable = true) { diff --git a/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php b/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php index b4b449f358611..bf0db5ad56512 100644 --- a/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php @@ -126,11 +126,11 @@ public function testNullableTypesSignature() ), $arguments); } - private function signature1(ArgumentMetadataFactoryTest $foo, array $bar, callable $baz) + private function signature1(self $foo, array $bar, callable $baz) { } - private function signature2(ArgumentMetadataFactoryTest $foo = null, FakeClassThatDoesNotExist $bar = null, ImportedAndFake $baz = null) + private function signature2(self $foo = null, FakeClassThatDoesNotExist $bar = null, ImportedAndFake $baz = null) { } diff --git a/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php b/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php index 243c3c5c5a7cb..2d5f0ca5ad59e 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php @@ -44,7 +44,7 @@ public function testCollect() public function testReset() { $collector = $this->getMockBuilder(DataCollectorInterface::class) - ->setMethods(['collect', 'getName', 'reset']) + ->setMethods(array('collect', 'getName', 'reset')) ->getMock(); $collector->expects($this->any())->method('getName')->willReturn('mock'); $collector->expects($this->once())->method('reset'); diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ParentDummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ParentDummy.php index 330496827cfc4..8d5c4fe107162 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ParentDummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ParentDummy.php @@ -29,7 +29,7 @@ class ParentDummy public $foo2; /** - * @var callback + * @var callable */ public $foo3; diff --git a/src/Symfony/Component/PropertyInfo/Type.php b/src/Symfony/Component/PropertyInfo/Type.php index 86bc2f7643db4..b2c8e36be44e0 100644 --- a/src/Symfony/Component/PropertyInfo/Type.php +++ b/src/Symfony/Component/PropertyInfo/Type.php @@ -61,12 +61,10 @@ class Type * @param bool $nullable * @param string|null $class * @param bool $collection - * @param Type|null $collectionKeyType - * @param Type|null $collectionValueType * * @throws \InvalidArgumentException */ - public function __construct($builtinType, $nullable = false, $class = null, $collection = false, Type $collectionKeyType = null, Type $collectionValueType = null) + public function __construct($builtinType, $nullable = false, $class = null, $collection = false, self $collectionKeyType = null, self $collectionValueType = null) { if (!in_array($builtinType, self::$builtinTypes)) { throw new \InvalidArgumentException(sprintf('"%s" is not a valid PHP type.', $builtinType)); diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/DumperCollection.php b/src/Symfony/Component/Routing/Matcher/Dumper/DumperCollection.php index 6916297b8c174..dd057d2ee8301 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/DumperCollection.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/DumperCollection.php @@ -106,7 +106,7 @@ protected function getParent() /** * Sets the parent collection. */ - protected function setParent(DumperCollection $parent) + protected function setParent(self $parent) { $this->parent = $parent; } diff --git a/src/Symfony/Component/Routing/RouteCollectionBuilder.php b/src/Symfony/Component/Routing/RouteCollectionBuilder.php index e8a9a165d6734..3aec146951314 100644 --- a/src/Symfony/Component/Routing/RouteCollectionBuilder.php +++ b/src/Symfony/Component/Routing/RouteCollectionBuilder.php @@ -118,7 +118,7 @@ public function createBuilder() * @param string $prefix * @param RouteCollectionBuilder $builder */ - public function mount($prefix, RouteCollectionBuilder $builder) + public function mount($prefix, self $builder) { $builder->prefix = trim(trim($prefix), '/'); $this->routes[] = $builder; @@ -251,8 +251,6 @@ public function setMethods($methods) /** * Adds a resource for this collection. * - * @param ResourceInterface $resource - * * @return $this */ private function addResource(ResourceInterface $resource) diff --git a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php index 5b74523d631b0..9b3bfedcc8121 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php @@ -46,12 +46,8 @@ class ContextListener implements ListenerInterface private $logoutOnUserChange = false; /** - * @param TokenStorageInterface $tokenStorage - * @param iterable|UserProviderInterface[] $userProviders - * @param string $contextKey - * @param LoggerInterface|null $logger - * @param EventDispatcherInterface|null $dispatcher - * @param AuthenticationTrustResolverInterface|null $trustResolver + * @param iterable|UserProviderInterface[] $userProviders + * @param string $contextKey */ public function __construct(TokenStorageInterface $tokenStorage, $userProviders, $contextKey, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, AuthenticationTrustResolverInterface $trustResolver = null) { diff --git a/src/Symfony/Component/Serializer/Mapping/AttributeMetadataInterface.php b/src/Symfony/Component/Serializer/Mapping/AttributeMetadataInterface.php index 944a7b3133f35..d9a15d5ac0de5 100644 --- a/src/Symfony/Component/Serializer/Mapping/AttributeMetadataInterface.php +++ b/src/Symfony/Component/Serializer/Mapping/AttributeMetadataInterface.php @@ -60,5 +60,5 @@ public function getMaxDepth(); /** * Merges an {@see AttributeMetadataInterface} with in the current one. */ - public function merge(AttributeMetadataInterface $attributeMetadata); + public function merge(self $attributeMetadata); } diff --git a/src/Symfony/Component/Serializer/Mapping/ClassMetadataInterface.php b/src/Symfony/Component/Serializer/Mapping/ClassMetadataInterface.php index 3811e56548a0c..a0765861643bb 100644 --- a/src/Symfony/Component/Serializer/Mapping/ClassMetadataInterface.php +++ b/src/Symfony/Component/Serializer/Mapping/ClassMetadataInterface.php @@ -46,7 +46,7 @@ public function getAttributesMetadata(); /** * Merges a {@link ClassMetadataInterface} in the current one. */ - public function merge(ClassMetadataInterface $classMetadata); + public function merge(self $classMetadata); /** * Returns a {@link \ReflectionClass} instance for this class. diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index 25d6ff6a9d64e..ec03fef8cfbc6 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -301,7 +301,6 @@ private function validateAndDenormalize($currentClass, $attribute, $data, $forma /** * Sets an attribute and apply the name converter if necessary. * - * @param array $data * @param string $attribute * @param mixed $attributeValue * diff --git a/src/Symfony/Component/Translation/MessageCatalogueInterface.php b/src/Symfony/Component/Translation/MessageCatalogueInterface.php index 4dad27fbf6aa3..e0dbb2bd962cb 100644 --- a/src/Symfony/Component/Translation/MessageCatalogueInterface.php +++ b/src/Symfony/Component/Translation/MessageCatalogueInterface.php @@ -105,7 +105,7 @@ public function add($messages, $domain = 'messages'); * * The two catalogues must have the same locale. */ - public function addCatalogue(MessageCatalogueInterface $catalogue); + public function addCatalogue(self $catalogue); /** * Merges translations from the given Catalogue into the current one @@ -113,7 +113,7 @@ public function addCatalogue(MessageCatalogueInterface $catalogue); * * This is used to provide default translations when they do not exist for the current locale. */ - public function addFallbackCatalogue(MessageCatalogueInterface $catalogue); + public function addFallbackCatalogue(self $catalogue); /** * Gets the fallback catalogue. diff --git a/src/Symfony/Component/Validator/Mapping/ClassMetadata.php b/src/Symfony/Component/Validator/Mapping/ClassMetadata.php index f716ce3432398..84b0e3f4f7731 100644 --- a/src/Symfony/Component/Validator/Mapping/ClassMetadata.php +++ b/src/Symfony/Component/Validator/Mapping/ClassMetadata.php @@ -335,7 +335,7 @@ public function addGetterMethodConstraints($property, $method, array $constraint /** * Merges the constraints of the given metadata into this object. */ - public function mergeConstraints(ClassMetadata $source) + public function mergeConstraints(self $source) { if ($source->isGroupSequenceProvider()) { $this->setGroupSequenceProvider(true); From 88a3b90860117f58f016d14f1dcad413b3ecdeb1 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 16 May 2018 15:47:24 +0200 Subject: [PATCH 49/59] [PropertyInfo] fix resolving parent|self type hints --- .../Extractor/ReflectionExtractor.php | 24 +++++++++++++------ .../PhpDocExtractorTest.php | 2 +- .../ReflectionExtractorTest.php | 6 +++++ .../SerializerExtractorTest.php | 2 +- .../PropertyInfo/Tests/Fixtures/Dummy.php | 14 +++++++++++ .../PropertyInfo/Tests/Fixtures/Php7Dummy.php | 10 +++++++- 6 files changed, 48 insertions(+), 10 deletions(-) rename src/Symfony/Component/PropertyInfo/Tests/{Extractors => Extractor}/PhpDocExtractorTest.php (99%) rename src/Symfony/Component/PropertyInfo/Tests/{Extractors => Extractor}/ReflectionExtractorTest.php (93%) rename src/Symfony/Component/PropertyInfo/Tests/{Extractors => Extractor}/SerializerExtractorTest.php (95%) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index bc9ae5074d08c..4e527eb05db12 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -176,7 +176,7 @@ private function extractFromMutator($class, $property) if (!$reflectionType = $reflectionParameter->getType()) { return; } - $type = $this->extractFromReflectionType($reflectionType); + $type = $this->extractFromReflectionType($reflectionType, $reflectionMethod); // HHVM reports variadics with "array" but not builtin type hints if (!$reflectionType->isBuiltin() && Type::BUILTIN_TYPE_ARRAY === $type->getBuiltinType()) { @@ -188,7 +188,7 @@ private function extractFromMutator($class, $property) } elseif (Type::BUILTIN_TYPE_CALLABLE === $info[1]) { $type = new Type(Type::BUILTIN_TYPE_CALLABLE, $reflectionParameter->allowsNull()); } else { - $type = new Type(Type::BUILTIN_TYPE_OBJECT, $reflectionParameter->allowsNull(), $info[1]); + $type = new Type(Type::BUILTIN_TYPE_OBJECT, $reflectionParameter->allowsNull(), $this->resolveTypeName($info[1], $reflectionMethod)); } } else { return; @@ -217,7 +217,7 @@ private function extractFromAccessor($class, $property) } if ($this->supportsParameterType && $reflectionType = $reflectionMethod->getReturnType()) { - return array($this->extractFromReflectionType($reflectionType)); + return array($this->extractFromReflectionType($reflectionType, $reflectionMethod)); } if (\in_array($prefix, array('is', 'can'))) { @@ -228,11 +228,9 @@ private function extractFromAccessor($class, $property) /** * Extracts data from the PHP 7 reflection type. * - * @param \ReflectionType $reflectionType - * * @return Type */ - private function extractFromReflectionType(\ReflectionType $reflectionType) + private function extractFromReflectionType(\ReflectionType $reflectionType, \ReflectionMethod $reflectionMethod) { $phpTypeOrClass = $reflectionType instanceof \ReflectionNamedType ? $reflectionType->getName() : $reflectionType->__toString(); $nullable = $reflectionType->allowsNull(); @@ -244,12 +242,24 @@ private function extractFromReflectionType(\ReflectionType $reflectionType) } elseif ($reflectionType->isBuiltin()) { $type = new Type($phpTypeOrClass, $nullable); } else { - $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $phpTypeOrClass); + $type = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $this->resolveTypeName($phpTypeOrClass, $reflectionMethod)); } return $type; } + private function resolveTypeName($name, \ReflectionMethod $reflectionMethod) + { + if ('self' === $lcName = strtolower($name)) { + return $reflectionMethod->getDeclaringClass()->name; + } + if ('parent' === $lcName && $parent = $reflectionMethod->getDeclaringClass()->getParentClass()) { + return $parent->name; + } + + return $name; + } + /** * Does the class have the given public property? * diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php similarity index 99% rename from src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php rename to src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php index dab463f7e5105..647d4c1072e64 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\PropertyInfo\Tests\PhpDocExtractors; +namespace Symfony\Component\PropertyInfo\Tests\PhpDocExtractor; use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php similarity index 93% rename from src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php rename to src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index 176e1511f8c22..f8c61dd48aa36 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -52,6 +52,8 @@ public function testGetProperties() 'DOB', 'Id', '123', + 'self', + 'realParent', 'c', 'd', 'e', @@ -135,6 +137,8 @@ public function typesProvider() array('donotexist', null), array('staticGetter', null), array('staticSetter', null), + array('self', array(new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy'))), + array('realParent', array(new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy'))), ); } @@ -153,6 +157,8 @@ public function php7TypesProvider() array('foo', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true))), array('bar', array(new Type(Type::BUILTIN_TYPE_INT))), array('baz', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING)))), + array('buz', array(new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy'))), + array('biz', array(new Type(Type::BUILTIN_TYPE_OBJECT, false, 'stdClass'))), array('donotexist', null), ); } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractors/SerializerExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/SerializerExtractorTest.php similarity index 95% rename from src/Symfony/Component/PropertyInfo/Tests/Extractors/SerializerExtractorTest.php rename to src/Symfony/Component/PropertyInfo/Tests/Extractor/SerializerExtractorTest.php index b1be5ee11821e..91cdf80f8d608 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractors/SerializerExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/SerializerExtractorTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Symfony\Component\PropertyInfo\Tests\Extractors; +namespace Symfony\Component\PropertyInfo\Tests\Extractor; use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php index 4e558eca014e5..5993d6e1d47e8 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php @@ -127,4 +127,18 @@ public function getId() public function get123() { } + + /** + * @param self $self + */ + public function setSelf(self $self) + { + } + + /** + * @param parent $realParent + */ + public function setRealParent(parent $realParent) + { + } } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php7Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php7Dummy.php index cd5ba380d9d53..5dcb4c565e768 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php7Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php7Dummy.php @@ -14,7 +14,7 @@ /** * @author Kévin Dunglas */ -class Php7Dummy +class Php7Dummy extends \stdClass { public function getFoo(): array { @@ -27,4 +27,12 @@ public function setBar(int $bar) public function addBaz(string $baz) { } + + public function getBuz(): self + { + } + + public function getBiz(): parent + { + } } From c18813d13dfcdd45a0920d6361cb8a277c2546c5 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 16 May 2018 17:16:55 +0200 Subject: [PATCH 50/59] Fix dep --- src/Symfony/Bundle/SecurityBundle/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 2e8c20312c9e9..1d0858c2def97 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -46,6 +46,7 @@ "twig/twig": "~1.34|~2.4" }, "conflict": { + "symfony/security": "4.1.0-beta1", "symfony/var-dumper": "<3.3", "symfony/event-dispatcher": "<3.4", "symfony/framework-bundle": "<3.4", From 44cef5a69d281c79338a87b9db157c0738cd391e Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 21 Nov 2017 17:18:34 +0100 Subject: [PATCH 51/59] Fix security/* cross-dependencies --- src/Symfony/Bridge/Doctrine/composer.json | 2 +- src/Symfony/Bridge/Twig/composer.json | 2 +- src/Symfony/Bundle/FrameworkBundle/composer.json | 3 +-- src/Symfony/Component/Form/composer.json | 2 +- src/Symfony/Component/Security/Guard/composer.json | 2 +- src/Symfony/Component/Security/Http/composer.json | 2 +- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index 20d02abac37f8..e5b5a39a38269 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -28,7 +28,7 @@ "symfony/http-kernel": "~2.2|~3.0.0", "symfony/property-access": "~2.3|~3.0.0", "symfony/property-info": "~2.8|3.0", - "symfony/security": "~2.2|~3.0.0", + "symfony/security": "^2.8.31|^3.3.13", "symfony/expression-language": "~2.2|~3.0.0", "symfony/validator": "~2.7.25|^2.8.18|~3.2.5", "symfony/translation": "^2.0.5|~3.0.0", diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index e1937deb671ea..48af8a77b4033 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -30,7 +30,7 @@ "symfony/templating": "~2.1|~3.0.0", "symfony/translation": "~2.7|~3.0.0", "symfony/yaml": "^2.0.5|~3.0.0", - "symfony/security": "~2.6|~3.0.0", + "symfony/security": "^2.8.31|^3.3.13", "symfony/security-acl": "~2.6|~3.0.0", "symfony/stopwatch": "~2.2|~3.0.0", "symfony/console": "~2.8|~3.0.0", diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 14de4ad38afbf..3e7b75ba127e2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -30,7 +30,7 @@ "symfony/filesystem": "~2.3|~3.0.0", "symfony/routing": "^2.8.17", "symfony/security-core": "~2.6.13|~2.7.9|~2.8|~3.0.0", - "symfony/security-csrf": "~2.6|~3.0.0", + "symfony/security-csrf": "^2.8.31|^3.3.13", "symfony/stopwatch": "~2.3|~3.0.0", "symfony/templating": "~2.7|~3.0.0", "symfony/translation": "~2.8", @@ -43,7 +43,6 @@ "symfony/css-selector": "^2.0.5|~3.0.0", "symfony/dom-crawler": "^2.0.5|~3.0.0", "symfony/polyfill-intl-icu": "~1.0", - "symfony/security": "~2.6|~3.0.0", "symfony/form": "^2.8.19", "symfony/expression-language": "~2.6|~3.0.0", "symfony/process": "^2.0.5|~3.0.0", diff --git a/src/Symfony/Component/Form/composer.json b/src/Symfony/Component/Form/composer.json index d670186cb7dc4..90cc9523fb70a 100644 --- a/src/Symfony/Component/Form/composer.json +++ b/src/Symfony/Component/Form/composer.json @@ -30,7 +30,7 @@ "symfony/dependency-injection": "~2.7|~3.0.0", "symfony/http-foundation": "~2.2|~3.0.0", "symfony/http-kernel": "~2.4|~3.0.0", - "symfony/security-csrf": "~2.4|~3.0.0", + "symfony/security-csrf": "^2.8.31|^3.3.13", "symfony/translation": "^2.0.5|~3.0.0" }, "conflict": { diff --git a/src/Symfony/Component/Security/Guard/composer.json b/src/Symfony/Component/Security/Guard/composer.json index 320892095cb1d..35c7456638ea8 100644 --- a/src/Symfony/Component/Security/Guard/composer.json +++ b/src/Symfony/Component/Security/Guard/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=5.3.9", "symfony/security-core": "~2.8|~3.0.0", - "symfony/security-http": "~2.7|~3.0.0" + "symfony/security-http": "^2.8.31|^3.3.13" }, "require-dev": { "psr/log": "~1.0" diff --git a/src/Symfony/Component/Security/Http/composer.json b/src/Symfony/Component/Security/Http/composer.json index bde88858ae5a3..a604766c0002f 100644 --- a/src/Symfony/Component/Security/Http/composer.json +++ b/src/Symfony/Component/Security/Http/composer.json @@ -27,7 +27,7 @@ }, "require-dev": { "symfony/routing": "~2.2|~3.0.0", - "symfony/security-csrf": "~2.4|~3.0.0", + "symfony/security-csrf": "^2.8.31|^3.3.13", "psr/log": "~1.0" }, "suggest": { From 0de3a61cfcf122afa0ce8015c837c8f6d8ebc33e Mon Sep 17 00:00:00 2001 From: Kyle Date: Wed, 16 May 2018 15:58:59 +0200 Subject: [PATCH 52/59] Add Occitan plural rule --- src/Symfony/Component/Translation/PluralizationRules.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Translation/PluralizationRules.php b/src/Symfony/Component/Translation/PluralizationRules.php index e5ece89620b7f..2b7b118336938 100644 --- a/src/Symfony/Component/Translation/PluralizationRules.php +++ b/src/Symfony/Component/Translation/PluralizationRules.php @@ -107,6 +107,7 @@ public static function get($number, $locale) case 'nl': case 'nn': case 'no': + case 'oc': case 'om': case 'or': case 'pa': From 4c3b950dc274e356950070da9cfb78f58d317aa4 Mon Sep 17 00:00:00 2001 From: "Thomason, James" Date: Mon, 14 May 2018 13:29:05 -0400 Subject: [PATCH 53/59] [DependencyInjection] resolve array env vars --- .../DependencyInjection/ContainerBuilder.php | 8 ++- .../Tests/ContainerBuilderTest.php | 52 ++++++++++++++----- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 7f79e2f4ffc55..7296a098ee0ed 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -1408,6 +1408,7 @@ public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs } $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders; + $completed = false; foreach ($envPlaceholders as $env => $placeholders) { foreach ($placeholders as $placeholder) { if (false !== stripos($value, $placeholder)) { @@ -1418,14 +1419,19 @@ public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs } if ($placeholder === $value) { $value = $resolved; + $completed = true; } else { if (!is_string($resolved) && !is_numeric($resolved)) { - throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "env(%s)" of type %s inside string value "%s".', $env, gettype($resolved), $value)); + throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "env(%s)" of type %s inside string value "%s".', $env, gettype($resolved), $this->resolveEnvPlaceholders($value))); } $value = str_ireplace($placeholder, $resolved, $value); } $usedEnvs[$env] = $env; $this->envCounters[$env] = isset($this->envCounters[$env]) ? 1 + $this->envCounters[$env] : 1; + + if ($completed) { + break 2; + } } } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 51038b6b1550f..f2e8368455f66 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -665,17 +665,49 @@ public function testCompileWithResolveEnv() putenv('DUMMY_ENV_VAR'); } + public function testCompileWithArrayResolveEnv() + { + putenv('ARRAY={"foo":"bar"}'); + + $container = new ContainerBuilder(); + $container->setParameter('foo', '%env(json:ARRAY)%'); + $container->compile(true); + + $this->assertSame(array('foo' => 'bar'), $container->getParameter('foo')); + + putenv('ARRAY'); + } + + public function testCompileWithArrayAndAnotherResolveEnv() + { + putenv('DUMMY_ENV_VAR=abc'); + putenv('ARRAY={"foo":"bar"}'); + + $container = new ContainerBuilder(); + $container->setParameter('foo', '%env(json:ARRAY)%'); + $container->setParameter('bar', '%env(DUMMY_ENV_VAR)%'); + $container->compile(true); + + $this->assertSame(array('foo' => 'bar'), $container->getParameter('foo')); + $this->assertSame('abc', $container->getParameter('bar')); + + putenv('DUMMY_ENV_VAR'); + putenv('ARRAY'); + } + /** * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException - * @expectedExceptionMessage A string value must be composed of strings and/or numbers, but found parameter "env(ARRAY)" of type array inside string value "ABC %env(ARRAY)%". + * @expectedExceptionMessage A string value must be composed of strings and/or numbers, but found parameter "env(json:ARRAY)" of type array inside string value "ABC %env(json:ARRAY)%". */ - public function testCompileWithArrayResolveEnv() + public function testCompileWithArrayInStringResolveEnv() { - $bag = new TestingEnvPlaceholderParameterBag(); - $container = new ContainerBuilder($bag); - $container->setParameter('foo', '%env(ARRAY)%'); - $container->setParameter('bar', 'ABC %env(ARRAY)%'); + putenv('ARRAY={"foo":"bar"}'); + + $container = new ContainerBuilder(); + $container->setParameter('foo', 'ABC %env(json:ARRAY)%'); $container->compile(true); + + putenv('ARRAY'); } /** @@ -1418,11 +1450,3 @@ public function __construct(A $a) { } } - -class TestingEnvPlaceholderParameterBag extends EnvPlaceholderParameterBag -{ - public function get($name) - { - return 'env(array)' === strtolower($name) ? array(123) : parent::get($name); - } -} From 919f93d91c73a8d95ccd991d66c9fc4ec5e7f5f2 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 18 May 2018 20:00:42 +0200 Subject: [PATCH 54/59] do not mock the session in token storage tests --- .../TokenStorage/SessionTokenStorageTest.php | 177 +++--------------- 1 file changed, 25 insertions(+), 152 deletions(-) diff --git a/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php b/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php index c629ca15255ff..306e19ad91bb9 100644 --- a/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php +++ b/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php @@ -12,6 +12,8 @@ namespace Symfony\Component\Security\Csrf\Tests\TokenStorage; use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage; /** @@ -22,7 +24,7 @@ class SessionTokenStorageTest extends TestCase const SESSION_NAMESPACE = 'foobar'; /** - * @var \PHPUnit_Framework_MockObject_MockObject + * @var Session */ private $session; @@ -33,118 +35,53 @@ class SessionTokenStorageTest extends TestCase protected function setUp() { - $this->session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface') - ->disableOriginalConstructor() - ->getMock(); + $this->session = new Session(new MockArraySessionStorage()); $this->storage = new SessionTokenStorage($this->session, self::SESSION_NAMESPACE); } - public function testStoreTokenInClosedSession() + public function testStoreTokenInNotStartedSessionStartsTheSession() { - $this->session->expects($this->any()) - ->method('isStarted') - ->will($this->returnValue(false)); - - $this->session->expects($this->once()) - ->method('start'); - - $this->session->expects($this->once()) - ->method('set') - ->with(self::SESSION_NAMESPACE.'/token_id', 'TOKEN'); - $this->storage->setToken('token_id', 'TOKEN'); + + $this->assertTrue($this->session->isStarted()); } public function testStoreTokenInActiveSession() { - $this->session->expects($this->any()) - ->method('isStarted') - ->will($this->returnValue(true)); - - $this->session->expects($this->never()) - ->method('start'); - - $this->session->expects($this->once()) - ->method('set') - ->with(self::SESSION_NAMESPACE.'/token_id', 'TOKEN'); - + $this->session->start(); $this->storage->setToken('token_id', 'TOKEN'); + + $this->assertSame('TOKEN', $this->session->get(self::SESSION_NAMESPACE.'/token_id')); } public function testCheckTokenInClosedSession() { - $this->session->expects($this->any()) - ->method('isStarted') - ->will($this->returnValue(false)); - - $this->session->expects($this->once()) - ->method('start'); + $this->session->set(self::SESSION_NAMESPACE.'/token_id', 'RESULT'); - $this->session->expects($this->once()) - ->method('has') - ->with(self::SESSION_NAMESPACE.'/token_id') - ->will($this->returnValue('RESULT')); - - $this->assertSame('RESULT', $this->storage->hasToken('token_id')); + $this->assertTrue($this->storage->hasToken('token_id')); + $this->assertTrue($this->session->isStarted()); } public function testCheckTokenInActiveSession() { - $this->session->expects($this->any()) - ->method('isStarted') - ->will($this->returnValue(true)); - - $this->session->expects($this->never()) - ->method('start'); + $this->session->start(); + $this->session->set(self::SESSION_NAMESPACE.'/token_id', 'RESULT'); - $this->session->expects($this->once()) - ->method('has') - ->with(self::SESSION_NAMESPACE.'/token_id') - ->will($this->returnValue('RESULT')); - - $this->assertSame('RESULT', $this->storage->hasToken('token_id')); + $this->assertTrue($this->storage->hasToken('token_id')); } public function testGetExistingTokenFromClosedSession() { - $this->session->expects($this->any()) - ->method('isStarted') - ->will($this->returnValue(false)); - - $this->session->expects($this->once()) - ->method('start'); - - $this->session->expects($this->once()) - ->method('has') - ->with(self::SESSION_NAMESPACE.'/token_id') - ->will($this->returnValue(true)); - - $this->session->expects($this->once()) - ->method('get') - ->with(self::SESSION_NAMESPACE.'/token_id') - ->will($this->returnValue('RESULT')); + $this->session->set(self::SESSION_NAMESPACE.'/token_id', 'RESULT'); $this->assertSame('RESULT', $this->storage->getToken('token_id')); + $this->assertTrue($this->session->isStarted()); } public function testGetExistingTokenFromActiveSession() { - $this->session->expects($this->any()) - ->method('isStarted') - ->will($this->returnValue(true)); - - $this->session->expects($this->never()) - ->method('start'); - - $this->session->expects($this->once()) - ->method('has') - ->with(self::SESSION_NAMESPACE.'/token_id') - ->will($this->returnValue(true)); - - $this->session->expects($this->once()) - ->method('get') - ->with(self::SESSION_NAMESPACE.'/token_id') - ->will($this->returnValue('RESULT')); + $this->session->start(); + $this->session->set(self::SESSION_NAMESPACE.'/token_id', 'RESULT'); $this->assertSame('RESULT', $this->storage->getToken('token_id')); } @@ -154,18 +91,6 @@ public function testGetExistingTokenFromActiveSession() */ public function testGetNonExistingTokenFromClosedSession() { - $this->session->expects($this->any()) - ->method('isStarted') - ->will($this->returnValue(false)); - - $this->session->expects($this->once()) - ->method('start'); - - $this->session->expects($this->once()) - ->method('has') - ->with(self::SESSION_NAMESPACE.'/token_id') - ->will($this->returnValue(false)); - $this->storage->getToken('token_id'); } @@ -174,85 +99,33 @@ public function testGetNonExistingTokenFromClosedSession() */ public function testGetNonExistingTokenFromActiveSession() { - $this->session->expects($this->any()) - ->method('isStarted') - ->will($this->returnValue(true)); - - $this->session->expects($this->never()) - ->method('start'); - - $this->session->expects($this->once()) - ->method('has') - ->with(self::SESSION_NAMESPACE.'/token_id') - ->will($this->returnValue(false)); - + $this->session->start(); $this->storage->getToken('token_id'); } public function testRemoveNonExistingTokenFromClosedSession() { - $this->session->expects($this->any()) - ->method('isStarted') - ->will($this->returnValue(false)); - - $this->session->expects($this->once()) - ->method('start'); - - $this->session->expects($this->once()) - ->method('remove') - ->with(self::SESSION_NAMESPACE.'/token_id') - ->will($this->returnValue(null)); - $this->assertNull($this->storage->removeToken('token_id')); } public function testRemoveNonExistingTokenFromActiveSession() { - $this->session->expects($this->any()) - ->method('isStarted') - ->will($this->returnValue(true)); - - $this->session->expects($this->never()) - ->method('start'); - - $this->session->expects($this->once()) - ->method('remove') - ->with(self::SESSION_NAMESPACE.'/token_id') - ->will($this->returnValue(null)); + $this->session->start(); $this->assertNull($this->storage->removeToken('token_id')); } public function testRemoveExistingTokenFromClosedSession() { - $this->session->expects($this->any()) - ->method('isStarted') - ->will($this->returnValue(false)); - - $this->session->expects($this->once()) - ->method('start'); - - $this->session->expects($this->once()) - ->method('remove') - ->with(self::SESSION_NAMESPACE.'/token_id') - ->will($this->returnValue('TOKEN')); + $this->session->set(self::SESSION_NAMESPACE.'/token_id', 'TOKEN'); $this->assertSame('TOKEN', $this->storage->removeToken('token_id')); } public function testRemoveExistingTokenFromActiveSession() { - $this->session->expects($this->any()) - ->method('isStarted') - ->will($this->returnValue(true)); - - $this->session->expects($this->never()) - ->method('start'); - - $this->session->expects($this->once()) - ->method('remove') - ->with(self::SESSION_NAMESPACE.'/token_id') - ->will($this->returnValue('TOKEN')); + $this->session->start(); + $this->session->set(self::SESSION_NAMESPACE.'/token_id', 'TOKEN'); $this->assertSame('TOKEN', $this->storage->removeToken('token_id')); } From f2419ddda6d10102ecb5217ddb6ae343a36c04c8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 21 May 2018 12:48:22 +0200 Subject: [PATCH 55/59] fixed bad merge --- .../Tests/DependencyInjection/ConfigurationTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index bc0baea128b10..e694454f0bcbe 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -142,7 +142,6 @@ public function testInvalidValueTrustedProxies() )); } ->>>>>>> 3.4 public function testAssetsCanBeEnabled() { $processor = new Processor(); From 2ce15f9179583277094e224a62fab5eedf847bb5 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 21 May 2018 12:58:57 +0200 Subject: [PATCH 56/59] removed obsolete tests --- .../DependencyInjection/ConfigurationTest.php | 63 ------------------- 1 file changed, 63 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index e694454f0bcbe..70ad9f3c15fd9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -79,69 +79,6 @@ public function getTestInvalidSessionName() ); } - /** - * @dataProvider getTestValidTrustedProxiesData - */ - public function testValidTrustedProxies($trustedProxies, $processedProxies) - { - $processor = new Processor(); - $configuration = new Configuration(true); - $config = $processor->processConfiguration($configuration, array(array( - 'secret' => 's3cr3t', - 'trusted_proxies' => $trustedProxies, - ))); - - $this->assertEquals($processedProxies, $config['trusted_proxies']); - } - - public function getTestValidTrustedProxiesData() - { - return array( - array(array('127.0.0.1'), array('127.0.0.1')), - array(array('::1'), array('::1')), - array(array('127.0.0.1', '::1'), array('127.0.0.1', '::1')), - array(null, array()), - array(false, array()), - array(array(), array()), - array(array('10.0.0.0/8'), array('10.0.0.0/8')), - array(array('::ffff:0:0/96'), array('::ffff:0:0/96')), - array(array('0.0.0.0/0'), array('0.0.0.0/0')), - ); - } - - /** - * @group legacy - * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException - */ - public function testInvalidTypeTrustedProxies() - { - $processor = new Processor(); - $configuration = new Configuration(true); - $processor->processConfiguration($configuration, array( - array( - 'secret' => 's3cr3t', - 'trusted_proxies' => 'Not an IP address', - ), - )); - } - - /** - * @group legacy - * @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException - */ - public function testInvalidValueTrustedProxies() - { - $processor = new Processor(); - $configuration = new Configuration(true); - - $processor->processConfiguration($configuration, array( - array( - 'secret' => 's3cr3t', - 'trusted_proxies' => array('Not an IP address'), - ), - )); - } - public function testAssetsCanBeEnabled() { $processor = new Processor(); From dff61b82ffd5cbe96571ae2bc687e2f51096fcaf Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 21 May 2018 13:07:53 +0200 Subject: [PATCH 57/59] fixed bad merge --- src/Symfony/Bridge/Doctrine/composer.json | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index df9f7c671a869..9ad37c23e3615 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -24,7 +24,6 @@ "require-dev": { "symfony/stopwatch": "~3.4|~4.0", "symfony/dependency-injection": "~3.4|~4.0", -<<<<<<< HEAD "symfony/form": "~3.4|~4.0", "symfony/http-kernel": "~3.4|~4.0", "symfony/property-access": "~3.4|~4.0", @@ -34,17 +33,6 @@ "symfony/expression-language": "~3.4|~4.0", "symfony/validator": "~3.4|~4.0", "symfony/translation": "~3.4|~4.0", -======= - "symfony/form": "^3.3.10|~4.0", - "symfony/http-kernel": "~2.8|~3.0|~4.0", - "symfony/property-access": "~2.8|~3.0|~4.0", - "symfony/property-info": "~2.8|3.0|~4.0", - "symfony/proxy-manager-bridge": "~2.8|~3.0|~4.0", - "symfony/security": "^2.8.31|^3.3.13|~4.0", - "symfony/expression-language": "~2.8|~3.0|~4.0", - "symfony/validator": "^3.2.5|~4.0", - "symfony/translation": "~2.8|~3.0|~4.0", ->>>>>>> 3.4 "doctrine/data-fixtures": "1.0.*", "doctrine/dbal": "~2.4", "doctrine/orm": "^2.4.5" From c5dc846806f16d0252688d3f195810e2897d2982 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 21 May 2018 16:02:26 +0200 Subject: [PATCH 58/59] updated CHANGELOG for 4.0.10 --- CHANGELOG-4.0.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CHANGELOG-4.0.md b/CHANGELOG-4.0.md index 9abb4a61a6634..906a472b9fe36 100644 --- a/CHANGELOG-4.0.md +++ b/CHANGELOG-4.0.md @@ -7,6 +7,34 @@ in 4.0 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/v4.0.0...v4.0.1 +* 4.0.10 (2018-05-21) + + * bug #27264 [Validator] Use strict type in URL validator (mimol91) + * bug #27267 [DependencyInjection] resolve array env vars (jamesthomasonjr) + * bug #26781 [Form] Fix precision of MoneyToLocalizedStringTransformer's divisions on transform() (syastrebov) + * bug #27286 [Translation] Add Occitan plural rule (kylekatarnls) + * bug #27271 [DI] Allow defining bindings on ChildDefinition (nicolas-grekas) + * bug #27246 Disallow invalid characters in session.name (ostrolucky) + * bug #27287 [PropertyInfo] fix resolving parent|self type hints (nicolas-grekas) + * bug #27281 [HttpKernel] Fix dealing with self/parent in ArgumentMetadataFactory (fabpot) + * bug #24805 [Security] Fix logout (MatTheCat) + * bug #27265 [DI] Shared services should not be inlined in non-shared ones (nicolas-grekas) + * bug #27141 [Process] Suppress warnings when open_basedir is non-empty (cbj4074) + * bug #27250 [Session] limiting :key for GET_LOCK to 64 chars (oleg-andreyev) + * bug #27237 [Debug] Fix populating error_get_last() for handled silent errors (nicolas-grekas) + * bug #27232 [Cache][Lock] Fix usages of error_get_last() (nicolas-grekas) + * bug #27236 [Filesystem] Fix usages of error_get_last() (nicolas-grekas) + * bug #27191 [DI] Display previous error messages when throwing unused bindings (nicolas-grekas) + * bug #27231 [FrameworkBundle] Fix cache:clear on vagrant (nicolas-grekas) + * bug #27222 [WebProfilerBundle][Cache] Fix misses calculation when calling getItems (fsevestre) + * bug #27227 [HttpKernel] Handle NoConfigurationException "onKernelException()" (nicolas-grekas) + * bug #27152 [HttpFoundation] use brace-style regex delimiters (xabbuh) + * bug #27158 [Cache] fix logic for fetching tag versions on TagAwareAdapter (dmaicher) + * bug #27143 [Console] By default hide the short exception trace line from exception messages in Symfony's commands (yceruto) + * bug #27133 [Doctrine Bridge] fix priority for doctrine event listeners (dmaicher) + * bug #27135 [FrameworkBundle] Use the correct service id for CachePoolPruneCommand in its compiler pass (DemonTPx) + * feature #24896 Add CODE_OF_CONDUCT.md (egircys) + * 4.0.9 (2018-04-30) * bug #27074 [Debug][WebProfilerBundle] Fix setting file link format (lyrixx, nicolas-grekas) From 1313ba3f46c569f6c08f59567ef392ac8e2f1f2f Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 21 May 2018 16:02:31 +0200 Subject: [PATCH 59/59] updated VERSION for 4.0.10 --- 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 2840606fdb422..79e96ffb1abf4 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.10-DEV'; + const VERSION = '4.0.10'; const VERSION_ID = 40010; const MAJOR_VERSION = 4; const MINOR_VERSION = 0; const RELEASE_VERSION = 10; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '07/2018'; const END_OF_LIFE = '01/2019';