From 8fd5569577ae13504d4098ddd498f78085e00407 Mon Sep 17 00:00:00 2001 From: Alexander Schwenn Date: Tue, 25 Jul 2017 00:00:19 +0200 Subject: [PATCH 01/80] [HttpFoundation] Generate safe fallback filename for wrongly encoded filename --- .../Component/HttpFoundation/BinaryFileResponse.php | 4 ++-- .../HttpFoundation/Tests/BinaryFileResponseTest.php | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php index 0314621907356..177b708e8f054 100644 --- a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php +++ b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php @@ -150,7 +150,7 @@ public function setAutoEtag() * Sets the Content-Disposition header with the given filename. * * @param string $disposition ResponseHeaderBag::DISPOSITION_INLINE or ResponseHeaderBag::DISPOSITION_ATTACHMENT - * @param string $filename Optionally use this filename instead of the real name of the file + * @param string $filename Optionally use this UTF-8 encoded filename instead of the real name of the file * @param string $filenameFallback A fallback filename, containing only ASCII characters. Defaults to an automatically encoded filename * * @return $this @@ -162,7 +162,7 @@ public function setContentDisposition($disposition, $filename = '', $filenameFal } if ('' === $filenameFallback && (!preg_match('/^[\x20-\x7e]*$/', $filename) || false !== strpos($filename, '%'))) { - $encoding = mb_detect_encoding($filename, null, true); + $encoding = mb_detect_encoding($filename, null, true) ?: '8bit'; for ($i = 0, $filenameLength = mb_strlen($filename, $encoding); $i < $filenameLength; ++$i) { $char = mb_substr($filename, $i, 1, $encoding); diff --git a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php index e4607201a2151..e41a2372b9df8 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php @@ -68,6 +68,17 @@ public function testSetContentDispositionGeneratesSafeFallbackFilename() $this->assertSame('attachment; filename="f__.html"; filename*=utf-8\'\'f%C3%B6%C3%B6.html', $response->headers->get('Content-Disposition')); } + public function testSetContentDispositionGeneratesSafeFallbackFilenameForWronglyEncodedFilename() + { + $response = new BinaryFileResponse(__FILE__); + + $iso88591EncodedFilename = utf8_decode('föö.html'); + $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $iso88591EncodedFilename); + + // the parameter filename* is invalid in this case (rawurldecode('f%F6%F6') does not provide a UTF-8 string but an ISO-8859-1 encoded one) + $this->assertSame('attachment; filename="f__.html"; filename*=utf-8\'\'f%F6%F6.html', $response->headers->get('Content-Disposition')); + } + /** * @dataProvider provideRanges */ From 2282a6f895dfa2b0cf8756ccfe992a3101e646f6 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 28 Jul 2017 15:02:25 +0200 Subject: [PATCH 02/80] Bump minimal PHP version to ^5.5.9|>=7.0.8 --- composer.json | 2 +- src/Symfony/Bridge/Doctrine/composer.json | 2 +- src/Symfony/Bridge/Monolog/composer.json | 2 +- src/Symfony/Bridge/ProxyManager/composer.json | 2 +- src/Symfony/Bridge/Twig/composer.json | 2 +- src/Symfony/Bundle/DebugBundle/composer.json | 2 +- src/Symfony/Bundle/FrameworkBundle/composer.json | 2 +- src/Symfony/Bundle/SecurityBundle/composer.json | 2 +- src/Symfony/Bundle/TwigBundle/composer.json | 2 +- src/Symfony/Bundle/WebProfilerBundle/composer.json | 2 +- src/Symfony/Bundle/WebServerBundle/composer.json | 2 +- src/Symfony/Component/Asset/composer.json | 2 +- src/Symfony/Component/BrowserKit/composer.json | 2 +- src/Symfony/Component/Cache/composer.json | 2 +- src/Symfony/Component/ClassLoader/composer.json | 2 +- src/Symfony/Component/Config/composer.json | 2 +- src/Symfony/Component/Console/composer.json | 2 +- src/Symfony/Component/CssSelector/composer.json | 2 +- src/Symfony/Component/Debug/composer.json | 2 +- src/Symfony/Component/DependencyInjection/composer.json | 2 +- src/Symfony/Component/DomCrawler/composer.json | 2 +- src/Symfony/Component/Dotenv/composer.json | 2 +- src/Symfony/Component/EventDispatcher/composer.json | 2 +- src/Symfony/Component/ExpressionLanguage/composer.json | 2 +- src/Symfony/Component/Filesystem/composer.json | 2 +- src/Symfony/Component/Finder/composer.json | 2 +- .../Form/Extension/DataCollector/FormDataCollector.php | 3 --- src/Symfony/Component/Form/composer.json | 2 +- src/Symfony/Component/HttpFoundation/composer.json | 2 +- src/Symfony/Component/HttpKernel/composer.json | 2 +- src/Symfony/Component/Inflector/composer.json | 2 +- src/Symfony/Component/Intl/composer.json | 2 +- src/Symfony/Component/Ldap/composer.json | 2 +- src/Symfony/Component/OptionsResolver/composer.json | 2 +- src/Symfony/Component/Process/composer.json | 2 +- src/Symfony/Component/PropertyAccess/composer.json | 2 +- src/Symfony/Component/PropertyInfo/composer.json | 2 +- src/Symfony/Component/Routing/composer.json | 2 +- src/Symfony/Component/Security/Core/composer.json | 2 +- src/Symfony/Component/Security/Csrf/composer.json | 2 +- src/Symfony/Component/Security/Guard/composer.json | 2 +- src/Symfony/Component/Security/Http/composer.json | 2 +- src/Symfony/Component/Security/composer.json | 2 +- src/Symfony/Component/Serializer/composer.json | 2 +- src/Symfony/Component/Stopwatch/composer.json | 2 +- src/Symfony/Component/Templating/composer.json | 2 +- src/Symfony/Component/Translation/composer.json | 2 +- src/Symfony/Component/Validator/composer.json | 2 +- src/Symfony/Component/VarDumper/composer.json | 2 +- src/Symfony/Component/WebLink/composer.json | 2 +- src/Symfony/Component/Workflow/composer.json | 2 +- src/Symfony/Component/Yaml/composer.json | 2 +- 52 files changed, 51 insertions(+), 54 deletions(-) diff --git a/composer.json b/composer.json index cf55aeb8ef072..faf29256bc0c9 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "ext-xml": "*", "doctrine/common": "~2.4", "fig/link-util": "^1.0", diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index 67854035ce6b8..8876d794a1100 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "doctrine/common": "~2.4", "symfony/polyfill-mbstring": "~1.0" }, diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index d60949aab872c..23240155d267f 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "monolog/monolog": "~1.19", "symfony/http-kernel": "~2.8|~3.0" }, diff --git a/src/Symfony/Bridge/ProxyManager/composer.json b/src/Symfony/Bridge/ProxyManager/composer.json index 42751d000e59d..43a674eac9b25 100644 --- a/src/Symfony/Bridge/ProxyManager/composer.json +++ b/src/Symfony/Bridge/ProxyManager/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/dependency-injection": "~2.8|~3.0", "ocramius/proxy-manager": "~0.4|~1.0|~2.0" }, diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index 8fe41945b72aa..e00e3dc7fad35 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "twig/twig": "~1.34|~2.4" }, "require-dev": { diff --git a/src/Symfony/Bundle/DebugBundle/composer.json b/src/Symfony/Bundle/DebugBundle/composer.json index 77e2d1c5621ba..15a8611363ad5 100644 --- a/src/Symfony/Bundle/DebugBundle/composer.json +++ b/src/Symfony/Bundle/DebugBundle/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "ext-xml": "*", "symfony/http-kernel": "~2.8|~3.0", "symfony/twig-bridge": "~2.8|~3.0", diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 1105daa373f43..c605471911974 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "ext-xml": "*", "symfony/cache": "~3.3", "symfony/class-loader": "~3.2", diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 2c9a641e503d7..48de2c03ef46a 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "ext-xml": "*", "symfony/security": "~3.3", "symfony/dependency-injection": "~3.3", diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index 1b3cc91c1969c..1a0908a580a83 100644 --- a/src/Symfony/Bundle/TwigBundle/composer.json +++ b/src/Symfony/Bundle/TwigBundle/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/config": "~3.2", "symfony/twig-bridge": "^3.3", "symfony/http-foundation": "~2.8|~3.0", diff --git a/src/Symfony/Bundle/WebProfilerBundle/composer.json b/src/Symfony/Bundle/WebProfilerBundle/composer.json index 626ac4d307d51..12b168150c58d 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/composer.json +++ b/src/Symfony/Bundle/WebProfilerBundle/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/http-kernel": "~3.2", "symfony/polyfill-php70": "~1.0", "symfony/routing": "~2.8|~3.0", diff --git a/src/Symfony/Bundle/WebServerBundle/composer.json b/src/Symfony/Bundle/WebServerBundle/composer.json index 829e110c35206..d1c64e970fcca 100644 --- a/src/Symfony/Bundle/WebServerBundle/composer.json +++ b/src/Symfony/Bundle/WebServerBundle/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/console": "~3.3", "symfony/http-kernel": "~3.3", "symfony/process": "~3.3" diff --git a/src/Symfony/Component/Asset/composer.json b/src/Symfony/Component/Asset/composer.json index 8ed8d9d725212..39ccf2c00170d 100644 --- a/src/Symfony/Component/Asset/composer.json +++ b/src/Symfony/Component/Asset/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "suggest": { "symfony/http-foundation": "" diff --git a/src/Symfony/Component/BrowserKit/composer.json b/src/Symfony/Component/BrowserKit/composer.json index a18d66e81ea73..b6b7cb01016ab 100644 --- a/src/Symfony/Component/BrowserKit/composer.json +++ b/src/Symfony/Component/BrowserKit/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/dom-crawler": "~2.8|~3.0" }, "require-dev": { diff --git a/src/Symfony/Component/Cache/composer.json b/src/Symfony/Component/Cache/composer.json index 5c0df4b2a598a..f32117b038479 100644 --- a/src/Symfony/Component/Cache/composer.json +++ b/src/Symfony/Component/Cache/composer.json @@ -20,7 +20,7 @@ "psr/simple-cache-implementation": "1.0" }, "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "psr/cache": "~1.0", "psr/log": "~1.0", "psr/simple-cache": "^1.0" diff --git a/src/Symfony/Component/ClassLoader/composer.json b/src/Symfony/Component/ClassLoader/composer.json index a1dfc3fa0e096..d1b10ef649f46 100644 --- a/src/Symfony/Component/ClassLoader/composer.json +++ b/src/Symfony/Component/ClassLoader/composer.json @@ -17,7 +17,7 @@ ], "minimum-stability": "dev", "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "require-dev": { "symfony/finder": "~2.8|~3.0", diff --git a/src/Symfony/Component/Config/composer.json b/src/Symfony/Component/Config/composer.json index 7a51c91ed591a..f2bff19662b41 100644 --- a/src/Symfony/Component/Config/composer.json +++ b/src/Symfony/Component/Config/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/filesystem": "~2.8|~3.0" }, "require-dev": { diff --git a/src/Symfony/Component/Console/composer.json b/src/Symfony/Component/Console/composer.json index db76bf3b2c7a7..d4fef1ea5856c 100644 --- a/src/Symfony/Component/Console/composer.json +++ b/src/Symfony/Component/Console/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-mbstring": "~1.0", "symfony/debug": "~2.8|~3.0" }, diff --git a/src/Symfony/Component/CssSelector/composer.json b/src/Symfony/Component/CssSelector/composer.json index e94cfbded0d33..9661f70ea317d 100644 --- a/src/Symfony/Component/CssSelector/composer.json +++ b/src/Symfony/Component/CssSelector/composer.json @@ -20,7 +20,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "autoload": { "psr-4": { "Symfony\\Component\\CssSelector\\": "" }, diff --git a/src/Symfony/Component/Debug/composer.json b/src/Symfony/Component/Debug/composer.json index 6531eefd999ee..38323dd41c11a 100644 --- a/src/Symfony/Component/Debug/composer.json +++ b/src/Symfony/Component/Debug/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "psr/log": "~1.0" }, "conflict": { diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json index 8c88d4f02a790..0ce0ffeeaf57b 100644 --- a/src/Symfony/Component/DependencyInjection/composer.json +++ b/src/Symfony/Component/DependencyInjection/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "psr/container": "^1.0" }, "require-dev": { diff --git a/src/Symfony/Component/DomCrawler/composer.json b/src/Symfony/Component/DomCrawler/composer.json index 84df31fdeae2f..8835234c1171c 100644 --- a/src/Symfony/Component/DomCrawler/composer.json +++ b/src/Symfony/Component/DomCrawler/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { diff --git a/src/Symfony/Component/Dotenv/composer.json b/src/Symfony/Component/Dotenv/composer.json index 020342bdd4a96..0e6eda933f3fc 100644 --- a/src/Symfony/Component/Dotenv/composer.json +++ b/src/Symfony/Component/Dotenv/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "require-dev": { "symfony/process": "^3.2" diff --git a/src/Symfony/Component/EventDispatcher/composer.json b/src/Symfony/Component/EventDispatcher/composer.json index faa0429e2d1a0..994e8ca64ad3c 100644 --- a/src/Symfony/Component/EventDispatcher/composer.json +++ b/src/Symfony/Component/EventDispatcher/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "require-dev": { "symfony/dependency-injection": "~3.3", diff --git a/src/Symfony/Component/ExpressionLanguage/composer.json b/src/Symfony/Component/ExpressionLanguage/composer.json index d9d95f00cf4e4..cd8933d6be356 100644 --- a/src/Symfony/Component/ExpressionLanguage/composer.json +++ b/src/Symfony/Component/ExpressionLanguage/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/cache": "~3.1" }, "autoload": { diff --git a/src/Symfony/Component/Filesystem/composer.json b/src/Symfony/Component/Filesystem/composer.json index 715a34f7d86bc..122b6cea016d8 100644 --- a/src/Symfony/Component/Filesystem/composer.json +++ b/src/Symfony/Component/Filesystem/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" }, diff --git a/src/Symfony/Component/Finder/composer.json b/src/Symfony/Component/Finder/composer.json index b57dd8bcda24e..8eed8f53e5be5 100644 --- a/src/Symfony/Component/Finder/composer.json +++ b/src/Symfony/Component/Finder/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "autoload": { "psr-4": { "Symfony\\Component\\Finder\\": "" }, diff --git a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php index 943ad3fba5f3d..378edf563b972 100644 --- a/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php +++ b/src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php @@ -85,9 +85,6 @@ public function __construct(FormDataExtractorInterface $dataExtractor) */ public function collect(Request $request, Response $response, \Exception $exception = null) { - if (70000 <= \PHP_VERSION_ID && \PHP_VERSION_ID < 70008) { - @trigger_error('A bug in PHP 7.0.0 to 7.0.7 is breaking the Form panel, please upgrade to 7.0.8 or higher.', E_USER_DEPRECATED); - } } /** diff --git a/src/Symfony/Component/Form/composer.json b/src/Symfony/Component/Form/composer.json index 85250b87f357b..a88c0d64eec09 100644 --- a/src/Symfony/Component/Form/composer.json +++ b/src/Symfony/Component/Form/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/event-dispatcher": "~2.8|~3.0", "symfony/intl": "^2.8.18|^3.2.5", "symfony/options-resolver": "~2.8|~3.0", diff --git a/src/Symfony/Component/HttpFoundation/composer.json b/src/Symfony/Component/HttpFoundation/composer.json index dfa25f79ec405..a964975ecb3f2 100644 --- a/src/Symfony/Component/HttpFoundation/composer.json +++ b/src/Symfony/Component/HttpFoundation/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-mbstring": "~1.1" }, "require-dev": { diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index babc8663b6487..cc543c6d854fb 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/event-dispatcher": "~2.8|~3.0", "symfony/http-foundation": "~3.3", "symfony/debug": "~2.8|~3.0", diff --git a/src/Symfony/Component/Inflector/composer.json b/src/Symfony/Component/Inflector/composer.json index 79f4ed788f62b..df6c12f518746 100644 --- a/src/Symfony/Component/Inflector/composer.json +++ b/src/Symfony/Component/Inflector/composer.json @@ -23,7 +23,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "autoload": { "psr-4": { "Symfony\\Component\\Inflector\\": "" }, diff --git a/src/Symfony/Component/Intl/composer.json b/src/Symfony/Component/Intl/composer.json index dea362ed22040..452582bb8fecb 100644 --- a/src/Symfony/Component/Intl/composer.json +++ b/src/Symfony/Component/Intl/composer.json @@ -24,7 +24,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-intl-icu": "~1.0" }, "require-dev": { diff --git a/src/Symfony/Component/Ldap/composer.json b/src/Symfony/Component/Ldap/composer.json index a2f580f4319fc..5cc3ce11e8c6d 100644 --- a/src/Symfony/Component/Ldap/composer.json +++ b/src/Symfony/Component/Ldap/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-php56": "~1.0", "symfony/options-resolver": "~2.8|~3.0", "ext-ldap": "*" diff --git a/src/Symfony/Component/OptionsResolver/composer.json b/src/Symfony/Component/OptionsResolver/composer.json index a751730af3819..4311b59c78172 100644 --- a/src/Symfony/Component/OptionsResolver/composer.json +++ b/src/Symfony/Component/OptionsResolver/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "autoload": { "psr-4": { "Symfony\\Component\\OptionsResolver\\": "" }, diff --git a/src/Symfony/Component/Process/composer.json b/src/Symfony/Component/Process/composer.json index f899c52b2b818..a6d7c7c464bb0 100644 --- a/src/Symfony/Component/Process/composer.json +++ b/src/Symfony/Component/Process/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "autoload": { "psr-4": { "Symfony\\Component\\Process\\": "" }, diff --git a/src/Symfony/Component/PropertyAccess/composer.json b/src/Symfony/Component/PropertyAccess/composer.json index 508dd78cc70f4..011ffa7783e46 100644 --- a/src/Symfony/Component/PropertyAccess/composer.json +++ b/src/Symfony/Component/PropertyAccess/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-php70": "~1.0", "symfony/inflector": "~3.1" }, diff --git a/src/Symfony/Component/PropertyInfo/composer.json b/src/Symfony/Component/PropertyInfo/composer.json index 4d6cac3ef98d9..fbc8f06a73a6d 100644 --- a/src/Symfony/Component/PropertyInfo/composer.json +++ b/src/Symfony/Component/PropertyInfo/composer.json @@ -23,7 +23,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/inflector": "~3.1" }, "require-dev": { diff --git a/src/Symfony/Component/Routing/composer.json b/src/Symfony/Component/Routing/composer.json index 38069dc4e9ab0..bb4f6a554bd7b 100644 --- a/src/Symfony/Component/Routing/composer.json +++ b/src/Symfony/Component/Routing/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "require-dev": { "symfony/config": "~2.8|~3.0", diff --git a/src/Symfony/Component/Security/Core/composer.json b/src/Symfony/Component/Security/Core/composer.json index 3e045fb227545..09db36781a2d0 100644 --- a/src/Symfony/Component/Security/Core/composer.json +++ b/src/Symfony/Component/Security/Core/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-php56": "~1.0" }, "require-dev": { diff --git a/src/Symfony/Component/Security/Csrf/composer.json b/src/Symfony/Component/Security/Csrf/composer.json index 913cc458b2e2a..46cca3a0abab0 100644 --- a/src/Symfony/Component/Security/Csrf/composer.json +++ b/src/Symfony/Component/Security/Csrf/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-php56": "~1.0", "symfony/polyfill-php70": "~1.0", "symfony/security-core": "~2.8|~3.0" diff --git a/src/Symfony/Component/Security/Guard/composer.json b/src/Symfony/Component/Security/Guard/composer.json index 4bf473a89fa93..b21039a275cd6 100644 --- a/src/Symfony/Component/Security/Guard/composer.json +++ b/src/Symfony/Component/Security/Guard/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/security-core": "~2.8|~3.0", "symfony/security-http": "~3.1" }, diff --git a/src/Symfony/Component/Security/Http/composer.json b/src/Symfony/Component/Security/Http/composer.json index b1458eaa93c7a..595364436723c 100644 --- a/src/Symfony/Component/Security/Http/composer.json +++ b/src/Symfony/Component/Security/Http/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/security-core": "~3.2", "symfony/event-dispatcher": "~2.8|~3.0", "symfony/http-foundation": "~2.8|~3.0", diff --git a/src/Symfony/Component/Security/composer.json b/src/Symfony/Component/Security/composer.json index e6835fe883e2e..f39bfcf8ccb58 100644 --- a/src/Symfony/Component/Security/composer.json +++ b/src/Symfony/Component/Security/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/event-dispatcher": "~2.8|~3.0", "symfony/http-foundation": "~2.8|~3.0", "symfony/http-kernel": "~3.3", diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json index 37dd110bc3f25..cd9fd883716d7 100644 --- a/src/Symfony/Component/Serializer/composer.json +++ b/src/Symfony/Component/Serializer/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "require-dev": { "symfony/yaml": "~3.3", diff --git a/src/Symfony/Component/Stopwatch/composer.json b/src/Symfony/Component/Stopwatch/composer.json index 0b40c8d102d0d..06194a018693e 100644 --- a/src/Symfony/Component/Stopwatch/composer.json +++ b/src/Symfony/Component/Stopwatch/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "autoload": { "psr-4": { "Symfony\\Component\\Stopwatch\\": "" }, diff --git a/src/Symfony/Component/Templating/composer.json b/src/Symfony/Component/Templating/composer.json index 7b1d0fb03bf5e..6b34d63a4ebe4 100644 --- a/src/Symfony/Component/Templating/composer.json +++ b/src/Symfony/Component/Templating/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "require-dev": { "psr/log": "~1.0" diff --git a/src/Symfony/Component/Translation/composer.json b/src/Symfony/Component/Translation/composer.json index e107e2538a15d..f9ed96dc62446 100644 --- a/src/Symfony/Component/Translation/composer.json +++ b/src/Symfony/Component/Translation/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { diff --git a/src/Symfony/Component/Validator/composer.json b/src/Symfony/Component/Validator/composer.json index ca441954b894f..3fd2d05fcabc4 100644 --- a/src/Symfony/Component/Validator/composer.json +++ b/src/Symfony/Component/Validator/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-mbstring": "~1.0", "symfony/translation": "~2.8|~3.0" }, diff --git a/src/Symfony/Component/VarDumper/composer.json b/src/Symfony/Component/VarDumper/composer.json index 930896026ae53..ae74aa4901a45 100644 --- a/src/Symfony/Component/VarDumper/composer.json +++ b/src/Symfony/Component/VarDumper/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { diff --git a/src/Symfony/Component/WebLink/composer.json b/src/Symfony/Component/WebLink/composer.json index 336feaf006031..a3df726a63b94 100644 --- a/src/Symfony/Component/WebLink/composer.json +++ b/src/Symfony/Component/WebLink/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "fig/link-util": "^1.0", "psr/link": "^1.0" }, diff --git a/src/Symfony/Component/Workflow/composer.json b/src/Symfony/Component/Workflow/composer.json index 2e5825f48d0fb..7feef3fe983d6 100644 --- a/src/Symfony/Component/Workflow/composer.json +++ b/src/Symfony/Component/Workflow/composer.json @@ -20,7 +20,7 @@ } ], "require": { - "php": ">=5.5.9", + "php": "^5.5.9|>=7.0.8", "symfony/property-access": "~2.3|~3.0" }, "require-dev": { diff --git a/src/Symfony/Component/Yaml/composer.json b/src/Symfony/Component/Yaml/composer.json index 698b5ced17364..2103d6cfd0092 100644 --- a/src/Symfony/Component/Yaml/composer.json +++ b/src/Symfony/Component/Yaml/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.5.9" + "php": "^5.5.9|>=7.0.8" }, "require-dev": { "symfony/console": "~2.8|~3.0" From a0cd96812e3055a2a9cfebfbde5ad460d12a1ac5 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 1 Aug 2017 09:06:55 +0200 Subject: [PATCH 03/80] updated CHANGELOG for 2.7.33 --- CHANGELOG-2.7.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md index 335dfd82e4186..d08766327bc5e 100644 --- a/CHANGELOG-2.7.md +++ b/CHANGELOG-2.7.md @@ -7,6 +7,17 @@ in 2.7 minor versions. To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.7.0...v2.7.1 +* 2.7.33 (2017-08-01) + + * bug #22244 [Console] Fix passing options with defaultCommand (Jakub Sacha) + * bug #23684 [Debug] Missing escape in debug output (c960657) + * bug #23662 [VarDumper] Adapt to php 7.2 changes (nicolas-grekas) + * bug #23649 [Form][TwigBridge] Don't render _method in form_rest() for a child form (fmarchalemisys) + * bug #23619 [Validator] Fix IbanValidator for ukrainian IBANs (paroe) + * bug #23238 [Security] ensure the 'route' index is set before attempting to use it (gsdevme) + * bug #23580 Fix login redirect when referer contains a query string (fabpot) + * bug #23574 [VarDumper] Move locale sniffing to dump() time (nicolas-grekas) + * 2.7.32 (2017-07-17) * security #23507 [Security] validate empty passwords again (xabbuh) From 55123da8f52a01f12c2e6960edff5707ad04add2 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 1 Aug 2017 09:07:01 +0200 Subject: [PATCH 04/80] update CONTRIBUTORS for 2.7.33 --- CONTRIBUTORS.md | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 47a6cf9986dcf..1b059f5012cb7 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -20,11 +20,11 @@ Symfony is the result of the work of many people who made the code better - Javier Eguiluz (javier.eguiluz) - Hugo Hamon (hhamon) - Maxime Steinhausser (ogizanagi) - - Abdellatif Ait boudad (aitboudad) - Robin Chalas (chalas_r) + - Abdellatif Ait boudad (aitboudad) + - Grégoire Pineau (lyrixx) - Romain Neutron (romain) - Pascal Borreli (pborreli) - - Grégoire Pineau (lyrixx) - Wouter De Jong (wouterj) - Joseph Bielawski (stloyd) - Karma Dordrak (drak) @@ -34,8 +34,8 @@ Symfony is the result of the work of many people who made the code better - Jean-François Simon (jfsimon) - Benjamin Eberlei (beberlei) - Igor Wiedler (igorw) - - Eriksen Costa (eriksencosta) - Roland Franssen (ro0) + - Eriksen Costa (eriksencosta) - Jules Pietri (heah) - Sarah Khalil (saro0h) - Guilhem Niot (energetick) @@ -66,6 +66,7 @@ Symfony is the result of the work of many people who made the code better - Eric Clemmons (ericclemmons) - Charles Sarrazin (csarrazi) - Christian Raue + - Konstantin Myakshin (koc) - Arnout Boks (aboks) - Deni - Henrik Westphal (snc) @@ -73,7 +74,7 @@ Symfony is the result of the work of many people who made the code better - Jáchym Toušek (enumag) - Titouan Galopin (tgalopin) - Douglas Greenshields (shieldo) - - Konstantin Myakshin (koc) + - Dany Maillard (maidmaid) - Lee McDermott - Brandon Turner - Luis Cordova (cordoval) @@ -89,23 +90,22 @@ Symfony is the result of the work of many people who made the code better - Fran Moreno (franmomu) - Antoine Hérault (herzult) - Paráda József (paradajozsef) + - Issei Murasawa (issei_m) - Arnaud Le Blanc (arnaud-lb) - Maxime STEINHAUSSER - Alexander M. Turek (derrabus) - Michal Piotrowski (eventhorizon) - - Dany Maillard (maidmaid) - - Issei Murasawa (issei_m) - Tim Nagel (merk) + - Yonel Ceruto González (yonelceruto) - Brice BERNARD (brikou) - Baptiste Clavié (talus) - Vladimir Reznichenko (kalessil) - marc.weistroff - - Yonel Ceruto González (yonelceruto) - lenar + - Tobias Nyholm (tobias) - Włodzimierz Gajda (gajdaw) - Alexander Schwenn (xelaris) - Jacob Dreesen (jdreesen) - - Tobias Nyholm (tobias) - Florian Voutzinos (florianv) - Colin Frei - Adrien Brault (adrienbrault) @@ -132,13 +132,13 @@ Symfony is the result of the work of many people who made the code better - Daniel Gomes (danielcsgomes) - Hidenori Goto (hidenorigoto) - Guilherme Blanco (guilhermeblanco) + - David Maicher (dmaicher) - Pablo Godel (pgodel) - Jérémie Augustin (jaugustin) - Andréia Bohner (andreia) - Rafael Dohms (rdohms) - Arnaud Kleinpeter (nanocom) - jwdeitch - - David Maicher (dmaicher) - Mikael Pajunen - Joel Wurtz (brouznouf) - Jérôme Vasseur (jvasseur) @@ -175,6 +175,7 @@ Symfony is the result of the work of many people who made the code better - Dennis Benkert (denderello) - Benjamin Dulau (dbenjamin) - Mathieu Lemoine (lemoinem) + - Christian Schmidt - Andreas Hucks (meandmymonkey) - Noel Guilbert (noel) - Stepan Anchugov (kix) @@ -200,7 +201,6 @@ Symfony is the result of the work of many people who made the code better - John Kary (johnkary) - Justin Hileman (bobthecow) - Blanchon Vincent (blanchonvincent) - - Christian Schmidt - Michele Orselli (orso) - Tom Van Looy (tvlooy) - Sven Paulus (subsven) @@ -236,6 +236,7 @@ Symfony is the result of the work of many people who made the code better - Katsuhiro OGAWA - Patrick McDougle (patrick-mcdougle) - Alif Rachmawadi + - Alessandro Chitolina - Kristen Gilden (kgilden) - Pierre-Yves LEBECQ (pylebecq) - Jordan Samouh (jordansamouh) @@ -261,6 +262,8 @@ Symfony is the result of the work of many people who made the code better - Pavel Batanov (scaytrase) - Nikita Konstantinov - Wodor Wodorski + - Rob Frawley 2nd (robfrawley) + - Gregor Harlan (gharlan) - Thomas Lallement (raziel057) - Giorgio Premi - Matthieu Napoli (mnapoli) @@ -276,7 +279,6 @@ Symfony is the result of the work of many people who made the code better - Marc Weistroff (futurecat) - Christian Schmidt - Hidde Wieringa (hiddewie) - - Alessandro Chitolina - Chad Sikorra (chadsikorra) - Chris Smith (cs278) - Florian Klein (docteurklein) @@ -313,7 +315,6 @@ Symfony is the result of the work of many people who made the code better - Thierry Thuon (lepiaf) - Ricard Clau (ricardclau) - Mark Challoner (markchalloner) - - Gregor Harlan (gharlan) - Gennady Telegin (gtelegin) - Ben Davies (bendavies) - Erin Millard @@ -322,7 +323,6 @@ Symfony is the result of the work of many people who made the code better - Magnus Nordlander (magnusnordlander) - alquerci - Francesco Levorato - - Rob Frawley 2nd (robfrawley) - Vitaliy Zakharov (zakharovvi) - Tobias Sjösten (tobiassjosten) - Gyula Sallai (salla) @@ -339,6 +339,7 @@ Symfony is the result of the work of many people who made the code better - Thomas Calvet (fancyweb) - Niels Keurentjes (curry684) - JhonnyL + - David Badura (davidbadura) - hossein zolfi (ocean) - Clément Gautier (clementgautier) - Eduardo Gulias (egulias) @@ -428,7 +429,6 @@ Symfony is the result of the work of many people who made the code better - Christian Wahler - Gintautas Miselis - Rob Bast - - David Badura (davidbadura) - Zander Baldwin - Adam Harvey - Maxime Veber (nek-) @@ -543,6 +543,7 @@ Symfony is the result of the work of many people who made the code better - Max Rath (drak3) - Stéphane Escandell (sescandell) - Konstantin S. M. Möllers (ksmmoellers) + - James Johnston - Sinan Eldem - Alexandre Dupuy (satchette) - Andre Rømcke (andrerom) @@ -591,6 +592,7 @@ Symfony is the result of the work of many people who made the code better - Ulumuddin Yunus (joenoez) - Luc Vieillescazes (iamluc) - Johann Saunier (prophet777) + - Valentin Udaltsov (vudaltsov) - Michael Devery (mickadoo) - Antoine Corcy - Artur Eshenbrener @@ -909,6 +911,7 @@ Symfony is the result of the work of many people who made the code better - Alex Demchenko (pilot) - Tadas Gliaubicas (tadcka) - Benoit Garret + - Jakub Sacha - DerManoMann - Olaf Klischat - orlovv @@ -1173,6 +1176,7 @@ Symfony is the result of the work of many people who made the code better - Malte Wunsch - wusuopu - povilas + - Gavin Staniforth - Alessandro Tagliapietra (alex88) - Biji (biji) - Gunnar Lium (gunnarlium) @@ -1234,6 +1238,7 @@ Symfony is the result of the work of many people who made the code better - flack - izzyp - František Bereň + - Mike Francis - Christoph Nissle (derstoffel) - Ionel Scutelnicu (ionelscutelnicu) - Nicolas Tallefourtané (nicolab) @@ -1244,6 +1249,7 @@ Symfony is the result of the work of many people who made the code better - jjanvier - Julius Beckmann - Romain Dorgueil + - Christopher Parotat - Grayson Koonce (breerly) - Fabien LUCAS (flucas2) - Indra Gunawan (indragunawan) @@ -1535,11 +1541,13 @@ Symfony is the result of the work of many people who made the code better - Ladislav Tánczos - Brian Freytag - Skorney + - fmarchalemisys - mieszko4 - Steve Preston - Neophy7e - bokonet - Arrilot + - Shaun Simmons - Markus Staab - Pierre-Louis LAUNAY - djama @@ -1568,6 +1576,7 @@ Symfony is the result of the work of many people who made the code better - Penny Leach - Richard Trebichavský - g123456789l + - Jonathan Vollebregt - oscartv - DanSync - Peter Zwosta @@ -1680,7 +1689,6 @@ Symfony is the result of the work of many people who made the code better - Moritz Kraft (userfriendly) - Víctor Mateo (victormateo) - Vincent (vincent1870) - - Valentin Udaltsov (vudaltsov) - Eugene Babushkin (warl) - Wouter Sioen (wouter_sioen) - Xavier Amado (xamado) @@ -1702,6 +1710,7 @@ Symfony is the result of the work of many people who made the code better - Sergey Fedotov - Michael - fh-github@fholzhauer.de + - AbdElKader Bouadjadja - Jan Emrich - Mark Topper - Xavier REN From b30d34baf60f97d03548de60d7f22198f4ad0a2c Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 1 Aug 2017 09:07:03 +0200 Subject: [PATCH 05/80] updated VERSION for 2.7.33 --- 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 6221e163755f1..60ced9c9d646e 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.7.33-DEV'; + const VERSION = '2.7.33'; const VERSION_ID = 20733; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; const RELEASE_VERSION = 33; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From 8acbd12a24af4714a4c83d57bf766286a69a240c Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 1 Aug 2017 09:21:40 +0200 Subject: [PATCH 06/80] bumped Symfony version to 2.7.34 --- 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 60ced9c9d646e..401a3626d84b4 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '2.7.33'; - const VERSION_ID = 20733; + const VERSION = '2.7.34-DEV'; + const VERSION_ID = 20734; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; - const RELEASE_VERSION = 33; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 34; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From acd0af6d29c7e15d3c8dc53a14c2ed4bdef3a9e0 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 1 Aug 2017 11:05:00 +0200 Subject: [PATCH 07/80] updated CHANGELOG for 2.8.26 --- CHANGELOG-2.8.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG-2.8.md b/CHANGELOG-2.8.md index a73a824d4cf45..5fdc52f111daa 100644 --- a/CHANGELOG-2.8.md +++ b/CHANGELOG-2.8.md @@ -7,6 +7,19 @@ 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.26 (2017-08-01) + + * bug #22244 [Console] Fix passing options with defaultCommand (Jakub Sacha) + * bug #23684 [Debug] Missing escape in debug output (c960657) + * bug #23662 [VarDumper] Adapt to php 7.2 changes (nicolas-grekas) + * bug #23649 [Form][TwigBridge] Don't render _method in form_rest() for a child form (fmarchalemisys) + * bug #23023 [DoctrineBridge][PropertyInfo] Added support for Doctrine Embeddables (vudaltsov) + * bug #23619 [Validator] Fix IbanValidator for ukrainian IBANs (paroe) + * bug #23238 [Security] ensure the 'route' index is set before attempting to use it (gsdevme) + * bug #23330 [WebProfilerBundle] Fix full sized dump hovering in toolbar (ogizanagi) + * bug #23580 Fix login redirect when referer contains a query string (fabpot) + * bug #23574 [VarDumper] Move locale sniffing to dump() time (nicolas-grekas) + * 2.8.25 (2017-07-17) * security #23507 [Security] validate empty passwords again (xabbuh) From d2e8f38a78a3028f15f4f86686003f9de780b7f0 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 1 Aug 2017 11:05:02 +0200 Subject: [PATCH 08/80] updated VERSION for 2.8.26 --- 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 69d5dbdceeb39..118d67aaec835 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.26-DEV'; + const VERSION = '2.8.26'; const VERSION_ID = 20826; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; const RELEASE_VERSION = 26; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From 6f05bebe1f6829a964396de552e69cbb56d571f0 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 1 Aug 2017 11:29:28 +0200 Subject: [PATCH 09/80] bumped Symfony version to 2.8.27 --- 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 118d67aaec835..ff1dc40d15fb8 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.26'; - const VERSION_ID = 20826; + const VERSION = '2.8.27-DEV'; + const VERSION_ID = 20827; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; - const RELEASE_VERSION = 26; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 27; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From ab0cbd48616ba1501d94ca5129e3ab80b8f5e8f5 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 1 Aug 2017 11:40:12 +0200 Subject: [PATCH 10/80] updated CHANGELOG for 3.2.13 --- CHANGELOG-3.2.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG-3.2.md b/CHANGELOG-3.2.md index 1a4d44e19981e..544ae4b071c06 100644 --- a/CHANGELOG-3.2.md +++ b/CHANGELOG-3.2.md @@ -7,6 +7,22 @@ in 3.2 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.2.0...v3.2.1 +* 3.2.13 (2017-08-01) + + * bug #22244 [Console] Fix passing options with defaultCommand (Jakub Sacha) + * bug #23684 [Debug] Missing escape in debug output (c960657) + * bug #23654 [DI] Fix using private services in expressions (nicolas-grekas) + * bug #23662 [VarDumper] Adapt to php 7.2 changes (nicolas-grekas) + * bug #23649 [Form][TwigBridge] Don't render _method in form_rest() for a child form (fmarchalemisys) + * bug #23023 [DoctrineBridge][PropertyInfo] Added support for Doctrine Embeddables (vudaltsov) + * bug #23619 [Validator] Fix IbanValidator for ukrainian IBANs (paroe) + * bug #23586 Fix case sensitive sameSite cookie (mikefrancis) + * bug #23238 [Security] ensure the 'route' index is set before attempting to use it (gsdevme) + * bug #23330 [WebProfilerBundle] Fix full sized dump hovering in toolbar (ogizanagi) + * bug #23580 Fix login redirect when referer contains a query string (fabpot) + * bug #23558 [FrameworkBundle] fix ValidatorCacheWarmer: use serializing ArrayAdapter (dmaicher) + * bug #23574 [VarDumper] Move locale sniffing to dump() time (nicolas-grekas) + * 3.2.12 (2017-07-17) * bug #23549 [PropertyInfo] conflict for phpdocumentor/reflection-docblock 3.2 (xabbuh) From 7ce788b5ddb7f811dae50cb48376ef2e6395e8df Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 1 Aug 2017 11:40:19 +0200 Subject: [PATCH 11/80] updated VERSION for 3.2.13 --- 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 30d692cbf4e45..3b3d87814b6ab 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '3.2.13-DEV'; + const VERSION = '3.2.13'; const VERSION_ID = 30213; const MAJOR_VERSION = 3; const MINOR_VERSION = 2; const RELEASE_VERSION = 13; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '07/2017'; const END_OF_LIFE = '01/2018'; From 927f95001913724cb12e6b79043193497e7062e1 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 1 Aug 2017 12:20:44 +0200 Subject: [PATCH 12/80] bumped Symfony version to 3.2.14 --- 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 3b3d87814b6ab..9093145d3404b 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -58,12 +58,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface protected $startTime; protected $loadClassCache; - const VERSION = '3.2.13'; - const VERSION_ID = 30213; + const VERSION = '3.2.14-DEV'; + const VERSION_ID = 30214; const MAJOR_VERSION = 3; const MINOR_VERSION = 2; - const RELEASE_VERSION = 13; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 14; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '07/2017'; const END_OF_LIFE = '01/2018'; From 468b44a03136ea2735c8040961c350a81a522fd8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 1 Aug 2017 13:24:30 +0200 Subject: [PATCH 13/80] bumped Symfony version to 3.3.7 --- 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 0372a86cf7cbb..f6a62a6341cfa 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -61,12 +61,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface private $projectDir; - const VERSION = '3.3.6'; - const VERSION_ID = 30306; + const VERSION = '3.3.7-DEV'; + const VERSION_ID = 30307; const MAJOR_VERSION = 3; const MINOR_VERSION = 3; - const RELEASE_VERSION = 6; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 7; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '01/2018'; const END_OF_LIFE = '07/2018'; From ce86449f814f45e95e089ccf28a1a8c53e175905 Mon Sep 17 00:00:00 2001 From: Valentin Date: Tue, 1 Aug 2017 18:09:35 +0300 Subject: [PATCH 14/80] Docblock improvement --- .../Component/Security/Guard/GuardAuthenticatorInterface.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Security/Guard/GuardAuthenticatorInterface.php b/src/Symfony/Component/Security/Guard/GuardAuthenticatorInterface.php index fef4a04fb9702..307d70f9e973e 100644 --- a/src/Symfony/Component/Security/Guard/GuardAuthenticatorInterface.php +++ b/src/Symfony/Component/Security/Guard/GuardAuthenticatorInterface.php @@ -153,6 +153,7 @@ public function onAuthenticationSuccess(Request $request, TokenInterface $token, * done by having a _remember_me checkbox in your form, but * can be configured by the "always_remember_me" and "remember_me_parameter" * parameters under the "remember_me" firewall key + * D) The onAuthenticationSuccess method returns a Response object * * @return bool */ From a63ab776247cb76ee0c0fec9c37f6a09d2ee0b61 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 2 Aug 2017 07:57:29 +0200 Subject: [PATCH 15/80] [Config] Fix checking class existence freshness --- .../Config/Resource/ClassExistenceResource.php | 7 ++++++- .../Config/Tests/Fixtures/BadParent.php | 7 +++++++ .../Resource/ClassExistenceResourceTest.php | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Config/Tests/Fixtures/BadParent.php diff --git a/src/Symfony/Component/Config/Resource/ClassExistenceResource.php b/src/Symfony/Component/Config/Resource/ClassExistenceResource.php index 623124ab8d988..e3fd095b6008d 100644 --- a/src/Symfony/Component/Config/Resource/ClassExistenceResource.php +++ b/src/Symfony/Component/Config/Resource/ClassExistenceResource.php @@ -65,7 +65,7 @@ public function isFresh($timestamp) { $loaded = class_exists($this->resource, false) || interface_exists($this->resource, false) || trait_exists($this->resource, false); - if (null !== $exists = &self::$existsCache[$this->resource]) { + if (null !== $exists = &self::$existsCache[(int) (0 >= $timestamp)][$this->resource]) { $exists = $exists || $loaded; } elseif (!$exists = $loaded) { if (!self::$autoloadLevel++) { @@ -76,6 +76,11 @@ public function isFresh($timestamp) try { $exists = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false); + } catch (\ReflectionException $e) { + if (0 >= $timestamp) { + unset(self::$existsCache[1][$this->resource]); + throw $e; + } } finally { self::$autoloadedClass = $autoloadedClass; if (!--self::$autoloadLevel) { diff --git a/src/Symfony/Component/Config/Tests/Fixtures/BadParent.php b/src/Symfony/Component/Config/Tests/Fixtures/BadParent.php new file mode 100644 index 0000000000000..68d7296ed8696 --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Fixtures/BadParent.php @@ -0,0 +1,7 @@ +assertTrue($res->isFresh(time())); + } + + /** + * @expectedException \ReflectionException + * @expectedExceptionMessage Class Symfony\Component\Config\Tests\Fixtures\MissingParent not found + */ + public function testBadParentWithNoTimestamp() + { + $res = new ClassExistenceResource(BadParent::class, false); + $res->isFresh(0); + } + public function testConditionalClass() { $res = new ClassExistenceResource(ConditionalClass::class, false); From 103b23efb62e42c4bb53064471b22bf28ccdf7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Parmentier?= Date: Wed, 2 Aug 2017 16:33:39 +0200 Subject: [PATCH 16/80] Fix comment --- .../FrameworkBundle/DependencyInjection/FrameworkExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 131db0ae86343..c6b1f294ab269 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1273,7 +1273,7 @@ private function registerSecurityCsrfConfiguration(array $config, ContainerBuild private function registerSerializerConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader) { if (class_exists('Symfony\Component\Serializer\Normalizer\DataUriNormalizer')) { - // Run after serializer.normalizer.object + // Run before serializer.normalizer.object $definition = $container->register('serializer.normalizer.data_uri', DataUriNormalizer::class); $definition->setPublic(false); $definition->addTag('serializer.normalizer', array('priority' => -920)); From 81396c7facd4d3806734f7402b6b8b6b9eca1df5 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Tue, 1 Aug 2017 10:05:24 -0400 Subject: [PATCH 17/80] Removed useless argument $definition --- src/Symfony/Component/Form/DependencyInjection/FormPass.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Form/DependencyInjection/FormPass.php b/src/Symfony/Component/Form/DependencyInjection/FormPass.php index 55e4cc1239b2f..88574558b7b7a 100644 --- a/src/Symfony/Component/Form/DependencyInjection/FormPass.php +++ b/src/Symfony/Component/Form/DependencyInjection/FormPass.php @@ -16,7 +16,6 @@ use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Reference; @@ -53,12 +52,12 @@ public function process(ContainerBuilder $container) if (new IteratorArgument(array()) != $definition->getArgument(2)) { return; } - $definition->replaceArgument(0, $this->processFormTypes($container, $definition)); + $definition->replaceArgument(0, $this->processFormTypes($container)); $definition->replaceArgument(1, $this->processFormTypeExtensions($container)); $definition->replaceArgument(2, $this->processFormTypeGuessers($container)); } - private function processFormTypes(ContainerBuilder $container, Definition $definition) + private function processFormTypes(ContainerBuilder $container) { // Get service locator argument $servicesMap = array(); From 2d79ffa0caac35839fc1be50f0d71139cce44bda Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 31 Jul 2017 15:17:36 +0200 Subject: [PATCH 18/80] [Bridge\ProxyManager] Dont call __destruct() on non-instantiated services --- .../LazyLoadingValueHolderFactoryV1.php | 31 ++++++++++++++ .../LazyLoadingValueHolderFactoryV2.php | 32 +++++++++++++++ .../Instantiator/RuntimeInstantiator.php | 6 ++- .../LazyLoadingValueHolderGenerator.php | 41 +++++++++++++++++++ .../LazyProxy/PhpDumper/ProxyDumper.php | 1 - .../Tests/LazyProxy/ContainerBuilderTest.php | 6 +++ .../Tests/LazyProxy/Fixtures/includes/foo.php | 7 ++++ 7 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/LazyLoadingValueHolderFactoryV1.php create mode 100644 src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/LazyLoadingValueHolderFactoryV2.php create mode 100644 src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/LazyLoadingValueHolderGenerator.php diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/LazyLoadingValueHolderFactoryV1.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/LazyLoadingValueHolderFactoryV1.php new file mode 100644 index 0000000000000..3298b84d46278 --- /dev/null +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/LazyLoadingValueHolderFactoryV1.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\ProxyManager\LazyProxy\Instantiator; + +use ProxyManager\Factory\LazyLoadingValueHolderFactory as BaseFactory; +use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\LazyLoadingValueHolderGenerator; + +/** + * @internal + */ +class LazyLoadingValueHolderFactoryV1 extends BaseFactory +{ + private $generatorV1; + + /** + * {@inheritdoc} + */ + protected function getGenerator() + { + return $this->generatorV1 ?: $this->generatorV1 = new LazyLoadingValueHolderGenerator(); + } +} diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/LazyLoadingValueHolderFactoryV2.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/LazyLoadingValueHolderFactoryV2.php new file mode 100644 index 0000000000000..f41fc20b5d523 --- /dev/null +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/LazyLoadingValueHolderFactoryV2.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\ProxyManager\LazyProxy\Instantiator; + +use ProxyManager\ProxyGenerator\ProxyGeneratorInterface; +use ProxyManager\Factory\LazyLoadingValueHolderFactory as BaseFactory; +use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\LazyLoadingValueHolderGenerator; + +/** + * @internal + */ +class LazyLoadingValueHolderFactoryV2 extends BaseFactory +{ + private $generator; + + /** + * {@inheritdoc} + */ + protected function getGenerator(): ProxyGeneratorInterface + { + return $this->generator ?: $this->generator = new LazyLoadingValueHolderGenerator(); + } +} diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/RuntimeInstantiator.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/RuntimeInstantiator.php index 0101026794c7c..33fc49e1012d9 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/RuntimeInstantiator.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/RuntimeInstantiator.php @@ -36,7 +36,11 @@ public function __construct() $config = new Configuration(); $config->setGeneratorStrategy(new EvaluatingGeneratorStrategy()); - $this->factory = new LazyLoadingValueHolderFactory($config); + if (method_exists('ProxyManager\Version', 'getVersion')) { + $this->factory = new LazyLoadingValueHolderFactoryV2($config); + } else { + $this->factory = new LazyLoadingValueHolderFactoryV1($config); + } } /** diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/LazyLoadingValueHolderGenerator.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/LazyLoadingValueHolderGenerator.php new file mode 100644 index 0000000000000..1d9432f622b41 --- /dev/null +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/LazyLoadingValueHolderGenerator.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper; + +use ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator as BaseGenerator; +use Zend\Code\Generator\ClassGenerator; + +/** + * @internal + */ +class LazyLoadingValueHolderGenerator extends BaseGenerator +{ + /** + * {@inheritdoc} + */ + public function generate(\ReflectionClass $originalClass, ClassGenerator $classGenerator) + { + parent::generate($originalClass, $classGenerator); + + if ($classGenerator->hasMethod('__destruct')) { + $destructor = $classGenerator->getMethod('__destruct'); + $body = $destructor->getBody(); + $newBody = preg_replace('/^(\$this->initializer[a-zA-Z0-9]++) && .*;\n\nreturn (\$this->valueHolder)/', '$1 || $2', $body); + + if ($body === $newBody) { + throw new \UnexpectedValueException(sprintf('Unexpected lazy-proxy format generated for method %s::__destruct()', $originalClass->name)); + } + + $destructor->setBody($newBody); + } + } +} diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index eb72a7d5d83cb..40791358500a0 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -13,7 +13,6 @@ use ProxyManager\Generator\ClassGenerator; use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy; -use ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Definition; diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/ContainerBuilderTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/ContainerBuilderTest.php index b634a69488a34..858e9d76b64c9 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/ContainerBuilderTest.php +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/ContainerBuilderTest.php @@ -39,6 +39,9 @@ public function testCreateProxyServiceWithRuntimeInstantiator() /* @var $foo1 \ProxyManager\Proxy\LazyLoadingInterface|\ProxyManager\Proxy\ValueHolderInterface */ $foo1 = $builder->get('foo1'); + $foo1->__destruct(); + $this->assertSame(0, $foo1::$destructorCount); + $this->assertSame($foo1, $builder->get('foo1'), 'The same proxy is retrieved on multiple subsequent calls'); $this->assertInstanceOf('\ProxyManagerBridgeFooClass', $foo1); $this->assertInstanceOf('\ProxyManager\Proxy\LazyLoadingInterface', $foo1); @@ -50,5 +53,8 @@ public function testCreateProxyServiceWithRuntimeInstantiator() $this->assertTrue($foo1->isProxyInitialized()); $this->assertInstanceOf('\ProxyManagerBridgeFooClass', $foo1->getWrappedValueHolderValue()); $this->assertNotInstanceOf('\ProxyManager\Proxy\LazyLoadingInterface', $foo1->getWrappedValueHolderValue()); + + $foo1->__destruct(); + $this->assertSame(1, $foo1::$destructorCount); } } diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/includes/foo.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/includes/foo.php index 16c898a370845..8ffc5be9af40a 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/includes/foo.php +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/includes/foo.php @@ -2,6 +2,8 @@ class ProxyManagerBridgeFooClass { + public static $destructorCount = 0; + public $foo; public $moo; @@ -38,4 +40,9 @@ public function setBar($value = null) { $this->bar = $value; } + + public function __destruct() + { + ++self::$destructorCount; + } } From feb5e62a5a8c04744e866b7f81dc297adc85fd24 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 3 Aug 2017 13:53:37 +0200 Subject: [PATCH 19/80] [FrameworkBundle] Warmup annotations for bundle-less controllers and entities --- .../DependencyInjection/FrameworkExtension.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 131db0ae86343..b5359b4f7a467 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -242,8 +242,8 @@ public function load(array $configs, ContainerBuilder $container) } $this->addAnnotatedClassesToCompile(array( - '**Bundle\\Controller\\', - '**Bundle\\Entity\\', + '**\\Controller\\', + '**\\Entity\\', // Added explicitly so that we don't rely on the class map being dumped to make it work 'Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller', From e5ef9fb74a5d17a7b5df184c08ad28a3ec1d5e21 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 3 Aug 2017 22:11:44 +0200 Subject: [PATCH 20/80] Avoid infinite loops when profiler data is malformed --- .../HttpKernel/Profiler/FileProfilerStorage.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php b/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php index 29da4abf32ccf..045058991063d 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php +++ b/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php @@ -144,11 +144,19 @@ public function write(Profile $profile) } } + $profileToken = $profile->getToken(); + // when there are errors in sub-requests, the parent and/or children tokens + // may equal the profile token, resulting in infinite loops + $parentToken = $profile->getParentToken() !== $profileToken ? $profile->getParentToken() : null; + $childrenToken = array_filter(array_map(function ($p) use ($profileToken) { + return $profileToken !== $p->getToken() ? $p->getToken() : null; + }, $profile->getChildren())); + // Store profile $data = array( - 'token' => $profile->getToken(), - 'parent' => $profile->getParentToken(), - 'children' => array_map(function ($p) { return $p->getToken(); }, $profile->getChildren()), + 'token' => $profileToken, + 'parent' => $parentToken, + 'children' => $childrenToken, 'data' => $profile->getCollectors(), 'ip' => $profile->getIp(), 'method' => $profile->getMethod(), From 56ee4aa5431a4e3a036b30b9e651ca75a216e17a Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 21 Jul 2017 20:01:38 +0200 Subject: [PATCH 21/80] better errors when security deps are missing --- .../Compiler/WorkflowGuardListenerPass.php | 50 +++++++ .../FrameworkExtension.php | 6 + .../FrameworkBundle/FrameworkBundle.php | 2 + .../WorkflowGuardListenerPassTest.php | 127 ++++++++++++++++++ 4 files changed, 185 insertions(+) create mode 100644 src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/WorkflowGuardListenerPassTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php new file mode 100644 index 0000000000000..349d78cfc4fed --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\LogicException; + +/** + * @author Christian Flothmann + */ +class WorkflowGuardListenerPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasParameter('workflow.has_guard_listeners')) { + return; + } + + $container->getParameterBag()->remove('workflow.has_guard_listeners'); + + if (!$container->has('security.token_storage')) { + throw new LogicException('The "security.token_storage" service is needed to be able to use the workflow guard listener.'); + } + + if (!$container->has('security.authorization_checker')) { + throw new LogicException('The "security.authorization_checker" service is needed to be able to use the workflow guard listener.'); + } + + if (!$container->has('security.authentication.trust_resolver')) { + throw new LogicException('The "security.authentication.trust_resolver" service is needed to be able to use the workflow guard listener.'); + } + + if (!$container->has('security.role_hierarchy')) { + throw new LogicException('The "security.role_hierarchy" service is needed to be able to use the workflow guard listener.'); + } + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 131db0ae86343..1ffb86e17dc7b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -46,6 +46,7 @@ use Symfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface; use Symfony\Component\PropertyInfo\PropertyListExtractorInterface; use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; +use Symfony\Component\Security\Core\Security; use Symfony\Component\Serializer\Encoder\CsvEncoder; use Symfony\Component\Serializer\Encoder\DecoderInterface; use Symfony\Component\Serializer\Encoder\EncoderInterface; @@ -597,6 +598,10 @@ private function registerWorkflowConfiguration(array $workflows, ContainerBuilde throw new LogicException('Cannot guard workflows as the ExpressionLanguage component is not installed.'); } + if (!class_exists(Security::class)) { + throw new LogicException('Cannot guard workflows as the Security component is not installed.'); + } + $eventName = sprintf('workflow.%s.guard.%s', $name, $transitionName); $guard->addTag('kernel.event_listener', array('event' => $eventName, 'method' => 'onTransition')); $configuration[$eventName] = $config['guard']; @@ -612,6 +617,7 @@ private function registerWorkflowConfiguration(array $workflows, ContainerBuilde )); $container->setDefinition(sprintf('%s.listener.guard', $workflowId), $guard); + $container->setParameter('workflow.has_guard_listeners', true); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index 99ab06b337772..104795e5593c3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -28,6 +28,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationExtractorPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationDumperPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\UnusedTagsPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\WorkflowGuardListenerPass; use Symfony\Component\Config\DependencyInjection\ConfigCachePass; use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass; use Symfony\Component\HttpKernel\DependencyInjection\ControllerArgumentValueResolverPass; @@ -109,6 +110,7 @@ public function build(ContainerBuilder $container) $this->addCompilerPassIfExists($container, ValidateWorkflowsPass::class); $container->addCompilerPass(new CachePoolClearerPass(), PassConfig::TYPE_AFTER_REMOVING); $this->addCompilerPassIfExists($container, FormPass::class); + $container->addCompilerPass(new WorkflowGuardListenerPass()); if ($container->getParameter('kernel.debug')) { $container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -32); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/WorkflowGuardListenerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/WorkflowGuardListenerPassTest.php new file mode 100644 index 0000000000000..fead9e28f26d0 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/WorkflowGuardListenerPassTest.php @@ -0,0 +1,127 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\WorkflowGuardListenerPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Symfony\Component\Security\Core\Role\RoleHierarchy; +use Symfony\Component\Workflow\EventListener\GuardListener; + +class WorkflowGuardListenerPassTest extends TestCase +{ + private $container; + private $compilerPass; + + protected function setUp() + { + $this->container = new ContainerBuilder(); + $this->container->register('foo.listener.guard', GuardListener::class); + $this->container->register('bar.listener.guard', GuardListener::class); + $this->compilerPass = new WorkflowGuardListenerPass(); + } + + public function testListenersAreNotRemovedIfParameterIsNotSet() + { + $this->compilerPass->process($this->container); + + $this->assertTrue($this->container->hasDefinition('foo.listener.guard')); + $this->assertTrue($this->container->hasDefinition('bar.listener.guard')); + } + + public function testParameterIsRemovedWhenThePassIsProcessed() + { + $this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard')); + + try { + $this->compilerPass->process($this->container); + } catch (LogicException $e) { + // Here, we are not interested in the exception handling. This is tested further down. + } + + $this->assertFalse($this->container->hasParameter('workflow.has_guard_listeners')); + } + + public function testListenersAreNotRemovedIfAllDependenciesArePresent() + { + $this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard')); + $this->container->register('security.token_storage', TokenStorageInterface::class); + $this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class); + $this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class); + $this->container->register('security.role_hierarchy', RoleHierarchy::class); + + $this->compilerPass->process($this->container); + + $this->assertTrue($this->container->hasDefinition('foo.listener.guard')); + $this->assertTrue($this->container->hasDefinition('bar.listener.guard')); + } + + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException + * @expectedExceptionMessage The "security.token_storage" service is needed to be able to use the workflow guard listener. + */ + public function testListenersAreRemovedIfTheTokenStorageServiceIsNotPresent() + { + $this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard')); + $this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class); + $this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class); + $this->container->register('security.role_hierarchy', RoleHierarchy::class); + + $this->compilerPass->process($this->container); + } + + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException + * @expectedExceptionMessage The "security.authorization_checker" service is needed to be able to use the workflow guard listener. + */ + public function testListenersAreRemovedIfTheAuthorizationCheckerServiceIsNotPresent() + { + $this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard')); + $this->container->register('security.token_storage', TokenStorageInterface::class); + $this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class); + $this->container->register('security.role_hierarchy', RoleHierarchy::class); + + $this->compilerPass->process($this->container); + } + + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException + * @expectedExceptionMessage The "security.authentication.trust_resolver" service is needed to be able to use the workflow guard listener. + */ + public function testListenersAreRemovedIfTheAuthenticationTrustResolverServiceIsNotPresent() + { + $this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard')); + $this->container->register('security.token_storage', TokenStorageInterface::class); + $this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class); + $this->container->register('security.role_hierarchy', RoleHierarchy::class); + + $this->compilerPass->process($this->container); + } + + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException + * @expectedExceptionMessage The "security.role_hierarchy" service is needed to be able to use the workflow guard listener. + */ + public function testListenersAreRemovedIfTheRoleHierarchyServiceIsNotPresent() + { + $this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard')); + $this->container->register('security.token_storage', TokenStorageInterface::class); + $this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class); + $this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class); + + $this->compilerPass->process($this->container); + } +} From 2f3ac8f53ef5eb8fa4a1a207edd1ce4dce4e854c Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 5 Aug 2017 08:05:00 +0200 Subject: [PATCH 22/80] allow phpdocumentor/reflection-docblock >=3.2.1 --- composer.json | 2 +- src/Symfony/Component/PropertyInfo/composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index faf29256bc0c9..bf18c7b79995f 100644 --- a/composer.json +++ b/composer.json @@ -102,7 +102,7 @@ "sensio/framework-extra-bundle": "^3.0.2" }, "conflict": { - "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0", + "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.1", "phpdocumentor/type-resolver": "<0.2.0", "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" }, diff --git a/src/Symfony/Component/PropertyInfo/composer.json b/src/Symfony/Component/PropertyInfo/composer.json index fbc8f06a73a6d..20bdccf00156b 100644 --- a/src/Symfony/Component/PropertyInfo/composer.json +++ b/src/Symfony/Component/PropertyInfo/composer.json @@ -34,7 +34,7 @@ "doctrine/annotations": "~1.0" }, "conflict": { - "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0", + "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.1", "phpdocumentor/type-resolver": "<0.2.0", "symfony/dependency-injection": "<3.3" }, From 6443c963a69cf96fa08937cba55ccbd2d6918a70 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 5 Aug 2017 08:45:41 +0200 Subject: [PATCH 23/80] [Serializer] fix tests for Yaml component 3.4 --- .../Component/Serializer/Tests/Encoder/YamlEncoderTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/YamlEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/YamlEncoderTest.php index c602039667394..0e280245ec2ee 100644 --- a/src/Symfony/Component/Serializer/Tests/Encoder/YamlEncoderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Encoder/YamlEncoderTest.php @@ -61,7 +61,9 @@ public function testContext() $obj = new \stdClass(); $obj->bar = 2; - $this->assertEquals(" foo: !php/object:O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}\n", $encoder->encode(array('foo' => $obj), 'yaml')); + $legacyTag = " foo: !php/object:O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}\n"; + $spacedTag = " foo: !php/object 'O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}'\n"; + $this->assertThat($encoder->encode(array('foo' => $obj), 'yaml'), $this->logicalOr($this->equalTo($legacyTag), $this->equalTo($spacedTag))); $this->assertEquals(' { foo: null }', $encoder->encode(array('foo' => $obj), 'yaml', array('yaml_inline' => 0, 'yaml_indent' => 2, 'yaml_flags' => 0))); $this->assertEquals(array('foo' => $obj), $encoder->decode('foo: !php/object:O:8:"stdClass":1:{s:3:"bar";i:2;}', 'yaml')); $this->assertEquals(array('foo' => null), $encoder->decode('foo: !php/object:O:8:"stdClass":1:{s:3:"bar";i:2;}', 'yaml', array('yaml_flags' => 0))); From 259f9cc4adaf452a1dffc31b9ee9c5bce12cda0b Mon Sep 17 00:00:00 2001 From: Yurii K Date: Sun, 6 Aug 2017 02:56:19 +0300 Subject: [PATCH 24/80] Update Container.php: Deprecated -> @deprecated Deprecated -> @deprecated --- src/Symfony/Component/DependencyInjection/Container.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index f435a99baec0f..379c7f6d0eb76 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -111,7 +111,7 @@ public function isCompiled() /** * Returns true if the container parameter bag are frozen. * - * Deprecated since 3.3, to be removed in 4.0. + * @deprecated since version 3.3, to be removed in 4.0. * * @return bool true if the container parameter bag are frozen, false otherwise */ From f6c83cf51877151f7eb1ad491f1fb7458733dc27 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Sun, 6 Aug 2017 13:40:38 +0200 Subject: [PATCH 25/80] [Security] Fix security.interactive_login event const doc block --- src/Symfony/Component/Security/Http/SecurityEvents.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Security/Http/SecurityEvents.php b/src/Symfony/Component/Security/Http/SecurityEvents.php index 46c8257f18e74..3bd80723d1ef5 100644 --- a/src/Symfony/Component/Security/Http/SecurityEvents.php +++ b/src/Symfony/Component/Security/Http/SecurityEvents.php @@ -14,8 +14,11 @@ final class SecurityEvents { /** - * The INTERACTIVE_LOGIN event occurs after a user is logged in - * interactively for authentication based on http, cookies or X509. + * The INTERACTIVE_LOGIN event occurs after a user has actively logged + * into your website. It is important to distinguish this action from + * non-interactive authentication methods, such as: + * - authentication based on your session. + * - authentication using a HTTP basic or HTTP digest header. * * The event listener method receives a * Symfony\Component\Security\Http\Event\InteractiveLoginEvent instance. From e0a601092b71ce30383b78a2189eee340ff3d6e2 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Sun, 6 Aug 2017 14:00:34 +0200 Subject: [PATCH 26/80] [HttpKernel] Remove isset call used for legacy --- .../Component/HttpKernel/EventListener/ProfilerListener.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php b/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php index c3772b688e548..4fea1168aa47f 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php @@ -107,8 +107,7 @@ public function onKernelTerminate(PostResponseEvent $event) { // attach children to parents foreach ($this->profiles as $request) { - // isset call should be removed when requestStack is required - if (isset($this->parents[$request]) && null !== $parentRequest = $this->parents[$request]) { + if (null !== $parentRequest = $this->parents[$request]) { if (isset($this->profiles[$parentRequest])) { $this->profiles[$parentRequest]->addChild($this->profiles[$request]); } From 30eed995b4482f614b89c34853b82744c88c756b Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Sun, 6 Aug 2017 14:05:07 +0200 Subject: [PATCH 27/80] Github template: Remove EOM 3.2 from branch suggestion --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index cb9b8a69c1638..1bad363eca810 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ | Q | A | ------------- | --- -| Branch? | 3.4 or master / 2.7, 2.8, 3.2 or 3.3 +| Branch? | 3.4 or master / 2.7, 2.8 or 3.3 | Bug fix? | yes/no | New feature? | yes/no | BC breaks? | yes/no From c35cdba6d2e0b1f0a75908195a34291e302151b1 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Sun, 6 Aug 2017 15:12:58 +0200 Subject: [PATCH 28/80] [Profiler] Fix request_collector check in main layout --- .../WebProfilerBundle/Resources/views/Profiler/layout.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig index bd097d3cbc49b..822323315e37d 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/layout.html.twig @@ -20,7 +20,7 @@ {% set request_collector = profile.collectors.request|default(false) %} - {% if request_collector is defined and request_collector.redirect -%} + {% if request_collector and request_collector.redirect -%} {%- set redirect = request_collector.redirect -%} {%- set controller = redirect.controller -%} {%- set redirect_route = '@' ~ redirect.route %} From 94b1b12b55f400a9b38e3307375311a06db9fea6 Mon Sep 17 00:00:00 2001 From: Lars Strojny Date: Wed, 2 Aug 2017 15:53:45 +0200 Subject: [PATCH 29/80] Hash cache keys on save --- src/Symfony/Component/Cache/Adapter/AbstractAdapter.php | 9 +++++---- .../Cache/Tests/Adapter/PhpArrayAdapterTest.php | 1 + .../Component/Cache/Tests/Simple/PhpArrayCacheTest.php | 3 +++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php index 26b33e683e2ff..9bc05fd2b30fd 100644 --- a/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/AbstractAdapter.php @@ -55,19 +55,20 @@ function ($key, $value, $isHit) use ($defaultLifetime) { null, CacheItem::class ); + $getId = function ($key) { return $this->getId((string) $key); }; $this->mergeByLifetime = \Closure::bind( - function ($deferred, $namespace, &$expiredIds) { + function ($deferred, $namespace, &$expiredIds) use ($getId) { $byLifetime = array(); $now = time(); $expiredIds = array(); foreach ($deferred as $key => $item) { if (null === $item->expiry) { - $byLifetime[0 < $item->defaultLifetime ? $item->defaultLifetime : 0][$namespace.$key] = $item->value; + $byLifetime[0 < $item->defaultLifetime ? $item->defaultLifetime : 0][$getId($key)] = $item->value; } elseif ($item->expiry > $now) { - $byLifetime[$item->expiry - $now][$namespace.$key] = $item->value; + $byLifetime[$item->expiry - $now][$getId($key)] = $item->value; } else { - $expiredIds[] = $namespace.$key; + $expiredIds[] = $getId($key); } } diff --git a/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php index ae0edb7d11dd6..134dba7c90444 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php @@ -22,6 +22,7 @@ class PhpArrayAdapterTest extends AdapterTestCase { protected $skippedTests = array( 'testBasicUsage' => 'PhpArrayAdapter is read-only.', + 'testBasicUsageWithLongKey' => 'PhpArrayAdapter is read-only.', 'testClear' => 'PhpArrayAdapter is read-only.', 'testClearWithDeferredItems' => 'PhpArrayAdapter is read-only.', 'testDeleteItem' => 'PhpArrayAdapter is read-only.', diff --git a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php index 3016ac560ed06..57361905f8869 100644 --- a/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php +++ b/src/Symfony/Component/Cache/Tests/Simple/PhpArrayCacheTest.php @@ -21,6 +21,8 @@ class PhpArrayCacheTest extends CacheTestCase { protected $skippedTests = array( + 'testBasicUsageWithLongKey' => 'PhpArrayCache does no writes', + 'testDelete' => 'PhpArrayCache does no writes', 'testDeleteMultiple' => 'PhpArrayCache does no writes', 'testDeleteMultipleGenerator' => 'PhpArrayCache does no writes', @@ -57,6 +59,7 @@ protected function tearDown() FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); } } + public function createSimpleCache() { return new PhpArrayCacheWrapper(self::$file, new NullCache()); From 29538b621c934358e3cf64a4c181a4d4c4fef6c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Tue, 1 Aug 2017 22:29:59 +0200 Subject: [PATCH 30/80] Ignore memcached missing key error on dession destroy --- .../Session/Storage/Handler/MemcacheSessionHandler.php | 4 +++- .../Session/Storage/Handler/MemcachedSessionHandler.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcacheSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcacheSessionHandler.php index 962a3878d9767..4e490a05d4ce0 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcacheSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcacheSessionHandler.php @@ -95,7 +95,9 @@ public function write($sessionId, $data) */ public function destroy($sessionId) { - return $this->memcache->delete($this->prefix.$sessionId); + $this->memcache->delete($this->prefix.$sessionId); + + return true; } /** diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php index 76b08e2db944c..67a49ad6f5e2a 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php @@ -101,7 +101,9 @@ public function write($sessionId, $data) */ public function destroy($sessionId) { - return $this->memcached->delete($this->prefix.$sessionId); + $result = $this->memcached->delete($this->prefix.$sessionId); + + return $result || $this->memcached->getResultCode() == \Memcached::RES_NOTFOUND; } /** From 0a612799d78537d2c4071cb1da466c1ec9351888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Mon, 7 Aug 2017 18:03:37 +0200 Subject: [PATCH 31/80] Fixed UPGRADE-4.0 about Container::set --- UPGRADE-4.0.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index 505ed8968a37b..7b3a98abdccd7 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -116,8 +116,8 @@ DependencyInjection * Using unsupported options to configure service aliases raises an exception. - * Setting or unsetting a private service with the `Container::set()` method is - no longer supported. Only public services can be set or unset. + * Setting or unsetting a service with the `Container::set()` method is + no longer supported. Only synthetic services can be set or unset. * Checking the existence of a private service with the `Container::has()` method is no longer supported and will return `false`. From 90099706c635d8672be67c0df4fc321a5e28c4f3 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 8 Aug 2017 08:40:28 +0200 Subject: [PATCH 32/80] Revert "feature #21038 [FrameworkBundle] deprecated cache:clear with warmup (fabpot)" This reverts commit 3495b35e4fcdb2bf90b8aea443c1216c161dd469, reversing changes made to 7f7b897ee275d4cbbd4284dbdd05f1d207699fac. --- UPGRADE-3.3.md | 3 --- UPGRADE-4.0.md | 3 --- src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md | 1 - .../FrameworkBundle/Command/CacheClearCommand.php | 10 ---------- .../CacheClearCommand/CacheClearCommandTest.php | 3 --- 5 files changed, 20 deletions(-) diff --git a/UPGRADE-3.3.md b/UPGRADE-3.3.md index e43c365e6c5b6..3cff95d8506ce 100644 --- a/UPGRADE-3.3.md +++ b/UPGRADE-3.3.md @@ -165,9 +165,6 @@ Form FrameworkBundle --------------- - * The `cache:clear` command should always be called with the `--no-warmup` option. - Warmup should be done via the `cache:warmup` command. - * [BC BREAK] The "framework.trusted_proxies" configuration option and the corresponding "kernel.trusted_proxies" parameter have been removed. Use the Request::setTrustedProxies() method in your front controller instead. diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index 505ed8968a37b..67b2aa788de15 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -223,9 +223,6 @@ Form FrameworkBundle --------------- - * The `cache:clear` command does not warmup the cache anymore. Warmup should - be done via the `cache:warmup` command. - * The "framework.trusted_proxies" configuration option and the corresponding "kernel.trusted_proxies" parameter have been removed. Use the `Request::setTrustedProxies()` method in your front controller instead. * The default value of the `framework.workflows.[name].type` configuration options is now `state_machine`. diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index ba704e00f2a7a..d89c4dc254134 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -14,7 +14,6 @@ CHANGELOG the same helpers as the `Controller` class, but does not allow accessing the dependency injection container, in order to encourage explicit dependency declarations. * Added support for the `controller.service_arguments` tag, for injecting services into controllers' actions - * Deprecated `cache:clear` with warmup (always call it with `--no-warmup`) * Changed default configuration for assets/forms/validation/translation/serialization/csrf from `canBeEnabled()` to `canBeDisabled()` when Flex is used diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php index 2331afecb4e84..b7613f7436b2a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php @@ -77,12 +77,6 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($input->getOption('no-warmup')) { $filesystem->rename($realCacheDir, $oldCacheDir); } else { - $warning = 'Calling cache:clear without the --no-warmup option is deprecated since version 3.3. Cache warmup should be done with the cache:warmup command instead.'; - - @trigger_error($warning, E_USER_DEPRECATED); - - $io->warning($warning); - $this->warmupCache($input, $output, $realCacheDir, $oldCacheDir); } @@ -132,8 +126,6 @@ private function warmupCache(InputInterface $input, OutputInterface $output, $re * @param string $warmupDir * @param string $realCacheDir * @param bool $enableOptionalWarmers - * - * @internal to be removed in 4.0 */ protected function warmup($warmupDir, $realCacheDir, $enableOptionalWarmers = true) { @@ -200,8 +192,6 @@ protected function warmup($warmupDir, $realCacheDir, $enableOptionalWarmers = tr * @param string $warmupDir * * @return KernelInterface - * - * @internal to be removed in 4.0 */ protected function getTempKernel(KernelInterface $parent, $namespace, $parentClass, $warmupDir) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php index b9fe63ec5bbab..fd3b611202252 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php @@ -43,9 +43,6 @@ protected function tearDown() $this->fs->remove($this->rootDir); } - /** - * @group legacy - */ public function testCacheIsFreshAfterCacheClearedWithWarmup() { $input = new ArrayInput(array('cache:clear')); From cadbed301fc66ab3ada38313f62e112c83d2c97d Mon Sep 17 00:00:00 2001 From: Harold Iedema Date: Tue, 8 Aug 2017 12:48:54 +0200 Subject: [PATCH 33/80] [Console] Log exit codes as debug messages instead of errors --- .../Component/Console/EventListener/ErrorListener.php | 4 ++-- .../Console/Tests/EventListener/ErrorListenerTest.php | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Console/EventListener/ErrorListener.php b/src/Symfony/Component/Console/EventListener/ErrorListener.php index 8e35d97dfd489..3774f9e6666d4 100644 --- a/src/Symfony/Component/Console/EventListener/ErrorListener.php +++ b/src/Symfony/Component/Console/EventListener/ErrorListener.php @@ -59,10 +59,10 @@ public function onConsoleTerminate(ConsoleTerminateEvent $event) } if (!$inputString = $this->getInputString($event)) { - return $this->logger->error('The console exited with code "{code}"', array('code' => $exitCode)); + return $this->logger->debug('The console exited with code "{code}"', array('code' => $exitCode)); } - $this->logger->error('Command "{command}" exited with code "{code}"', array('command' => $inputString, 'code' => $exitCode)); + $this->logger->debug('Command "{command}" exited with code "{code}"', array('command' => $inputString, 'code' => $exitCode)); } public static function getSubscribedEvents() diff --git a/src/Symfony/Component/Console/Tests/EventListener/ErrorListenerTest.php b/src/Symfony/Component/Console/Tests/EventListener/ErrorListenerTest.php index c857a97d0b9bc..17eaae09084c8 100644 --- a/src/Symfony/Component/Console/Tests/EventListener/ErrorListenerTest.php +++ b/src/Symfony/Component/Console/Tests/EventListener/ErrorListenerTest.php @@ -61,7 +61,7 @@ public function testOnConsoleTerminateForNonZeroExitCodeWritesToLog() $logger = $this->getLogger(); $logger ->expects($this->once()) - ->method('error') + ->method('debug') ->with('Command "{command}" exited with code "{code}"', array('command' => 'test:run', 'code' => 255)) ; @@ -74,7 +74,7 @@ public function testOnConsoleTerminateForZeroExitCodeDoesNotWriteToLog() $logger = $this->getLogger(); $logger ->expects($this->never()) - ->method('error') + ->method('debug') ; $listener = new ErrorListener($logger); @@ -97,7 +97,7 @@ public function testAllKindsOfInputCanBeLogged() $logger = $this->getLogger(); $logger ->expects($this->exactly(3)) - ->method('error') + ->method('debug') ->with('Command "{command}" exited with code "{code}"', array('command' => 'test:run --foo=bar', 'code' => 255)) ; @@ -112,7 +112,7 @@ public function testCommandNameIsDisplayedForNonStringableInput() $logger = $this->getLogger(); $logger ->expects($this->once()) - ->method('error') + ->method('debug') ->with('Command "{command}" exited with code "{code}"', array('command' => 'test:run', 'code' => 255)) ; From cd8af2284df5220b2d7cbd87b8f844d2a7b6b07a Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 8 Aug 2017 15:39:42 +0200 Subject: [PATCH 34/80] Fixed the exception page design in responsive mode --- .../Bundle/TwigBundle/Resources/views/exception.css.twig | 8 ++++---- src/Symfony/Component/Debug/ExceptionHandler.php | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig b/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig index 9d03015f2f04e..84112fad6ed94 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig +++ b/src/Symfony/Bundle/TwigBundle/Resources/views/exception.css.twig @@ -80,7 +80,7 @@ header .container { display: flex; justify-content: space-between; } .exception-hierarchy .icon svg { height: 13px; width: 13px; vertical-align: -2px; } .exception-without-message .exception-message-wrapper { display: none; } -.exception-message-wrapper .container { display: flex; align-items: flex-start; min-height: 70px; padding: 10px 0 8px; } +.exception-message-wrapper .container { display: flex; align-items: flex-start; min-height: 70px; padding: 10px 15px 8px; } .exception-message { flex-grow: 1; } .exception-message, .exception-message a { color: #FFF; font-size: 21px; font-weight: 400; margin: 0; } .exception-message.long { font-size: 18px; } @@ -107,11 +107,11 @@ header .container { display: flex; justify-content: space-between; } .trace-line .icon svg { height: 16px; width: 16px; } .trace-line-header { padding-left: 36px; } -.trace-file-path, .trace-file-path a { color: #999; color: #795da3; color: #B0413E; color: #222; font-size: 13px; } +.trace-file-path, .trace-file-path a { color: #222; font-size: 13px; } .trace-class { color: #B0413E; } .trace-type { padding: 0 2px; } -.trace-method { color: #B0413E; color: #222; font-weight: bold; color: #B0413E; } -.trace-arguments { color: #222; color: #999; font-weight: normal; color: #795da3; color: #777; padding-left: 2px; } +.trace-method { color: #B0413E; font-weight: bold; } +.trace-arguments { color: #777; font-weight: normal; padding-left: 2px; } .trace-code { background: #FFF; font-size: 12px; margin: 10px 10px 2px 10px; padding: 10px; overflow-x: auto; white-space: nowrap; } .trace-code ol { margin: 0; float: left; } diff --git a/src/Symfony/Component/Debug/ExceptionHandler.php b/src/Symfony/Component/Debug/ExceptionHandler.php index d84cfdd496d38..0ecd2a5347f27 100644 --- a/src/Symfony/Component/Debug/ExceptionHandler.php +++ b/src/Symfony/Component/Debug/ExceptionHandler.php @@ -320,11 +320,11 @@ public function getStylesheet(FlattenException $exception) .trace-message { font-size: 14px; font-weight: normal; margin: .5em 0 0; } - .trace-file-path, .trace-file-path a { margin-top: 3px; color: #999; color: #795da3; color: #B0413E; color: #222; font-size: 13px; } + .trace-file-path, .trace-file-path a { color: #222; margin-top: 3px; font-size: 13px; } .trace-class { color: #B0413E; } .trace-type { padding: 0 2px; } - .trace-method { color: #B0413E; color: #222; font-weight: bold; color: #B0413E; } - .trace-arguments { color: #222; color: #999; font-weight: normal; color: #795da3; color: #777; padding-left: 2px; } + .trace-method { color: #B0413E; font-weight: bold; } + .trace-arguments { color: #777; font-weight: normal; padding-left: 2px; } @media (min-width: 575px) { .hidden-xs-down { display: initial; } From a22e839592c4c5a4579d54b837f026f159c0b7ae Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 8 Aug 2017 19:53:57 +0200 Subject: [PATCH 35/80] [DI] Fix some docblocks --- .../Component/DependencyInjection/ChildDefinition.php | 4 ++-- .../Component/DependencyInjection/Definition.php | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/ChildDefinition.php b/src/Symfony/Component/DependencyInjection/ChildDefinition.php index 5701caa474e57..862be880badfb 100644 --- a/src/Symfony/Component/DependencyInjection/ChildDefinition.php +++ b/src/Symfony/Component/DependencyInjection/ChildDefinition.php @@ -33,7 +33,7 @@ public function __construct($parent) } /** - * Returns the Definition being decorated. + * Returns the Definition to inherit from. * * @return string */ @@ -43,7 +43,7 @@ public function getParent() } /** - * Sets the Definition being decorated. + * Sets the Definition to inherit from. * * @param string $parent * diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php index 68b3368da2ecc..fc3cfb2943d8d 100644 --- a/src/Symfony/Component/DependencyInjection/Definition.php +++ b/src/Symfony/Component/DependencyInjection/Definition.php @@ -250,6 +250,14 @@ public function replaceArgument($index, $argument) return $this; } + /** + * Sets a specific argument. + * + * @param int|string $key + * @param mixed $value + * + * @return $this + */ public function setArgument($key, $value) { $this->arguments[$key] = $value; @@ -778,7 +786,7 @@ public function isAutowired() } /** - * Sets autowired. + * Enables/disables autowiring. * * @param bool $autowired * From dd8622915d1decc1fdf52aad8d45ff9ff513ec5c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 8 Aug 2017 19:11:20 +0200 Subject: [PATCH 36/80] [DI] Fix some docblocks --- .../DependencyInjection/ContainerBuilder.php | 4 ++-- .../DependencyInjection/Definition.php | 22 ++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 5bafa94398e61..c1a2ee85c42c5 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -710,8 +710,8 @@ public function getAlias($id) * This methods allows for simple registration of service definition * with a fluid interface. * - * @param string $id The service identifier - * @param string $class The service class + * @param string $id The service identifier + * @param string $class|null The service class * * @return Definition A Definition instance */ diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php index aa76c96805a86..cad6398f7fb8e 100644 --- a/src/Symfony/Component/DependencyInjection/Definition.php +++ b/src/Symfony/Component/DependencyInjection/Definition.php @@ -257,6 +257,13 @@ public function setArguments(array $arguments) return $this; } + /** + * Sets the properties to define when creating the service. + * + * @param array $properties + * + * @return $this + */ public function setProperties(array $properties) { $this->properties = $properties; @@ -264,11 +271,24 @@ public function setProperties(array $properties) return $this; } + /** + * Gets the properties to define when creating the service. + * + * @return array + */ public function getProperties() { return $this->properties; } + /** + * Sets a specific property. + * + * @param string $name + * @param mixed $value + * + * @return $this + */ public function setProperty($name, $value) { $this->properties[$name] = $value; @@ -291,7 +311,7 @@ public function addArgument($argument) } /** - * Sets a specific argument. + * Replaces a specific argument. * * @param int $index * @param mixed $argument From f876fd925374ad84c6284e9066f72b5544c33df7 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Wed, 9 Aug 2017 12:24:19 +0200 Subject: [PATCH 37/80] [DebugBundle] Reword an outdated comment about var dumper wiring --- src/Symfony/Bundle/DebugBundle/DebugBundle.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/DebugBundle/DebugBundle.php b/src/Symfony/Bundle/DebugBundle/DebugBundle.php index 335ec5abd2541..b00c06af78289 100644 --- a/src/Symfony/Bundle/DebugBundle/DebugBundle.php +++ b/src/Symfony/Bundle/DebugBundle/DebugBundle.php @@ -27,8 +27,10 @@ public function boot() $container = $this->container; // This code is here to lazy load the dump stack. This default - // configuration for CLI mode is overridden in HTTP mode on - // 'kernel.request' event + // configuration is overridden in CLI mode on 'console.command' event. + // The dump data collector is used by default, so dump output is sent to + // the WDT. In a CLI context, if dump is used too soon, the data collector + // will buffer it, and release it at the end of the script. VarDumper::setHandler(function ($var) use ($container) { $dumper = $container->get('data_collector.dump'); $cloner = $container->get('var_dumper.cloner'); From 2309fd91d882a2570e7caf4a4c5f6bbae898784a Mon Sep 17 00:00:00 2001 From: Sam Partington Date: Tue, 8 Aug 2017 11:23:31 +0100 Subject: [PATCH 38/80] [2.8] Modify 2.8 upgrade doc - key option is deprecated. --- UPGRADE-2.8.md | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/UPGRADE-2.8.md b/UPGRADE-2.8.md index 1d299af3e63a4..cf3edac756cae 100644 --- a/UPGRADE-2.8.md +++ b/UPGRADE-2.8.md @@ -546,6 +546,95 @@ Security * The `VoterInterface::supportsClass` and `supportsAttribute` methods were deprecated and will be removed from the interface in 3.0. + + * The the `key` setting of `anonymous`, `remember_me` and `http_digest` + is deprecated, and will be removed in 3.0. Use `secret` instead. + + Before: + + ```yaml + security: + # ... + firewalls: + default: + # ... + anonymous: { key: "%secret%" } + remember_me: + key: "%secret%" + http_digest: + key: "%secret%" + ``` + + ```xml + + + + + + + + + + + + + ``` + + ```php + // ... + $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( + // ... + 'anonymous' => array('key' => '%secret%'), + 'remember_me' => array('key' => '%secret%'), + 'http_digest' => array('key' => '%secret%'), + ), + )); + ``` + + After: + + ```yaml + security: + # ... + firewalls: + default: + # ... + anonymous: { secret: "%secret%" } + remember_me: + secret: "%secret%" + http_digest: + secret: "%secret%" + ``` + + ```xml + + + + + + + + + + + + + ``` + + ```php + // ... + $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( + // ... + 'anonymous' => array('secret' => '%secret%'), + 'remember_me' => array('secret' => '%secret%'), + 'http_digest' => array('secret' => '%secret%'), + ), + )); + ``` * The `intention` option is deprecated for all the authentication listeners, and will be removed in 3.0. Use the `csrf_token_id` option instead. From 4879eb4f362fa077e237548dcc55db347a095820 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 10 Aug 2017 08:50:59 +0200 Subject: [PATCH 39/80] fixed CS --- UPGRADE-2.8.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/UPGRADE-2.8.md b/UPGRADE-2.8.md index cf3edac756cae..64a31dde75600 100644 --- a/UPGRADE-2.8.md +++ b/UPGRADE-2.8.md @@ -546,11 +546,11 @@ Security * The `VoterInterface::supportsClass` and `supportsAttribute` methods were deprecated and will be removed from the interface in 3.0. - - * The the `key` setting of `anonymous`, `remember_me` and `http_digest` - is deprecated, and will be removed in 3.0. Use `secret` instead. - - Before: + + * The `key` setting of `anonymous`, `remember_me` and `http_digest` is + deprecated, and will be removed in 3.0. Use `secret` instead. + + Before: ```yaml security: From 685ff0e2804a2e197ca7d62334f270088d30089d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 10 Aug 2017 13:45:16 +0200 Subject: [PATCH 40/80] [DI] Fix YamlDumper not dumping abstract and autoconfigure --- .../DependencyInjection/Dumper/YamlDumper.php | 8 ++++++++ .../Tests/Dumper/YamlDumperTest.php | 12 ++++++++++++ .../Tests/Fixtures/yaml/services_dump_load.yml | 14 ++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_dump_load.yml diff --git a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php index e71df2af24c14..9567fee56a583 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php @@ -116,6 +116,14 @@ private function addService($id, $definition) $code .= sprintf(" autowiring_types:\n%s", $autowiringTypesCode); } + if ($definition->isAutoconfigured()) { + $code .= " autoconfigure: true\n"; + } + + if ($definition->isAbstract()) { + $code .= " abstract: true\n"; + } + if ($definition->isLazy()) { $code .= " lazy: true\n"; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php index 22277c7b7a85f..eaaad0c75ca58 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php @@ -12,8 +12,10 @@ namespace Symfony\Component\DependencyInjection\Tests\Dumper; use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Dumper\YamlDumper; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\Yaml\Yaml; use Symfony\Component\Yaml\Parser; @@ -64,6 +66,16 @@ public function testDumpAutowireData() $this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services24.yml', $dumper->dump()); } + public function testDumpLoad() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_dump_load.yml'); + + $dumper = new YamlDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_dump_load.yml', $dumper->dump()); + } + private function assertEqualYamlStructure($expected, $yaml, $message = '') { $parser = new Parser(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_dump_load.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_dump_load.yml new file mode 100644 index 0000000000000..43b0c7d58a00f --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_dump_load.yml @@ -0,0 +1,14 @@ + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + synthetic: true + foo: + autoconfigure: true + abstract: true + Psr\Container\ContainerInterface: + alias: service_container + public: false + Symfony\Component\DependencyInjection\ContainerInterface: + alias: service_container + public: false From 676012748ab5be2f5a510ee9cfce0bfc03828a80 Mon Sep 17 00:00:00 2001 From: ElectricMaxxx Date: Thu, 10 Aug 2017 09:29:20 +0200 Subject: [PATCH 41/80] restrict reflection doc block The version 3.2.0 and 3.2.1 of reflection-docblock is broken and lower version as 3.1 miss some tags --- composer.json | 2 +- .../Tests/Extractors/PhpDocExtractorTest.php | 1 + .../Extractors/ReflectionExtractorTest.php | 81 ++++++++++++------- .../PropertyInfo/Tests/Fixtures/Dummy.php | 7 ++ .../Component/PropertyInfo/composer.json | 2 +- 5 files changed, 64 insertions(+), 29 deletions(-) diff --git a/composer.json b/composer.json index bf18c7b79995f..00faa0845d422 100644 --- a/composer.json +++ b/composer.json @@ -102,7 +102,7 @@ "sensio/framework-extra-bundle": "^3.0.2" }, "conflict": { - "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.1", + "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2", "phpdocumentor/type-resolver": "<0.2.0", "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" }, diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php index d0eb3eed06c49..f41056050870c 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractors/PhpDocExtractorTest.php @@ -72,6 +72,7 @@ public function typesProvider() array('donotexist', null, null, null), array('staticGetter', null, null, null), array('staticSetter', null, null, null), + array('emptyVar', null, null, null), ); } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php index 573528c012f55..905b50d5dff86 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php @@ -41,6 +41,7 @@ public function testGetProperties() 'B', 'Guid', 'g', + 'emptyVar', 'foo', 'foo2', 'foo3', @@ -122,37 +123,63 @@ public function php71TypesProvider() ); } - public function testIsReadable() + /** + * @dataProvider getReadableProperties + */ + public function testIsReadable($property, $expected) + { + $this->assertSame( + $expected, + $this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', $property, array()) + ); + } + + public function getReadableProperties() + { + return array( + array('bar', false), + array('baz', false), + array('parent', true), + array('a', true), + array('b', false), + array('c', true), + array('d', true), + array('e', false), + array('f', false), + array('Id', true), + array('id', true), + array('Guid', true), + array('guid', false), + ); + } + + /** + * @dataProvider getWritableProperties + */ + public function testIsWritable($property, $expected) { - $this->assertFalse($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'bar', array())); - $this->assertFalse($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'baz', array())); - $this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'parent', array())); - $this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'a', array())); - $this->assertFalse($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'b', array())); - $this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'c', array())); - $this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'd', array())); - $this->assertFalse($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'e', array())); - $this->assertFalse($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'f', array())); - $this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'Id', array())); - $this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'id', array())); - $this->assertTrue($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'Guid', array())); - $this->assertFalse($this->extractor->isReadable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'guid', array())); + $this->assertSame( + $expected, + $this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', $property, array()) + ); } - public function testIsWritable() + public function getWritableProperties() { - $this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'bar', array())); - $this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'baz', array())); - $this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'parent', array())); - $this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'a', array())); - $this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'b', array())); - $this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'c', array())); - $this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'd', array())); - $this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'e', array())); - $this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'f', array())); - $this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'Id', array())); - $this->assertTrue($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'Guid', array())); - $this->assertFalse($this->extractor->isWritable('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', 'guid', array())); + return array( + array('bar', false), + array('baz', false), + array('parent', true), + array('a', false), + array('b', true), + array('c', false), + array('d', false), + array('e', true), + array('f', true), + array('Id', false), + array('Guid', true), + array('guid', false), + ); } public function testSingularize() diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php index d358bae13ad61..4e558eca014e5 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php @@ -68,6 +68,13 @@ class Dummy extends ParentDummy */ public $g; + /** + * This should not be removed. + * + * @var + */ + public $emptyVar; + public static function getStatic() { } diff --git a/src/Symfony/Component/PropertyInfo/composer.json b/src/Symfony/Component/PropertyInfo/composer.json index 20bdccf00156b..13aebfbf0e31e 100644 --- a/src/Symfony/Component/PropertyInfo/composer.json +++ b/src/Symfony/Component/PropertyInfo/composer.json @@ -34,7 +34,7 @@ "doctrine/annotations": "~1.0" }, "conflict": { - "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.1", + "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2", "phpdocumentor/type-resolver": "<0.2.0", "symfony/dependency-injection": "<3.3" }, From c396e8cb9cfa2c5fdd46f4d6c821cd1c462c4cbb Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 10 Aug 2017 16:37:13 +0200 Subject: [PATCH 42/80] [DI] Fix dumping abstract with YamlDumper --- .../DependencyInjection/Dumper/YamlDumper.php | 4 ++++ .../Tests/Dumper/YamlDumperTest.php | 12 ++++++++++++ .../Tests/Fixtures/yaml/services_dump_load.yml | 4 ++++ 3 files changed, 20 insertions(+) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_dump_load.yml diff --git a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php index 810e7539fe1bd..9125a97836b6f 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php @@ -104,6 +104,10 @@ private function addService($id, $definition) $code .= sprintf(" factory_class: %s\n", $this->dumper->dump($definition->getFactoryClass(false))); } + if ($definition->isAbstract()) { + $code .= " abstract: true\n"; + } + if ($definition->isLazy()) { $code .= " lazy: true\n"; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php index f19a2f5cb8346..81bbd5316c444 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php @@ -12,8 +12,10 @@ namespace Symfony\Component\DependencyInjection\Tests\Dumper; use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Dumper\YamlDumper; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\Yaml\Yaml; class YamlDumperTest extends TestCase @@ -77,6 +79,16 @@ public function testAddService() } } + public function testDumpLoad() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_dump_load.yml'); + + $dumper = new YamlDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_dump_load.yml', $dumper->dump()); + } + private function assertEqualYamlStructure($yaml, $expected, $message = '') { $this->assertEquals(Yaml::parse($expected), Yaml::parse($yaml), $message); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_dump_load.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_dump_load.yml new file mode 100644 index 0000000000000..bcf8f31b36115 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_dump_load.yml @@ -0,0 +1,4 @@ + +services: + foo: + abstract: true From 9c29f9c19be02839c1780b429283684b9ca0f706 Mon Sep 17 00:00:00 2001 From: Florent Mata Date: Fri, 11 Aug 2017 14:43:59 +0200 Subject: [PATCH 43/80] [Workflow] fixed InvalidDefinitionException message for StateMachineValidator --- .../Component/Workflow/Validator/StateMachineValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Workflow/Validator/StateMachineValidator.php b/src/Symfony/Component/Workflow/Validator/StateMachineValidator.php index 16948f6769b6e..8fe5eecc4a22a 100644 --- a/src/Symfony/Component/Workflow/Validator/StateMachineValidator.php +++ b/src/Symfony/Component/Workflow/Validator/StateMachineValidator.php @@ -31,7 +31,7 @@ public function validate(Definition $definition, $name) // Make sure that each transition has exactly one FROM $froms = $transition->getFroms(); if (1 !== count($froms)) { - throw new InvalidDefinitionException(sprintf('A transition in StateMachine can only have one input. But the transition "%s" in StateMachine "%s" has %d inputs.', $transition->getName(), $name, count($transition->getTos()))); + throw new InvalidDefinitionException(sprintf('A transition in StateMachine can only have one input. But the transition "%s" in StateMachine "%s" has %d inputs.', $transition->getName(), $name, count($froms))); } // Enforcing uniqueness of the names of transitions starting at each node From 1bea774f4de173de64f63d0d64d83473c706a989 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 12 Aug 2017 22:32:56 +0200 Subject: [PATCH 44/80] [VarDumper] play nice with open_basedir when looking for composer.json --- src/Symfony/Component/VarDumper/Caster/LinkStub.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarDumper/Caster/LinkStub.php b/src/Symfony/Component/VarDumper/Caster/LinkStub.php index 1a9aa419d148f..eb9bc85c914f9 100644 --- a/src/Symfony/Component/VarDumper/Caster/LinkStub.php +++ b/src/Symfony/Component/VarDumper/Caster/LinkStub.php @@ -89,7 +89,11 @@ private function getComposerRoot($file, &$inVendor) } $parent = $dir; - while (!file_exists($parent.'/composer.json')) { + while (!@file_exists($parent.'/composer.json')) { + if (!@file_exists($parent)) { + // open_basedir restriction in effect + break; + } if ($parent === dirname($parent)) { return self::$composerRoots[$dir] = false; } From 423656f8eaf85ba09158f6b984b2e758170d8076 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 13 Aug 2017 23:58:09 +0200 Subject: [PATCH 45/80] Fixed some param/return annotations in PHPDOC blocks. --- src/Symfony/Component/DependencyInjection/Container.php | 2 +- src/Symfony/Component/DependencyInjection/Definition.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index 379c7f6d0eb76..3b0a82d80ea10 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -427,7 +427,7 @@ public static function underscore($id) /** * Fetches a variable from the environment. * - * @param string The name of the environment variable + * @param string $name The name of the environment variable * * @return scalar The value to use for the provided environment variable name * diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php index 173578acd5815..2900ddc24d269 100644 --- a/src/Symfony/Component/DependencyInjection/Definition.php +++ b/src/Symfony/Component/DependencyInjection/Definition.php @@ -71,6 +71,8 @@ public function getChanges() /** * Sets the tracked changes for the Definition object. * + * @param array $changes An array of changes for this Definition + * * @return $this */ public function setChanges(array $changes) @@ -401,6 +403,8 @@ public function getMethodCalls() * Sets the definition templates to conditionally apply on the current definition, keyed by parent interface/class. * * @param $instanceof ChildDefinition[] + * + * @return $this */ public function setInstanceofConditionals(array $instanceof) { From 339592da14a7daa2ec023ae9aa88a3a68223630b Mon Sep 17 00:00:00 2001 From: Matthieu Mota Date: Thu, 10 Aug 2017 18:24:09 +0200 Subject: [PATCH 46/80] Fix testHtml method with regexp --- src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php index bfd9527a05c83..495a4a9d14a34 100644 --- a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php @@ -353,7 +353,7 @@ public function testText() public function testHtml() { $this->assertEquals('Bar', $this->createTestCrawler()->filterXPath('//a[5]')->html()); - $this->assertEquals('', trim($this->createTestCrawler()->filterXPath('//form[@id="FooFormId"]')->html())); + $this->assertEquals('', trim(preg_replace('~>\s+<~', '><', $this->createTestCrawler()->filterXPath('//form[@id="FooFormId"]')->html()))); try { $this->createTestCrawler()->filterXPath('//ol')->html(); From 8cbf0947027211882ba9e29a79b72cbc98b9f4d0 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Tue, 15 Aug 2017 11:12:55 +0200 Subject: [PATCH 47/80] [Console] Remove useless http-kernel dev dep --- .../Tests/DependencyInjection/AddConsoleCommandPassTest.php | 5 ----- src/Symfony/Component/Console/composer.json | 1 - 2 files changed, 6 deletions(-) diff --git a/src/Symfony/Component/Console/Tests/DependencyInjection/AddConsoleCommandPassTest.php b/src/Symfony/Component/Console/Tests/DependencyInjection/AddConsoleCommandPassTest.php index 0cf4631754522..3423c5d9e92e9 100644 --- a/src/Symfony/Component/Console/Tests/DependencyInjection/AddConsoleCommandPassTest.php +++ b/src/Symfony/Component/Console/Tests/DependencyInjection/AddConsoleCommandPassTest.php @@ -16,7 +16,6 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\HttpKernel\Bundle\Bundle; class AddConsoleCommandPassTest extends TestCase { @@ -122,7 +121,3 @@ public function testProcessPrivateServicesWithSameCommand() class MyCommand extends Command { } - -class ExtensionPresentBundle extends Bundle -{ -} diff --git a/src/Symfony/Component/Console/composer.json b/src/Symfony/Component/Console/composer.json index d4fef1ea5856c..415b9e096d2ac 100644 --- a/src/Symfony/Component/Console/composer.json +++ b/src/Symfony/Component/Console/composer.json @@ -22,7 +22,6 @@ }, "require-dev": { "symfony/config": "~3.3", - "symfony/http-kernel": "~2.8|~3.0", "symfony/event-dispatcher": "~2.8|~3.0", "symfony/dependency-injection": "~3.3", "symfony/filesystem": "~2.8|~3.0", From 0a3dc11af9dab60754745b6d5ab994151e2f5e52 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 15 Aug 2017 10:54:46 +0200 Subject: [PATCH 48/80] [HttpKernel] Clean test directory on tear down --- src/Symfony/Component/HttpKernel/Tests/KernelTest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php index dad52401daf39..a6d6285481015 100644 --- a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpKernel\Bundle\BundleInterface; use Symfony\Component\HttpKernel\Config\EnvParametersResource; use Symfony\Component\HttpKernel\Kernel; @@ -25,6 +26,12 @@ class KernelTest extends TestCase { + public static function tearDownAfterClass() + { + $fs = new Filesystem(); + $fs->remove(__DIR__.'/Fixtures/cache'); + } + public function testConstructor() { $env = 'test_env'; From 22a6642632133d3ee7b288da78199bf9db5ddcf2 Mon Sep 17 00:00:00 2001 From: Johannes Goslar Date: Tue, 15 Aug 2017 14:38:43 +0200 Subject: [PATCH 49/80] Update JsonBundleReader.php --- .../Intl/Data/Bundle/Reader/JsonBundleReader.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Intl/Data/Bundle/Reader/JsonBundleReader.php b/src/Symfony/Component/Intl/Data/Bundle/Reader/JsonBundleReader.php index 84644b9fe7f2c..90012a7ad64ab 100644 --- a/src/Symfony/Component/Intl/Data/Bundle/Reader/JsonBundleReader.php +++ b/src/Symfony/Component/Intl/Data/Bundle/Reader/JsonBundleReader.php @@ -32,17 +32,15 @@ public function read($path, $locale) if (!file_exists($fileName)) { throw new ResourceBundleNotFoundException(sprintf( - 'The resource bundle "%s/%s.json" does not exist.', - $path, - $locale + 'The resource bundle "%s" does not exist.', + $fileName )); } if (!is_file($fileName)) { throw new RuntimeException(sprintf( - 'The resource bundle "%s/%s.json" is not a file.', - $path, - $locale + 'The resource bundle "%s" is not a file.', + $fileName )); } @@ -50,9 +48,8 @@ public function read($path, $locale) if (null === $data) { throw new RuntimeException(sprintf( - 'The resource bundle "%s/%s.json" contains invalid JSON: %s', - $path, - $locale, + 'The resource bundle "%s" contains invalid JSON: %s', + $fileName, self::getLastJsonError() )); } From 1a5fd79c21cf43274e517884fdb5b187038bff64 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 15 Aug 2017 15:11:19 +0200 Subject: [PATCH 50/80] Allow phpdocumentor/reflection-docblock 4. --- composer.json | 2 +- src/Symfony/Bundle/FrameworkBundle/composer.json | 2 +- src/Symfony/Component/PropertyInfo/composer.json | 2 +- src/Symfony/Component/Serializer/composer.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 00faa0845d422..ff894a349e227 100644 --- a/composer.json +++ b/composer.json @@ -98,7 +98,7 @@ "symfony/phpunit-bridge": "~3.2", "symfony/polyfill-apcu": "~1.1", "symfony/security-acl": "~2.8|~3.0", - "phpdocumentor/reflection-docblock": "^3.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0", "sensio/framework-extra-bundle": "^3.0.2" }, "conflict": { diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index c605471911974..f542a5a2a8f9a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -55,7 +55,7 @@ "symfony/property-info": "~3.3", "symfony/web-link": "~3.3", "doctrine/annotations": "~1.0", - "phpdocumentor/reflection-docblock": "^3.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0", "twig/twig": "~1.34|~2.4", "sensio/framework-extra-bundle": "^3.0.2" }, diff --git a/src/Symfony/Component/PropertyInfo/composer.json b/src/Symfony/Component/PropertyInfo/composer.json index 13aebfbf0e31e..d068a5ff6a3c3 100644 --- a/src/Symfony/Component/PropertyInfo/composer.json +++ b/src/Symfony/Component/PropertyInfo/composer.json @@ -30,7 +30,7 @@ "symfony/serializer": "~2.8|~3.0", "symfony/cache": "~3.1", "symfony/dependency-injection": "~3.3", - "phpdocumentor/reflection-docblock": "^3.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0", "doctrine/annotations": "~1.0" }, "conflict": { diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json index cd9fd883716d7..e4ee63a730bc0 100644 --- a/src/Symfony/Component/Serializer/composer.json +++ b/src/Symfony/Component/Serializer/composer.json @@ -28,7 +28,7 @@ "doctrine/annotations": "~1.0", "symfony/dependency-injection": "~3.2", "doctrine/cache": "~1.0", - "phpdocumentor/reflection-docblock": "~3.0" + "phpdocumentor/reflection-docblock": "^3.0|^4.0" }, "conflict": { "symfony/dependency-injection": "<3.2", From adff65a60246817685de0c1a68998364c9d6ffcf Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 16 Aug 2017 10:13:36 +0200 Subject: [PATCH 51/80] [DI] Fix reading env vars from fastcgi params --- .../Compiler/ServiceLocatorTagPass.php | 7 ++--- .../DependencyInjection/Container.php | 5 +++- .../DependencyInjection/ContainerBuilder.php | 15 ++++++----- .../EnvPlaceholderParameterBag.php | 26 +++++++++++++++++++ .../Tests/ContainerBuilderTest.php | 24 +++++++++++------ 5 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ServiceLocatorTagPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ServiceLocatorTagPass.php index bf9f83bbe80d0..59c5e390223ca 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ServiceLocatorTagPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ServiceLocatorTagPass.php @@ -54,20 +54,17 @@ protected function processValue($value, $isRoot = false) $value->setArguments($arguments); - if ($public = $value->isPublic()) { - $value->setPublic(false); - } $id = 'service_locator.'.md5(serialize($value)); if ($isRoot) { if ($id !== $this->currentId) { - $this->container->setAlias($id, new Alias($this->currentId, $public)); + $this->container->setAlias($id, new Alias($this->currentId, false)); } return $value; } - $this->container->setDefinition($id, $value); + $this->container->setDefinition($id, $value->setPublic(false)); return new Reference($id); } diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index 3b0a82d80ea10..81241e3415cc8 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -429,7 +429,7 @@ public static function underscore($id) * * @param string $name The name of the environment variable * - * @return scalar The value to use for the provided environment variable name + * @return mixed The value to use for the provided environment variable name * * @throws EnvNotFoundException When the environment variable is not found and has no default value */ @@ -438,6 +438,9 @@ protected function getEnv($name) if (isset($this->envCache[$name]) || array_key_exists($name, $this->envCache)) { return $this->envCache[$name]; } + if (0 !== strpos($name, 'HTTP_') && isset($_SERVER[$name])) { + return $this->envCache[$name] = $_SERVER[$name]; + } if (isset($_ENV[$name])) { return $this->envCache[$name] = $_ENV[$name]; } diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 555c3b09734b2..4f86cd046868f 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -729,9 +729,10 @@ public function compile(/*$resolveEnvPlaceholders = false*/) $bag = $this->getParameterBag(); if ($resolveEnvPlaceholders && $bag instanceof EnvPlaceholderParameterBag) { - $this->parameterBag = new ParameterBag($this->resolveEnvPlaceholders($bag->all(), true)); + $bag->resolveEnvReferences(); + $this->parameterBag = new ParameterBag($bag->all()); $this->envPlaceholders = $bag->getEnvPlaceholders(); - $this->parameterBag = $bag = new ParameterBag($this->resolveEnvPlaceholders($this->parameterBag->all())); + $this->parameterBag = $bag = new ParameterBag($this->resolveEnvPlaceholders($bag->all(), true)); } $compiler->compile($this); @@ -746,7 +747,9 @@ public function compile(/*$resolveEnvPlaceholders = false*/) parent::compile(); - $this->envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : array(); + if ($bag instanceof EnvPlaceholderParameterBag) { + $this->envPlaceholders = $bag->getEnvPlaceholders(); + } } /** @@ -1311,10 +1314,10 @@ public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs foreach ($envPlaceholders as $env => $placeholders) { foreach ($placeholders as $placeholder) { if (false !== stripos($value, $placeholder)) { - if (true === $format) { - $resolved = $bag->escapeValue($this->getEnv($env)); - } else { + if (true !== $format) { $resolved = sprintf($format, $env); + } elseif ($placeholder === $resolved = $bag->escapeValue($this->getEnv($env))) { + $resolved = $bag->all()[strtolower("env($env)")]; } $value = str_ireplace($placeholder, $resolved, $value); $usedEnvs[$env] = $env; diff --git a/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php b/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php index d20e53531aa3b..34f79477fa034 100644 --- a/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php +++ b/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php @@ -20,6 +20,7 @@ class EnvPlaceholderParameterBag extends ParameterBag { private $envPlaceholders = array(); + private $resolveEnvReferences = false; /** * {@inheritdoc} @@ -101,4 +102,29 @@ public function resolve() } } } + + /** + * Replaces "%env(FOO)%" references by their placeholder, keeping regular "%parameters%" references as is. + */ + public function resolveEnvReferences() + { + $this->resolveEnvReferences = true; + try { + $this->resolve(); + } finally { + $this->resolveEnvReferences = false; + } + } + + /** + * {@inheritdoc} + */ + public function resolveString($value, array $resolving = array()) + { + if ($this->resolveEnvReferences) { + return preg_replace_callback('/%%|%(env\([^%\s]+\))%/', function ($match) { return isset($match[1]) ? $this->get($match[1]) : '%%'; }, $value); + } + + return parent::resolveString($value, $resolving); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 51397309b7dce..7ab2e7c6f6c31 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -603,29 +603,37 @@ public function testMergeThrowsExceptionForDuplicateAutomaticInstanceofDefinitio public function testResolveEnvValues() { $_ENV['DUMMY_ENV_VAR'] = 'du%%y'; + $_SERVER['DUMMY_SERVER_VAR'] = 'ABC'; + $_SERVER['HTTP_DUMMY_VAR'] = 'DEF'; $container = new ContainerBuilder(); - $container->setParameter('bar', '%% %env(DUMMY_ENV_VAR)%'); + $container->setParameter('bar', '%% %env(DUMMY_ENV_VAR)% %env(DUMMY_SERVER_VAR)% %env(HTTP_DUMMY_VAR)%'); + $container->setParameter('env(HTTP_DUMMY_VAR)', '123'); - $this->assertSame('%% du%%%%y', $container->resolveEnvPlaceholders('%bar%', true)); + $this->assertSame('%% du%%%%y ABC 123', $container->resolveEnvPlaceholders('%bar%', true)); - unset($_ENV['DUMMY_ENV_VAR']); + unset($_ENV['DUMMY_ENV_VAR'], $_SERVER['DUMMY_SERVER_VAR'], $_SERVER['HTTP_DUMMY_VAR']); } public function testCompileWithResolveEnv() { - $_ENV['DUMMY_ENV_VAR'] = 'du%%y'; + putenv('DUMMY_ENV_VAR=du%%y'); + $_SERVER['DUMMY_SERVER_VAR'] = 'ABC'; + $_SERVER['HTTP_DUMMY_VAR'] = 'DEF'; $container = new ContainerBuilder(); $container->setParameter('env(FOO)', 'Foo'); - $container->setParameter('bar', '%% %env(DUMMY_ENV_VAR)%'); + $container->setParameter('bar', '%% %env(DUMMY_ENV_VAR)% %env(DUMMY_SERVER_VAR)% %env(HTTP_DUMMY_VAR)%'); $container->setParameter('foo', '%env(FOO)%'); + $container->setParameter('baz', '%foo%'); + $container->setParameter('env(HTTP_DUMMY_VAR)', '123'); $container->compile(true); - $this->assertSame('% du%%y', $container->getParameter('bar')); - $this->assertSame('Foo', $container->getParameter('foo')); + $this->assertSame('% du%%y ABC 123', $container->getParameter('bar')); + $this->assertSame('Foo', $container->getParameter('baz')); - unset($_ENV['DUMMY_ENV_VAR']); + unset($_SERVER['DUMMY_SERVER_VAR'], $_SERVER['HTTP_DUMMY_VAR']); + putenv('DUMMY_ENV_VAR'); } /** From b72ced22ad80b335358a312ae82343ef1ad82d25 Mon Sep 17 00:00:00 2001 From: "Issei.M" Date: Thu, 17 Aug 2017 16:14:13 +0900 Subject: [PATCH 52/80] [Validator] Add a property tag for File::$maxSize --- src/Symfony/Component/Validator/Constraints/File.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Symfony/Component/Validator/Constraints/File.php b/src/Symfony/Component/Validator/Constraints/File.php index b9c06bfdb142c..7756978b35216 100644 --- a/src/Symfony/Component/Validator/Constraints/File.php +++ b/src/Symfony/Component/Validator/Constraints/File.php @@ -18,6 +18,8 @@ * @Annotation * @Target({"PROPERTY", "METHOD", "ANNOTATION"}) * + * @property int $maxSize + * * @author Bernhard Schussek */ class File extends Constraint From 62174fda109e6a6bdd9534eb70139aeea81f4ece Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 17 Aug 2017 10:01:13 +0200 Subject: [PATCH 53/80] [Console] Initialize lazily to render exceptions properly --- src/Symfony/Component/Console/Application.php | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index 2c57de4af3e9e..873b09e808729 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -72,6 +72,7 @@ class Application private $dispatcher; private $terminalDimensions; private $defaultCommand; + private $initialized; /** * Constructor. @@ -84,12 +85,6 @@ public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') $this->name = $name; $this->version = $version; $this->defaultCommand = 'list'; - $this->helperSet = $this->getDefaultHelperSet(); - $this->definition = $this->getDefaultInputDefinition(); - - foreach ($this->getDefaultCommands() as $command) { - $this->add($command); - } } public function setDispatcher(EventDispatcherInterface $dispatcher) @@ -189,10 +184,11 @@ public function doRun(InputInterface $input, OutputInterface $output) if (!$name) { $name = $this->defaultCommand; - $this->definition->setArguments(array_merge( - $this->definition->getArguments(), + $definition = $this->getDefinition(); + $definition->setArguments(array_merge( + $definition->getArguments(), array( - 'command' => new InputArgument('command', InputArgument::OPTIONAL, $this->definition->getArgument('command')->getDescription(), $name), + 'command' => new InputArgument('command', InputArgument::OPTIONAL, $definition->getArgument('command')->getDescription(), $name), ) )); } @@ -225,6 +221,10 @@ public function setHelperSet(HelperSet $helperSet) */ public function getHelperSet() { + if (!$this->helperSet) { + $this->helperSet = $this->getDefaultHelperSet(); + } + return $this->helperSet; } @@ -245,6 +245,10 @@ public function setDefinition(InputDefinition $definition) */ public function getDefinition() { + if (!$this->definition) { + $this->definition = $this->getDefaultInputDefinition(); + } + return $this->definition; } @@ -374,6 +378,8 @@ public function addCommands(array $commands) */ public function add(Command $command) { + $this->init(); + $command->setApplication($this); if (!$command->isEnabled()) { @@ -406,6 +412,8 @@ public function add(Command $command) */ public function get($name) { + $this->init(); + if (!isset($this->commands[$name])) { throw new \InvalidArgumentException(sprintf('The command "%s" does not exist.', $name)); } @@ -433,6 +441,8 @@ public function get($name) */ public function has($name) { + $this->init(); + return isset($this->commands[$name]); } @@ -510,6 +520,8 @@ public function findNamespace($namespace) */ public function find($name) { + $this->init(); + $allCommands = array_keys($this->commands); $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name); $commands = preg_grep('{^'.$expr.'}', $allCommands); @@ -565,6 +577,8 @@ public function find($name) */ public function all($namespace = null) { + $this->init(); + if (null === $namespace) { return $this->commands; } @@ -1151,4 +1165,16 @@ private function extractAllNamespaces($name) return $namespaces; } + + private function init() + { + if ($this->initialized) { + return; + } + $this->initialized = true; + + foreach ($this->getDefaultCommands() as $command) { + $this->add($command); + } + } } From 773f166d5e78b5aaa012580f17a62fb1104407e9 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 17 Aug 2017 15:29:00 +0200 Subject: [PATCH 54/80] [VarDumper] Fix tests with phpredis 3.1.3 --- .../Component/VarDumper/Tests/Caster/RedisCasterTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/RedisCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/RedisCasterTest.php index af038192f5c8d..80acdb66798f9 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/RedisCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/RedisCasterTest.php @@ -61,8 +61,7 @@ public function testConnected() EODUMP; } else { $xCast = <<<'EODUMP' -Redis { - +"socket": Redis Socket Buffer resource +Redis {%A isConnected: true host: "127.0.0.1" port: 6379 From 00b927322c8b47cd2eaed9a447e0504c1ff519b8 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 16 Aug 2017 23:15:56 +0200 Subject: [PATCH 55/80] [DI] Fix merging of env vars in configs --- .../MergeExtensionConfigurationPass.php | 71 ++++++++++++++++++- .../DependencyInjection/ContainerBuilder.php | 5 +- .../Extension/Extension.php | 16 ++++- .../EnvPlaceholderParameterBag.php | 4 +- .../MergeExtensionConfigurationPassTest.php | 49 +++++++++++-- 5 files changed, 132 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php index 9434ac70b543b..bddfa8b0e6bf4 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php @@ -13,7 +13,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; +use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; +use Symfony\Component\DependencyInjection\Parameterbag\EnvPlaceholderParameterBag; /** * Merges extension configs into the container builder. @@ -43,7 +45,10 @@ public function process(ContainerBuilder $container) // this extension was not called continue; } - $config = $container->getParameterBag()->resolveValue($config); + // EnvPlaceholderParameterBag tracks env vars when calling resolveValue(). + // Clone so that tracking is done in a dedicated bag. + $resolvingBag = clone $container->getParameterBag(); + $config = $resolvingBag->resolveValue($config); $tmpContainer = new ContainerBuilder($container->getParameterBag()); $tmpContainer->setResourceTracking($container->isTrackingResources()); @@ -58,6 +63,15 @@ public function process(ContainerBuilder $container) $extension->load($config, $tmpContainer); + if ($resolvingBag instanceof EnvPlaceholderParameterBag) { + // $resolvingBag keeps track of env vars encoutered *before* merging configs + if ($extension instanceof Extension) { + // but we don't want to keep track of env vars that are *overridden* when configs are merged + $resolvingBag = new MergeExtensionConfigurationParameterBag($extension, $resolvingBag); + } + $container->getParameterBag()->mergeEnvPlaceholders($resolvingBag); + } + $container->merge($tmpContainer); $container->getParameterBag()->add($parameters); } @@ -66,3 +80,58 @@ public function process(ContainerBuilder $container) $container->addAliases($aliases); } } + +/** + * @internal + */ +class MergeExtensionConfigurationParameterBag extends EnvPlaceholderParameterBag +{ + private $beforeProcessingEnvPlaceholders; + + public function __construct(Extension $extension, parent $resolvingBag) + { + $this->beforeProcessingEnvPlaceholders = $resolvingBag->getEnvPlaceholders(); + $config = $this->resolveEnvPlaceholders($extension->getProcessedConfigs()); + parent::__construct($this->resolveEnvReferences($config)); + } + + /** + * {@inheritdoc} + */ + public function getEnvPlaceholders() + { + // contains the list of env vars that are still used after configs have been merged + $envPlaceholders = parent::getEnvPlaceholders(); + + foreach ($envPlaceholders as $env => $placeholders) { + if (isset($this->beforeProcessingEnvPlaceholders[$env])) { + // for still-used env vars, keep track of their before-processing placeholders + $envPlaceholders[$env] += $this->beforeProcessingEnvPlaceholders[$env]; + } + } + + return $envPlaceholders; + } + + /** + * Replaces-back env placeholders to their original "%env(FOO)%" version. + */ + private function resolveEnvPlaceholders($value) + { + if (is_array($value)) { + foreach ($value as $k => $v) { + $value[$this->resolveEnvPlaceholders($k)] = $this->resolveEnvPlaceholders($v); + } + } elseif (is_string($value)) { + foreach ($this->beforeProcessingEnvPlaceholders as $env => $placeholders) { + foreach ($placeholders as $placeholder) { + if (false !== stripos($value, $placeholder)) { + $value = str_ireplace($placeholder, "%env($env)%", $value); + } + } + } + } + + return $value; + } +} diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 4f86cd046868f..2e14caa1f8349 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -729,10 +729,9 @@ public function compile(/*$resolveEnvPlaceholders = false*/) $bag = $this->getParameterBag(); if ($resolveEnvPlaceholders && $bag instanceof EnvPlaceholderParameterBag) { - $bag->resolveEnvReferences(); - $this->parameterBag = new ParameterBag($bag->all()); + $this->parameterBag = new ParameterBag($bag->resolveEnvReferences($bag->all())); $this->envPlaceholders = $bag->getEnvPlaceholders(); - $this->parameterBag = $bag = new ParameterBag($this->resolveEnvPlaceholders($bag->all(), true)); + $this->parameterBag = $bag = new ParameterBag($this->resolveEnvPlaceholders($this->parameterBag->all(), true)); } $compiler->compile($this); diff --git a/src/Symfony/Component/DependencyInjection/Extension/Extension.php b/src/Symfony/Component/DependencyInjection/Extension/Extension.php index 117ee58c111f4..d3d382ae449de 100644 --- a/src/Symfony/Component/DependencyInjection/Extension/Extension.php +++ b/src/Symfony/Component/DependencyInjection/Extension/Extension.php @@ -25,6 +25,8 @@ */ abstract class Extension implements ExtensionInterface, ConfigurationExtensionInterface { + private $processedConfigs = array(); + /** * {@inheritdoc} */ @@ -91,7 +93,19 @@ final protected function processConfiguration(ConfigurationInterface $configurat { $processor = new Processor(); - return $processor->processConfiguration($configuration, $configs); + return $this->processedConfigs[] = $processor->processConfiguration($configuration, $configs); + } + + /** + * @internal + */ + final public function getProcessedConfigs() + { + try { + return $this->processedConfigs; + } finally { + $this->processedConfigs = array(); + } } /** diff --git a/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php b/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php index 34f79477fa034..8c80abf26bb76 100644 --- a/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php +++ b/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php @@ -106,11 +106,11 @@ public function resolve() /** * Replaces "%env(FOO)%" references by their placeholder, keeping regular "%parameters%" references as is. */ - public function resolveEnvReferences() + public function resolveEnvReferences(array $value) { $this->resolveEnvReferences = true; try { - $this->resolve(); + return $this->resolveValue($value); } finally { $this->resolveEnvReferences = false; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/MergeExtensionConfigurationPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/MergeExtensionConfigurationPassTest.php index b35521d206204..3934418474bd6 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/MergeExtensionConfigurationPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/MergeExtensionConfigurationPassTest.php @@ -17,6 +17,7 @@ use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; class MergeExtensionConfigurationPassTest extends TestCase @@ -55,13 +56,10 @@ public function testExpressionLanguageProviderForwarding() public function testExtensionConfigurationIsTrackedByDefault() { - $extension = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\Extension\\Extension')->getMock(); - $extension->expects($this->once()) + $extension = $this->getMockBuilder(FooExtension::class)->setMethods(array('getConfiguration'))->getMock(); + $extension->expects($this->exactly(2)) ->method('getConfiguration') ->will($this->returnValue(new FooConfiguration())); - $extension->expects($this->any()) - ->method('getAlias') - ->will($this->returnValue('foo')); $container = new ContainerBuilder(new ParameterBag()); $container->registerExtension($extension); @@ -72,12 +70,51 @@ public function testExtensionConfigurationIsTrackedByDefault() $this->assertContains(new FileResource(__FILE__), $container->getResources(), '', false, false); } + + public function testOverriddenEnvsAreMerged() + { + $container = new ContainerBuilder(); + $container->registerExtension(new FooExtension()); + $container->prependExtensionConfig('foo', array('bar' => '%env(FOO)%')); + $container->prependExtensionConfig('foo', array('bar' => '%env(BAR)%')); + + $pass = new MergeExtensionConfigurationPass(); + $pass->process($container); + + $this->assertSame(array('FOO'), array_keys($container->getParameterBag()->getEnvPlaceholders())); + } } class FooConfiguration implements ConfigurationInterface { public function getConfigTreeBuilder() { - return new TreeBuilder(); + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('foo'); + $rootNode + ->children() + ->scalarNode('bar')->end() + ->end(); + + return $treeBuilder; + } +} + +class FooExtension extends Extension +{ + public function getAlias() + { + return 'foo'; + } + + public function getConfiguration(array $config, ContainerBuilder $container) + { + return new FooConfiguration(); + } + + public function load(array $configs, ContainerBuilder $container) + { + $configuration = $this->getConfiguration($configs, $container); + $config = $this->processConfiguration($configuration, $configs); } } From 1d1085717960e4a4f68eca85ed0bd9da2f533bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Wed, 26 Jul 2017 10:53:23 +0200 Subject: [PATCH 56/80] [WebProfilerBundle] Re add missing link to the controller --- .../Resources/views/Collector/request.html.twig | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig index 4fc6a82c58298..5fe45a0f4ed39 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -1,21 +1,19 @@ {% extends '@WebProfiler/Profiler/layout.html.twig' %} {% block toolbar %} + {% import _self as helper %} {% set request_handler %} - {% import _self as helper %} {{ helper.set_handler(collector.controller) }} {% endset %} {% if collector.redirect %} {% set redirect_handler %} - {% import _self as helper %} {{ helper.set_handler(collector.redirect.controller, collector.redirect.route, 'GET' != collector.redirect.method ? collector.redirect.method) }} {% endset %} {% endif %} {% if collector.forward|default(false) %} {% set forward_handler %} - {% import _self as helper %} {{ helper.set_handler(collector.forward.controller) }} {% endset %} {% endif %} @@ -108,6 +106,12 @@ {% endblock %} {% block panel %} + {% import _self as helper %} + +

+ {{ helper.set_handler(collector.controller) }} +

+

Request

@@ -268,7 +272,7 @@ {% for child in profile.children %}

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

From ec8f56acd09501ee8ad3ac8538d8e9441b0a4b28 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 18 Aug 2017 18:00:55 +0200 Subject: [PATCH 57/80] [FrameworkBundle] Add soft conflict rule of "cache:clear" + HttpKernel 3.4 --- .../FrameworkBundle/Command/CacheClearCommand.php | 5 +++++ .../CacheClearCommand/CacheClearCommandTest.php | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php index b7613f7436b2a..ca119f198d5c1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php @@ -15,6 +15,7 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\Finder\Finder; @@ -56,6 +57,10 @@ protected function execute(InputInterface $input, OutputInterface $output) { $io = new SymfonyStyle($input, $output); + if (Kernel::VERSION_ID >= 30400) { + throw new \LogicException('The "cache:clear" command in Symfony 3.3 is incompatible with HttpKernel 3.4, please upgrade "symfony/framework-bundle" or downgrade "symfony/http-kernel".'); + } + $realCacheDir = $this->getContainer()->getParameter('kernel.cache_dir'); // the old cache dir name must not be longer than the real one to avoid exceeding // the maximum length of a directory or file path within it (esp. Windows MAX_PATH) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php index fd3b611202252..71f2ed551b668 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php @@ -20,6 +20,7 @@ use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; +use Symfony\Component\HttpKernel\Kernel; class CacheClearCommandTest extends TestCase { @@ -49,6 +50,17 @@ public function testCacheIsFreshAfterCacheClearedWithWarmup() $application = new Application($this->kernel); $application->setCatchExceptions(false); + if (Kernel::VERSION_ID >= 30400) { + $expectedMsg = 'The "cache:clear" command in Symfony 3.3 is incompatible with HttpKernel 3.4, please upgrade "symfony/framework-bundle" or downgrade "symfony/http-kernel".'; + + if (method_exists($this, 'expectException')) { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage($expectedMsg); + } else { + $this->setExpectedException(\LogicException::class, $expectedMsg); + } + } + $application->doRun($input, new NullOutput()); // Ensure that all *.meta files are fresh From 921959422f791fdd36a455d98ca372c48a7f4956 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 18 Aug 2017 17:51:40 +0200 Subject: [PATCH 58/80] [DI] Fix resolving env vars when compiling a ContainerBuilder --- .../MergeExtensionConfigurationPass.php | 10 +++- .../Compiler/ResolveEnvPlaceholdersPass.php | 44 ++++++++++++++++ .../DependencyInjection/ContainerBuilder.php | 50 +++++++++++++++---- .../EnvPlaceholderParameterBag.php | 26 ---------- .../Tests/ContainerBuilderTest.php | 26 ++++++++++ 5 files changed, 120 insertions(+), 36 deletions(-) create mode 100644 src/Symfony/Component/DependencyInjection/Compiler/ResolveEnvPlaceholdersPass.php diff --git a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php index bddfa8b0e6bf4..2f1b088f92b66 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php @@ -92,7 +92,15 @@ public function __construct(Extension $extension, parent $resolvingBag) { $this->beforeProcessingEnvPlaceholders = $resolvingBag->getEnvPlaceholders(); $config = $this->resolveEnvPlaceholders($extension->getProcessedConfigs()); - parent::__construct($this->resolveEnvReferences($config)); + parent::__construct($this->resolveValue($config)); + } + + /** + * {@inheritdoc} + */ + public function get($name) + { + return $this->has($name) || (0 === strpos($name, 'env(') && ')' === substr($name, -1) && 'env()' !== $name) ? parent::get($name) : ''; } /** diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveEnvPlaceholdersPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveEnvPlaceholdersPass.php new file mode 100644 index 0000000000000..8e44008317c27 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveEnvPlaceholdersPass.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; + +/** + * Replaces env var placeholders by their current values. + */ +class ResolveEnvPlaceholdersPass extends AbstractRecursivePass +{ + protected function processValue($value, $isRoot = false) + { + if (is_string($value)) { + return $this->container->resolveEnvPlaceholders($value, true); + } + if ($value instanceof Definition) { + $changes = $value->getChanges(); + if (isset($changes['class'])) { + $value->setClass($this->container->resolveEnvPlaceholders($value->getClass(), true)); + } + if (isset($changes['file'])) { + $value->setFile($this->container->resolveEnvPlaceholders($value->getFile(), true)); + } + } + + $value = parent::processValue($value, $isRoot); + + if ($value && is_array($value)) { + $value = array_combine($this->container->resolveEnvPlaceholders(array_keys($value), true), $value); + } + + return $value; + } +} diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 2e14caa1f8349..5a3922264554f 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -18,6 +18,7 @@ use Symfony\Component\DependencyInjection\Compiler\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\PassConfig; +use Symfony\Component\DependencyInjection\Compiler\ResolveEnvPlaceholdersPass; use Symfony\Component\DependencyInjection\Exception\BadMethodCallException; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\LogicException; @@ -729,9 +730,7 @@ public function compile(/*$resolveEnvPlaceholders = false*/) $bag = $this->getParameterBag(); if ($resolveEnvPlaceholders && $bag instanceof EnvPlaceholderParameterBag) { - $this->parameterBag = new ParameterBag($bag->resolveEnvReferences($bag->all())); - $this->envPlaceholders = $bag->getEnvPlaceholders(); - $this->parameterBag = $bag = new ParameterBag($this->resolveEnvPlaceholders($this->parameterBag->all(), true)); + $compiler->addPass(new ResolveEnvPlaceholdersPass(), PassConfig::TYPE_AFTER_REMOVING, -1000); } $compiler->compile($this); @@ -744,11 +743,15 @@ public function compile(/*$resolveEnvPlaceholders = false*/) $this->extensionConfigs = array(); - parent::compile(); - if ($bag instanceof EnvPlaceholderParameterBag) { + if ($resolveEnvPlaceholders) { + $this->parameterBag = new ParameterBag($this->resolveEnvPlaceholders($bag->all(), true)); + } + $this->envPlaceholders = $bag->getEnvPlaceholders(); } + + parent::compile(); } /** @@ -1313,12 +1316,19 @@ public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs foreach ($envPlaceholders as $env => $placeholders) { foreach ($placeholders as $placeholder) { if (false !== stripos($value, $placeholder)) { - if (true !== $format) { + if (true === $format) { + $resolved = $bag->escapeValue($this->getEnv($env)); + } else { $resolved = sprintf($format, $env); - } elseif ($placeholder === $resolved = $bag->escapeValue($this->getEnv($env))) { - $resolved = $bag->all()[strtolower("env($env)")]; } - $value = str_ireplace($placeholder, $resolved, $value); + if ($placeholder === $value) { + $value = $resolved; + } 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)); + } + $value = str_ireplace($placeholder, $resolved, $value); + } $usedEnvs[$env] = $env; $this->envCounters[$env] = isset($this->envCounters[$env]) ? 1 + $this->envCounters[$env] : 1; } @@ -1393,6 +1403,28 @@ public static function getServiceConditionals($value) return $services; } + /** + * {@inheritdoc} + */ + protected function getEnv($name) + { + $value = parent::getEnv($name); + + if (!is_string($value) || !$this->getParameterBag() instanceof EnvPlaceholderParameterBag) { + return $value; + } + + foreach ($this->getParameterBag()->getEnvPlaceholders() as $env => $placeholders) { + if (isset($placeholders[$value])) { + $bag = new ParameterBag($this->getParameterBag()->all()); + + return $bag->unescapeValue($bag->get("env($name)")); + } + } + + return $value; + } + /** * Retrieves the currently set proxy instantiator or instantiates one. * diff --git a/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php b/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php index 8c80abf26bb76..d20e53531aa3b 100644 --- a/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php +++ b/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php @@ -20,7 +20,6 @@ class EnvPlaceholderParameterBag extends ParameterBag { private $envPlaceholders = array(); - private $resolveEnvReferences = false; /** * {@inheritdoc} @@ -102,29 +101,4 @@ public function resolve() } } } - - /** - * Replaces "%env(FOO)%" references by their placeholder, keeping regular "%parameters%" references as is. - */ - public function resolveEnvReferences(array $value) - { - $this->resolveEnvReferences = true; - try { - return $this->resolveValue($value); - } finally { - $this->resolveEnvReferences = false; - } - } - - /** - * {@inheritdoc} - */ - public function resolveString($value, array $resolving = array()) - { - if ($this->resolveEnvReferences) { - return preg_replace_callback('/%%|%(env\([^%\s]+\))%/', function ($match) { return isset($match[1]) ? $this->get($match[1]) : '%%'; }, $value); - } - - return parent::resolveString($value, $resolving); - } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 7ab2e7c6f6c31..efe9840e42c40 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -623,19 +623,37 @@ public function testCompileWithResolveEnv() $container = new ContainerBuilder(); $container->setParameter('env(FOO)', 'Foo'); + $container->setParameter('env(DUMMY_ENV_VAR)', 'GHI'); $container->setParameter('bar', '%% %env(DUMMY_ENV_VAR)% %env(DUMMY_SERVER_VAR)% %env(HTTP_DUMMY_VAR)%'); $container->setParameter('foo', '%env(FOO)%'); $container->setParameter('baz', '%foo%'); $container->setParameter('env(HTTP_DUMMY_VAR)', '123'); + $container->register('teatime', 'stdClass') + ->setProperty('foo', '%env(DUMMY_ENV_VAR)%') + ; $container->compile(true); $this->assertSame('% du%%y ABC 123', $container->getParameter('bar')); $this->assertSame('Foo', $container->getParameter('baz')); + $this->assertSame('du%%y', $container->get('teatime')->foo); unset($_SERVER['DUMMY_SERVER_VAR'], $_SERVER['HTTP_DUMMY_VAR']); putenv('DUMMY_ENV_VAR'); } + /** + * @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)%". + */ + public function testCompileWithArrayResolveEnv() + { + $bag = new TestingEnvPlaceholderParameterBag(); + $container = new ContainerBuilder($bag); + $container->setParameter('foo', '%env(ARRAY)%'); + $container->setParameter('bar', 'ABC %env(ARRAY)%'); + $container->compile(true); + } + /** * @expectedException \Symfony\Component\DependencyInjection\Exception\EnvNotFoundException * @expectedExceptionMessage Environment variable not found: "FOO". @@ -1127,3 +1145,11 @@ public function __construct(A $a) { } } + +class TestingEnvPlaceholderParameterBag extends EnvPlaceholderParameterBag +{ + public function get($name) + { + return 'env(array)' === strtolower($name) ? array(123) : parent::get($name); + } +} From bdae7f530c923427095834afe410d12b17f6827d Mon Sep 17 00:00:00 2001 From: Oleksii Zhurbytskyi Date: Tue, 22 Aug 2017 13:13:34 +0300 Subject: [PATCH 59/80] [Validator] Fix Greek translation --- .../Validator/Resources/translations/validators.el.xlf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf index 4fa0d42220500..a3199bcc9d79e 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.el.xlf @@ -100,7 +100,7 @@ This value is not valid. - Αυτή η τιμή δεν είναι έκγυρη. + Αυτή η τιμή δεν είναι έγκυρη. This value is not a valid time. @@ -136,11 +136,11 @@ This is not a valid IP address. - Αυτό δεν είναι μια έκγυρη διεύθυνση IP. + Αυτό δεν είναι μια έγκυρη διεύθυνση IP. This value is not a valid language. - Αυτή η τιμή δεν αντιστοιχεί σε μια έκγυρη γλώσσα. + Αυτή η τιμή δεν αντιστοιχεί σε μια έγκυρη γλώσσα. This value is not a valid locale. @@ -148,7 +148,7 @@ This value is not a valid country. - Αυτή η τιμή δεν αντιστοιχεί σε μια έκγυρη χώρα. + Αυτή η τιμή δεν αντιστοιχεί σε μια έγκυρη χώρα. This value is already used. From 048eb186c7b9f3976567c105de25ad0a1022a6e1 Mon Sep 17 00:00:00 2001 From: Valentin Date: Fri, 11 Aug 2017 22:45:37 +0300 Subject: [PATCH 60/80] [DI] Use GlobResource for non-tracked directories --- .../DependencyInjection/FrameworkExtension.php | 2 +- .../TwigBundle/DependencyInjection/TwigExtension.php | 10 +++++++--- .../Component/DependencyInjection/ContainerBuilder.php | 10 +++++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 2bd54d731197b..d84255d94e3c9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1346,7 +1346,7 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder $fileRecorder('yml', $file); } - if ($container->fileExists($dir = $dirname.'/Resources/config/serialization')) { + if ($container->fileExists($dir = $dirname.'/Resources/config/serialization', '/^$/')) { $this->registerMappingFilesFromDir($dir, $fileRecorder); } } diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php index e8c10786c457d..a1ae0caba145d 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php @@ -13,6 +13,7 @@ use Symfony\Bridge\Twig\Extension\WebLinkExtension; use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Resource\FileExistenceResource; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; @@ -118,9 +119,10 @@ public function load(array $configs, ContainerBuilder $container) } } - if ($container->fileExists($dir = $container->getParameter('kernel.root_dir').'/Resources/views', false)) { + if (file_exists($dir = $container->getParameter('kernel.root_dir').'/Resources/views')) { $twigFilesystemLoaderDefinition->addMethodCall('addPath', array($dir)); } + $container->addResource(new FileExistenceResource($dir)); if (!empty($config['globals'])) { $def = $container->getDefinition('twig'); @@ -178,13 +180,15 @@ private function getBundleHierarchy(ContainerBuilder $container) ); } - if ($container->fileExists($dir = $container->getParameter('kernel.root_dir').'/Resources/'.$name.'/views', false)) { + if (file_exists($dir = $container->getParameter('kernel.root_dir').'/Resources/'.$name.'/views')) { $bundleHierarchy[$name]['paths'][] = $dir; } + $container->addResource(new FileExistenceResource($dir)); - if ($container->fileExists($dir = $bundle['path'].'/Resources/views', false)) { + if (file_exists($dir = $bundle['path'].'/Resources/views')) { $bundleHierarchy[$name]['paths'][] = $dir; } + $container->addResource(new FileExistenceResource($dir)); if (null === $bundle['parent']) { continue; diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 555c3b09734b2..803e7937b1740 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -407,9 +407,13 @@ public function fileExists($path, $trackContents = true) return $exists; } - if ($trackContents && is_dir($path)) { - $this->addResource(new DirectoryResource($path, is_string($trackContents) ? $trackContents : null)); - } elseif ($trackContents || is_dir($path)) { + if (is_dir($path)) { + if ($trackContents) { + $this->addResource(new DirectoryResource($path, is_string($trackContents) ? $trackContents : null)); + } else { + $this->addResource(new GlobResource($path, '/*', false)); + } + } elseif ($trackContents) { $this->addResource(new FileResource($path)); } From c5a1218555f6aa54110d481e1845a39f021daf92 Mon Sep 17 00:00:00 2001 From: Oleg Voronkovich Date: Sun, 6 Aug 2017 03:05:34 +0300 Subject: [PATCH 61/80] [Dotenv][WebServerBundle] Override previously loaded variables --- .../Bundle/WebServerBundle/WebServer.php | 5 ++ src/Symfony/Component/Dotenv/Dotenv.php | 16 +++++- .../Component/Dotenv/Tests/DotenvTest.php | 56 +++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/WebServerBundle/WebServer.php b/src/Symfony/Bundle/WebServerBundle/WebServer.php index 8edbe2bf56ec2..e3425ec8bb13a 100644 --- a/src/Symfony/Bundle/WebServerBundle/WebServer.php +++ b/src/Symfony/Bundle/WebServerBundle/WebServer.php @@ -154,6 +154,11 @@ private function createServerProcess(WebServerConfig $config) $process->setWorkingDirectory($config->getDocumentRoot()); $process->setTimeout(null); + if (in_array('APP_ENV', explode(',', getenv('SYMFONY_DOTENV_VARS')))) { + $process->setEnv(array('APP_ENV' => false)); + $process->inheritEnvironmentVariables(); + } + return $process; } diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php index 2e907b8c980b8..0d3c01d93639e 100644 --- a/src/Symfony/Component/Dotenv/Dotenv.php +++ b/src/Symfony/Component/Dotenv/Dotenv.php @@ -60,20 +60,32 @@ public function load($path/*, ...$paths*/) /** * Sets values as environment variables (via putenv, $_ENV, and $_SERVER). * - * Note that existing environment variables are never overridden. + * Note that existing environment variables are not overridden. * * @param array $values An array of env variables */ public function populate($values) { + $loadedVars = array_flip(explode(',', getenv('SYMFONY_DOTENV_VARS'))); + unset($loadedVars['']); + foreach ($values as $name => $value) { - if (isset($_ENV[$name]) || isset($_SERVER[$name]) || false !== getenv($name)) { + if (!isset($loadedVars[$name]) && (isset($_ENV[$name]) || isset($_SERVER[$name]) || false !== getenv($name))) { continue; } putenv("$name=$value"); $_ENV[$name] = $value; $_SERVER[$name] = $value; + + $loadedVars[$name] = true; + } + + if ($loadedVars) { + $loadedVars = implode(',', array_keys($loadedVars)); + putenv("SYMFONY_DOTENV_VARS=$loadedVars"); + $_ENV['SYMFONY_DOTENV_VARS'] = $loadedVars; + $_SERVER['SYMFONY_DOTENV_VARS'] = $loadedVars; } } diff --git a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php index 47598030a87f1..dc1a7b5b2c4a7 100644 --- a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php +++ b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php @@ -214,4 +214,60 @@ public function testEnvVarIsNotOverriden() $this->assertSame('original_value', getenv('TEST_ENV_VAR')); } + + public function testMemorizingLoadedVarsNamesInSpecialVar() + { + // Special variable not exists + unset($_ENV['SYMFONY_DOTENV_VARS']); + unset($_SERVER['SYMFONY_DOTENV_VARS']); + putenv('SYMFONY_DOTENV_VARS'); + + unset($_ENV['APP_DEBUG']); + unset($_SERVER['APP_DEBUG']); + putenv('APP_DEBUG'); + unset($_ENV['DATABASE_URL']); + unset($_SERVER['DATABASE_URL']); + putenv('DATABASE_URL'); + + $dotenv = new DotEnv(); + $dotenv->populate(array('APP_DEBUG' => '1', 'DATABASE_URL' => 'mysql://root@localhost/db')); + + $this->assertSame('APP_DEBUG,DATABASE_URL', getenv('SYMFONY_DOTENV_VARS')); + + // Special variable has a value + $_ENV['SYMFONY_DOTENV_VARS'] = 'APP_ENV'; + $_SERVER['SYMFONY_DOTENV_VARS'] = 'APP_ENV'; + putenv('SYMFONY_DOTENV_VARS=APP_ENV'); + + $_ENV['APP_DEBUG'] = '1'; + $_SERVER['APP_DEBUG'] = '1'; + putenv('APP_DEBUG=1'); + unset($_ENV['DATABASE_URL']); + unset($_SERVER['DATABASE_URL']); + putenv('DATABASE_URL'); + + $dotenv = new DotEnv(); + $dotenv->populate(array('APP_DEBUG' => '0', 'DATABASE_URL' => 'mysql://root@localhost/db')); + $dotenv->populate(array('DATABASE_URL' => 'sqlite:///somedb.sqlite')); + + $this->assertSame('APP_ENV,DATABASE_URL', getenv('SYMFONY_DOTENV_VARS')); + } + + public function testOverridingEnvVarsWithNamesMemorizedInSpecialVar() + { + putenv('SYMFONY_DOTENV_VARS=FOO,BAR,BAZ'); + + putenv('FOO=foo'); + putenv('BAR=bar'); + putenv('BAZ=baz'); + putenv('DOCUMENT_ROOT=/var/www'); + + $dotenv = new DotEnv(); + $dotenv->populate(array('FOO' => 'foo1', 'BAR' => 'bar1', 'BAZ' => 'baz1', 'DOCUMENT_ROOT' => '/boot')); + + $this->assertSame('foo1', getenv('FOO')); + $this->assertSame('bar1', getenv('BAR')); + $this->assertSame('baz1', getenv('BAZ')); + $this->assertSame('/var/www', getenv('DOCUMENT_ROOT')); + } } From f76e420e0959b52e73f1486a7b99771d6553ff01 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 22 Aug 2017 15:31:38 +0200 Subject: [PATCH 62/80] [Dotenv] Get env using $_SERVER to work with fastcgi_param and workaround thread safety issues --- .../DependencyInjection/Container.php | 4 ++-- src/Symfony/Component/Dotenv/Dotenv.php | 18 +++++++++++++++--- .../Component/Dotenv/Tests/DotenvTest.php | 13 +++++++++++++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index 81241e3415cc8..6eceb0defeba9 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -438,13 +438,13 @@ protected function getEnv($name) if (isset($this->envCache[$name]) || array_key_exists($name, $this->envCache)) { return $this->envCache[$name]; } - if (0 !== strpos($name, 'HTTP_') && isset($_SERVER[$name])) { + if (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) { return $this->envCache[$name] = $_SERVER[$name]; } if (isset($_ENV[$name])) { return $this->envCache[$name] = $_ENV[$name]; } - if (false !== $env = getenv($name)) { + if (false !== ($env = getenv($name)) && null !== $env) { // null is a possible value because of thread safety issues return $this->envCache[$name] = $env; } if (!$this->hasParameter("env($name)")) { diff --git a/src/Symfony/Component/Dotenv/Dotenv.php b/src/Symfony/Component/Dotenv/Dotenv.php index 0d3c01d93639e..910a1622f303b 100644 --- a/src/Symfony/Component/Dotenv/Dotenv.php +++ b/src/Symfony/Component/Dotenv/Dotenv.php @@ -70,13 +70,17 @@ public function populate($values) unset($loadedVars['']); foreach ($values as $name => $value) { - if (!isset($loadedVars[$name]) && (isset($_ENV[$name]) || isset($_SERVER[$name]) || false !== getenv($name))) { + $notHttpName = 0 !== strpos($name, 'HTTP_'); + // don't check existence with getenv() because of thread safety issues + if (!isset($loadedVars[$name]) && (isset($_ENV[$name]) || (isset($_SERVER[$name]) && $notHttpName))) { continue; } putenv("$name=$value"); $_ENV[$name] = $value; - $_SERVER[$name] = $value; + if ($notHttpName) { + $_SERVER[$name] = $value; + } $loadedVars[$name] = true; } @@ -363,7 +367,15 @@ private function resolveVariables($value) } $name = $matches[3]; - $value = isset($this->values[$name]) ? $this->values[$name] : (isset($_ENV[$name]) ? $_ENV[$name] : (string) getenv($name)); + if (isset($this->values[$name])) { + $value = $this->values[$name]; + } elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) { + $value = $_SERVER[$name]; + } elseif (isset($_ENV[$name])) { + $value = $_ENV[$name]; + } else { + $value = (string) getenv($name); + } if (!$matches[2] && isset($matches[4])) { $value .= '}'; diff --git a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php index dc1a7b5b2c4a7..ce7d3a93396b2 100644 --- a/src/Symfony/Component/Dotenv/Tests/DotenvTest.php +++ b/src/Symfony/Component/Dotenv/Tests/DotenvTest.php @@ -208,6 +208,7 @@ public function testServerSuperglobalIsNotOverriden() public function testEnvVarIsNotOverriden() { putenv('TEST_ENV_VAR=original_value'); + $_SERVER['TEST_ENV_VAR'] = 'original_value'; $dotenv = new DotEnv(); $dotenv->populate(array('TEST_ENV_VAR' => 'new_value')); @@ -215,6 +216,18 @@ public function testEnvVarIsNotOverriden() $this->assertSame('original_value', getenv('TEST_ENV_VAR')); } + public function testHttpVarIsPartiallyOverriden() + { + $_SERVER['HTTP_TEST_ENV_VAR'] = 'http_value'; + + $dotenv = new DotEnv(); + $dotenv->populate(array('HTTP_TEST_ENV_VAR' => 'env_value')); + + $this->assertSame('env_value', getenv('HTTP_TEST_ENV_VAR')); + $this->assertSame('env_value', $_ENV['HTTP_TEST_ENV_VAR']); + $this->assertSame('http_value', $_SERVER['HTTP_TEST_ENV_VAR']); + } + public function testMemorizingLoadedVarsNamesInSpecialVar() { // Special variable not exists From 94d55ca0de7f7752ae18a285f8c62513e27e8575 Mon Sep 17 00:00:00 2001 From: Shawn Iwinski Date: Wed, 23 Aug 2017 16:52:57 -0400 Subject: [PATCH 63/80] [Console] Require PHP 7 for ApplicationTest --- .../Component/Console/Tests/ApplicationTest.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index 6c06025697b2a..f12b1b4e1882c 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -1040,6 +1040,9 @@ public function testRunDispatchesAllEventsWithExceptionInListener() $this->assertContains('before.error.after.', $tester->getDisplay()); } + /** + * @requires PHP 7 + */ public function testRunWithError() { $application = new Application(); @@ -1160,6 +1163,7 @@ public function testErrorIsRethrownIfNotHandledByConsoleErrorEvent() } /** + * @requires PHP 7 * @expectedException \LogicException * @expectedExceptionMessage error */ @@ -1181,6 +1185,9 @@ public function testRunWithErrorAndDispatcher() $this->assertContains('before.dym.error.after.', $tester->getDisplay(), 'The PHP Error did not dispached events'); } + /** + * @requires PHP 7 + */ public function testRunDispatchesAllEventsWithError() { $application = new Application(); @@ -1198,6 +1205,9 @@ public function testRunDispatchesAllEventsWithError() $this->assertContains('before.dym.error.after.', $tester->getDisplay(), 'The PHP Error did not dispached events'); } + /** + * @requires PHP 7 + */ public function testRunWithErrorFailingStatusCode() { $application = new Application(); From 2348d64b86fba16ca631f7fdbdf41ecf02534300 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 24 Aug 2017 08:50:28 +0200 Subject: [PATCH 64/80] [Cache] Fix >30 days expirations with Memcached --- .../Cache/Tests/Adapter/AdapterTestCase.php | 20 +++++++++++++++++++ .../Tests/Adapter/MemcachedAdapterTest.php | 1 - .../Component/Cache/Traits/MemcachedTrait.php | 4 ++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php b/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php index c3cbd3bef7e54..faecda830cd7c 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php @@ -45,6 +45,26 @@ public function testDefaultLifeTime() $this->assertFalse($item->isHit()); } + public function testExpiration() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $cache = $this->createCachePool(); + $cache->save($cache->getItem('k1')->set('v1')->expiresAfter(2)); + $cache->save($cache->getItem('k2')->set('v2')->expiresAfter(366 * 86400)); + + sleep(3); + $item = $cache->getItem('k1'); + $this->assertFalse($item->isHit()); + $this->assertNull($item->get(), "Item's value must be null when isHit() is false."); + + $item = $cache->getItem('k2'); + $this->assertTrue($item->isHit()); + $this->assertSame('v2', $item->get()); + } + public function testNotUnserializable() { if (isset($this->skippedTests[__FUNCTION__])) { diff --git a/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php index 82b41c3b4d870..00e129398ed9a 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php @@ -17,7 +17,6 @@ class MemcachedAdapterTest extends AdapterTestCase { protected $skippedTests = array( - 'testExpiration' => 'Testing expiration slows down the test suite', 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', ); diff --git a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php index c2832946f98c2..9dc44355c042a 100644 --- a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php +++ b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php @@ -187,6 +187,10 @@ public static function createConnection($servers, array $options = array()) */ protected function doSave(array $values, $lifetime) { + if ($lifetime && $lifetime > 30 * 86400) { + $lifetime += time(); + } + return $this->checkResultCode($this->client->setMulti($values, $lifetime)); } From 51d210e2c03fa16af11d9a04c9e8a8ddac7a2f3b Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 24 Aug 2017 10:32:12 +0200 Subject: [PATCH 65/80] [travis] Add timing info --- .travis.yml | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index af674057da4b8..b7ce58bd8ffbb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,15 +51,38 @@ before_install: export PHPUNIT_X="$PHPUNIT --exclude-group tty,benchmark,intl-data" export COMPOSER_UP='composer update --no-progress --no-suggest --ansi' + nanoseconds() { + local cmd="date" + local format="+%s%N" + local os=$(uname) + if hash gdate > /dev/null 2>&1; then + cmd="gdate" + elif [[ "$os" = Darwin ]]; then + format="+%s000000000" + fi + $cmd -u $format + } + export -f nanoseconds + # tfold is a helper to create folded reports tfold () { - title=$1 - fold=$(echo $title | sed -r 's/[^-_A-Za-z\d]+/./g') + local title=$1 + local fold=$(echo $title | sed -r 's/[^-_A-Za-z0-9]+/./g') shift - echo -e "travis_fold:start:$fold\\n\\e[1;34m$title\\e[0m" - bash -xc "$*" 2>&1 && + local id=$(printf %08x $(( RANDOM * RANDOM ))) + local start=$(nanoseconds) + echo -e "travis_fold:start:$fold" + echo -e "travis_time:start:$id" + echo -e "\\e[1;34m$title\\e[0m" + + bash -xc "$*" 2>&1 + local ok=$? + local end=$(nanoseconds) + echo -e "\\ntravis_time:end:$id:start=$start,finish=$end,duration=$(($end-$start))" + (exit $ok) && echo -e "\\e[32mOK\\e[0m $title\\n\\ntravis_fold:end:$fold" || - ( echo -e "\\e[41mKO\\e[0m $title\\n" && exit 1 ) + echo -e "\\e[41mKO\\e[0m $title\\n" + (exit $ok) } export -f tfold From d8c400bf582e3b11f6c78179b1e38fefec3ad8e1 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 24 Aug 2017 09:48:32 +0200 Subject: [PATCH 66/80] [Cache] Fix lazy Memcached connections --- .../Component/Cache/Traits/MemcachedTrait.php | 45 ++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php index 9dc44355c042a..8a836bac18c45 100644 --- a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php +++ b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php @@ -30,6 +30,7 @@ trait MemcachedTrait ); private $client; + private $lazyClient; public static function isSupported() { @@ -41,14 +42,18 @@ private function init(\Memcached $client, $namespace, $defaultLifetime) if (!static::isSupported()) { throw new CacheException('Memcached >= 2.2.0 is required'); } - $opt = $client->getOption(\Memcached::OPT_SERIALIZER); - if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) { - throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); + if (get_class($client) === 'Memcached') { + $opt = $client->getOption(\Memcached::OPT_SERIALIZER); + if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) { + throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); + } + $this->maxIdLength -= strlen($client->getOption(\Memcached::OPT_PREFIX_KEY)); + $this->client = $client; + } else { + $this->lazyClient = $client; } - $this->maxIdLength -= strlen($client->getOption(\Memcached::OPT_PREFIX_KEY)); parent::__construct($namespace, $defaultLifetime); - $this->client = $client; } /** @@ -191,7 +196,7 @@ protected function doSave(array $values, $lifetime) $lifetime += time(); } - return $this->checkResultCode($this->client->setMulti($values, $lifetime)); + return $this->checkResultCode($this->getClient()->setMulti($values, $lifetime)); } /** @@ -201,7 +206,7 @@ protected function doFetch(array $ids) { $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback'); try { - return $this->checkResultCode($this->client->getMulti($ids)); + return $this->checkResultCode($this->getClient()->getMulti($ids)); } catch (\Error $e) { throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()); } finally { @@ -214,7 +219,7 @@ protected function doFetch(array $ids) */ protected function doHave($id) { - return false !== $this->client->get($id) || $this->checkResultCode(\Memcached::RES_SUCCESS === $this->client->getResultCode()); + return false !== $this->getClient()->get($id) || $this->checkResultCode(\Memcached::RES_SUCCESS === $this->client->getResultCode()); } /** @@ -223,7 +228,7 @@ protected function doHave($id) protected function doDelete(array $ids) { $ok = true; - foreach ($this->checkResultCode($this->client->deleteMulti($ids)) as $result) { + foreach ($this->checkResultCode($this->getClient()->deleteMulti($ids)) as $result) { if (\Memcached::RES_SUCCESS !== $result && \Memcached::RES_NOTFOUND !== $result) { $ok = false; } @@ -237,7 +242,7 @@ protected function doDelete(array $ids) */ protected function doClear($namespace) { - return $this->checkResultCode($this->client->flush()); + return $this->checkResultCode($this->getClient()->flush()); } private function checkResultCode($result) @@ -250,4 +255,24 @@ private function checkResultCode($result) throw new CacheException(sprintf('MemcachedAdapter client error: %s.', strtolower($this->client->getResultMessage()))); } + + /** + * @return \Memcached + */ + private function getClient() + { + if ($this->client) { + return $this->client; + } + + $opt = $this->lazyClient->getOption(\Memcached::OPT_SERIALIZER); + if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) { + throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); + } + if ('' !== $prefix = (string) $this->lazyClient->getOption(\Memcached::OPT_PREFIX_KEY)) { + throw new CacheException(sprintf('MemcachedAdapter: "prefix_key" option must be empty when using proxified connections, "%s" given.', $prefix)); + } + + return $this->client = $this->lazyClient; + } } From 5e05fc958f9d17a23f58b9dba2856b8a7a8a5350 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 25 Aug 2017 13:47:49 +0200 Subject: [PATCH 67/80] [VarDumper] Strengthen dumped JS --- .../Component/VarDumper/Dumper/HtmlDumper.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php index cf94b1af93039..02ec543b5a706 100644 --- a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php @@ -187,7 +187,7 @@ function toggle(a, recursive) { function collapse(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; - if ('sf-dump-expanded' == oldClass) { + if (/\bsf-dump-expanded\b/.test(oldClass)) { toggle(a, recursive); return true; @@ -199,7 +199,7 @@ function collapse(a, recursive) { function expand(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; - if ('sf-dump-compact' == oldClass) { + if (/\bsf-dump-compact\b/.test(oldClass)) { toggle(a, recursive); return true; @@ -254,8 +254,8 @@ function highlight(root, activeNode, nodes) { function resetHighlightedNodes(root) { Array.from(root.querySelectorAll('.sf-dump-str, .sf-dump-key, .sf-dump-public, .sf-dump-protected, .sf-dump-private')).forEach(function (strNode) { - strNode.className = strNode.className.replace(/\b sf-dump-highlight\b/, ''); - strNode.className = strNode.className.replace(/\b sf-dump-highlight-active\b/, ''); + strNode.className = strNode.className.replace(/\bsf-dump-highlight\b/, ''); + strNode.className = strNode.className.replace(/\bsf-dump-highlight-active\b/, ''); }); } @@ -352,7 +352,7 @@ function xpathString(str) { } else if (/\bsf-dump-str-toggle\b/.test(a.className)) { e.preventDefault(); e = a.parentNode.parentNode; - e.className = e.className.replace(/sf-dump-str-(expand|collapse)/, a.parentNode.className); + e.className = e.className.replace(/\bsf-dump-str-(expand|collapse)\b/, a.parentNode.className); } }); @@ -518,8 +518,7 @@ function showCurrent(state) Array.from(search.querySelectorAll('.sf-dump-search-input-next, .sf-dump-search-input-previous')).forEach(function (btn) { addEventListener(btn, 'click', function (e) { e.preventDefault(); - var direction = -1 !== e.target.className.indexOf('next') ? 'next' : 'previous'; - 'next' === direction ? state.next() : state.previous(); + -1 !== e.target.className.indexOf('next') ? state.next() : state.previous(); searchInput.focus(); collapseAll(root); showCurrent(state); From 5c1bd1001761d9edcd3aa05a5f64318a74909842 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 25 Aug 2017 13:47:49 +0200 Subject: [PATCH 68/80] [VarDumper] Strengthen dumped JS --- .../Component/VarDumper/Dumper/HtmlDumper.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php index 4f572caea3f8c..28596bf83d1ce 100644 --- a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php @@ -132,10 +132,10 @@ protected function getDumpHeader() function toggle(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass; - if ('sf-dump-compact' == oldClass) { + if (/\bsf-dump-compact\b/.test(oldClass)) { arrow = '▼'; newClass = 'sf-dump-expanded'; - } else if ('sf-dump-expanded' == oldClass) { + } else if (/\bsf-dump-expanded\b/.test(oldClass)) { arrow = '▶'; newClass = 'sf-dump-compact'; } else { @@ -143,13 +143,13 @@ function toggle(a, recursive) { } a.lastChild.innerHTML = arrow; - s.className = newClass; + s.className = s.className.replace(/\bsf-dump-(compact|expanded)\b/, newClass); if (recursive) { try { a = s.querySelectorAll('.'+oldClass); for (s = 0; s < a.length; ++s) { - if (a[s].className !== newClass) { + if (-1 == a[s].className.indexOf(newClass)) { a[s].className = newClass; a[s].previousSibling.lastChild.innerHTML = arrow; } @@ -205,7 +205,7 @@ function isCtrlKey(e) { if (f && t && f[0] !== t[0]) { r.innerHTML = r.innerHTML.replace(new RegExp('^'+f[0].replace(rxEsc, '\\$1'), 'mg'), t[0]); } - if ('sf-dump-compact' == r.className) { + if (/\bsf-dump-compact\b/.test(r.className)) { toggle(s, isCtrlKey(e)); } } @@ -255,10 +255,10 @@ function isCtrlKey(e) { a.title = (a.title ? a.title+'\n[' : '[')+keyHint+'+click] Expand all children'; a.innerHTML += ''; a.className += ' sf-dump-toggle'; - if ('sf-dump' != elt.parentNode.className) { + if (!/\bsf-dump\b/.test(elt.parentNode.className)) { toggle(a); } - } else if ("sf-dump-ref" == elt.className && (a = elt.getAttribute('href'))) { + } else if (/\bsf-dump-ref\b/.test(elt.className) && (a = elt.getAttribute('href'))) { a = a.substr(1); elt.className += ' '+a; From 1cab07ebee6dbf2e10d14a3eaebb156b10511f39 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 25 Aug 2017 17:28:27 +0200 Subject: [PATCH 69/80] [Cache] Workaround zend.detect_unicode + zend.multibyte --- .../Component/Cache/Adapter/PhpArrayAdapter.php | 1 + .../Component/Cache/Adapter/PhpFilesAdapter.php | 1 + .../Component/Cache/Simple/PhpArrayCache.php | 1 + .../Component/Cache/Simple/PhpFilesCache.php | 1 + .../Component/Cache/Traits/PhpArrayTrait.php | 14 ++++++++++++-- .../Component/Cache/Traits/PhpFilesTrait.php | 7 +++++++ 6 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php index ea102ddbf75fb..889a97f80a5fb 100644 --- a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php @@ -38,6 +38,7 @@ public function __construct($file, AdapterInterface $fallbackPool) { $this->file = $file; $this->fallbackPool = $fallbackPool; + $this->zendMultiByte = ini_get('zend.multibyte'); $this->createCacheItem = \Closure::bind( function ($key, $value, $isHit) { $item = new CacheItem(); diff --git a/src/Symfony/Component/Cache/Adapter/PhpFilesAdapter.php b/src/Symfony/Component/Cache/Adapter/PhpFilesAdapter.php index fee500dbfc7e2..75ac9092df024 100644 --- a/src/Symfony/Component/Cache/Adapter/PhpFilesAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/PhpFilesAdapter.php @@ -35,5 +35,6 @@ public function __construct($namespace = '', $defaultLifetime = 0, $directory = $e = new \Exception(); $this->includeHandler = function () use ($e) { throw $e; }; + $this->zendMultiByte = ini_get('zend.multibyte'); } } diff --git a/src/Symfony/Component/Cache/Simple/PhpArrayCache.php b/src/Symfony/Component/Cache/Simple/PhpArrayCache.php index c65b8fffaac41..d4c3926548ca3 100644 --- a/src/Symfony/Component/Cache/Simple/PhpArrayCache.php +++ b/src/Symfony/Component/Cache/Simple/PhpArrayCache.php @@ -34,6 +34,7 @@ public function __construct($file, CacheInterface $fallbackPool) { $this->file = $file; $this->fallbackPool = $fallbackPool; + $this->zendMultiByte = ini_get('zend.multibyte'); } /** diff --git a/src/Symfony/Component/Cache/Simple/PhpFilesCache.php b/src/Symfony/Component/Cache/Simple/PhpFilesCache.php index 810b80f81275c..02273ada7a32a 100644 --- a/src/Symfony/Component/Cache/Simple/PhpFilesCache.php +++ b/src/Symfony/Component/Cache/Simple/PhpFilesCache.php @@ -35,5 +35,6 @@ public function __construct($namespace = '', $defaultLifetime = 0, $directory = $e = new \Exception(); $this->includeHandler = function () use ($e) { throw $e; }; + $this->zendMultiByte = ini_get('zend.multibyte'); } } diff --git a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php index 2d2c7db3d014f..b57e4e0b98de3 100644 --- a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php @@ -25,6 +25,7 @@ trait PhpArrayTrait private $file; private $values; private $fallbackPool; + private $zendMultiByte; /** * Store an array of cached values. @@ -106,7 +107,7 @@ public function warmUp(array $values) @rename($tmpFile, $this->file); - $this->values = (include $this->file) ?: array(); + $this->initialize(); } /** @@ -126,6 +127,15 @@ public function clear() */ private function initialize() { - $this->values = file_exists($this->file) ? (include $this->file ?: array()) : array(); + if ($this->zendMultiByte) { + $zmb = ini_set('zend.multibyte', 0); + } + try { + $this->values = file_exists($this->file) ? (include $this->file ?: array()) : array(); + } finally { + if ($this->zendMultiByte) { + ini_set('zend.multibyte', $zmb); + } + } } } diff --git a/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php b/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php index 259caf0c74168..d9d976a023a30 100644 --- a/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php @@ -25,6 +25,7 @@ trait PhpFilesTrait use FilesystemCommonTrait; private $includeHandler; + private $zendMultiByte; public static function isSupported() { @@ -39,6 +40,9 @@ protected function doFetch(array $ids) $values = array(); $now = time(); + if ($this->zendMultiByte) { + $zmb = ini_set('zend.multibyte', 0); + } set_error_handler($this->includeHandler); try { foreach ($ids as $id) { @@ -54,6 +58,9 @@ protected function doFetch(array $ids) } } finally { restore_error_handler(); + if ($this->zendMultiByte) { + ini_set('zend.multibyte', $zmb); + } } foreach ($values as $id => $value) { From c7601cb40ea87a727396ff6d0d05907c16b62abf Mon Sep 17 00:00:00 2001 From: Billie Thompson Date: Fri, 25 Aug 2017 17:06:14 +0100 Subject: [PATCH 70/80] Change number PHPDoc type to int|float While number is a valid type inside PHP internally, it's not a part of the PHPDoc standard. This causes IDEs and static analysers to raise errors on this function. The internal PHP type `number` is the same as `int|float`, this changes the type to that. https://php.net/manual/en/language.pseudo-types.php#language.types.number https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md#keyword --- .../Component/Intl/NumberFormatter/NumberFormatter.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php b/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php index 50ee30a217da1..ce03e9f5d6642 100644 --- a/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php +++ b/src/Symfony/Component/Intl/NumberFormatter/NumberFormatter.php @@ -355,9 +355,9 @@ public function formatCurrency($value, $currency) /** * Format a number. * - * @param number $value The value to format - * @param int $type Type of the formatting, one of the format type constants - * Only type NumberFormatter::TYPE_DEFAULT is currently supported. + * @param int|float $value The value to format + * @param int $type Type of the formatting, one of the format type constants + * Only type NumberFormatter::TYPE_DEFAULT is currently supported. * * @return bool|string The formatted value or false on error * From 8d7b203d8036f31a9f8d29c639d705dbb74efa39 Mon Sep 17 00:00:00 2001 From: Sergey Linnik Date: Fri, 18 Aug 2017 00:27:11 +0300 Subject: [PATCH 71/80] [Validator] Fix use of GroupSequenceProvider in child classes --- .../Validator/Mapping/ClassMetadata.php | 4 ++++ .../GroupSequenceProviderChildEntity.php | 16 ++++++++++++++ .../Tests/Mapping/ClassMetadataTest.php | 22 ++++++++++--------- 3 files changed, 32 insertions(+), 10 deletions(-) create mode 100644 src/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderChildEntity.php diff --git a/src/Symfony/Component/Validator/Mapping/ClassMetadata.php b/src/Symfony/Component/Validator/Mapping/ClassMetadata.php index f895ad40402dc..5b82cf6d5d9d6 100644 --- a/src/Symfony/Component/Validator/Mapping/ClassMetadata.php +++ b/src/Symfony/Component/Validator/Mapping/ClassMetadata.php @@ -381,6 +381,10 @@ public function addGetterMethodConstraints($property, $method, array $constraint */ public function mergeConstraints(ClassMetadata $source) { + if ($source->isGroupSequenceProvider()) { + $this->setGroupSequenceProvider(true); + } + foreach ($source->getConstraints() as $constraint) { $this->addConstraint(clone $constraint); } diff --git a/src/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderChildEntity.php b/src/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderChildEntity.php new file mode 100644 index 0000000000000..be7191f9b6e1d --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderChildEntity.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator\Tests\Fixtures; + +class GroupSequenceProviderChildEntity extends GroupSequenceProviderEntity +{ +} diff --git a/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php b/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php index 9a23e8cf355a0..a3f8a8c1ec8a3 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php +++ b/src/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php @@ -24,6 +24,7 @@ class ClassMetadataTest extends TestCase const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity'; const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent'; const PROVIDERCLASS = 'Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity'; + const PROVIDERCHILDCLASS = 'Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderChildEntity'; protected $metadata; @@ -301,6 +302,17 @@ public function testGroupSequenceProvider() $this->assertTrue($metadata->isGroupSequenceProvider()); } + public function testMergeConstraintsMergesGroupSequenceProvider() + { + $parent = new ClassMetadata(self::PROVIDERCLASS); + $parent->setGroupSequenceProvider(true); + + $metadata = new ClassMetadata(self::PROVIDERCHILDCLASS); + $metadata->mergeConstraints($parent); + + $this->assertTrue($metadata->isGroupSequenceProvider()); + } + /** * https://github.com/symfony/symfony/issues/11604. */ @@ -309,13 +321,3 @@ public function testGetPropertyMetadataReturnsEmptyArrayWithoutConfiguredMetadat $this->assertCount(0, $this->metadata->getPropertyMetadata('foo'), '->getPropertyMetadata() returns an empty collection if no metadata is configured for the given property'); } } - -class ParentClass -{ - public $example = 0; -} - -class ChildClass extends ParentClass -{ - public $example = 1; // overrides parent property of same name -} From 466da3fd6372904da4f71ab06db01df67b92e739 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 25 Aug 2017 19:21:35 +0200 Subject: [PATCH 72/80] [Debug] Remove false-positive check in DebugClassLoader --- .../Component/Debug/DebugClassLoader.php | 6 ++++-- .../Debug/Tests/DebugClassLoaderTest.php | 19 +++++++++++++++++++ .../Debug/Tests/Fixtures/Throwing.php | 3 +++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Component/Debug/Tests/Fixtures/Throwing.php diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index 8ca836bd74a2d..2094a85c4cd6a 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -26,6 +26,7 @@ class DebugClassLoader { private $classLoader; private $isFinder; + private $loaded = array(); private $wasFinder; private static $caseCheck; private static $deprecated = array(); @@ -164,9 +165,10 @@ public function loadClass($class) ErrorHandler::stackErrors(); try { - if ($this->isFinder) { + if ($this->isFinder && !isset($this->loaded[$class])) { + $this->loaded[$class] = true; if ($file = $this->classLoader[0]->findFile($class)) { - require_once $file; + require $file; } } else { call_user_func($this->classLoader, $class); diff --git a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php index 133ca28e546b7..1843418e919c9 100644 --- a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php +++ b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php @@ -59,6 +59,23 @@ public function testIdempotence() $this->fail('DebugClassLoader did not register'); } + /** + * @expectedException \Exception + * @expectedExceptionMessage boo + */ + public function testThrowingClass() + { + try { + class_exists(__NAMESPACE__.'\Fixtures\Throwing'); + $this->fail('Exception expected'); + } catch (\Exception $e) { + $this->assertSame('boo', $e->getMessage()); + } + + // the second call also should throw + class_exists(__NAMESPACE__.'\Fixtures\Throwing'); + } + public function testUnsilencing() { if (\PHP_VERSION_ID >= 70000) { @@ -128,6 +145,7 @@ class ChildTestingStacking extends TestingStacking { function foo($bar) {} } /** * @expectedException \RuntimeException + * @expectedExceptionMessage Case mismatch between loaded and declared class names */ public function testNameCaseMismatch() { @@ -149,6 +167,7 @@ class_exists(__NAMESPACE__.'\Fixtures\CaseMismatch', true); /** * @expectedException \RuntimeException + * @expectedExceptionMessage Case mismatch between loaded and declared class names */ public function testPsr4CaseMismatch() { diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/Throwing.php b/src/Symfony/Component/Debug/Tests/Fixtures/Throwing.php new file mode 100644 index 0000000000000..21e0aba17d358 --- /dev/null +++ b/src/Symfony/Component/Debug/Tests/Fixtures/Throwing.php @@ -0,0 +1,3 @@ + Date: Sun, 27 Aug 2017 10:38:05 +0200 Subject: [PATCH 73/80] [VarDumper] Enhance docblock to tell about AbstractDumper::dumpLine(-1) --- src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php b/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php index abbe9629540ba..cd892a9687e0c 100644 --- a/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php @@ -160,7 +160,8 @@ public function dump(Data $data, $output = null) /** * Dumps the current line. * - * @param int $depth The recursive depth in the dumped structure for the line being dumped + * @param int $depth The recursive depth in the dumped structure for the line being dumped, + * or -1 to signal the end-of-dump to the line dumper callable */ protected function dumpLine($depth) { From 6fe9072c42c3b3e3467a196491d2c4165f9decc7 Mon Sep 17 00:00:00 2001 From: Phil Taylor Date: Sun, 27 Aug 2017 14:23:17 +0100 Subject: [PATCH 74/80] Fix case sensitive typo in use class name closes #24001 Simple typo fix --- .../Compiler/MergeExtensionConfigurationPass.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php index 2f1b088f92b66..041d2215bad1f 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php @@ -15,7 +15,7 @@ use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; -use Symfony\Component\DependencyInjection\Parameterbag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; /** * Merges extension configs into the container builder. From e600cd8647e68e631dfb2a0179afd248ec070d68 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 28 Aug 2017 10:20:24 +0200 Subject: [PATCH 75/80] [Cache] Use zend.detect_unicode instead of zend.multibyte --- .../Component/Cache/Adapter/PhpArrayAdapter.php | 2 +- .../Component/Cache/Adapter/PhpFilesAdapter.php | 2 +- src/Symfony/Component/Cache/Simple/PhpArrayCache.php | 2 +- src/Symfony/Component/Cache/Simple/PhpFilesCache.php | 2 +- src/Symfony/Component/Cache/Traits/PhpArrayTrait.php | 10 +++++----- src/Symfony/Component/Cache/Traits/PhpFilesTrait.php | 10 +++++----- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php index 889a97f80a5fb..7e9686a01855e 100644 --- a/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/PhpArrayAdapter.php @@ -38,7 +38,7 @@ public function __construct($file, AdapterInterface $fallbackPool) { $this->file = $file; $this->fallbackPool = $fallbackPool; - $this->zendMultiByte = ini_get('zend.multibyte'); + $this->zendDetectUnicode = ini_get('zend.detect_unicode'); $this->createCacheItem = \Closure::bind( function ($key, $value, $isHit) { $item = new CacheItem(); diff --git a/src/Symfony/Component/Cache/Adapter/PhpFilesAdapter.php b/src/Symfony/Component/Cache/Adapter/PhpFilesAdapter.php index 75ac9092df024..96846e69ba29c 100644 --- a/src/Symfony/Component/Cache/Adapter/PhpFilesAdapter.php +++ b/src/Symfony/Component/Cache/Adapter/PhpFilesAdapter.php @@ -35,6 +35,6 @@ public function __construct($namespace = '', $defaultLifetime = 0, $directory = $e = new \Exception(); $this->includeHandler = function () use ($e) { throw $e; }; - $this->zendMultiByte = ini_get('zend.multibyte'); + $this->zendDetectUnicode = ini_get('zend.detect_unicode'); } } diff --git a/src/Symfony/Component/Cache/Simple/PhpArrayCache.php b/src/Symfony/Component/Cache/Simple/PhpArrayCache.php index d4c3926548ca3..92180e63168bc 100644 --- a/src/Symfony/Component/Cache/Simple/PhpArrayCache.php +++ b/src/Symfony/Component/Cache/Simple/PhpArrayCache.php @@ -34,7 +34,7 @@ public function __construct($file, CacheInterface $fallbackPool) { $this->file = $file; $this->fallbackPool = $fallbackPool; - $this->zendMultiByte = ini_get('zend.multibyte'); + $this->zendDetectUnicode = ini_get('zend.detect_unicode'); } /** diff --git a/src/Symfony/Component/Cache/Simple/PhpFilesCache.php b/src/Symfony/Component/Cache/Simple/PhpFilesCache.php index 02273ada7a32a..dd92a8a03bd67 100644 --- a/src/Symfony/Component/Cache/Simple/PhpFilesCache.php +++ b/src/Symfony/Component/Cache/Simple/PhpFilesCache.php @@ -35,6 +35,6 @@ public function __construct($namespace = '', $defaultLifetime = 0, $directory = $e = new \Exception(); $this->includeHandler = function () use ($e) { throw $e; }; - $this->zendMultiByte = ini_get('zend.multibyte'); + $this->zendDetectUnicode = ini_get('zend.detect_unicode'); } } diff --git a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php index b57e4e0b98de3..ccc48886d0cc3 100644 --- a/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpArrayTrait.php @@ -25,7 +25,7 @@ trait PhpArrayTrait private $file; private $values; private $fallbackPool; - private $zendMultiByte; + private $zendDetectUnicode; /** * Store an array of cached values. @@ -127,14 +127,14 @@ public function clear() */ private function initialize() { - if ($this->zendMultiByte) { - $zmb = ini_set('zend.multibyte', 0); + if ($this->zendDetectUnicode) { + $zmb = ini_set('zend.detect_unicode', 0); } try { $this->values = file_exists($this->file) ? (include $this->file ?: array()) : array(); } finally { - if ($this->zendMultiByte) { - ini_set('zend.multibyte', $zmb); + if ($this->zendDetectUnicode) { + ini_set('zend.detect_unicode', $zmb); } } } diff --git a/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php b/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php index d9d976a023a30..d40a947badd21 100644 --- a/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php +++ b/src/Symfony/Component/Cache/Traits/PhpFilesTrait.php @@ -25,7 +25,7 @@ trait PhpFilesTrait use FilesystemCommonTrait; private $includeHandler; - private $zendMultiByte; + private $zendDetectUnicode; public static function isSupported() { @@ -40,8 +40,8 @@ protected function doFetch(array $ids) $values = array(); $now = time(); - if ($this->zendMultiByte) { - $zmb = ini_set('zend.multibyte', 0); + if ($this->zendDetectUnicode) { + $zmb = ini_set('zend.detect_unicode', 0); } set_error_handler($this->includeHandler); try { @@ -58,8 +58,8 @@ protected function doFetch(array $ids) } } finally { restore_error_handler(); - if ($this->zendMultiByte) { - ini_set('zend.multibyte', $zmb); + if ($this->zendDetectUnicode) { + ini_set('zend.detect_unicode', $zmb); } } From 30336ead94e6a4014d3e21d3148c5ebb4bfe497f Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 22 Aug 2017 18:43:40 +0200 Subject: [PATCH 76/80] install PHPUnit 6 on PHP 7.2 --- src/Symfony/Bridge/PhpUnit/CHANGELOG.md | 5 +++++ src/Symfony/Bridge/PhpUnit/bin/simple-phpunit | 13 +++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/CHANGELOG.md b/src/Symfony/Bridge/PhpUnit/CHANGELOG.md index 1cb07da782b6d..7f1ac2e3fa9c3 100644 --- a/src/Symfony/Bridge/PhpUnit/CHANGELOG.md +++ b/src/Symfony/Bridge/PhpUnit/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +3.4.0 +----- + + * PHPUnit 6 is installed when using PHP 7.2+ + 3.3.0 ----- diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit index 4683682a1bf6e..c19d30f4af9e6 100755 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit @@ -15,8 +15,17 @@ error_reporting(-1); -// PHPUnit 4.8 does not support PHP 7, while 5.1 requires PHP 5.6+ -$PHPUNIT_VERSION = PHP_VERSION_ID >= 50600 ? getenv('SYMFONY_PHPUNIT_VERSION') ?: '5.7' : '4.8'; +if (PHP_VERSION_ID >= 70200) { + // PHPUnit 6 is required for PHP 7.2+ + $PHPUNIT_VERSION = getenv('SYMFONY_PHPUNIT_VERSION') ?: '6.3'; +} elseif (PHP_VERSION_ID >= 50600) { + // PHPUnit 4 does not support PHP 7 + $PHPUNIT_VERSION = getenv('SYMFONY_PHPUNIT_VERSION') ?: '5.7'; +} else { + // PHPUnit 5.1 requires PHP 5.6+ + $PHPUNIT_VERSION = '4.8'; +} + $oldPwd = getcwd(); $PHPUNIT_DIR = getenv('SYMFONY_PHPUNIT_DIR') ?: (__DIR__.'/.phpunit'); $PHP = defined('PHP_BINARY') ? PHP_BINARY : 'php'; From 2230e317270db3b77eaeb9552f03dfbc9952adfc Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Aug 2017 04:33:29 -0700 Subject: [PATCH 77/80] removed obsolete comment --- src/Symfony/Bridge/PhpUnit/CHANGELOG.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/CHANGELOG.md b/src/Symfony/Bridge/PhpUnit/CHANGELOG.md index 7f1ac2e3fa9c3..1cb07da782b6d 100644 --- a/src/Symfony/Bridge/PhpUnit/CHANGELOG.md +++ b/src/Symfony/Bridge/PhpUnit/CHANGELOG.md @@ -1,11 +1,6 @@ CHANGELOG ========= -3.4.0 ------ - - * PHPUnit 6 is installed when using PHP 7.2+ - 3.3.0 ----- From baaff20f4aa3b587617c05e201208527922871fd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 28 Aug 2017 17:40:54 +0200 Subject: [PATCH 78/80] [DI] Fix tracking env vars when merging configs (bis) --- .../MergeExtensionConfigurationPass.php | 62 +++++++------------ .../DependencyInjection/ContainerBuilder.php | 6 ++ .../MergeExtensionConfigurationPassTest.php | 11 +++- 3 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php index 041d2215bad1f..3e4acf5664e76 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php @@ -45,12 +45,14 @@ public function process(ContainerBuilder $container) // this extension was not called continue; } - // EnvPlaceholderParameterBag tracks env vars when calling resolveValue(). - // Clone so that tracking is done in a dedicated bag. - $resolvingBag = clone $container->getParameterBag(); + $resolvingBag = $container->getParameterBag(); + if ($resolvingBag instanceof EnvPlaceholderParameterBag && $extension instanceof Extension) { + // create a dedicated bag so that we can track env vars per-extension + $resolvingBag = new MergeExtensionConfigurationParameterBag($resolvingBag); + } $config = $resolvingBag->resolveValue($config); - $tmpContainer = new ContainerBuilder($container->getParameterBag()); + $tmpContainer = new ContainerBuilder($resolvingBag); $tmpContainer->setResourceTracking($container->isTrackingResources()); $tmpContainer->addObjectResource($extension); if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) { @@ -63,13 +65,9 @@ public function process(ContainerBuilder $container) $extension->load($config, $tmpContainer); - if ($resolvingBag instanceof EnvPlaceholderParameterBag) { - // $resolvingBag keeps track of env vars encoutered *before* merging configs - if ($extension instanceof Extension) { - // but we don't want to keep track of env vars that are *overridden* when configs are merged - $resolvingBag = new MergeExtensionConfigurationParameterBag($extension, $resolvingBag); - } - $container->getParameterBag()->mergeEnvPlaceholders($resolvingBag); + if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) { + // don't keep track of env vars that are *overridden* when configs are merged + $resolvingBag->freezeAfterProcessing($extension); } $container->merge($tmpContainer); @@ -86,21 +84,18 @@ public function process(ContainerBuilder $container) */ class MergeExtensionConfigurationParameterBag extends EnvPlaceholderParameterBag { - private $beforeProcessingEnvPlaceholders; + private $processedEnvPlaceholders; - public function __construct(Extension $extension, parent $resolvingBag) + public function __construct(parent $parameterBag) { - $this->beforeProcessingEnvPlaceholders = $resolvingBag->getEnvPlaceholders(); - $config = $this->resolveEnvPlaceholders($extension->getProcessedConfigs()); - parent::__construct($this->resolveValue($config)); + parent::__construct($parameterBag->all()); + $this->mergeEnvPlaceholders($parameterBag); } - /** - * {@inheritdoc} - */ - public function get($name) + public function freezeAfterProcessing(Extension $extension) { - return $this->has($name) || (0 === strpos($name, 'env(') && ')' === substr($name, -1) && 'env()' !== $name) ? parent::get($name) : ''; + $this->processedEnvPlaceholders = array(); + $this->processMergedConfig($extension->getProcessedConfigs(), parent::getEnvPlaceholders()); } /** @@ -108,33 +103,22 @@ public function get($name) */ public function getEnvPlaceholders() { - // contains the list of env vars that are still used after configs have been merged - $envPlaceholders = parent::getEnvPlaceholders(); - - foreach ($envPlaceholders as $env => $placeholders) { - if (isset($this->beforeProcessingEnvPlaceholders[$env])) { - // for still-used env vars, keep track of their before-processing placeholders - $envPlaceholders[$env] += $this->beforeProcessingEnvPlaceholders[$env]; - } - } - - return $envPlaceholders; + return null !== $this->processedEnvPlaceholders ? $this->processedEnvPlaceholders : parent::getEnvPlaceholders(); } - /** - * Replaces-back env placeholders to their original "%env(FOO)%" version. - */ - private function resolveEnvPlaceholders($value) + private function processMergedConfig($value, array $envPlaceholders) { if (is_array($value)) { foreach ($value as $k => $v) { - $value[$this->resolveEnvPlaceholders($k)] = $this->resolveEnvPlaceholders($v); + $this->processMergedConfig($k, $envPlaceholders); + $this->processMergedConfig($v, $envPlaceholders); } } elseif (is_string($value)) { - foreach ($this->beforeProcessingEnvPlaceholders as $env => $placeholders) { + foreach ($envPlaceholders as $env => $placeholders) { foreach ($placeholders as $placeholder) { if (false !== stripos($value, $placeholder)) { - $value = str_ireplace($placeholder, "%env($env)%", $value); + $this->processedEnvPlaceholders[$env] = $placeholders; + break; } } } diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 2e8afa6545414..698080b9715e8 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -641,10 +641,16 @@ public function merge(ContainerBuilder $container) } if ($this->getParameterBag() instanceof EnvPlaceholderParameterBag && $container->getParameterBag() instanceof EnvPlaceholderParameterBag) { + $envPlaceholders = $container->getParameterBag()->getEnvPlaceholders(); $this->getParameterBag()->mergeEnvPlaceholders($container->getParameterBag()); + } else { + $envPlaceholders = array(); } foreach ($container->envCounters as $env => $count) { + if (!$count && !isset($envPlaceholders[$env])) { + continue; + } if (!isset($this->envCounters[$env])) { $this->envCounters[$env] = $count; } else { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/MergeExtensionConfigurationPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/MergeExtensionConfigurationPassTest.php index 3934418474bd6..033e6c00fc342 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/MergeExtensionConfigurationPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/MergeExtensionConfigurationPassTest.php @@ -76,12 +76,13 @@ public function testOverriddenEnvsAreMerged() $container = new ContainerBuilder(); $container->registerExtension(new FooExtension()); $container->prependExtensionConfig('foo', array('bar' => '%env(FOO)%')); - $container->prependExtensionConfig('foo', array('bar' => '%env(BAR)%')); + $container->prependExtensionConfig('foo', array('bar' => '%env(BAR)%', 'baz' => '%env(BAZ)%')); $pass = new MergeExtensionConfigurationPass(); $pass->process($container); - $this->assertSame(array('FOO'), array_keys($container->getParameterBag()->getEnvPlaceholders())); + $this->assertSame(array('FOO', 'BAZ'), array_keys($container->getParameterBag()->getEnvPlaceholders())); + $this->assertSame(array('BAZ' => 1, 'FOO' => 0), $container->getEnvCounters()); } } @@ -94,6 +95,7 @@ public function getConfigTreeBuilder() $rootNode ->children() ->scalarNode('bar')->end() + ->scalarNode('baz')->end() ->end(); return $treeBuilder; @@ -116,5 +118,10 @@ public function load(array $configs, ContainerBuilder $container) { $configuration = $this->getConfiguration($configs, $container); $config = $this->processConfiguration($configuration, $configs); + + if (isset($config['baz'])) { + $container->getParameterBag()->get('env(BOZ)'); + $container->resolveEnvPlaceholders($config['baz']); + } } } From 2a7cf1993cfd9f2a029e690546f932fd47fa2882 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Aug 2017 12:34:07 -0700 Subject: [PATCH 79/80] updated CHANGELOG for 3.3.7 --- CHANGELOG-3.3.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/CHANGELOG-3.3.md b/CHANGELOG-3.3.md index e005c1dabe0d0..185d1432cc409 100644 --- a/CHANGELOG-3.3.md +++ b/CHANGELOG-3.3.md @@ -7,6 +7,46 @@ in 3.3 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.3.0...v3.3.1 +* 3.3.7 (2017-08-28) + + * bug #24009 [DI] Fix tracking env vars when merging configs (bis) (nicolas-grekas) + * bug #23952 [PhpUnitBridge] install PHPUnit 6 on PHP 7.2 (xabbuh) + * bug #23985 [Cache] Workaround zend.detect_unicode + zend.multibyte (nicolas-grekas) + * bug #23989 [Debug] Remove false-positive check in DebugClassLoader (nicolas-grekas) + * bug #23983 [VarDumper] Strengthen dumped JS (nicolas-grekas) + * bug #23982 [VarDumper] Strengthen dumped JS (nicolas-grekas) + * bug #23925 [Validator] Fix use of GroupSequenceProvider in child classes (linniksa) + * bug #23971 [Cache] Fix lazy Memcached connections (nicolas-grekas) + * bug #23970 [Cache] Fix >30 days expirations with Memcached (nicolas-grekas) + * bug #23949 [Dotenv] Get env using $_SERVER to work with fastcgi_param and workaround thread safety issues (nicolas-grekas) + * bug #23799 [Dotenv][WebServerBundle] Override previously loaded variables (voronkovich) + * bug #23676 [WebProfilerBundle] Re add missing link to the controller (lyrixx) + * bug #23870 [DI] Use GlobResource for non-tracked directories (vudaltsov) + * bug #23945 [Validator] Fix Greek translation (azhurb) + * bug #23940 [DI] Fix resolving env vars when compiling a ContainerBuilder (nicolas-grekas) + * bug #23903 [DI] Fix merging of env vars in configs (nicolas-grekas) + * bug #23825 Revert "feature #21038 [FrameworkBundle] deprecated cache:clear with warmup (fabpot)" (nicolas-grekas) + * bug #23899 [DI] Fix reading env vars from fastcgi params (nicolas-grekas) + * bug #23909 [Console] Initialize lazily to render exceptions properly (nicolas-grekas) + * bug #23878 [VarDumper] play nice with open_basedir when looking for composer.json (nicolas-grekas) + * bug #23897 Allow phpdocumentor/reflection-docblock 4 (derrabus) + * bug #23865 [Workflow] fixed InvalidDefinitionException message for StateMachineValidator (fmata) + * bug #23856 [DI] Fix dumping abstract with YamlDumper (nicolas-grekas) + * bug #23848 restrict reflection doc block (ElectricMaxxx) + * bug #23854 [DI] Fix YamlDumper not dumping abstract and autoconfigure (nicolas-grekas) + * bug #23752 Ignore memcached missing key error on session destroy (jderusse) + * bug #23829 Fixed the exception page design in responsive mode (javiereguiluz) + * bug #23828 [Console] Log exit codes as debug messages instead of errors (haroldiedema) + * bug #23763 [Cache] Hash cache key on save (lstrojny) + * bug #23806 [Profiler] Fix request_collector check in main layout (ogizanagi) + * bug #23658 [HttpFoundation] Generate safe fallback filename for wrongly encoded filename (xelaris) + * bug #23776 [FrameworkBundle] Warmup annotations for bundle-less controllers and entities (nicolas-grekas) + * bug #23783 Avoid infinite loops when profiler data is malformed (javiereguiluz) + * bug #23638 [FrameworkBundle][Workflow] better errors when security deps are missing (xabbuh) + * bug #23729 [Bridge\ProxyManager] Dont call __destruct() on non-instantiated services (nicolas-grekas) + * bug #23703 Bump minimal PHP version to ^5.5.9|>=7.0.8 (nicolas-grekas) + * bug #23755 [Config] Fix checking class existence freshness (nicolas-grekas) + * 3.3.6 (2017-08-01) * bug #22244 [Console] Fix passing options with defaultCommand (Jakub Sacha) From 8a33ecb05842c8db497811df10b8cd93324ca351 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 28 Aug 2017 12:34:14 -0700 Subject: [PATCH 80/80] updated VERSION for 3.3.7 --- 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 f6a62a6341cfa..815841ec6c84f 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -61,12 +61,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface private $projectDir; - const VERSION = '3.3.7-DEV'; + const VERSION = '3.3.7'; const VERSION_ID = 30307; const MAJOR_VERSION = 3; const MINOR_VERSION = 3; const RELEASE_VERSION = 7; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '01/2018'; const END_OF_LIFE = '07/2018';