From 6954a071915dc2a4d214ade0a6041eae8bbceb22 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 12 Nov 2016 12:41:58 +0100 Subject: [PATCH 01/56] [Doctrine][Form] support large integers --- .../Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php | 2 +- .../Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php index 632cdbfec0558..8930dc9f27377 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php @@ -104,7 +104,7 @@ public function getEntitiesByIds($identifier, array $values) // Filter out non-integer values (e.g. ""). If we don't, some // databases such as PostgreSQL fail. $values = array_values(array_filter($values, function ($v) { - return (string) $v === (string) (int) $v; + return (string) $v === (string) (int) $v || ctype_digit($v); })); } elseif ('guid' === $metadata->getTypeOfField($identifier)) { $parameterType = Connection::PARAM_STR_ARRAY; diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php index d755af5430bc4..1f07b8e465db0 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php @@ -87,7 +87,7 @@ public function testFilterNonIntegerValues() $query->expects($this->once()) ->method('setParameter') - ->with('ORMQueryBuilderLoader_getEntitiesByIds_id', array(1, 2, 3), Connection::PARAM_INT_ARRAY) + ->with('ORMQueryBuilderLoader_getEntitiesByIds_id', array(1, 2, 3, '9223372036854775808'), Connection::PARAM_INT_ARRAY) ->willReturn($query); $qb = $this->getMockBuilder('Doctrine\ORM\QueryBuilder') @@ -103,7 +103,7 @@ public function testFilterNonIntegerValues() ->from('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity', 'e'); $loader = new ORMQueryBuilderLoader($qb); - $loader->getEntitiesByIds('id', array(1, '', 2, 3, 'foo')); + $loader->getEntitiesByIds('id', array(1, '', 2, 3, 'foo', '9223372036854775808')); } public function testEmbeddedIdentifierName() From af9016fa279e409468aa71c4dcb648c3f1d268bd Mon Sep 17 00:00:00 2001 From: Indra Gunawan Date: Wed, 16 Nov 2016 16:46:48 +0700 Subject: [PATCH 02/56] [Validator] improve and added more Indonesian translation. --- .../Resources/translations/validators.id.xlf | 58 ++++++++++++++----- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.id.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.id.xlf index 742f4a163ebd6..c7061470dc16a 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.id.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.id.xlf @@ -36,11 +36,11 @@ This field was not expected. - Bidang ini tidak diharapkan. + Ruas ini tidak diharapkan. This field is missing. - Bidang ini hilang. + Ruas ini hilang. This value is not a valid date. @@ -52,15 +52,15 @@ This value is not a valid email address. - Nilai ini bukan alamat email yang sah. + Nilai ini bukan alamat surel yang sah. The file could not be found. - Berkas tidak ditemukan. + Berkas tidak dapat ditemukan. The file is not readable. - Berkas tidak bisa dibaca. + Berkas tidak dapat dibaca. The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}. @@ -68,7 +68,7 @@ The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}. - Jenis berkas ({{ type }}) tidak sah. Jenis berkas yang diijinkan adalah {{ types }}. + Jenis berkas ({{ type }}) tidak sah. Jenis berkas yang diizinkan adalah {{ types }}. This value should be {{ limit }} or less. @@ -116,7 +116,7 @@ The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}. - Ukuran berkas terlalu besar. Ukuran maksimum yang diijinkan adalah {{ limit }} {{ suffix }}. + Ukuran berkas terlalu besar. Ukuran maksimum yang diizinkan adalah {{ limit }} {{ suffix }}. The file is too large. @@ -132,7 +132,7 @@ This file is not a valid image. - Berkas ini tidak termasuk gambar. + Berkas ini tidak termasuk citra. This is not a valid IP address. @@ -156,23 +156,23 @@ The size of the image could not be detected. - Ukuran dari gambar tidak bisa dideteksi. + Ukuran dari citra tidak bisa dideteksi. The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px. - Lebar gambar terlalu besar ({{ width }}px). Ukuran lebar maksimum adalah {{ max_width }}px. + Lebar citra terlalu besar ({{ width }}px). Ukuran lebar maksimum adalah {{ max_width }}px. The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px. - Lebar gambar terlalu kecil ({{ width }}px). Ukuran lebar minimum yang diharapkan adalah {{ min_width }}px. + Lebar citra terlalu kecil ({{ width }}px). Ukuran lebar minimum yang diharapkan adalah {{ min_width }}px. The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px. - Tinggi gambar terlalu besar ({{ height }}px). Ukuran tinggi maksimum adalah {{ max_height }}px. + Tinggi citra terlalu besar ({{ height }}px). Ukuran tinggi maksimum adalah {{ max_height }}px. The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px. - Tinggi gambar terlalu kecil ({{ height }}px). Ukuran tinggi minimum yang diharapkan adalah {{ min_height }}px. + Tinggi citra terlalu kecil ({{ height }}px). Ukuran tinggi minimum yang diharapkan adalah {{ min_height }}px. This value should be the user's current password. @@ -278,6 +278,38 @@ This value should not be identical to {{ compared_value_type }} {{ compared_value }}. Nilai ini seharusnya tidak identik dengan {{ compared_value_type }} {{ compared_value }}. + + The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}. + Rasio citra terlalu besar ({{ ratio }}). Rasio maksimum yang diizinkan adalah {{ max_ratio }}. + + + The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}. + Rasio citra terlalu kecil ({{ ratio }}). Rasio minimum yang diharapkan adalah {{ min_ratio }}. + + + The image is square ({{ width }}x{{ height }}px). Square images are not allowed. + Citra persegi ({{ width }}x{{ height }}px). Citra persegi tidak diizinkan. + + + The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed. + Citra berorientasi lanskap ({{ width }}x{{ height }}px). Citra berorientasi lanskap tidak diizinkan. + + + The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. + Citra berorientasi potret ({{ width }}x{{ height }}px). Citra berorientasi potret tidak diizinkan. + + + An empty file is not allowed. + Berkas kosong tidak diizinkan. + + + The host could not be resolved. + Host tidak dapat diselesaikan. + + + This value does not match the expected {{ charset }} charset. + Nilai ini tidak memenuhi set karakter {{ charset }} yang diharapkan. + From f376cdeb0a18792d91ad8b099cbb97ac53fb50eb Mon Sep 17 00:00:00 2001 From: Julien Falque Date: Wed, 16 Nov 2016 19:56:22 +0100 Subject: [PATCH 03/56] Fix time-sensitive tests that use data providers --- src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php index 646a9c2e6f1dd..5e34792f9c0f1 100644 --- a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php +++ b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php @@ -134,7 +134,7 @@ public function addSkippedTest(\PHPUnit_Framework_Test $test, \Exception $e, $ti public function startTest(\PHPUnit_Framework_Test $test) { if (-2 < $this->state && $test instanceof \PHPUnit_Framework_TestCase) { - $groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName()); + $groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName(false)); if (in_array('time-sensitive', $groups, true)) { ClockMock::register(get_class($test)); @@ -146,7 +146,7 @@ public function startTest(\PHPUnit_Framework_Test $test) public function endTest(\PHPUnit_Framework_Test $test, $time) { if (-2 < $this->state && $test instanceof \PHPUnit_Framework_TestCase) { - $groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName()); + $groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName(false)); if (in_array('time-sensitive', $groups, true)) { ClockMock::withClockMock(false); From 127af5765ce790c89ac3acb337ed1f20b628d09c Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Wed, 16 Nov 2016 19:01:25 +0100 Subject: [PATCH 04/56] [DoctrineBridge] Fix deprecation message/documentation of implementing UserProviderInterface using the entity provider --- UPGRADE-2.8.md | 5 +++++ UPGRADE-3.0.md | 3 +++ src/Symfony/Bridge/Doctrine/CHANGELOG.md | 6 ++++++ .../Bridge/Doctrine/Security/User/EntityUserProvider.php | 2 +- .../Doctrine/Tests/Security/User/EntityUserProviderTest.php | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/UPGRADE-2.8.md b/UPGRADE-2.8.md index ae87a131a9d17..1d299af3e63a4 100644 --- a/UPGRADE-2.8.md +++ b/UPGRADE-2.8.md @@ -658,3 +658,8 @@ Routing // url generated in @router service $router->generate('blog_show', array('slug' => 'my-blog-post'), UrlGeneratorInterface::ABSOLUTE_URL); ``` + +DoctrineBridge +-------------- + * Deprecated using the entity provider with a Doctrine repository implementing `UserProviderInterface`. + Make it implement `UserLoaderInterface` instead. diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md index f6bd000ad129d..d5b4842eb7a72 100644 --- a/UPGRADE-3.0.md +++ b/UPGRADE-3.0.md @@ -202,6 +202,9 @@ UPGRADE FROM 2.x to 3.0 closures, but the closure is now resolved in the type instead of in the loader. + * Using the entity provider with a Doctrine repository implementing `UserProviderInterface` is not supported anymore. + You should make the repository implement `UserLoaderInterface` instead. + ### EventDispatcher * The interface `Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface` diff --git a/src/Symfony/Bridge/Doctrine/CHANGELOG.md b/src/Symfony/Bridge/Doctrine/CHANGELOG.md index 4d8c44701dd3a..71a2707bab709 100644 --- a/src/Symfony/Bridge/Doctrine/CHANGELOG.md +++ b/src/Symfony/Bridge/Doctrine/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +2.8.0 +----- + + * deprecated using the entity provider with a Doctrine repository implementing UserProviderInterface + * added UserLoaderInterface for loading users through Doctrine. + 2.7.0 ----- diff --git a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php index 2882fd6ddd523..f67b4c9c3c8ac 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php @@ -55,7 +55,7 @@ public function loadUserByUsername($username) throw new \InvalidArgumentException(sprintf('You must either make the "%s" entity Doctrine Repository ("%s") implement "Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface" or set the "property" option in the corresponding entity provider configuration.', $this->classOrAlias, get_class($repository))); } - @trigger_error('Implementing loadUserByUsername from Symfony\Component\Security\Core\User\UserProviderInterface is deprecated since version 2.8 and will be removed in 3.0. Implement the Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface instead.', E_USER_DEPRECATED); + @trigger_error('Implementing Symfony\Component\Security\Core\User\UserProviderInterface in a Doctrine repository when using the entity provider is deprecated since version 2.8 and will not be supported in 3.0. Make the repository implement Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface instead.', E_USER_DEPRECATED); } $user = $repository->loadUserByUsername($username); diff --git a/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php index a4c1a77152a75..56d590b109b2c 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Security/User/EntityUserProviderTest.php @@ -81,6 +81,7 @@ public function testLoadUserByUsernameWithUserLoaderRepositoryAndWithoutProperty /** * @group legacy + * @expectedDeprecation Implementing Symfony\Component\Security\Core\User\UserProviderInterface in a Doctrine repository when using the entity provider is deprecated since version 2.8 and will not be supported in 3.0. Make the repository implement Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface instead. */ public function testLoadUserByUsernameWithUserProviderRepositoryAndWithoutProperty() { From 8e0da2f39ea26c8c83f00eb9bf6303239e14202f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 16 Nov 2016 19:37:44 -0500 Subject: [PATCH 05/56] [DI] Fix error when trying to resolve a DefinitionDecorator --- .../DependencyInjection/ContainerBuilder.php | 4 ++++ .../Tests/ContainerBuilderTest.php | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 6814d28e73116..7c9f5a243190a 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -840,6 +840,10 @@ public function findDefinition($id) */ public function createService(Definition $definition, $id, $tryProxy = true) { + if ('Symfony\Component\DependencyInjection\Definition' !== get_class($definition)) { + throw new RuntimeException(sprintf('Constructing service "%s" from a %s is not supported at build time.', $id, get_class($definition))); + } + if ($definition->isSynthetic()) { throw new RuntimeException(sprintf('You have requested a synthetic service ("%s"). The DIC does not know how to construct this service.', $id)); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index eab8fccbdfcaa..8f8c8b179f790 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -19,6 +19,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Exception\InactiveScopeException; use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; @@ -404,6 +405,20 @@ public function testResolveServices() $this->assertEquals($builder->get('foo'), $builder->resolveServices(new Expression('service("foo")')), '->resolveServices() resolves expressions'); } + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException + * @expectedExceptionMessage Constructing service "foo" from a Symfony\Component\DependencyInjection\DefinitionDecorator is not supported at build time. + */ + public function testResolveServicesWithDecoratedDefinition() + { + $builder = new ContainerBuilder(); + $builder->setDefinition('grandpa', new Definition('stdClass')); + $builder->setDefinition('parent', new DefinitionDecorator('grandpa')); + $builder->setDefinition('foo', new DefinitionDecorator('parent')); + + $builder->get('foo'); + } + public function testMerge() { $container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo'))); From c30ec36f216895d4f1c6ec62e4130b82fcedc66c Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Thu, 17 Nov 2016 21:40:35 +0100 Subject: [PATCH 06/56] Fixed generation mistake in changelog --- CHANGELOG-3.2.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CHANGELOG-3.2.md b/CHANGELOG-3.2.md index 80a81116bae33..b1fe6f167c120 100644 --- a/CHANGELOG-3.2.md +++ b/CHANGELOG-3.2.md @@ -7,10 +7,6 @@ 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.0-RC1 (2016-11-17) - - * - * 3.2.0-RC1 (2016-11-17) * feature #20533 [DI] Revert "deprecate get() for uncompiled container builders" (nicolas-grekas) From bc25e08bb5ed6d9963114d3100c90b443e10385e Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 17 Nov 2016 15:47:16 -0500 Subject: [PATCH 07/56] bumped Symfony version to 3.2.0 --- 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 e4ca24c4851cf..f1013f23c61b2 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.0-RC1'; + const VERSION = '3.2.0-DEV'; const VERSION_ID = 30200; const MAJOR_VERSION = 3; const MINOR_VERSION = 2; const RELEASE_VERSION = 0; - const EXTRA_VERSION = 'RC1'; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '07/2017'; const END_OF_LIFE = '01/2018'; From 55e134cab0173c484cb9ed3f0252a4609f90ab7b Mon Sep 17 00:00:00 2001 From: Pierre-Chanel Gauthier Date: Fri, 18 Nov 2016 18:16:13 +0100 Subject: [PATCH 08/56] Fix annotation type for $context Previous type ExecutionContextInterface was referring to a non declared namespace. Replacing it by ExecutionContextInterface2Dot5 fixes autocomplete. --- src/Symfony/Component/Validator/ConstraintValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/ConstraintValidator.php b/src/Symfony/Component/Validator/ConstraintValidator.php index b156c6dde9a16..804a9b2a193ec 100644 --- a/src/Symfony/Component/Validator/ConstraintValidator.php +++ b/src/Symfony/Component/Validator/ConstraintValidator.php @@ -38,7 +38,7 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface const OBJECT_TO_STRING = 2; /** - * @var ExecutionContextInterface + * @var ExecutionContextInterface2Dot5 */ protected $context; From e0f9bda49aedcb6f46a20659ba3213626418627f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 17 Nov 2016 10:59:01 -0500 Subject: [PATCH 09/56] [ci] Testing with UTC hides bugs --- .travis.yml | 1 + appveyor.yml | 2 +- ...ntegerToLocalizedStringTransformerTest.php | 4 +-- .../MoneyToLocalizedStringTransformerTest.php | 4 +-- ...NumberToLocalizedStringTransformerTest.php | 34 +++++++++---------- ...ercentToLocalizedStringTransformerTest.php | 4 +-- .../Extension/Core/Type/CountryTypeTest.php | 2 +- .../Extension/Core/Type/CurrencyTypeTest.php | 2 +- .../Extension/Core/Type/DateTypeTest.php | 22 ++++++------ .../Extension/Core/Type/IntegerTypeTest.php | 2 +- .../Extension/Core/Type/LanguageTypeTest.php | 2 +- .../Extension/Core/Type/LocaleTypeTest.php | 2 +- .../Extension/Core/Type/MoneyTypeTest.php | 2 +- .../Extension/Core/Type/NumberTypeTest.php | 2 +- .../Collator/Verification/CollatorTest.php | 2 +- .../AbstractIntlDateFormatterTest.php | 4 +-- .../Verification/IntlDateFormatterTest.php | 4 ++- .../Globals/Verification/IntlGlobalsTest.php | 2 +- .../Tests/Locale/Verification/LocaleTest.php | 2 +- .../Verification/NumberFormatterTest.php | 9 ++++- .../Component/Intl/Util/IntlTestHelper.php | 29 +++++----------- .../Component/Locale/Tests/LocaleTest.php | 2 +- .../Tests/IdentityTranslatorTest.php | 2 +- .../Constraints/CountryValidatorTest.php | 2 +- .../Constraints/CurrencyValidatorTest.php | 2 +- .../Constraints/LanguageValidatorTest.php | 2 +- 26 files changed, 72 insertions(+), 75 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5e8436f831284..70e364f8f960d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,6 +47,7 @@ before_install: # A sigchild-enabled-PHP is used to test the Process component on the lowest PHP matrix line - if [[ ! $deps && $PHP = ${MIN_PHP%.*} && ! -d php-$MIN_PHP/sapi ]]; then wget http://museum.php.net/php5/php-$MIN_PHP.tar.bz2 -O - | tar -xj; (cd php-$MIN_PHP; ./configure --enable-sigchild --enable-pcntl; make -j2); fi - if [[ ! $PHP = hhvm* ]]; then INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; else INI_FILE=/etc/hhvm/php.ini; fi + - if [[ ! $skip ]]; then echo date.timezone = Europe/Paris >> $INI_FILE; fi - if [[ ! $skip ]]; then echo memory_limit = -1 >> $INI_FILE; fi - if [[ ! $skip ]]; then echo session.gc_probability = 0 >> $INI_FILE; fi - if [[ ! $skip && $PHP = 5.* ]]; then echo extension = mongo.so >> $INI_FILE; fi diff --git a/appveyor.yml b/appveyor.yml index adf63a1539493..f8162c0689ff0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -33,7 +33,7 @@ install: - cd .. - copy /Y php.ini-development php.ini-min - echo max_execution_time=1200 >> php.ini-min - - echo date.timezone="UTC" >> php.ini-min + - echo date.timezone="America/Los_Angeles" >> php.ini-min - echo extension_dir=ext >> php.ini-min - copy /Y php.ini-min php.ini-max - echo extension=php_openssl.dll >> php.ini-max diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php index c51132518ba67..b38296813c574 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/IntegerToLocalizedStringTransformerTest.php @@ -87,7 +87,7 @@ public function testTransformWithRounding($input, $output, $roundingMode) public function testReverseTransform() { // Since we test against "de_AT", we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -109,7 +109,7 @@ public function testReverseTransformEmpty() public function testReverseTransformWithGrouping() { // Since we test against "de_AT", we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php index 99e4c8a574cf2..0fa2df05641a4 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformerTest.php @@ -19,7 +19,7 @@ class MoneyToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase public function testTransform() { // Since we test against "de_AT", we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -47,7 +47,7 @@ public function testTransformEmpty() public function testReverseTransform() { // Since we test against "de_AT", we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php index 3bf8d93c8cf76..90d9719a90b72 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php @@ -42,7 +42,7 @@ public function provideTransformations() public function testTransform($from, $to, $locale) { // Since we test against other locales, we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault($locale); @@ -68,7 +68,7 @@ public function provideTransformationsWithGrouping() public function testTransformWithGrouping($from, $to, $locale) { // Since we test against other locales, we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault($locale); @@ -80,7 +80,7 @@ public function testTransformWithGrouping($from, $to, $locale) public function testTransformWithScale() { // Since we test against "de_AT", we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -185,7 +185,7 @@ public function transformWithRoundingProvider() public function testTransformWithRounding($scale, $input, $output, $roundingMode) { // Since we test against "de_AT", we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -197,7 +197,7 @@ public function testTransformWithRounding($scale, $input, $output, $roundingMode public function testTransformDoesNotRoundIfNoScale() { // Since we test against "de_AT", we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -212,7 +212,7 @@ public function testTransformDoesNotRoundIfNoScale() public function testReverseTransform($to, $from, $locale) { // Since we test against other locales, we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault($locale); @@ -227,7 +227,7 @@ public function testReverseTransform($to, $from, $locale) public function testReverseTransformWithGrouping($to, $from, $locale) { // Since we test against other locales, we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault($locale); @@ -244,7 +244,7 @@ public function testReverseTransformWithGrouping($to, $from, $locale) public function testReverseTransformWithGroupingAndFixedSpaces() { // Since we test against other locales, we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('ru'); @@ -256,7 +256,7 @@ public function testReverseTransformWithGroupingAndFixedSpaces() public function testReverseTransformWithGroupingButWithoutGroupSeparator() { // Since we test against "de_AT", we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -376,7 +376,7 @@ public function testReverseTransformDoesNotRoundIfNoScale() public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsNotDot() { // Since we test against other locales, we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('fr'); $transformer = new NumberToLocalizedStringTransformer(null, true); @@ -396,7 +396,7 @@ public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsNotDot() public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDot() { // Since we test against "de_AT", we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -411,7 +411,7 @@ public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDot() public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDotWithNoGroupSep() { // Since we test against "de_AT", we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -423,7 +423,7 @@ public function testDecimalSeparatorMayNotBeDotIfGroupingSeparatorIsDotWithNoGro public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsDotButNoGroupingUsed() { // Since we test against other locales, we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('fr'); $transformer = new NumberToLocalizedStringTransformer(); @@ -435,7 +435,7 @@ public function testDecimalSeparatorMayBeDotIfGroupingSeparatorIsDotButNoGroupin public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsNotComma() { // Since we test against other locales, we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('bg'); $transformer = new NumberToLocalizedStringTransformer(null, true); @@ -588,7 +588,7 @@ public function testReverseTransformDisallowsCenteredExtraCharacters() public function testReverseTransformDisallowsCenteredExtraCharactersMultibyte() { // Since we test against other locales, we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('ru'); @@ -605,7 +605,7 @@ public function testReverseTransformDisallowsCenteredExtraCharactersMultibyte() public function testReverseTransformIgnoresTrailingSpacesInExceptionMessage() { // Since we test against other locales, we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('ru'); @@ -633,7 +633,7 @@ public function testReverseTransformDisallowsTrailingExtraCharacters() public function testReverseTransformDisallowsTrailingExtraCharactersMultibyte() { // Since we test against other locales, we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('ru'); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php index 99f06741b90d7..c0447656f3e51 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php @@ -53,7 +53,7 @@ public function testTransformWithInteger() public function testTransformWithScale() { // Since we test against "de_AT", we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -92,7 +92,7 @@ public function testReverseTransformWithInteger() public function testReverseTransformWithScale() { // Since we test against "de_AT", we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php index 16af981e624ab..a14287c82741f 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CountryTypeTest.php @@ -19,7 +19,7 @@ class CountryTypeTest extends TestCase { protected function setUp() { - IntlTestHelper::requireIntl($this); + IntlTestHelper::requireIntl($this, false); parent::setUp(); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CurrencyTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CurrencyTypeTest.php index 2d572d60b45df..f2b096f026863 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/CurrencyTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/CurrencyTypeTest.php @@ -19,7 +19,7 @@ class CurrencyTypeTest extends TestCase { protected function setUp() { - IntlTestHelper::requireIntl($this); + IntlTestHelper::requireIntl($this, false); parent::setUp(); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php index 1672af481bd8a..ea302d020eec3 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php @@ -70,7 +70,7 @@ public function testSubmitFromSingleTextDateTimeWithDefaultFormat() public function testSubmitFromSingleTextDateTime() { // we test against "de_AT", so we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -91,7 +91,7 @@ public function testSubmitFromSingleTextDateTime() public function testSubmitFromSingleTextString() { // we test against "de_AT", so we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -112,7 +112,7 @@ public function testSubmitFromSingleTextString() public function testSubmitFromSingleTextTimestamp() { // we test against "de_AT", so we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -135,7 +135,7 @@ public function testSubmitFromSingleTextTimestamp() public function testSubmitFromSingleTextRaw() { // we test against "de_AT", so we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -399,7 +399,7 @@ public function testThrowExceptionIfDaysIsInvalid() public function testSetDataWithNegativeTimezoneOffsetStringInput() { // we test against "de_AT", so we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -421,7 +421,7 @@ public function testSetDataWithNegativeTimezoneOffsetStringInput() public function testSetDataWithNegativeTimezoneOffsetDateTimeInput() { // we test against "de_AT", so we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -495,7 +495,7 @@ public function testMonthsOptionShortFormat() public function testMonthsOptionLongFormat() { // we test against "de_AT", so we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -515,7 +515,7 @@ public function testMonthsOptionLongFormat() public function testMonthsOptionLongFormatWithDifferentTimezone() { // we test against "de_AT", so we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -621,7 +621,7 @@ public function testIsPartiallyFilledReturnsTrueIfChoiceAndDayEmpty() public function testPassDatePatternToView() { // we test against "de_AT", so we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -634,7 +634,7 @@ public function testPassDatePatternToView() public function testPassDatePatternToViewDifferentFormat() { // we test against "de_AT", so we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_AT'); @@ -682,7 +682,7 @@ public function testDontPassDatePatternIfText() public function testDatePatternFormatWithQuotedStrings() { // we test against "es_ES", so we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('es_ES'); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php index 85f91ff18126d..bad3d0881bdf1 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/IntegerTypeTest.php @@ -18,7 +18,7 @@ class IntegerTypeTest extends TestCase { protected function setUp() { - IntlTestHelper::requireIntl($this); + IntlTestHelper::requireIntl($this, false); parent::setUp(); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php index ea6255d034b6b..fb331681003e0 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LanguageTypeTest.php @@ -19,7 +19,7 @@ class LanguageTypeTest extends TestCase { protected function setUp() { - IntlTestHelper::requireIntl($this); + IntlTestHelper::requireIntl($this, false); parent::setUp(); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php index 7f6d922ec9867..f33d705b31807 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/LocaleTypeTest.php @@ -19,7 +19,7 @@ class LocaleTypeTest extends TestCase { protected function setUp() { - IntlTestHelper::requireIntl($this); + IntlTestHelper::requireIntl($this, false); parent::setUp(); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php index c499908d7713c..e454a4f07d048 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php @@ -20,7 +20,7 @@ protected function setUp() { // we test against different locales, so we need the full // implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); parent::setUp(); } diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php index f21a7d1ec47d4..90ef11efa95f2 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/NumberTypeTest.php @@ -21,7 +21,7 @@ protected function setUp() parent::setUp(); // we test against "de_DE", so we need the full implementation - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('de_DE'); } diff --git a/src/Symfony/Component/Intl/Tests/Collator/Verification/CollatorTest.php b/src/Symfony/Component/Intl/Tests/Collator/Verification/CollatorTest.php index 5da56cc9af8c8..378463cac854e 100644 --- a/src/Symfony/Component/Intl/Tests/Collator/Verification/CollatorTest.php +++ b/src/Symfony/Component/Intl/Tests/Collator/Verification/CollatorTest.php @@ -24,7 +24,7 @@ class CollatorTest extends AbstractCollatorTest { protected function setUp() { - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); parent::setUp(); } diff --git a/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php b/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php index 759b995efc85b..f2788ba469cda 100644 --- a/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php +++ b/src/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php @@ -908,9 +908,7 @@ protected function getDateTime($timestamp, $timeZone) { $dateTime = new \DateTime(); $dateTime->setTimestamp(null === $timestamp ? time() : $timestamp); - if (null !== $timeZone) { - $dateTime->setTimezone(new \DateTimeZone($timeZone)); - } + $dateTime->setTimezone(new \DateTimeZone($timeZone ?: getenv('TZ') ?: 'UTC')); return $dateTime; } diff --git a/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php b/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php index dcf38473f2e29..1754a08438dbd 100644 --- a/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php +++ b/src/Symfony/Component/Intl/Tests/DateFormatter/Verification/IntlDateFormatterTest.php @@ -25,7 +25,7 @@ class IntlDateFormatterTest extends AbstractIntlDateFormatterTest { protected function setUp() { - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); parent::setUp(); } @@ -45,6 +45,8 @@ public function testFormatWithTimezoneFromEnvironmentVariable() protected function getDateFormatter($locale, $datetype, $timetype, $timezone = null, $calendar = IntlDateFormatter::GREGORIAN, $pattern = null) { + IntlTestHelper::requireFullIntl($this, '55.1'); + if (!$formatter = new \IntlDateFormatter($locale, $datetype, $timetype, $timezone, $calendar, $pattern)) { throw new \InvalidArgumentException(intl_get_error_message()); } diff --git a/src/Symfony/Component/Intl/Tests/Globals/Verification/IntlGlobalsTest.php b/src/Symfony/Component/Intl/Tests/Globals/Verification/IntlGlobalsTest.php index c46033d8805a9..b5cd1c13c32ff 100644 --- a/src/Symfony/Component/Intl/Tests/Globals/Verification/IntlGlobalsTest.php +++ b/src/Symfony/Component/Intl/Tests/Globals/Verification/IntlGlobalsTest.php @@ -24,7 +24,7 @@ class IntlGlobalsTest extends AbstractIntlGlobalsTest { protected function setUp() { - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); parent::setUp(); } diff --git a/src/Symfony/Component/Intl/Tests/Locale/Verification/LocaleTest.php b/src/Symfony/Component/Intl/Tests/Locale/Verification/LocaleTest.php index 39d4f3cb03b36..adfec280a7997 100644 --- a/src/Symfony/Component/Intl/Tests/Locale/Verification/LocaleTest.php +++ b/src/Symfony/Component/Intl/Tests/Locale/Verification/LocaleTest.php @@ -24,7 +24,7 @@ class LocaleTest extends AbstractLocaleTest { protected function setUp() { - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); parent::setUp(); } diff --git a/src/Symfony/Component/Intl/Tests/NumberFormatter/Verification/NumberFormatterTest.php b/src/Symfony/Component/Intl/Tests/NumberFormatter/Verification/NumberFormatterTest.php index 28e6fe9090302..181b489c1564d 100644 --- a/src/Symfony/Component/Intl/Tests/NumberFormatter/Verification/NumberFormatterTest.php +++ b/src/Symfony/Component/Intl/Tests/NumberFormatter/Verification/NumberFormatterTest.php @@ -22,7 +22,7 @@ class NumberFormatterTest extends AbstractNumberFormatterTest { protected function setUp() { - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, '55.1'); parent::setUp(); } @@ -32,6 +32,13 @@ public function testCreate() $this->assertInstanceOf('\NumberFormatter', \NumberFormatter::create('en', \NumberFormatter::DECIMAL)); } + public function testGetTextAttribute() + { + IntlTestHelper::requireFullIntl($this); + + parent::testGetTextAttribute(); + } + protected function getNumberFormatter($locale = 'en', $style = null, $pattern = null) { return new \NumberFormatter($locale, $style, $pattern); diff --git a/src/Symfony/Component/Intl/Util/IntlTestHelper.php b/src/Symfony/Component/Intl/Util/IntlTestHelper.php index ecd5ed6b660d6..71fb4acdd72fa 100644 --- a/src/Symfony/Component/Intl/Util/IntlTestHelper.php +++ b/src/Symfony/Component/Intl/Util/IntlTestHelper.php @@ -28,19 +28,21 @@ class IntlTestHelper { /** * Should be called before tests that work fine with the stub implementation. - * - * @param \PhpUnit_Framework_TestCase $testCase */ - public static function requireIntl(\PHPUnit_Framework_TestCase $testCase) + public static function requireIntl(\PHPUnit_Framework_TestCase $testCase, $minimumIcuVersion = null) { + if (null === $minimumIcuVersion) { + $minimumIcuVersion = Intl::getIcuStubVersion(); + } + // We only run tests if the version is *one specific version*. // This condition is satisfied if // // * the intl extension is loaded with version Intl::getIcuStubVersion() // * the intl extension is not loaded - if (IcuVersion::compare(Intl::getIcuVersion(), Intl::getIcuStubVersion(), '!=', 1)) { - $testCase->markTestSkipped('ICU version '.Intl::getIcuStubVersion().' is required.'); + if (($minimumIcuVersion || defined('HHVM_VERSION_ID')) && IcuVersion::compare(Intl::getIcuVersion(), $minimumIcuVersion, '!=', 1)) { + $testCase->markTestSkipped('ICU version '.$minimumIcuVersion.' is required.'); } // Normalize the default locale in case this is not done explicitly @@ -60,24 +62,15 @@ public static function requireIntl(\PHPUnit_Framework_TestCase $testCase) /** * Should be called before tests that require a feature-complete intl * implementation. - * - * @param \PhpUnit_Framework_TestCase $testCase */ - public static function requireFullIntl(\PHPUnit_Framework_TestCase $testCase) + public static function requireFullIntl(\PHPUnit_Framework_TestCase $testCase, $minimumIcuVersion = null) { // We only run tests if the intl extension is loaded... if (!Intl::isExtensionLoaded()) { $testCase->markTestSkipped('Extension intl is required.'); } - // ... and only if the version is *one specific version* - if (IcuVersion::compare(Intl::getIcuVersion(), Intl::getIcuStubVersion(), '!=', 1)) { - $testCase->markTestSkipped('ICU version '.Intl::getIcuStubVersion().' is required.'); - } - - // Normalize the default locale in case this is not done explicitly - // in the test - \Locale::setDefault('en'); + self::requireIntl($testCase, $minimumIcuVersion); // Consequently, tests will // @@ -89,8 +82,6 @@ public static function requireFullIntl(\PHPUnit_Framework_TestCase $testCase) /** * Skips the test unless the current system has a 32bit architecture. - * - * @param \PhpUnit_Framework_TestCase $testCase */ public static function require32Bit(\PHPUnit_Framework_TestCase $testCase) { @@ -101,8 +92,6 @@ public static function require32Bit(\PHPUnit_Framework_TestCase $testCase) /** * Skips the test unless the current system has a 64bit architecture. - * - * @param \PhpUnit_Framework_TestCase $testCase */ public static function require64Bit(\PHPUnit_Framework_TestCase $testCase) { diff --git a/src/Symfony/Component/Locale/Tests/LocaleTest.php b/src/Symfony/Component/Locale/Tests/LocaleTest.php index 7419d2836961e..6d160a08332ba 100644 --- a/src/Symfony/Component/Locale/Tests/LocaleTest.php +++ b/src/Symfony/Component/Locale/Tests/LocaleTest.php @@ -36,7 +36,7 @@ public function testGetDisplayCountries() public function testGetDisplayCountriesForSwitzerland() { - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); $countries = Locale::getDisplayCountries('de_CH'); $this->assertEquals('Schweiz', $countries['CH']); diff --git a/src/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php b/src/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php index 352dd318dc73c..648c54afd153d 100644 --- a/src/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php +++ b/src/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php @@ -60,7 +60,7 @@ public function testGetSetLocale() public function testGetLocaleReturnsDefaultLocaleIfNotSet() { // in order to test with "pt_BR" - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); $translator = new IdentityTranslator(); diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php index ba63fd4d1c482..563af7076320e 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php @@ -96,7 +96,7 @@ public function getInvalidCountries() public function testValidateUsingCountrySpecificLocale() { // in order to test with "en_GB" - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('en_GB'); diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php index eeb782c1a520c..d24e01c2e7b8d 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/CurrencyValidatorTest.php @@ -65,7 +65,7 @@ public function testValidCurrencies($currency) **/ public function testValidCurrenciesWithCountrySpecificLocale($currency) { - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('en_GB'); diff --git a/src/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php index c10f26c88f6af..dd149b24ee90f 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php @@ -95,7 +95,7 @@ public function getInvalidLanguages() public function testValidateUsingCountrySpecificLocale() { - IntlTestHelper::requireFullIntl($this); + IntlTestHelper::requireFullIntl($this, false); \Locale::setDefault('fr_FR'); $existingLanguage = 'en'; From cdb11a7ec988ff1fa0652a993b0fb8e547a005ee Mon Sep 17 00:00:00 2001 From: Noah Heck Date: Thu, 17 Nov 2016 08:00:37 -0700 Subject: [PATCH 10/56] [YAML] Fix processing timestamp with timezone Parse date strings containing timezone data correctly Default date strings not containing timezone data to UTC --- src/Symfony/Component/Yaml/Inline.php | 6 ++---- .../Component/Yaml/Tests/InlineTest.php | 20 ++++++++++++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index 9169c592b8639..a8acf0a2afbbb 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -606,10 +606,8 @@ private static function evaluateScalar($scalar, $flags, $references = array()) return (float) str_replace(',', '', $scalar); case preg_match(self::getTimestampRegex(), $scalar): if (Yaml::PARSE_DATETIME & $flags) { - $date = new \DateTime($scalar); - $date->setTimeZone(new \DateTimeZone('UTC')); - - return $date; + // When no timezone is provided in the parsed date, YAML spec says we must assume UTC. + return new \DateTime($scalar, new \DateTimeZone('UTC')); } $timeZone = date_default_timezone_get(); diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index 83d20cc96c82a..bbafadb774a33 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -502,7 +502,7 @@ public function testParseTimestampAsUnixTimestampByDefault($yaml, $year, $month, /** * @dataProvider getTimestampTests */ - public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second) + public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second, $timezone) { $expected = new \DateTime($yaml); $expected->setTimeZone(new \DateTimeZone('UTC')); @@ -514,16 +514,18 @@ public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $ $expected->setTime($hour, $minute, $second); } - $this->assertEquals($expected, Inline::parse($yaml, Yaml::PARSE_DATETIME)); + $date = Inline::parse($yaml, Yaml::PARSE_DATETIME); + $this->assertEquals($expected, $date); + $this->assertSame($timezone, $date->format('O')); } public function getTimestampTests() { return array( - 'canonical' => array('2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43.1), - 'ISO-8601' => array('2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43.1), - 'spaced' => array('2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43.1), - 'date' => array('2001-12-15', 2001, 12, 15, 0, 0, 0), + 'canonical' => array('2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43.1, '+0000'), + 'ISO-8601' => array('2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43.1, '-0500'), + 'spaced' => array('2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43.1, '-0500'), + 'date' => array('2001-12-15', 2001, 12, 15, 0, 0, 0, '+0000'), ); } @@ -535,7 +537,11 @@ public function testParseNestedTimestampListAsDateTimeObject($yaml, $year, $mont $expected = new \DateTime($yaml); $expected->setTimeZone(new \DateTimeZone('UTC')); $expected->setDate($year, $month, $day); - @$expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second)); + if (PHP_VERSION_ID >= 70100) { + $expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second)); + } else { + $expected->setTime($hour, $minute, $second); + } $expectedNested = array('nested' => array($expected)); $yamlNested = "{nested: [$yaml]}"; From 2094715152d6419c4f95ce3caeba3075d646f9ea Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 18 Nov 2016 16:58:27 -0500 Subject: [PATCH 11/56] [Serializer] Fix test assuming UTC default TZ --- .../Serializer/Tests/Normalizer/DateTimeNormalizerTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php index e68dfe335eb29..6bf6642ff0529 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/DateTimeNormalizerTest.php @@ -77,9 +77,9 @@ public function testDenormalize() public function testDenormalizeUsingFormatPassedInContext() { - $this->assertEquals(new \DateTimeImmutable('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016.01.01', \DateTimeInterface::class, null, array(DateTimeNormalizer::FORMAT_KEY => 'Y.m.d|'))); - $this->assertEquals(new \DateTimeImmutable('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016.01.01', \DateTimeImmutable::class, null, array(DateTimeNormalizer::FORMAT_KEY => 'Y.m.d|'))); - $this->assertEquals(new \DateTime('2016/01/01', new \DateTimeZone('UTC')), $this->normalizer->denormalize('2016.01.01', \DateTime::class, null, array(DateTimeNormalizer::FORMAT_KEY => 'Y.m.d|'))); + $this->assertEquals(new \DateTimeImmutable('2016/01/01'), $this->normalizer->denormalize('2016.01.01', \DateTimeInterface::class, null, array(DateTimeNormalizer::FORMAT_KEY => 'Y.m.d|'))); + $this->assertEquals(new \DateTimeImmutable('2016/01/01'), $this->normalizer->denormalize('2016.01.01', \DateTimeImmutable::class, null, array(DateTimeNormalizer::FORMAT_KEY => 'Y.m.d|'))); + $this->assertEquals(new \DateTime('2016/01/01'), $this->normalizer->denormalize('2016.01.01', \DateTime::class, null, array(DateTimeNormalizer::FORMAT_KEY => 'Y.m.d|'))); } /** From aefd0489a9d57e9fbe533513bde7c1931f47a834 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 20 Nov 2016 17:12:23 -0800 Subject: [PATCH 12/56] updated CHANGELOG for 2.7.21 --- CHANGELOG-2.7.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG-2.7.md b/CHANGELOG-2.7.md index c6f63e1b6c2b5..fd12d3a03612e 100644 --- a/CHANGELOG-2.7.md +++ b/CHANGELOG-2.7.md @@ -7,6 +7,24 @@ 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.21 (2016-11-21) + + * bug #20543 [DI] Fix error when trying to resolve a DefinitionDecorator (nicolas-grekas) + * bug #20484 bumped min version of Twig to 1.28 (fabpot) + * bug #20519 [Debug] Remove GLOBALS from exception context to avoid endless recursion (Seldaek) + * bug #20455 [ClassLoader] Fix ClassCollectionLoader inlining with __halt_compiler (giosh94mhz) + * bug #20307 [Form] Fix Date\TimeType marked as invalid on request with single_text and zero seconds (LuisDeimos) + * bug #20466 [Translation] fixed nested fallback catalogue using multiple locales. (aitboudad) + * bug #20465 [#18637][TranslationDebug] workaround for getFallbackLocales. (aitboudad) + * bug #20440 [TwigBridge][TwigBundle][HttpKernel] prefer getSourceContext() over getSource() (xabbuh) + * bug #20422 [Translation][fallback] add missing resources in parent catalogues. (aitboudad) + * bug #20378 [Form] Fixed show float values as choice value in ChoiceType (yceruto) + * bug #20375 [HttpFoundation][Session] Fix memcache session handler (klandaika) + * bug #20377 [Console] Fix infinite loop on missing input (chalasr) + * bug #20342 [Form] Fix UrlType transforms valid protocols (ogizanagi) + * bug #20292 Enhance GAE compat by removing some realpath() (nicolas-grekas) + * bug #20321 Compatibility with Twig 1.27 (xkobal) + * 2.7.20 (2016-10-27) * bug #20289 Fix edge case with StreamedResponse where headers are sent twice (Nicofuma) From 4367d0c853363be7f26eca812f24c070e12eda2a Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 20 Nov 2016 17:12:28 -0800 Subject: [PATCH 13/56] update CONTRIBUTORS for 2.7.21 --- CONTRIBUTORS.md | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 41c883159c8e2..c5fb26e0e91d8 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -22,16 +22,16 @@ Symfony is the result of the work of many people who made the code better - Abdellatif Ait boudad (aitboudad) - Pascal Borreli (pborreli) - Wouter De Jong (wouterj) - - Joseph Bielawski (stloyd) - Romain Neutron (romain) + - Joseph Bielawski (stloyd) - Karma Dordrak (drak) - Lukas Kahwe Smith (lsmith) - Martin Hasoň (hason) - Jeremy Mikola (jmikola) - Jean-François Simon (jfsimon) + - Grégoire Pineau (lyrixx) - Benjamin Eberlei (beberlei) - Igor Wiedler (igorw) - - Grégoire Pineau (lyrixx) - Eriksen Costa (eriksencosta) - Jules Pietri (heah) - Sarah Khalil (saro0h) @@ -45,11 +45,11 @@ Symfony is the result of the work of many people who made the code better - stealth35 ‏ (stealth35) - Alexander Mols (asm89) - Bulat Shakirzyanov (avalanche123) + - Robin Chalas (chalas_r) - Saša Stamenković (umpirsky) - Henrik Bjørnskov (henrikbjorn) - Miha Vrhovnik - Diego Saint Esteben (dii3g0) - - Robin Chalas (chalas_r) - Ener-Getick (energetick) - Konstantin Kudryashov (everzet) - Bilal Amarni (bamarni) @@ -84,19 +84,19 @@ 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) + - Roland Franssen (ro0) + - Dariusz Ruminski - Jáchym Toušek (enumag) - Arnaud Le Blanc (arnaud-lb) - Jérôme Tamarelle (gromnan) - Michal Piotrowski (eventhorizon) - Tim Nagel (merk) - - Dariusz Ruminski - Brice BERNARD (brikou) - Alexander M. Turek (derrabus) - marc.weistroff - Issei Murasawa (issei_m) - lenar - Włodzimierz Gajda (gajdaw) - - Roland Franssen (ro0) - Baptiste Clavié (talus) - Alexander Schwenn (xelaris) - Florian Voutzinos (florianv) @@ -132,6 +132,7 @@ Symfony is the result of the work of many people who made the code better - Rafael Dohms (rdohms) - Arnaud Kleinpeter (nanocom) - jwdeitch + - Tobias Nyholm (tobias) - Joel Wurtz (brouznouf) - Philipp Wahala (hifi) - Vyacheslav Pavlov @@ -145,12 +146,14 @@ Symfony is the result of the work of many people who made the code better - Clemens Tolboom - Helmer Aaviksoo - Hiromi Hishida (77web) + - Yonel Ceruto González (yonelceruto) - Richard van Laak (rvanlaak) - Matthieu Ouellette-Vachon (maoueh) - Michał Pipa (michal.pipa) - Amal Raghav (kertz) - Jonathan Ingram (jonathaningram) - Artur Kotyrba + - jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent) - Warnar Boekkooi (boekkooi) - Dmitrii Chekaliuk (lazyhammer) - Clément JOBEILI (dator) @@ -160,13 +163,12 @@ Symfony is the result of the work of many people who made the code better - Richard Miller (mr_r_miller) - Mario A. Alvarez Garcia (nomack84) - Dennis Benkert (denderello) - - jeremyFreeAgent (Jérémy Romey) (jeremyfreeagent) - Benjamin Dulau (dbenjamin) - Mathieu Lemoine (lemoinem) - Andreas Hucks (meandmymonkey) - Noel Guilbert (noel) - Lars Strojny (lstrojny) - - Yonel Ceruto González (yonelceruto) + - Maxime STEINHAUSSER - Stepan Anchugov (kix) - bronze1man - sun (sun) @@ -236,7 +238,6 @@ Symfony is the result of the work of many people who made the code better - Grégoire Paris (greg0ire) - Leo Feyer - Chekote - - Tobias Nyholm (tobias) - Thomas Adam - Albert Casademont (acasademont) - Jhonny Lidfors (jhonne) @@ -245,6 +246,7 @@ Symfony is the result of the work of many people who made the code better - Nikita Konstantinov - Wodor Wodorski - Thomas Lallement (raziel057) + - Giorgio Premi - Matthieu Napoli (mnapoli) - Beau Simensen (simensen) - Michael Hirschler (mvhirsch) @@ -295,7 +297,6 @@ Symfony is the result of the work of many people who made the code better - Mark Challoner (markchalloner) - Gregor Harlan (gharlan) - Gennady Telegin (gtelegin) - - Giorgio Premi - Ben Davies (bendavies) - Erin Millard - Artur Melo (restless) @@ -393,7 +394,6 @@ Symfony is the result of the work of many people who made the code better - Christian Schmidt - Marcin Sikoń (marphi) - Dominik Zogg (dominik.zogg) - - Maxime STEINHAUSSER - Marek Pietrzak - Chad Sikorra (chadsikorra) - franek (franek) @@ -439,6 +439,7 @@ Symfony is the result of the work of many people who made the code better - Vicent Soria Durá (vicentgodella) - Nicolas Dewez (nicolas_dewez) - Anthony Ferrara + - Victor Bocharsky (bocharsky_bw) - Ioan Negulescu - Jakub Škvára (jskvara) - Andrew Udvare (audvare) @@ -611,7 +612,6 @@ Symfony is the result of the work of many people who made the code better - Andrew Tchircoff (andrewtch) - michaelwilliams - 1emming - - Victor Bocharsky (bocharsky_bw) - Leevi Graham (leevigraham) - Jordan Deitch - Casper Valdemar Poulsen @@ -769,6 +769,7 @@ Symfony is the result of the work of many people who made the code better - fabios - Sander Coolen (scoolen) - Nicolas Le Goff (nlegoff) + - Andreas Braun - Ben Oman - Manuele Menozzi - Anton Babenko (antonbabenko) @@ -858,6 +859,7 @@ Symfony is the result of the work of many people who made the code better - rpg600 - Péter Buri (burci) - Davide Borsatto (davide.borsatto) + - Indra Gunawan (guind) - kaiwa - Charles Sanquer (csanquer) - Albert Ganiev (helios-ag) @@ -969,6 +971,7 @@ Symfony is the result of the work of many people who made the code better - Sandro Hopf - Łukasz Makuch - George Giannoulopoulos + - Luis Ramirez (luisdeimos) - Daniel Richter (richtermeister) - ChrisC - Ilya Biryukov @@ -985,6 +988,7 @@ Symfony is the result of the work of many people who made the code better - Pete Mitchell (peterjmit) - Tom Corrigan (tomcorrigan) - Martin Pärtel + - Noah Heck (myesain) - Patrick Daley (padrig) - Xavier Briand (xavierbriand) - Max Summe @@ -1041,6 +1045,7 @@ Symfony is the result of the work of many people who made the code better - Sebastian Ionescu - Thomas Ploch - Simon Neidhold + - Xavier HAUSHERR - Valentin VALCIU - Kevin Dew - James Cowgill @@ -1163,6 +1168,7 @@ Symfony is the result of the work of many people who made the code better - Koalabaerchen - michalmarcinkowski - Warwick + - VJ - Chris - JakeFr - Simon Sargeant @@ -1236,6 +1242,7 @@ Symfony is the result of the work of many people who made the code better - Joel Marcey - David Christmann - root + - Wouter J - James Hudson - Tom Maguire - David Zuelke @@ -1312,6 +1319,7 @@ Symfony is the result of the work of many people who made the code better - Jelle Bekker (jbekker) - Ian Jenkins (jenkoian) - Jorge Martin (jorgemartind) + - Julien Falque (julienfalque) - Kevin Herrera (kherge) - Luis Ramón López López (lrlopez) - Muriel (metalmumu) @@ -1379,6 +1387,7 @@ Symfony is the result of the work of many people who made the code better - Jörg Rühl - wesleyh - sergey + - Karim Miladi - Michael Genereux - patrick-mcdougle - Dariusz Czech @@ -1559,6 +1568,7 @@ Symfony is the result of the work of many people who made the code better - Sergey Fedotov - Michael - fh-github@fholzhauer.de + - Jan Emrich - Mark Topper - Xavier REN - Zander Baldwin From dec83adc4b434763b047d20dc6ee003cb5118c29 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 20 Nov 2016 17:12:54 -0800 Subject: [PATCH 14/56] updated VERSION for 2.7.21 --- 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 5bd08cbd1537b..423bcd19f2225 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.21-DEV'; + const VERSION = '2.7.21'; const VERSION_ID = 20721; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; const RELEASE_VERSION = 21; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From 2af58be68f891806f6fed363838584e90a852350 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 20 Nov 2016 18:19:38 -0800 Subject: [PATCH 15/56] bumped Symfony version to 2.7.22 --- 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 423bcd19f2225..4ed457d9931a1 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.21'; - const VERSION_ID = 20721; + const VERSION = '2.7.22-DEV'; + const VERSION_ID = 20722; const MAJOR_VERSION = 2; const MINOR_VERSION = 7; - const RELEASE_VERSION = 21; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 22; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '05/2018'; const END_OF_LIFE = '05/2019'; From 38118a324bee582bce33078a15e6ca5e3353aace Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 20 Nov 2016 18:24:38 -0800 Subject: [PATCH 16/56] updated CHANGELOG for 2.8.14 --- CHANGELOG-2.8.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGELOG-2.8.md b/CHANGELOG-2.8.md index 8f0a5d2bd6bf9..e5ad3abf25202 100644 --- a/CHANGELOG-2.8.md +++ b/CHANGELOG-2.8.md @@ -7,6 +7,28 @@ 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.14 (2016-11-21) + + * bug #20543 [DI] Fix error when trying to resolve a DefinitionDecorator (nicolas-grekas) + * bug #20544 [PhpUnitBridge] Fix time-sensitive tests that use data providers (julienfalque) + * bug #20484 bumped min version of Twig to 1.28 (fabpot) + * bug #20519 [Debug] Remove GLOBALS from exception context to avoid endless recursion (Seldaek) + * bug #20455 [ClassLoader] Fix ClassCollectionLoader inlining with __halt_compiler (giosh94mhz) + * bug #20307 [Form] Fix Date\TimeType marked as invalid on request with single_text and zero seconds (LuisDeimos) + * bug #20466 [Translation] fixed nested fallback catalogue using multiple locales. (aitboudad) + * bug #20465 [#18637][TranslationDebug] workaround for getFallbackLocales. (aitboudad) + * bug #20440 [TwigBridge][TwigBundle][HttpKernel] prefer getSourceContext() over getSource() (xabbuh) + * bug #20422 [Translation][fallback] add missing resources in parent catalogues. (aitboudad) + * bug #20378 [Form] Fixed show float values as choice value in ChoiceType (yceruto) + * bug #20294 Improved the design of the metrics in the profiler (javiereguiluz) + * bug #20375 [HttpFoundation][Session] Fix memcache session handler (klandaika) + * bug #20377 [Console] Fix infinite loop on missing input (chalasr) + * bug #20372 [Console] simplified code (fabpot) + * bug #20342 [Form] Fix UrlType transforms valid protocols (ogizanagi) + * bug #20292 Enhance GAE compat by removing some realpath() (nicolas-grekas) + * bug #20326 [VarDumper] Fix dumping Twig source in stack traces (nicolas-grekas) + * bug #20321 Compatibility with Twig 1.27 (xkobal) + * 2.8.13 (2016-10-27) * bug #20289 Fix edge case with StreamedResponse where headers are sent twice (Nicofuma) From 8af226fe39e68849bdb0b3a9be3eb79fe60284e8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 20 Nov 2016 18:24:42 -0800 Subject: [PATCH 17/56] updated VERSION for 2.8.14 --- 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 62c27c0322e16..5d958b272298a 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.14-DEV'; + const VERSION = '2.8.14'; const VERSION_ID = 20814; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; const RELEASE_VERSION = 14; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From d94a631f4d49cb001c425bec6e3bfca21bf98ebd Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 20 Nov 2016 18:42:55 -0800 Subject: [PATCH 18/56] bumped Symfony version to 2.8.15 --- 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 5d958b272298a..408ff9d874913 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.14'; - const VERSION_ID = 20814; + const VERSION = '2.8.15-DEV'; + const VERSION_ID = 20815; const MAJOR_VERSION = 2; const MINOR_VERSION = 8; - const RELEASE_VERSION = 14; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 15; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '11/2018'; const END_OF_LIFE = '11/2019'; From ba6420bf88a95ef17afeff5d6b643e8eab83d882 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 20 Nov 2016 18:44:16 -0800 Subject: [PATCH 19/56] updated CHANGELOG for 3.1.7 --- CHANGELOG-3.1.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/CHANGELOG-3.1.md b/CHANGELOG-3.1.md index 07d0350ddfada..228cbff557b8e 100644 --- a/CHANGELOG-3.1.md +++ b/CHANGELOG-3.1.md @@ -7,6 +7,33 @@ in 3.1 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.1.0...v3.1.1 +* 3.1.7 (2016-11-21) + + * bug #20550 [YAML] Fix processing timestamp strings with timezone (myesain) + * bug #20543 [DI] Fix error when trying to resolve a DefinitionDecorator (nicolas-grekas) + * bug #20544 [PhpUnitBridge] Fix time-sensitive tests that use data providers (julienfalque) + * bug #20484 bumped min version of Twig to 1.28 (fabpot) + * bug #20519 [Debug] Remove GLOBALS from exception context to avoid endless recursion (Seldaek) + * bug #20455 [ClassLoader] Fix ClassCollectionLoader inlining with __halt_compiler (giosh94mhz) + * bug #20307 [Form] Fix Date\TimeType marked as invalid on request with single_text and zero seconds (LuisDeimos) + * bug #20480 [FrameworkBundle] Register the ArrayDenormalizer (dunglas) + * bug #20286 [Serializer] Fix DataUriNormalizer's regex (dunglas) + * bug #20466 [Translation] fixed nested fallback catalogue using multiple locales. (aitboudad) + * bug #20465 [#18637][TranslationDebug] workaround for getFallbackLocales. (aitboudad) + * bug #20453 [Cache] Make directory hashing case insensitive (nicolas-grekas) + * bug #20440 [TwigBridge][TwigBundle][HttpKernel] prefer getSourceContext() over getSource() (xabbuh) + * bug #20287 Properly format value in UniqueEntityValidator (alcaeus) + * bug #20422 [Translation][fallback] add missing resources in parent catalogues. (aitboudad) + * bug #20378 [Form] Fixed show float values as choice value in ChoiceType (yceruto) + * bug #20294 Improved the design of the metrics in the profiler (javiereguiluz) + * bug #20375 [HttpFoundation][Session] Fix memcache session handler (klandaika) + * bug #20377 [Console] Fix infinite loop on missing input (chalasr) + * bug #20372 [Console] simplified code (fabpot) + * bug #20342 [Form] Fix UrlType transforms valid protocols (ogizanagi) + * bug #20292 Enhance GAE compat by removing some realpath() (nicolas-grekas) + * bug #20326 [VarDumper] Fix dumping Twig source in stack traces (nicolas-grekas) + * bug #20321 Compatibility with Twig 1.27 (xkobal) + * 3.1.6 (2016-10-27) * bug #20291 [Yaml] Fix 7.1 compat (nicolas-grekas) From 386fd29f6787735405032e1a2d5e843ff61fc3af Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 20 Nov 2016 18:44:20 -0800 Subject: [PATCH 20/56] updated VERSION for 3.1.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 e923c098b00af..2e82d9c28ea08 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 = '3.1.7-DEV'; + const VERSION = '3.1.7'; const VERSION_ID = 30107; const MAJOR_VERSION = 3; const MINOR_VERSION = 1; const RELEASE_VERSION = 7; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = ''; const END_OF_MAINTENANCE = '01/2017'; const END_OF_LIFE = '07/2017'; From f09b9335648e8f5b4baa2e53c5b931d33be990a8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 20 Nov 2016 19:12:53 -0800 Subject: [PATCH 21/56] bumped Symfony version to 3.1.8 --- 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 2e82d9c28ea08..f99ca25a15fe9 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 = '3.1.7'; - const VERSION_ID = 30107; + const VERSION = '3.1.8-DEV'; + const VERSION_ID = 30108; const MAJOR_VERSION = 3; const MINOR_VERSION = 1; - const RELEASE_VERSION = 7; - const EXTRA_VERSION = ''; + const RELEASE_VERSION = 8; + const EXTRA_VERSION = 'DEV'; const END_OF_MAINTENANCE = '01/2017'; const END_OF_LIFE = '07/2017'; From 69bfbbf8c2481f75673b0c796938a2d466690bb0 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 21 Nov 2016 09:40:36 +0100 Subject: [PATCH 22/56] [Process] Do feat test before enabling TTY mode --- src/Symfony/Component/Process/Process.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index d6adf21fa9390..5b23192eb9734 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -911,8 +911,16 @@ public function setTty($tty) if ('\\' === DIRECTORY_SEPARATOR && $tty) { throw new RuntimeException('TTY mode is not supported on Windows platform.'); } - if ($tty && (!file_exists('/dev/tty') || !is_readable('/dev/tty'))) { - throw new RuntimeException('TTY mode requires /dev/tty to be readable.'); + if ($tty) { + static $isTtySupported; + + if (null === $isTtySupported) { + $isTtySupported = (bool) @proc_open('echo 1 >/dev/null', array(array('file', '/dev/tty', 'r'), array('file', '/dev/tty', 'w'), array('file', '/dev/tty', 'w')), $pipes); + } + + if (!$isTtySupported) { + throw new RuntimeException('TTY mode requires /dev/tty to be read/writable.'); + } } $this->tty = (bool) $tty; @@ -1214,7 +1222,7 @@ public static function isPtySupported() return $result = false; } - return $result = (bool) @proc_open('echo 1', array(array('pty'), array('pty'), array('pty')), $pipes); + return $result = (bool) @proc_open('echo 1 >/dev/null', array(array('pty'), array('pty'), array('pty')), $pipes); } /** From 09adfda57e2b817ea8f6d0d3e7131490a401cbc6 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 21 Nov 2016 11:06:34 +0100 Subject: [PATCH 23/56] [FrameworkBundle] Mark cache.default_*_provider services private --- .../FrameworkBundle/DependencyInjection/FrameworkExtension.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 9e9d797191a4e..de71b26140ae7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1045,6 +1045,7 @@ private function registerCacheConfiguration(array $config, ContainerBuilder $con foreach (array('doctrine', 'psr6', 'redis') as $name) { if (isset($config[$name = 'default_'.$name.'_provider'])) { $container->setAlias('cache.'.$name, Compiler\CachePoolPass::getServiceProvider($container, $config[$name])); + $container->getAlias('cache.'.$name)->setPublic(false); } } foreach (array('app', 'system') as $name) { From b25c1d30f6bc1e8aa90a8f53963b6c8f38af18cf Mon Sep 17 00:00:00 2001 From: Julien Falque Date: Mon, 21 Nov 2016 23:14:54 +0100 Subject: [PATCH 24/56] Fix complete config tests --- .../DependencyInjection/CompleteConfigurationTest.php | 8 ++++++-- .../PhpCompleteConfigurationTest.php | 10 +++++++--- .../XmlCompleteConfigurationTest.php | 10 +++++++--- .../YamlCompleteConfigurationTest.php | 10 +++++++--- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php index 8a0a14ddb32a8..16e5787bdf60e 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php @@ -21,7 +21,9 @@ abstract class CompleteConfigurationTest extends \PHPUnit_Framework_TestCase { private static $containerCache = array(); - abstract protected function loadFromFile(ContainerBuilder $container, $file); + abstract protected function getLoader(ContainerBuilder $container); + + abstract protected function getFileExtension(); public function testRolesHierarchy() { @@ -237,6 +239,8 @@ public function testRememberMeThrowExceptions() protected function getContainer($file) { + $file = $file.'.'.$this->getFileExtension(); + if (isset(self::$containerCache[$file])) { return self::$containerCache[$file]; } @@ -246,7 +250,7 @@ protected function getContainer($file) $bundle = new SecurityBundle(); $bundle->build($container); // Attach all default factories - $this->loadFromFile($container, $file); + $this->getLoader($container)->load($file); $container->getCompilerPassConfig()->setOptimizationPasses(array()); $container->getCompilerPassConfig()->setRemovingPasses(array()); diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/PhpCompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/PhpCompleteConfigurationTest.php index 131c38d5e50b7..6495485d1bb87 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/PhpCompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/PhpCompleteConfigurationTest.php @@ -17,9 +17,13 @@ class PhpCompleteConfigurationTest extends CompleteConfigurationTest { - protected function loadFromFile(ContainerBuilder $container, $file) + protected function getLoader(ContainerBuilder $container) { - $loadXml = new PhpFileLoader($container, new FileLocator(__DIR__.'/Fixtures/php')); - $loadXml->load($file.'.php'); + return new PhpFileLoader($container, new FileLocator(__DIR__.'/Fixtures/php')); + } + + protected function getFileExtension() + { + return 'php'; } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/XmlCompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/XmlCompleteConfigurationTest.php index cf6833a22ab61..2399f5ee460dc 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/XmlCompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/XmlCompleteConfigurationTest.php @@ -17,9 +17,13 @@ class XmlCompleteConfigurationTest extends CompleteConfigurationTest { - protected function loadFromFile(ContainerBuilder $container, $file) + protected function getLoader(ContainerBuilder $container) { - $loadXml = new XmlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/xml')); - $loadXml->load($file.'.xml'); + return new XmlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/xml')); + } + + protected function getFileExtension() + { + return 'xml'; } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/YamlCompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/YamlCompleteConfigurationTest.php index 568b8623ea007..d5d5e693abdcd 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/YamlCompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/YamlCompleteConfigurationTest.php @@ -17,9 +17,13 @@ class YamlCompleteConfigurationTest extends CompleteConfigurationTest { - protected function loadFromFile(ContainerBuilder $container, $file) + protected function getLoader(ContainerBuilder $container) { - $loadXml = new YamlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/yml')); - $loadXml->load($file.'.yml'); + return new YamlFileLoader($container, new FileLocator(__DIR__.'/Fixtures/yml')); + } + + protected function getFileExtension() + { + return 'yml'; } } From 6c3150df63379516802a43ef9a832d376df42c45 Mon Sep 17 00:00:00 2001 From: Imangazaliev Date: Sun, 13 Nov 2016 14:38:04 +0300 Subject: [PATCH 25/56] [DOMCrawler] Bug fixed --- src/Symfony/Component/DomCrawler/Crawler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index cf588eae5aad8..d4b7d45009a40 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -816,7 +816,7 @@ public static function xpathLiteral($s) } } - return sprintf('concat(%s)', implode($parts, ', ')); + return sprintf('concat(%s)', implode(', ', $parts)); } /** From cb12f2200d4e1b9da1fdcbad1a6adb584a7de524 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 18 Nov 2016 16:03:27 +0100 Subject: [PATCH 26/56] [FrameworkBundle] Avoid warming up the validator cache for non-existent classes --- .../CacheWarmer/ValidatorCacheWarmer.php | 4 +++- .../Tests/Fixtures/Validation/Resources/person.xml | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php index 2e1c86e508998..ce5104dc41cc5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php +++ b/src/Symfony/Bundle/FrameworkBundle/CacheWarmer/ValidatorCacheWarmer.php @@ -68,7 +68,9 @@ public function warmUp($cacheDir) foreach ($this->extractSupportedLoaders($loaders) as $loader) { foreach ($loader->getMappedClasses() as $mappedClass) { - $metadataFactory->getMetadataFor($mappedClass); + if ($metadataFactory->hasMetadataFor($mappedClass)) { + $metadataFactory->getMetadataFor($mappedClass); + } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Resources/person.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Resources/person.xml index 72cc30dc662ec..b23760ae4556c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Resources/person.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Resources/person.xml @@ -15,4 +15,15 @@ + + + + + + + + + From f09ccf49d1eb044501a024477e70d9f9411d886e Mon Sep 17 00:00:00 2001 From: Maxime STEINHAUSSER Date: Tue, 22 Nov 2016 10:11:19 +0100 Subject: [PATCH 27/56] [SecurityBundle] Fix FirewallConfig nullable arguments Nullable arguments were replaced by empty string by the DIC config if values weren't replaced in the extension. --- .../DependencyInjection/SecurityExtension.php | 17 +++++++---------- .../Resources/config/security.xml | 2 +- .../SecurityBundle/Security/FirewallConfig.php | 11 ++++++----- .../CompleteConfigurationTest.php | 15 +++++++++++---- .../Tests/Security/FirewallConfigTest.php | 2 +- .../Tests/Security/FirewallContextTest.php | 2 +- 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php index 5c88548bcff1d..faa28fc1757aa 100644 --- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php +++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php @@ -267,6 +267,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a { $config = $container->setDefinition($configId, new DefinitionDecorator('security.firewall.config')); $config->replaceArgument(0, $id); + $config->replaceArgument(1, $firewall['user_checker']); // Matcher $matcher = null; @@ -279,8 +280,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a $matcher = $this->createRequestMatcher($container, $pattern, $host, $methods); } - $config->replaceArgument(1, (string) $matcher); - $config->replaceArgument(2, $firewall['user_checker']); + $config->replaceArgument(2, $matcher ? (string) $matcher : null); $config->replaceArgument(3, $firewall['security']); // Security disabled? @@ -306,6 +306,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a // Channel listener $listeners[] = new Reference('security.channel_listener'); + $contextKey = null; // Context serializer listener if (false === $firewall['stateless']) { $contextKey = $id; @@ -313,11 +314,11 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a $contextKey = $firewall['context']; } - $config->replaceArgument(6, $contextKey); - $listeners[] = new Reference($this->createContextListener($container, $contextKey)); } + $config->replaceArgument(6, $contextKey); + // Logout listener if (isset($firewall['logout'])) { $listenerKeys[] = 'logout'; @@ -399,12 +400,8 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a // Exception listener $exceptionListener = new Reference($this->createExceptionListener($container, $firewall, $id, $configuredEntryPoint ?: $defaultEntryPoint, $firewall['stateless'])); - if (isset($firewall['access_denied_handler'])) { - $config->replaceArgument(8, $firewall['access_denied_handler']); - } - if (isset($firewall['access_denied_url'])) { - $config->replaceArgument(9, $firewall['access_denied_url']); - } + $config->replaceArgument(8, isset($firewall['access_denied_handler']) ? $firewall['access_denied_handler'] : null); + $config->replaceArgument(9, isset($firewall['access_denied_url']) ? $firewall['access_denied_url'] : null); $container->setAlias(new Alias('security.user_checker.'.$id, false), $firewall['user_checker']); diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml index 8def320482486..54e573440299c 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml @@ -116,8 +116,8 @@ - + diff --git a/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php b/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php index a36ff955130d1..3cfb11404ccf8 100644 --- a/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php +++ b/src/Symfony/Bundle/SecurityBundle/Security/FirewallConfig.php @@ -17,8 +17,8 @@ final class FirewallConfig { private $name; - private $requestMatcher; private $userChecker; + private $requestMatcher; private $securityEnabled; private $stateless; private $provider; @@ -30,8 +30,8 @@ final class FirewallConfig /** * @param string $name - * @param string $requestMatcher * @param string $userChecker + * @param string|null $requestMatcher * @param bool $securityEnabled * @param bool $stateless * @param string|null $provider @@ -41,11 +41,11 @@ final class FirewallConfig * @param string|null $accessDeniedUrl * @param string[] $listeners */ - public function __construct($name, $requestMatcher, $userChecker, $securityEnabled = true, $stateless = false, $provider = null, $context = null, $entryPoint = null, $accessDeniedHandler = null, $accessDeniedUrl = null, $listeners = array()) + public function __construct($name, $userChecker, $requestMatcher = null, $securityEnabled = true, $stateless = false, $provider = null, $context = null, $entryPoint = null, $accessDeniedHandler = null, $accessDeniedUrl = null, $listeners = array()) { $this->name = $name; - $this->requestMatcher = $requestMatcher; $this->userChecker = $userChecker; + $this->requestMatcher = $requestMatcher; $this->securityEnabled = $securityEnabled; $this->stateless = $stateless; $this->provider = $provider; @@ -62,7 +62,8 @@ public function getName() } /** - * @return string The request matcher service id + * @return string|null The request matcher service id or null if neither the request matcher, pattern or host + * options were provided */ public function getRequestMatcher() { diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php index 34e3ad56114ac..712a708fde3e7 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php @@ -78,18 +78,21 @@ public function testFirewalls() $this->assertEquals(array( array( 'simple', - 'security.request_matcher.707b20193d4cb9f2718114abcbebb32af48f948484fc166a03482f49bf14f25e271f72c7', 'security.user_checker', + 'security.request_matcher.707b20193d4cb9f2718114abcbebb32af48f948484fc166a03482f49bf14f25e271f72c7', false, ), array( 'secure', - '', 'security.user_checker', + null, true, true, 'security.user.provider.concrete.default', + null, 'security.authentication.form_entry_point.secure', + null, + null, array( 'logout', 'switch_user', @@ -104,13 +107,15 @@ public function testFirewalls() ), array( 'host', - 'security.request_matcher.dda8b565689ad8509623ee68fb2c639cd81cd4cb339d60edbaf7d67d30e6aa09bd8c63c3', 'security.user_checker', + 'security.request_matcher.dda8b565689ad8509623ee68fb2c639cd81cd4cb339d60edbaf7d67d30e6aa09bd8c63c3', true, false, 'security.user.provider.concrete.default', 'host', 'security.authentication.basic_entry_point.host', + null, + null, array( 'http_basic', 'anonymous', @@ -118,13 +123,15 @@ public function testFirewalls() ), array( 'with_user_checker', - '', 'app.user_checker', + null, true, false, 'security.user.provider.concrete.default', 'with_user_checker', 'security.authentication.basic_entry_point.with_user_checker', + null, + null, array( 'http_basic', 'anonymous', diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php index eb6eeeb8dd588..a6fdeeed3768a 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallConfigTest.php @@ -32,8 +32,8 @@ public function testGetters() $config = new FirewallConfig( 'foo_firewall', - $options['request_matcher'], $options['user_checker'], + $options['request_matcher'], $options['security'], $options['stateless'], $options['provider'], diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallContextTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallContextTest.php index 098e2c51f80dd..e0790bf23c776 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallContextTest.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Security/FirewallContextTest.php @@ -20,7 +20,7 @@ class FirewallContextTest extends \PHPUnit_Framework_TestCase { public function testGetters() { - $config = new FirewallConfig('main', 'request_matcher', 'user_checker'); + $config = new FirewallConfig('main', 'user_checker', 'request_matcher'); $exceptionListener = $this ->getMockBuilder(ExceptionListener::class) From 7752308c962aafe24c645edff0bda2783ed6f20a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 22 Nov 2016 19:19:49 +0100 Subject: [PATCH 28/56] [DI] Aliases should preserve the aliased invalid behavior --- .../DependencyInjection/ContainerBuilder.php | 2 +- .../Tests/ContainerBuilderTest.php | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 7c9f5a243190a..d391459bcb284 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -430,7 +430,7 @@ public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INV } if (!array_key_exists($id, $this->definitions) && isset($this->aliasDefinitions[$id])) { - return $this->get($this->aliasDefinitions[$id]); + return $this->get($this->aliasDefinitions[$id], $invalidBehavior); } try { diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 8f8c8b179f790..7f13417fb97a9 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -231,6 +231,18 @@ public function testSetReplacesAlias() $this->assertSame($foo, $builder->get('alias'), '->set() replaces an existing alias'); } + public function testAliasesKeepInvalidBehavior() + { + $builder = new ContainerBuilder(); + + $aliased = new Definition('stdClass'); + $aliased->addMethodCall('setBar', array(new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE))); + $builder->setDefinition('aliased', $aliased); + $builder->setAlias('alias', 'aliased'); + + $this->assertEquals(new \stdClass(), $builder->get('alias')); + } + public function testAddGetCompilerPass() { $builder = new ContainerBuilder(); From b4c327d89bd2524f55ff707b2c58a9d58a1fdbc0 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 22 Nov 2016 15:41:10 +0100 Subject: [PATCH 29/56] [WebProfilerBundle] Fix deprecated uses of profiler_dump --- .../Controller/RouterController.php | 8 ++-- .../views/Collector/request.html.twig | 4 +- .../DataCollector/DataCollector.php | 2 +- .../DataCollector/RequestDataCollector.php | 45 +++++++++++-------- .../RequestDataCollectorTest.php | 6 +-- 5 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php index d77eb279f4a69..02449f601ef11 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php @@ -86,11 +86,11 @@ private function getTraces(RequestDataCollector $request, $method) { $traceRequest = Request::create( $request->getPathInfo(), - $request->getRequestServer()->get('REQUEST_METHOD'), - $request->getRequestAttributes()->all(), - $request->getRequestCookies()->all(), + $request->getRequestServer(true)->get('REQUEST_METHOD'), + $request->getRequestAttributes(true)->all(), + $request->getRequestCookies(true)->all(), array(), - $request->getRequestServer()->all() + $request->getRequestServer(true)->all() ); $context = $this->matcher->getContext(); 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 277a046789e48..cdf2839c6dcd2 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -154,7 +154,7 @@ {% endif %}

Request Headers

- {{ include('@WebProfiler/Profiler/bag.html.twig', { bag: collector.requestheaders, labels: ['Header', 'Value'] }, with_context = false) }} + {{ include('@WebProfiler/Profiler/bag.html.twig', { bag: collector.requestheaders, labels: ['Header', 'Value'], maxDepth: 1 }, with_context = false) }}

Request Content

@@ -183,7 +183,7 @@

Response Headers

- {{ include('@WebProfiler/Profiler/bag.html.twig', { bag: collector.responseheaders, labels: ['Header', 'Value'] }, with_context = false) }} + {{ include('@WebProfiler/Profiler/bag.html.twig', { bag: collector.responseheaders, labels: ['Header', 'Value'], maxDepth: 1 }, with_context = false) }}
diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php index 1f8538a9f2522..7bca1ddfe199f 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php @@ -130,7 +130,7 @@ private function decorateVar($var) return new ClassStub($var); } } - if (false !== strpos($var, DIRECTORY_SEPARATOR) && false === strpos($var, '://') && file_exists($var)) { + if (false !== strpos($var, DIRECTORY_SEPARATOR) && false === strpos($var, '://') && false === strpos($var, "\0") && is_file($var)) { return new LinkStub($var); } } diff --git a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index f0c18c51e51e7..6e8623a700240 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -12,10 +12,8 @@ namespace Symfony\Component\HttpKernel\DataCollector; use Symfony\Component\HttpFoundation\ParameterBag; -use Symfony\Component\HttpFoundation\HeaderBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\ResponseHeaderBag; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\HttpKernel\Event\FilterControllerEvent; @@ -54,14 +52,11 @@ public function collect(Request $request, Response $response, \Exception $except $attributes = array(); $route = ''; foreach ($request->attributes->all() as $key => $value) { - if ('_route' === $key && is_object($value)) { - $attributes[$key] = $this->cloneVar($value->getPath()); - } else { - $attributes[$key] = $this->cloneVar($value); - } - if ('_route' === $key) { $route = is_object($value) ? $value->getPath() : $value; + $attributes[$key] = $route; + } else { + $attributes[$key] = $value; } } @@ -97,8 +92,8 @@ public function collect(Request $request, Response $response, \Exception $except 'content_type' => $response->headers->get('Content-Type', 'text/html'), 'status_text' => isset(Response::$statusTexts[$statusCode]) ? Response::$statusTexts[$statusCode] : '', 'status_code' => $statusCode, - 'request_query' => array_map(array($this, 'cloneVar'), $request->query->all()), - 'request_request' => array_map(array($this, 'cloneVar'), $request->request->all()), + 'request_query' => $request->query->all(), + 'request_request' => $request->request->all(), 'request_headers' => $request->headers->all(), 'request_server' => $request->server->all(), 'request_cookies' => $request->cookies->all(), @@ -125,6 +120,18 @@ public function collect(Request $request, Response $response, \Exception $except $this->data['request_request']['_password'] = '******'; } + foreach ($this->data as $key => $value) { + if (!is_array($value)) { + continue; + } + if ('request_headers' === $key || 'response_headers' === $key) { + $value = array_map(function ($v) { return isset($v[1]) ? $v : $v[0]; }, $value); + } + if ('request_server' !== $key && 'request_attributes' !== $key && 'request_cookies' !== $key) { + $this->data[$key] = array_map(array($this, 'cloneVar'), $value); + } + } + if (isset($this->controllers[$request])) { $this->data['controller'] = $this->parseController($this->controllers[$request]); unset($this->controllers[$request]); @@ -170,27 +177,27 @@ public function getRequestQuery() public function getRequestHeaders() { - return new HeaderBag($this->data['request_headers']); + return new ParameterBag($this->data['request_headers']); } - public function getRequestServer() + public function getRequestServer($raw = false) { - return new ParameterBag($this->data['request_server']); + return new ParameterBag($raw ? $this->data['request_server'] : array_map(array($this, 'cloneVar'), $this->data['request_server'])); } - public function getRequestCookies() + public function getRequestCookies($raw = false) { - return new ParameterBag($this->data['request_cookies']); + return new ParameterBag($raw ? $this->data['request_cookies'] : array_map(array($this, 'cloneVar'), $this->data['request_cookies'])); } - public function getRequestAttributes() + public function getRequestAttributes($raw = false) { - return new ParameterBag($this->data['request_attributes']); + return new ParameterBag($raw ? $this->data['request_attributes'] : array_map(array($this, 'cloneVar'), $this->data['request_attributes'])); } public function getResponseHeaders() { - return new ResponseHeaderBag($this->data['response_headers']); + return new ParameterBag($this->data['response_headers']); } public function getSessionMetadata() @@ -264,7 +271,7 @@ public function getIdentifier() */ public function getRouteParams() { - return isset($this->data['request_attributes']['_route_params']) ? $this->data['request_attributes']['_route_params'] : $this->cloneVar(array()); + return isset($this->data['request_attributes']['_route_params']) ? array_map(array($this, 'cloneVar'), $this->data['request_attributes']['_route_params']) : array(); } /** diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php index 2ae1c5c09bb49..6fec6d88d0a3a 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php @@ -39,7 +39,7 @@ public function testCollect() $attributes = $c->getRequestAttributes(); $this->assertSame('request', $c->getName()); - $this->assertInstanceOf('Symfony\Component\HttpFoundation\HeaderBag', $c->getRequestHeaders()); + $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestHeaders()); $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestServer()); $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestCookies()); $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $attributes); @@ -47,13 +47,13 @@ public function testCollect() $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestQuery()); $this->assertSame('html', $c->getFormat()); $this->assertEquals('foobar', $c->getRoute()); - $this->assertEquals($cloner->cloneVar(array('name' => 'foo')), $c->getRouteParams()); + $this->assertEquals(array('name' => $cloner->cloneVar('foo')), $c->getRouteParams()); $this->assertSame(array(), $c->getSessionAttributes()); $this->assertSame('en', $c->getLocale()); $this->assertEquals($cloner->cloneVar($request->attributes->get('resource')), $attributes->get('resource')); $this->assertEquals($cloner->cloneVar($request->attributes->get('object')), $attributes->get('object')); - $this->assertInstanceOf('Symfony\Component\HttpFoundation\HeaderBag', $c->getResponseHeaders()); + $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getResponseHeaders()); $this->assertSame('OK', $c->getStatusText()); $this->assertSame(200, $c->getStatusCode()); $this->assertSame('application/json', $c->getContentType()); From 10992cd3bfe9b184987b7a06d462e69119917c7c Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Tue, 22 Nov 2016 21:44:12 +0100 Subject: [PATCH 30/56] [Process] Fix kill process on reached timeout using getIterator() --- src/Symfony/Component/Process/Process.php | 1 + .../Component/Process/Tests/ProcessTest.php | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index f95b34a312673..fd6ffe3573351 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -557,6 +557,7 @@ public function getIterator($flags = 0) yield self::OUT => ''; } + $this->checkTimeout(); $this->readPipesForOutput(__FUNCTION__, $blocking); } } diff --git a/src/Symfony/Component/Process/Tests/ProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php index cd57f3a8c32df..f317fc7d72938 100644 --- a/src/Symfony/Component/Process/Tests/ProcessTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessTest.php @@ -747,6 +747,27 @@ public function testRunProcessWithTimeout() throw $e; } + /** + * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException + * @expectedExceptionMessage exceeded the timeout of 0.1 seconds. + */ + public function testIterateOverProcessWithTimeout() + { + $process = $this->getProcess(self::$phpBin.' -r "sleep(30);"'); + $process->setTimeout(0.1); + $start = microtime(true); + try { + $process->start(); + foreach ($process as $buffer); + $this->fail('A RuntimeException should have been raised'); + } catch (RuntimeException $e) { + } + + $this->assertLessThan(15, microtime(true) - $start); + + throw $e; + } + public function testCheckTimeoutOnNonStartedProcess() { $process = $this->getProcess('echo foo'); From 519a47179aaefe8c4c288b35b5da51614b5d166c Mon Sep 17 00:00:00 2001 From: Samuel ROZE Date: Tue, 22 Nov 2016 12:01:02 +0000 Subject: [PATCH 31/56] [DI] Allow null as default env value --- .../EnvPlaceholderParameterBag.php | 8 +++---- .../EnvPlaceholderParameterBagTest.php | 24 ++++++++++++++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php b/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php index 46d2a739dc5e5..d20e53531aa3b 100644 --- a/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php +++ b/src/Symfony/Component/DependencyInjection/ParameterBag/EnvPlaceholderParameterBag.php @@ -41,8 +41,8 @@ public function get($name) if ($this->has($name)) { $defaultValue = parent::get($name); - if (!is_scalar($defaultValue)) { - throw new RuntimeException(sprintf('The default value of an env() parameter must be scalar, but "%s" given to "%s".', gettype($defaultValue), $name)); + if (null !== $defaultValue && !is_scalar($defaultValue)) { + throw new RuntimeException(sprintf('The default value of an env() parameter must be scalar or null, but "%s" given to "%s".', gettype($defaultValue), $name)); } } @@ -96,8 +96,8 @@ public function resolve() } if (is_numeric($default = $this->parameters[$name])) { $this->parameters[$name] = (string) $default; - } elseif (null !== $default && !is_string($default)) { - throw new RuntimeException(sprintf('The default value of env parameter "%s" must be string or null, %s given.', $env, gettype($default))); + } elseif (null !== $default && !is_scalar($default)) { + throw new RuntimeException(sprintf('The default value of env parameter "%s" must be scalar or null, %s given.', $env, gettype($default))); } } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/EnvPlaceholderParameterBagTest.php b/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/EnvPlaceholderParameterBagTest.php index 1a24b3d6e2663..c898038e39402 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/EnvPlaceholderParameterBagTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ParameterBag/EnvPlaceholderParameterBagTest.php @@ -130,7 +130,7 @@ public function testResolveEnvAllowsNull() /** * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException - * @expectedExceptionMessage The default value of env parameter "ARRAY_VAR" must be string or null, array given. + * @expectedExceptionMessage The default value of env parameter "ARRAY_VAR" must be scalar or null, array given. */ public function testResolveThrowsOnBadDefaultValue() { @@ -139,4 +139,26 @@ public function testResolveThrowsOnBadDefaultValue() $bag->set('env(Array_Var)', array()); $bag->resolve(); } + + public function testGetEnvAllowsNull() + { + $bag = new EnvPlaceholderParameterBag(); + $bag->set('env(NULL_VAR)', null); + $bag->get('env(NULL_VAR)'); + $bag->resolve(); + + $this->assertNull($bag->all()['env(null_var)']); + } + + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException + * @expectedExceptionMessage The default value of an env() parameter must be scalar or null, but "array" given to "env(ARRAY_VAR)". + */ + public function testGetThrowsOnBadDefaultValue() + { + $bag = new EnvPlaceholderParameterBag(); + $bag->set('env(ARRAY_VAR)', array()); + $bag->get('env(ARRAY_VAR)'); + $bag->resolve(); + } } From 0c3b7d7b8d9d6542b3484936754c9d27dc263fa6 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 23 Nov 2016 13:49:06 +0100 Subject: [PATCH 32/56] [HttpKernel] Revert BC breaking change of Request::isMethodSafe() --- .../Component/HttpFoundation/BinaryFileResponse.php | 2 +- src/Symfony/Component/HttpFoundation/Request.php | 6 ++++-- .../Component/HttpFoundation/Tests/RequestTest.php | 9 ++++++++- .../HttpKernel/EventListener/FragmentListener.php | 2 +- src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php | 2 +- .../Security/Http/Firewall/ExceptionListener.php | 2 +- 6 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php index a39984dffa717..f95d90c364051 100644 --- a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php +++ b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php @@ -190,7 +190,7 @@ public function prepare(Request $request) if (!$this->headers->has('Accept-Ranges')) { // Only accept ranges on safe HTTP methods - $this->headers->set('Accept-Ranges', $request->isMethodSafe() ? 'bytes' : 'none'); + $this->headers->set('Accept-Ranges', $request->isMethodSafe(false) ? 'bytes' : 'none'); } if (!$this->headers->has('Content-Type')) { diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index ad1578758663b..cdaa57e0e6ff6 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1466,11 +1466,13 @@ public function isMethod($method) /** * Checks whether the method is safe or not. * + * @param bool $andCacheable Adds the additional condition that the method should be cacheable. True by default. + * * @return bool */ - public function isMethodSafe() + public function isMethodSafe(/* $andCacheable = true */) { - return in_array($this->getMethod(), array('GET', 'HEAD', 'OPTIONS', 'TRACE')); + return in_array($this->getMethod(), 0 < func_num_args() && !func_get_arg(0) ? array('GET', 'HEAD', 'OPTIONS', 'TRACE') : array('GET', 'HEAD')); } /** diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index 2fa72d9aacfed..ad06622696298 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -1929,7 +1929,7 @@ public function testMethodSafe($method, $safe) { $request = new Request(); $request->setMethod($method); - $this->assertEquals($safe, $request->isMethodSafe()); + $this->assertEquals($safe, $request->isMethodSafe(false)); } public function methodSafeProvider() @@ -1948,6 +1948,13 @@ public function methodSafeProvider() ); } + public function testMethodSafeChecksCacheable() + { + $request = new Request(); + $request->setMethod('OPTION'); + $this->assertFalse($request->isMethodSafe()); + } + /** * @dataProvider methodCacheableProvider */ diff --git a/src/Symfony/Component/HttpKernel/EventListener/FragmentListener.php b/src/Symfony/Component/HttpKernel/EventListener/FragmentListener.php index 2ab6c8589eec3..ad6349286dde7 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/FragmentListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/FragmentListener.php @@ -81,7 +81,7 @@ public function onKernelRequest(GetResponseEvent $event) protected function validateRequest(Request $request) { // is the Request safe? - if (!$request->isMethodSafe()) { + if (!$request->isMethodSafe(false)) { throw new AccessDeniedHttpException(); } diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php index efb08d693c891..941d4c6fa033d 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php @@ -202,7 +202,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ } $this->traces[$request->getMethod().' '.$path] = array(); - if (!$request->isMethodSafe()) { + if (!$request->isMethodSafe(false)) { $response = $this->invalidate($request, $catch); } elseif ($request->headers->has('expect') || !$request->isMethodCacheable()) { $response = $this->pass($request, $catch); diff --git a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php index a1cae2a437214..4e8066b7e198b 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php @@ -209,7 +209,7 @@ private function startAuthentication(Request $request, AuthenticationException $ protected function setTargetPath(Request $request) { // session isn't required when using HTTP basic authentication mechanism for example - if ($request->hasSession() && $request->isMethodSafe() && !$request->isXmlHttpRequest()) { + if ($request->hasSession() && $request->isMethodSafe(false) && !$request->isXmlHttpRequest()) { $request->getSession()->set('_security.'.$this->providerKey.'.target_path', $request->getUri()); } } From 79ef474fdfd5805a8cbdc9a9b75b897a0a31cf55 Mon Sep 17 00:00:00 2001 From: Maxime STEINHAUSSER Date: Wed, 23 Nov 2016 15:35:00 +0100 Subject: [PATCH 33/56] [SecurityBundle] Remove FirewallContext mandatory FirewallConfig argument deprecation --- .../Bundle/SecurityBundle/Security/FirewallContext.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php b/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php index 9d00c121e5160..81b815e4d973e 100644 --- a/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php +++ b/src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php @@ -27,10 +27,6 @@ class FirewallContext public function __construct(array $listeners, ExceptionListener $exceptionListener = null, FirewallConfig $config = null) { - if (null === $config) { - @trigger_error(sprintf('"%s()" expects an instance of "%s" as third argument since version 3.2 and will trigger an error in 4.0 if not provided.', __METHOD__, FirewallConfig::class), E_USER_DEPRECATED); - } - $this->listeners = $listeners; $this->exceptionListener = $exceptionListener; $this->config = $config; From 34e7b956dd46cc03973ba90ce93523557a26a3e0 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 23 Nov 2016 13:49:06 +0100 Subject: [PATCH 34/56] [HttpKernel] Deprecate checking for cacheable HTTP methods in Request::isMethodSafe() --- .../Component/HttpFoundation/BinaryFileResponse.php | 2 +- src/Symfony/Component/HttpFoundation/Request.php | 12 +++++++++++- .../Component/HttpFoundation/Tests/RequestTest.php | 13 ++++++++++++- .../HttpKernel/EventListener/FragmentListener.php | 2 +- .../Component/HttpKernel/HttpCache/HttpCache.php | 2 +- .../Security/Http/Firewall/ExceptionListener.php | 2 +- 6 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php index a39984dffa717..f95d90c364051 100644 --- a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php +++ b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php @@ -190,7 +190,7 @@ public function prepare(Request $request) if (!$this->headers->has('Accept-Ranges')) { // Only accept ranges on safe HTTP methods - $this->headers->set('Accept-Ranges', $request->isMethodSafe() ? 'bytes' : 'none'); + $this->headers->set('Accept-Ranges', $request->isMethodSafe(false) ? 'bytes' : 'none'); } if (!$this->headers->has('Content-Type')) { diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index f857ac74fc3be..f17316a06a2d3 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1475,10 +1475,20 @@ public function isMethod($method) /** * Checks whether or not the method is safe. * + * @param bool $andCacheable Adds the additional condition that the method should be cacheable. True by default. + * * @return bool */ - public function isMethodSafe() + public function isMethodSafe(/* $andCacheable = true */) { + if (!func_num_args() || func_get_arg(0)) { + // This deprecation should be turned into a BadMethodCallException in 4.0 (without adding the argument in the signature) + // then setting $andCacheable to false should be deprecated in 4.1 + @trigger_error('Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is deprecated since version 3.2 and will throw an exception in 4.0. Disable checking only for cacheable methods by calling the method with `false` as first argument or use the Request::isMethodCacheable() instead.', E_USER_DEPRECATED); + + return in_array($this->getMethod(), array('GET', 'HEAD')); + } + return in_array($this->getMethod(), array('GET', 'HEAD', 'OPTIONS', 'TRACE')); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index 238be7601d321..ab0f3439dd66e 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -1994,7 +1994,7 @@ public function testMethodSafe($method, $safe) { $request = new Request(); $request->setMethod($method); - $this->assertEquals($safe, $request->isMethodSafe()); + $this->assertEquals($safe, $request->isMethodSafe(false)); } public function methodSafeProvider() @@ -2013,6 +2013,17 @@ public function methodSafeProvider() ); } + /** + * @group legacy + * @expectedDeprecation Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is deprecated since version 3.2 and will throw an exception in 4.0. Disable checking only for cacheable methods by calling the method with `false` as first argument or use the Request::isMethodCacheable() instead. + */ + public function testMethodSafeChecksCacheable() + { + $request = new Request(); + $request->setMethod('OPTION'); + $this->assertFalse($request->isMethodSafe()); + } + /** * @dataProvider methodCacheableProvider */ diff --git a/src/Symfony/Component/HttpKernel/EventListener/FragmentListener.php b/src/Symfony/Component/HttpKernel/EventListener/FragmentListener.php index 9fdaccfaf6857..37bf15c3a084f 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/FragmentListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/FragmentListener.php @@ -81,7 +81,7 @@ public function onKernelRequest(GetResponseEvent $event) protected function validateRequest(Request $request) { // is the Request safe? - if (!$request->isMethodSafe()) { + if (!$request->isMethodSafe(false)) { throw new AccessDeniedHttpException(); } diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php index 3e7ff0aab8251..686f0b852c202 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php @@ -182,7 +182,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ } $this->traces[$request->getMethod().' '.$path] = array(); - if (!$request->isMethodSafe()) { + if (!$request->isMethodSafe(false)) { $response = $this->invalidate($request, $catch); } elseif ($request->headers->has('expect') || !$request->isMethodCacheable()) { $response = $this->pass($request, $catch); diff --git a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php index 98f5ac04be303..3c9604ea7436b 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php @@ -220,7 +220,7 @@ private function startAuthentication(Request $request, AuthenticationException $ protected function setTargetPath(Request $request) { // session isn't required when using HTTP basic authentication mechanism for example - if ($request->hasSession() && $request->isMethodSafe() && !$request->isXmlHttpRequest()) { + if ($request->hasSession() && $request->isMethodSafe(false) && !$request->isXmlHttpRequest()) { $this->saveTargetPath($request->getSession(), $this->providerKey, $request->getUri()); } } From 82952bd43f91fcbbebc2f9932a311e77c25b0c43 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 23 Nov 2016 19:16:07 +0100 Subject: [PATCH 35/56] [FrameworkBundle] Add framework.cache.prefix_seed for predictible cache key prefixes --- .../DependencyInjection/Compiler/CachePoolPass.php | 7 ++++--- .../FrameworkBundle/DependencyInjection/Configuration.php | 4 ++++ .../DependencyInjection/FrameworkExtension.php | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php index c856c0206a5d7..6186cc9d5ff24 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php @@ -31,11 +31,12 @@ public function process(ContainerBuilder $container) { $namespaceSuffix = ''; - foreach (array('name', 'root_dir', 'environment', 'debug') as $key) { - if ($container->hasParameter('kernel.'.$key)) { - $namespaceSuffix .= '.'.$container->getParameter('kernel.'.$key); + foreach (array('kernel.name', 'kernel.environment', 'kernel.debug', 'cache.prefix.seed') as $key) { + if ($container->hasParameter($key)) { + $namespaceSuffix .= '.'.$container->getParameter($key); } } + $container->getParameterBag()->remove('cache.prefix.seed'); $aliases = $container->getAliases(); $attributes = array( diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index f33085f8724a8..5c6208e6e46f2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -667,6 +667,10 @@ private function addCacheSection(ArrayNodeDefinition $rootNode) ->addDefaultsIfNotSet() ->fixXmlConfig('pool') ->children() + ->scalarNode('prefix_seed') + ->info('Used to namespace cache keys when using several apps with the same shared backend') + ->example('my-application-name') + ->end() ->scalarNode('app') ->info('App related cache pools configuration') ->defaultValue('cache.adapter.filesystem') diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 5c009962eabfa..7a888e4cee431 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1242,6 +1242,9 @@ private function registerCacheConfiguration(array $config, ContainerBuilder $con $container->getDefinition('cache.adapter.system')->replaceArgument(2, $version); $container->getDefinition('cache.adapter.filesystem')->replaceArgument(2, $config['directory']); + if (isset($config['prefix_seed'])) { + $container->setParameter('cache.prefix.seed', $config['prefix_seed']); + } foreach (array('doctrine', 'psr6', 'redis') as $name) { if (isset($config[$name = 'default_'.$name.'_provider'])) { $container->setAlias('cache.'.$name, Compiler\CachePoolPass::getServiceProvider($container, $config[$name])); From 412fbe613fe9a8ff203c5b2cda796b2d77eb9813 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Wed, 23 Nov 2016 22:37:45 +0100 Subject: [PATCH 36/56] [DI] minor FileLoaders tests update --- .../DependencyInjection/Tests/Loader/XmlFileLoaderTest.php | 4 ++-- .../DependencyInjection/Tests/Loader/YamlFileLoaderTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index 2de5915f4ef41..1989c61fd3dae 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -131,8 +131,8 @@ public function testLoadImports() { $container = new ContainerBuilder(); $resolver = new LoaderResolver(array( - new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')), - new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')), + new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')), + new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yml')), $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')), )); $loader->setResolver($resolver); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index 0827b48eb8d12..b2082f07a126d 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -104,8 +104,8 @@ public function testLoadImports() { $container = new ContainerBuilder(); $resolver = new LoaderResolver(array( - new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')), - new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')), + new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')), + new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')), new PhpFileLoader($container, new FileLocator(self::$fixturesPath.'/php')), $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')), )); From 1b298e56228531bd541416defb86a63735d1bb81 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Wed, 23 Nov 2016 22:17:27 +0100 Subject: [PATCH 37/56] [Filesystem] Remove extra argv in dumpFile() tests --- src/Symfony/Component/Filesystem/Tests/FilesystemTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index db0fe5aa2ac05..37fbad496847d 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -1139,7 +1139,7 @@ public function testDumpFileWithFileScheme() $scheme = 'file://'; $filename = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt'; - $this->filesystem->dumpFile($filename, 'bar', null); + $this->filesystem->dumpFile($filename, 'bar'); $this->assertFileExists($filename); $this->assertSame('bar', file_get_contents($filename)); @@ -1150,7 +1150,7 @@ public function testDumpFileWithZlibScheme() $scheme = 'compress.zlib://'; $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt'; - $this->filesystem->dumpFile($filename, 'bar', null); + $this->filesystem->dumpFile($filename, 'bar'); // Zlib stat uses file:// wrapper so remove scheme $this->assertFileExists(str_replace($scheme, '', $filename)); From 7a5e11eb1206a121824b09a3e645d74b0781c92e Mon Sep 17 00:00:00 2001 From: kiler129 Date: Wed, 23 Nov 2016 11:45:56 -0600 Subject: [PATCH 38/56] =?UTF-8?q?[DI]=20Fixed=20custom=20services=20defini?= =?UTF-8?q?tion=20BC=20break=20introduced=20in=20ec7e70fb=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DependencyInjection/ContainerBuilder.php | 4 ++-- .../Tests/ContainerBuilderTest.php | 11 ++++++++++- .../Tests/Fixtures/CustomDefinition.php | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/CustomDefinition.php diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 7c9f5a243190a..28ff635854b48 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -840,8 +840,8 @@ public function findDefinition($id) */ public function createService(Definition $definition, $id, $tryProxy = true) { - if ('Symfony\Component\DependencyInjection\Definition' !== get_class($definition)) { - throw new RuntimeException(sprintf('Constructing service "%s" from a %s is not supported at build time.', $id, get_class($definition))); + if ($definition instanceof DefinitionDecorator) { + throw new RuntimeException(sprintf('Constructing decorated service "%s" from a %s is not supported at build time.', $id, get_class($definition))); } if ($definition->isSynthetic()) { diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 8f8c8b179f790..cb91eb50ed2d9 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -29,6 +29,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\DependencyInjection\Scope; use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition; use Symfony\Component\ExpressionLanguage\Expression; class ContainerBuilderTest extends \PHPUnit_Framework_TestCase @@ -407,7 +408,7 @@ public function testResolveServices() /** * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException - * @expectedExceptionMessage Constructing service "foo" from a Symfony\Component\DependencyInjection\DefinitionDecorator is not supported at build time. + * @expectedExceptionMessage Constructing decorated service "foo" from a Symfony\Component\DependencyInjection\DefinitionDecorator is not supported at build time. */ public function testResolveServicesWithDecoratedDefinition() { @@ -419,6 +420,14 @@ public function testResolveServicesWithDecoratedDefinition() $builder->get('foo'); } + public function testResolveServicesWithCustomDefinitionClass() + { + $builder = new ContainerBuilder(); + $builder->setDefinition('foo', new CustomDefinition('stdClass')); + + $this->assertInstanceOf('stdClass', $builder->get('foo')); + } + public function testMerge() { $container = new ContainerBuilder(new ParameterBag(array('bar' => 'foo'))); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CustomDefinition.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CustomDefinition.php new file mode 100644 index 0000000000000..65eea2106ed70 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CustomDefinition.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +use Symfony\Component\DependencyInjection\Definition; + +class CustomDefinition extends Definition +{ +} From 1df5e7fb9aa5beddda8fd41dd58d4a63d38a782f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 24 Nov 2016 11:42:22 +0100 Subject: [PATCH 39/56] Fix merge --- src/Symfony/Component/HttpFoundation/Tests/RequestTest.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index ccc09dda25911..ab0f3439dd66e 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -2013,13 +2013,6 @@ public function methodSafeProvider() ); } - public function testMethodSafeChecksCacheable() - { - $request = new Request(); - $request->setMethod('OPTION'); - $this->assertFalse($request->isMethodSafe()); - } - /** * @group legacy * @expectedDeprecation Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is deprecated since version 3.2 and will throw an exception in 4.0. Disable checking only for cacheable methods by calling the method with `false` as first argument or use the Request::isMethodCacheable() instead. From f62b82055b099f5c3226fe6eb86d5f2e0650a1ad Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 23 Nov 2016 09:28:29 +0100 Subject: [PATCH 40/56] [FrameworkBundle] Dont rely on any parent definition for "cache.annotations" --- .../Compiler/CachePoolClearerPass.php | 18 ++++++++++++++++++ .../DependencyInjection/FrameworkExtension.php | 1 + .../Bundle/FrameworkBundle/FrameworkBundle.php | 4 ++-- .../FrameworkBundle/Resources/config/cache.xml | 9 +++++++-- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php index 146c3c8c73416..c576a9d44805f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; +use Symfony\Component\Cache\Adapter\AbstractAdapter; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -36,5 +37,22 @@ public function process(ContainerBuilder $container) } } } + + if (!$container->has('cache.annotations')) { + return; + } + $factory = array(AbstractAdapter::class, 'createSystemCache'); + $annotationsPool = $container->getDefinition('cache.annotations'); + if ($factory !== $annotationsPool->getFactory() || 4 !== count($annotationsPool->getArguments())) { + return; + } + if ($container->has('monolog.logger.cache')) { + $annotationsPool->addArgument(new Reference('monolog.logger.cache')); + } elseif ($container->has('cache.system')) { + $systemPool = $container->getDefinition('cache.system'); + if ($factory === $systemPool->getFactory() && 5 <= count($systemArgs = $systemPool->getArguments())) { + $annotationsPool->addArgument($systemArgs[4]); + } + } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 5c009962eabfa..344ca91d038d2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1238,6 +1238,7 @@ private function registerPropertyInfoConfiguration(array $config, ContainerBuild private function registerCacheConfiguration(array $config, ContainerBuilder $container) { $version = substr(str_replace('/', '-', base64_encode(hash('sha256', uniqid(mt_rand(), true), true))), 0, 22); + $container->getDefinition('cache.annotations')->replaceArgument(2, $version); $container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $version); $container->getDefinition('cache.adapter.system')->replaceArgument(2, $version); $container->getDefinition('cache.adapter.filesystem')->replaceArgument(2, $config['directory']); diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index 72873aa6e97e8..4c20d146cb4bf 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -93,12 +93,12 @@ public function build(ContainerBuilder $container) $container->addCompilerPass(new SerializerPass()); $container->addCompilerPass(new PropertyInfoPass()); $container->addCompilerPass(new ControllerArgumentValueResolverPass()); - $container->addCompilerPass(new CachePoolPass()); + $container->addCompilerPass(new CachePoolPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 32); $container->addCompilerPass(new ValidateWorkflowsPass()); $container->addCompilerPass(new CachePoolClearerPass(), PassConfig::TYPE_AFTER_REMOVING); if ($container->getParameter('kernel.debug')) { - $container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1); + $container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -32); $container->addCompilerPass(new UnusedTagsPass(), PassConfig::TYPE_AFTER_REMOVING); $container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING); $container->addCompilerPass(new CompilerDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml index 461b40455a8c5..80cb00ada9652 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml @@ -22,8 +22,13 @@
- - + + + + + 0 + + %kernel.cache_dir%/pools From 2e404d07021d4c01f9ca831a7bb222efc15bed70 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 24 Nov 2016 17:53:44 +0100 Subject: [PATCH 41/56] [HttpKernel] Fix exception when serializing request attributes --- .../Controller/RouterController.php | 2 +- .../DataCollector/RequestDataCollector.php | 18 ++++++++++++++---- .../DataCollector/RequestDataCollectorTest.php | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php index 02449f601ef11..3ea170d7ea3ea 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php @@ -87,7 +87,7 @@ private function getTraces(RequestDataCollector $request, $method) $traceRequest = Request::create( $request->getPathInfo(), $request->getRequestServer(true)->get('REQUEST_METHOD'), - $request->getRequestAttributes(true)->all(), + array(), $request->getRequestCookies(true)->all(), array(), $request->getRequestServer(true)->all() diff --git a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php index 6e8623a700240..55c2f0e6f50a4 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php @@ -127,7 +127,7 @@ public function collect(Request $request, Response $response, \Exception $except if ('request_headers' === $key || 'response_headers' === $key) { $value = array_map(function ($v) { return isset($v[1]) ? $v : $v[0]; }, $value); } - if ('request_server' !== $key && 'request_attributes' !== $key && 'request_cookies' !== $key) { + if ('request_server' !== $key && 'request_cookies' !== $key) { $this->data[$key] = array_map(array($this, 'cloneVar'), $value); } } @@ -190,9 +190,9 @@ public function getRequestCookies($raw = false) return new ParameterBag($raw ? $this->data['request_cookies'] : array_map(array($this, 'cloneVar'), $this->data['request_cookies'])); } - public function getRequestAttributes($raw = false) + public function getRequestAttributes() { - return new ParameterBag($raw ? $this->data['request_attributes'] : array_map(array($this, 'cloneVar'), $this->data['request_attributes'])); + return new ParameterBag($this->data['request_attributes']); } public function getResponseHeaders() @@ -271,7 +271,17 @@ public function getIdentifier() */ public function getRouteParams() { - return isset($this->data['request_attributes']['_route_params']) ? array_map(array($this, 'cloneVar'), $this->data['request_attributes']['_route_params']) : array(); + if (!isset($this->data['request_attributes']['_route_params'])) { + return array(); + } + + $data = $this->data['request_attributes']['_route_params']; + $params = array(); + foreach ($data->getRawData()[1] as $k => $v) { + $params[$k] = $data->seek($k); + } + + return $params; } /** diff --git a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php index 6fec6d88d0a3a..245cd4c159693 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php @@ -47,7 +47,7 @@ public function testCollect() $this->assertInstanceOf('Symfony\Component\HttpFoundation\ParameterBag', $c->getRequestQuery()); $this->assertSame('html', $c->getFormat()); $this->assertEquals('foobar', $c->getRoute()); - $this->assertEquals(array('name' => $cloner->cloneVar('foo')), $c->getRouteParams()); + $this->assertEquals(array('name' => $cloner->cloneVar(array('name' => 'foo'))->seek('name')), $c->getRouteParams()); $this->assertSame(array(), $c->getSessionAttributes()); $this->assertSame('en', $c->getLocale()); $this->assertEquals($cloner->cloneVar($request->attributes->get('resource')), $attributes->get('resource')); From 962325a54e5e4c8deb8cb21ee414e8ac68dbf4e1 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 24 Nov 2016 18:44:53 +0100 Subject: [PATCH 42/56] [WebProfilerBundle] Dont use request attributes in RouterController --- .../Bundle/WebProfilerBundle/Controller/RouterController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php index d77eb279f4a69..b5d299e204184 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/RouterController.php @@ -87,7 +87,7 @@ private function getTraces(RequestDataCollector $request, $method) $traceRequest = Request::create( $request->getPathInfo(), $request->getRequestServer()->get('REQUEST_METHOD'), - $request->getRequestAttributes()->all(), + array(), $request->getRequestCookies()->all(), array(), $request->getRequestServer()->all() From c6b7aeb43932a5b4e456dcb55e5222fab911715a Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Thu, 24 Nov 2016 21:17:39 +0100 Subject: [PATCH 43/56] Add missing example for 'path' argument in debug:config --- .../Bundle/FrameworkBundle/Command/ConfigDebugCommand.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php index 39f7ac2f541c3..22811c6558894 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDebugCommand.php @@ -47,6 +47,10 @@ protected function configure() php %command.full_name% framework php %command.full_name% FrameworkBundle +For dumping a specific option, add its path as second argument: + + php %command.full_name% framework serializer.enabled + EOF ) ; From 330c0696047d1c9ea142b448858cbb2ca719b4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Mon, 21 Nov 2016 17:19:45 +0100 Subject: [PATCH 44/56] [Workflow] Fixed graphviz dumper for state machine --- .../Command/WorkflowDumpCommand.php | 4 +- .../Workflow/Dumper/GraphvizDumper.php | 71 ++++++++++------ .../Dumper/StateMachineGraphvizDumper.php | 80 +++++++++++++++++++ .../Tests/Dumper/GraphvizDumperTest.php | 12 +-- .../Dumper/StateMachineGraphvizDumperTest.php | 74 +++++++++++++++++ .../Workflow/Tests/StateMachineTest.php | 48 ++--------- .../Tests/Validator/WorkflowValidatorTest.php | 2 +- .../Workflow/Tests/WorkflowBuilderTrait.php | 37 ++++++++- .../Component/Workflow/Tests/WorkflowTest.php | 18 ++--- 9 files changed, 260 insertions(+), 86 deletions(-) create mode 100644 src/Symfony/Component/Workflow/Dumper/StateMachineGraphvizDumper.php create mode 100644 src/Symfony/Component/Workflow/Tests/Dumper/StateMachineGraphvizDumperTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php index ddfb987ff1937..40604e3d809db 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php @@ -15,6 +15,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Workflow\Dumper\GraphvizDumper; +use Symfony\Component\Workflow\Dumper\StateMachineGraphvizDumper; use Symfony\Component\Workflow\Marking; use Symfony\Component\Workflow\Workflow; @@ -60,13 +61,14 @@ protected function execute(InputInterface $input, OutputInterface $output) $serviceId = $input->getArgument('name'); if ($container->has('workflow.'.$serviceId)) { $workflow = $container->get('workflow.'.$serviceId); + $dumper = new GraphvizDumper(); } elseif ($container->has('state_machine.'.$serviceId)) { $workflow = $container->get('state_machine.'.$serviceId); + $dumper = new StateMachineGraphvizDumper(); } else { throw new \InvalidArgumentException(sprintf('No service found for "workflow.%1$s" nor "state_machine.%1$s".', $serviceId)); } - $dumper = new GraphvizDumper(); $marking = new Marking(); foreach ($input->getArgument('marking') as $place) { diff --git a/src/Symfony/Component/Workflow/Dumper/GraphvizDumper.php b/src/Symfony/Component/Workflow/Dumper/GraphvizDumper.php index 916c4bd460622..3681b6f1391a8 100644 --- a/src/Symfony/Component/Workflow/Dumper/GraphvizDumper.php +++ b/src/Symfony/Component/Workflow/Dumper/GraphvizDumper.php @@ -26,7 +26,7 @@ */ class GraphvizDumper implements DumperInterface { - private static $defaultOptions = array( + protected static $defaultOptions = array( 'graph' => array('ratio' => 'compress', 'rankdir' => 'LR'), 'node' => array('fontsize' => 9, 'fontname' => 'Arial', 'color' => '#333333', 'fillcolor' => 'lightblue', 'fixedsize' => true, 'width' => 1), 'edge' => array('fontsize' => 9, 'fontname' => 'Arial', 'color' => '#333333', 'arrowhead' => 'normal', 'arrowsize' => 0.5), @@ -58,7 +58,10 @@ public function dump(Definition $definition, Marking $marking = null, array $opt .$this->endDot(); } - private function findPlaces(Definition $definition, Marking $marking = null) + /** + * @internal + */ + protected function findPlaces(Definition $definition, Marking $marking = null) { $places = array(); @@ -79,7 +82,10 @@ private function findPlaces(Definition $definition, Marking $marking = null) return $places; } - private function findTransitions(Definition $definition) + /** + * @internal + */ + protected function findTransitions(Definition $definition) { $transitions = array(); @@ -93,37 +99,38 @@ private function findTransitions(Definition $definition) return $transitions; } - private function addPlaces(array $places) + /** + * @internal + */ + protected function addPlaces(array $places) { $code = ''; foreach ($places as $id => $place) { - $code .= sprintf(" place_%s [label=\"%s\", shape=circle%s];\n", - $this->dotize($id), - $id, - $this->addAttributes($place['attributes']) - ); + $code .= sprintf(" place_%s [label=\"%s\", shape=circle%s];\n", $this->dotize($id), $id, $this->addAttributes($place['attributes'])); } return $code; } - private function addTransitions(array $transitions) + /** + * @internal + */ + protected function addTransitions(array $transitions) { $code = ''; foreach ($transitions as $place) { - $code .= sprintf(" transition_%s [label=\"%s\", shape=box%s];\n", - $this->dotize($place['name']), - $place['name'], - $this->addAttributes($place['attributes']) - ); + $code .= sprintf(" transition_%s [label=\"%s\", shape=box%s];\n", $this->dotize($place['name']), $place['name'], $this->addAttributes($place['attributes'])); } return $code; } - private function findEdges(Definition $definition) + /** + * @internal + */ + protected function findEdges(Definition $definition) { $dotEdges = array(); @@ -147,7 +154,10 @@ private function findEdges(Definition $definition) return $dotEdges; } - private function addEdges($edges) + /** + * @internal + */ + protected function addEdges(array $edges) { $code = ''; @@ -163,7 +173,10 @@ private function addEdges($edges) return $code; } - private function startDot(array $options) + /** + * @internal + */ + protected function startDot(array $options) { return sprintf("digraph workflow {\n %s\n node [%s];\n edge [%s];\n\n", $this->addOptions($options['graph']), @@ -172,12 +185,23 @@ private function startDot(array $options) ); } - private function endDot() + /** + * @internal + */ + protected function endDot() { return "}\n"; } - private function addAttributes($attributes) + /** + * @internal + */ + protected function dotize($id) + { + return strtolower(preg_replace('/[^\w]/i', '_', $id)); + } + + private function addAttributes(array $attributes) { $code = array(); @@ -188,7 +212,7 @@ private function addAttributes($attributes) return $code ? ', '.implode(', ', $code) : ''; } - private function addOptions($options) + private function addOptions(array $options) { $code = array(); @@ -198,9 +222,4 @@ private function addOptions($options) return implode(' ', $code); } - - private function dotize($id) - { - return strtolower(preg_replace('/[^\w]/i', '_', $id)); - } } diff --git a/src/Symfony/Component/Workflow/Dumper/StateMachineGraphvizDumper.php b/src/Symfony/Component/Workflow/Dumper/StateMachineGraphvizDumper.php new file mode 100644 index 0000000000000..9f68e1daf72f3 --- /dev/null +++ b/src/Symfony/Component/Workflow/Dumper/StateMachineGraphvizDumper.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Workflow\Dumper; + +use Symfony\Component\Workflow\Definition; +use Symfony\Component\Workflow\Marking; + +class StateMachineGraphvizDumper extends GraphvizDumper +{ + /** + * {@inheritdoc} + * + * Dumps the workflow as a graphviz graph. + * + * Available options: + * + * * graph: The default options for the whole graph + * * node: The default options for nodes (places) + * * edge: The default options for edges + */ + public function dump(Definition $definition, Marking $marking = null, array $options = array()) + { + $places = $this->findPlaces($definition, $marking); + $edges = $this->findEdges($definition); + + $options = array_replace_recursive(self::$defaultOptions, $options); + + return $this->startDot($options) + .$this->addPlaces($places) + .$this->addEdges($edges) + .$this->endDot() + ; + } + + /** + * @internal + */ + protected function findEdges(Definition $definition) + { + $edges = array(); + + foreach ($definition->getTransitions() as $transition) { + foreach ($transition->getFroms() as $from) { + foreach ($transition->getTos() as $to) { + $edges[$from][] = array( + 'name' => $transition->getName(), + 'to' => $to, + ); + } + } + } + + return $edges; + } + + /** + * @internal + */ + protected function addEdges(array $edges) + { + $code = ''; + + foreach ($edges as $id => $edges) { + foreach ($edges as $edge) { + $code .= sprintf(" place_%s -> place_%s [label=\"%s\" style=\"%s\"];\n", $this->dotize($id), $this->dotize($edge['to']), $edge['name'], 'solid'); + } + } + + return $code; + } +} diff --git a/src/Symfony/Component/Workflow/Tests/Dumper/GraphvizDumperTest.php b/src/Symfony/Component/Workflow/Tests/Dumper/GraphvizDumperTest.php index 2b90ea8d5f197..01927b209c2ff 100644 --- a/src/Symfony/Component/Workflow/Tests/Dumper/GraphvizDumperTest.php +++ b/src/Symfony/Component/Workflow/Tests/Dumper/GraphvizDumperTest.php @@ -20,7 +20,7 @@ public function setUp() /** * @dataProvider provideWorkflowDefinitionWithoutMarking */ - public function testGraphvizDumperWithoutMarking($definition, $expected) + public function testDumpWithoutMarking($definition, $expected) { $dump = $this->dumper->dump($definition); @@ -30,7 +30,7 @@ public function testGraphvizDumperWithoutMarking($definition, $expected) /** * @dataProvider provideWorkflowDefinitionWithMarking */ - public function testWorkflowWithMarking($definition, $marking, $expected) + public function testDumpWithMarking($definition, $marking, $expected) { $dump = $this->dumper->dump($definition, $marking); @@ -40,9 +40,9 @@ public function testWorkflowWithMarking($definition, $marking, $expected) public function provideWorkflowDefinitionWithMarking() { yield array( - $this->createComplexWorkflow(), + $this->createComplexWorkflowDefinition(), new Marking(array('b' => 1)), - $this->createComplexWorkflowDumpWithMarking(), + $this->createComplexWorkflowDefinitionDumpWithMarking(), ); yield array( @@ -54,11 +54,11 @@ public function provideWorkflowDefinitionWithMarking() public function provideWorkflowDefinitionWithoutMarking() { - yield array($this->createComplexWorkflow(), $this->provideComplexWorkflowDumpWithoutMarking()); + yield array($this->createComplexWorkflowDefinition(), $this->provideComplexWorkflowDumpWithoutMarking()); yield array($this->createSimpleWorkflowDefinition(), $this->provideSimpleWorkflowDumpWithoutMarking()); } - public function createComplexWorkflowDumpWithMarking() + public function createComplexWorkflowDefinitionDumpWithMarking() { return 'digraph workflow { ratio="compress" rankdir="LR" diff --git a/src/Symfony/Component/Workflow/Tests/Dumper/StateMachineGraphvizDumperTest.php b/src/Symfony/Component/Workflow/Tests/Dumper/StateMachineGraphvizDumperTest.php new file mode 100644 index 0000000000000..c9a49b36f71e1 --- /dev/null +++ b/src/Symfony/Component/Workflow/Tests/Dumper/StateMachineGraphvizDumperTest.php @@ -0,0 +1,74 @@ +dumper = new StateMachineGraphvizDumper(); + } + + public function testDumpWithoutMarking() + { + $definition = $this->createComplexStateMachineDefinition(); + + $dump = $this->dumper->dump($definition); + + $expected = <<<'EOGRAPH' +digraph workflow { + ratio="compress" rankdir="LR" + node [fontsize="9" fontname="Arial" color="#333333" fillcolor="lightblue" fixedsize="1" width="1"]; + edge [fontsize="9" fontname="Arial" color="#333333" arrowhead="normal" arrowsize="0.5"]; + + place_a [label="a", shape=circle, style="filled"]; + place_b [label="b", shape=circle]; + place_c [label="c", shape=circle]; + place_d [label="d", shape=circle]; + place_a -> place_b [label="t1" style="solid"]; + place_d -> place_b [label="t1" style="solid"]; + place_b -> place_c [label="t2" style="solid"]; + place_b -> place_d [label="t3" style="solid"]; +} + +EOGRAPH; + + $this->assertEquals($expected, $dump); + } + + public function testDumpWithMarking() + { + $definition = $this->createComplexStateMachineDefinition(); + $marking = new Marking(array('b' => 1)); + + $expected = <<<'EOGRAPH' +digraph workflow { + ratio="compress" rankdir="LR" + node [fontsize="9" fontname="Arial" color="#333333" fillcolor="lightblue" fixedsize="1" width="1"]; + edge [fontsize="9" fontname="Arial" color="#333333" arrowhead="normal" arrowsize="0.5"]; + + place_a [label="a", shape=circle, style="filled"]; + place_b [label="b", shape=circle, color="#FF0000", shape="doublecircle"]; + place_c [label="c", shape=circle]; + place_d [label="d", shape=circle]; + place_a -> place_b [label="t1" style="solid"]; + place_d -> place_b [label="t1" style="solid"]; + place_b -> place_c [label="t2" style="solid"]; + place_b -> place_d [label="t3" style="solid"]; +} + +EOGRAPH; + + $dump = $this->dumper->dump($definition, $marking); + + $this->assertEquals($expected, $dump); + } +} diff --git a/src/Symfony/Component/Workflow/Tests/StateMachineTest.php b/src/Symfony/Component/Workflow/Tests/StateMachineTest.php index 6aa3c60fc1cc6..7dca9a824d7c1 100644 --- a/src/Symfony/Component/Workflow/Tests/StateMachineTest.php +++ b/src/Symfony/Component/Workflow/Tests/StateMachineTest.php @@ -2,21 +2,16 @@ namespace Symfony\Component\Workflow\Tests; -use Symfony\Component\Workflow\Definition; use Symfony\Component\Workflow\Marking; use Symfony\Component\Workflow\StateMachine; -use Symfony\Component\Workflow\Transition; class StateMachineTest extends \PHPUnit_Framework_TestCase { + use WorkflowBuilderTrait; + public function testCan() { - $places = array('a', 'b', 'c', 'd'); - $transitions[] = new Transition('t1', 'a', 'b'); - $transitions[] = new Transition('t1', 'd', 'b'); - $transitions[] = new Transition('t2', 'b', 'c'); - $transitions[] = new Transition('t3', 'b', 'd'); - $definition = new Definition($places, $transitions); + $definition = $this->createComplexStateMachineDefinition(); $net = new StateMachine($definition); $subject = new \stdClass(); @@ -29,47 +24,18 @@ public function testCan() $subject->marking = 'b'; $this->assertFalse($net->can($subject, 't1')); - - // The graph looks like: - // - // +-------------------------------+ - // v | - // +---+ +----+ +----+ +----+ +---+ +----+ - // | a | --> | t1 | --> | b | --> | t3 | --> | d | --> | t1 | - // +---+ +----+ +----+ +----+ +---+ +----+ - // | - // | - // v - // +----+ +----+ - // | t2 | --> | c | - // +----+ +----+ } public function testCanWithMultipleTransition() { - $places = array('a', 'b', 'c'); - $transitions[] = new Transition('t1', 'a', 'b'); - $transitions[] = new Transition('t2', 'a', 'c'); - $definition = new Definition($places, $transitions); + $definition = $this->createComplexStateMachineDefinition(); $net = new StateMachine($definition); $subject = new \stdClass(); - // If you are in place "a" you should be able to apply "t1" and "t2" - $subject->marking = 'a'; - $this->assertTrue($net->can($subject, 't1')); + // If you are in place "b" you should be able to apply "t1" and "t2" + $subject->marking = 'b'; $this->assertTrue($net->can($subject, 't2')); - - // The graph looks like: - // - // +----+ +----+ +---+ - // | a | --> | t1 | --> | b | - // +----+ +----+ +---+ - // | - // | - // v - // +----+ +----+ - // | t2 | --> | c | - // +----+ +----+ + $this->assertTrue($net->can($subject, 't3')); } } diff --git a/src/Symfony/Component/Workflow/Tests/Validator/WorkflowValidatorTest.php b/src/Symfony/Component/Workflow/Tests/Validator/WorkflowValidatorTest.php index 1b5fa67fdb083..30d2551fa1b0f 100644 --- a/src/Symfony/Component/Workflow/Tests/Validator/WorkflowValidatorTest.php +++ b/src/Symfony/Component/Workflow/Tests/Validator/WorkflowValidatorTest.php @@ -15,7 +15,7 @@ class WorkflowValidatorTest extends \PHPUnit_Framework_TestCase */ public function testSinglePlaceWorkflowValidatorAndComplexWorkflow() { - $definition = $this->createComplexWorkflow(); + $definition = $this->createComplexWorkflowDefinition(); (new WorkflowValidator(true))->validate($definition, 'foo'); } diff --git a/src/Symfony/Component/Workflow/Tests/WorkflowBuilderTrait.php b/src/Symfony/Component/Workflow/Tests/WorkflowBuilderTrait.php index d7b8de530445c..5e8db29061295 100644 --- a/src/Symfony/Component/Workflow/Tests/WorkflowBuilderTrait.php +++ b/src/Symfony/Component/Workflow/Tests/WorkflowBuilderTrait.php @@ -7,7 +7,7 @@ trait WorkflowBuilderTrait { - private function createComplexWorkflow() + private function createComplexWorkflowDefinition() { $places = range('a', 'g'); @@ -33,7 +33,7 @@ private function createComplexWorkflow() // +----+ +----+ +----+ +----+ } - public function createSimpleWorkflowDefinition() + private function createSimpleWorkflowDefinition() { $places = range('a', 'c'); @@ -42,5 +42,38 @@ public function createSimpleWorkflowDefinition() $transitions[] = new Transition('t2', 'b', 'c'); return new Definition($places, $transitions); + + // The graph looks like: + // +---+ +----+ +---+ +----+ +---+ + // | a | --> | t1 | --> | b | --> | t2 | --> | c | + // +---+ +----+ +---+ +----+ +---+ + } + + private function createComplexStateMachineDefinition() + { + $places = array('a', 'b', 'c', 'd'); + + $transitions[] = new Transition('t1', 'a', 'b'); + $transitions[] = new Transition('t1', 'd', 'b'); + $transitions[] = new Transition('t2', 'b', 'c'); + $transitions[] = new Transition('t3', 'b', 'd'); + + $definition = new Definition($places, $transitions); + + return $definition; + + // The graph looks like: + // t1 + // +------------------+ + // v | + // +---+ t1 +-----+ t2 +---+ | + // | a | ----> | b | ----> | c | | + // +---+ +-----+ +---+ | + // | | + // | t3 | + // v | + // +-----+ | + // | d | -------------+ + // +-----+ } } diff --git a/src/Symfony/Component/Workflow/Tests/WorkflowTest.php b/src/Symfony/Component/Workflow/Tests/WorkflowTest.php index 0a886752d5992..cb5256f412933 100644 --- a/src/Symfony/Component/Workflow/Tests/WorkflowTest.php +++ b/src/Symfony/Component/Workflow/Tests/WorkflowTest.php @@ -56,7 +56,7 @@ public function testGetMarkingWithImpossiblePlace() public function testGetMarkingWithEmptyInitialMarking() { - $definition = $this->createComplexWorkflow(); + $definition = $this->createComplexWorkflowDefinition(); $subject = new \stdClass(); $subject->marking = null; $workflow = new Workflow($definition, new MultipleStateMarkingStore()); @@ -70,7 +70,7 @@ public function testGetMarkingWithEmptyInitialMarking() public function testGetMarkingWithExistingMarking() { - $definition = $this->createComplexWorkflow(); + $definition = $this->createComplexWorkflowDefinition(); $subject = new \stdClass(); $subject->marking = null; $subject->marking = array('b' => 1, 'c' => 1); @@ -89,7 +89,7 @@ public function testGetMarkingWithExistingMarking() */ public function testCanWithUnexistingTransition() { - $definition = $this->createComplexWorkflow(); + $definition = $this->createComplexWorkflowDefinition(); $subject = new \stdClass(); $subject->marking = null; $workflow = new Workflow($definition, new MultipleStateMarkingStore()); @@ -99,7 +99,7 @@ public function testCanWithUnexistingTransition() public function testCan() { - $definition = $this->createComplexWorkflow(); + $definition = $this->createComplexWorkflowDefinition(); $subject = new \stdClass(); $subject->marking = null; $workflow = new Workflow($definition, new MultipleStateMarkingStore()); @@ -110,7 +110,7 @@ public function testCan() public function testCanWithGuard() { - $definition = $this->createComplexWorkflow(); + $definition = $this->createComplexWorkflowDefinition(); $subject = new \stdClass(); $subject->marking = null; $eventDispatcher = new EventDispatcher(); @@ -128,7 +128,7 @@ public function testCanWithGuard() */ public function testApplyWithImpossibleTransition() { - $definition = $this->createComplexWorkflow(); + $definition = $this->createComplexWorkflowDefinition(); $subject = new \stdClass(); $subject->marking = null; $workflow = new Workflow($definition, new MultipleStateMarkingStore()); @@ -138,7 +138,7 @@ public function testApplyWithImpossibleTransition() public function testApply() { - $definition = $this->createComplexWorkflow(); + $definition = $this->createComplexWorkflowDefinition(); $subject = new \stdClass(); $subject->marking = null; $workflow = new Workflow($definition, new MultipleStateMarkingStore()); @@ -153,7 +153,7 @@ public function testApply() public function testApplyWithEventDispatcher() { - $definition = $this->createComplexWorkflow(); + $definition = $this->createComplexWorkflowDefinition(); $subject = new \stdClass(); $subject->marking = null; $eventDispatcher = new EventDispatcherMock(); @@ -187,7 +187,7 @@ public function testApplyWithEventDispatcher() public function testGetEnabledTransitions() { - $definition = $this->createComplexWorkflow(); + $definition = $this->createComplexWorkflowDefinition(); $subject = new \stdClass(); $subject->marking = null; $eventDispatcher = new EventDispatcher(); From 97e94b4019ee2a386dfd5f543a2ffa4fe37c79d4 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Thu, 24 Nov 2016 22:33:31 +0100 Subject: [PATCH 45/56] Tag missing internals --- src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php | 4 ++-- src/Symfony/Component/Form/Util/OrderedHashMapIterator.php | 4 ++-- .../Core/Authentication/RememberMe/PersistentToken.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php b/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php index c429417c25f80..c479daa75ee78 100644 --- a/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php +++ b/src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php @@ -155,11 +155,11 @@ public function setValue($value) /** * Adds a choice to the current ones. * - * This method should only be used internally. - * * @param \DOMElement $node * * @throws \LogicException When choice provided is not multiple nor radio + * + * @internal */ public function addChoice(\DOMElement $node) { diff --git a/src/Symfony/Component/Form/Util/OrderedHashMapIterator.php b/src/Symfony/Component/Form/Util/OrderedHashMapIterator.php index 32f591c860698..534d74ea6f0e4 100644 --- a/src/Symfony/Component/Form/Util/OrderedHashMapIterator.php +++ b/src/Symfony/Component/Form/Util/OrderedHashMapIterator.php @@ -14,9 +14,9 @@ /** * Iterator for {@link OrderedHashMap} objects. * - * This class is internal and should not be used. - * * @author Bernhard Schussek + * + * @internal */ class OrderedHashMapIterator implements \Iterator { diff --git a/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentToken.php b/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentToken.php index d85572d0e07db..76873fc603cd7 100644 --- a/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentToken.php +++ b/src/Symfony/Component/Security/Core/Authentication/RememberMe/PersistentToken.php @@ -12,9 +12,9 @@ namespace Symfony\Component\Security\Core\Authentication\RememberMe; /** - * This class is only used by PersistentTokenRememberMeServices internally. - * * @author Johannes M. Schmitt + * + * @internal */ final class PersistentToken implements PersistentTokenInterface { From 5e3cbecd54af04fc7f3f99f8b37f8d82e1c56885 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 24 Nov 2016 11:24:08 +0100 Subject: [PATCH 46/56] [Bridge/Doctrine] Use cache.prefix.seed parameter for generating cache namespace --- .../AbstractDoctrineExtension.php | 11 ++++++++--- .../Compiler/CachePoolClearerPass.php | 2 ++ .../Compiler/CachePoolPass.php | 18 ++++++++---------- .../Compiler/CachePoolClearerPassTest.php | 4 ++++ .../Compiler/CachePoolPassTest.php | 16 ++++++++++++++-- 5 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php index 3a6a877e1fc4e..b9cac9f71845a 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -384,9 +384,14 @@ protected function loadCacheDriver($cacheName, $objectManagerName, array $cacheD if (!isset($cacheDriver['namespace'])) { // generate a unique namespace for the given application - $env = $container->getParameter('kernel.root_dir').$container->getParameter('kernel.environment'); - $hash = hash('sha256', $env); - $namespace = 'sf2'.$this->getMappingResourceExtension().'_'.$objectManagerName.'_'.$hash; + if ($container->hasParameter('cache.prefix.seed')) { + $seed = '.'.$container->getParameterBag()->resolveValue($container->getParameter('cache.prefix.seed')); + } else { + $seed = '_'.$container->getParameter('kernel.root_dir'); + } + $seed .= '.'.$container->getParameter('kernel.name').'.'.$container->getParameter('kernel.environment').'.'.$container->getParameter('kernel.debug'); + $hash = hash('sha256', $seed); + $namespace = 'sf_'.$this->getMappingResourceExtension().'_'.$objectManagerName.'_'.$hash; $cacheDriver['namespace'] = $namespace; } diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php index 146c3c8c73416..901722756bd4a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php @@ -25,6 +25,8 @@ final class CachePoolClearerPass implements CompilerPassInterface */ public function process(ContainerBuilder $container) { + $container->getParameterBag()->remove('cache.prefix.seed'); + foreach ($container->findTaggedServiceIds('cache.pool') as $id => $attributes) { foreach (array_reverse($attributes) as $attr) { if (isset($attr['clearer'])) { diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php index 6186cc9d5ff24..593b7782c66b0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php @@ -29,14 +29,12 @@ class CachePoolPass implements CompilerPassInterface */ public function process(ContainerBuilder $container) { - $namespaceSuffix = ''; - - foreach (array('kernel.name', 'kernel.environment', 'kernel.debug', 'cache.prefix.seed') as $key) { - if ($container->hasParameter($key)) { - $namespaceSuffix .= '.'.$container->getParameter($key); - } + if ($container->hasParameter('cache.prefix.seed')) { + $seed = '.'.$container->getParameterBag()->resolveValue($container->getParameter('cache.prefix.seed')); + } else { + $seed = '_'.$container->getParameter('kernel.root_dir'); } - $container->getParameterBag()->remove('cache.prefix.seed'); + $seed .= '.'.$container->getParameter('kernel.name').'.'.$container->getParameter('kernel.environment').'.'.$container->getParameter('kernel.debug'); $aliases = $container->getAliases(); $attributes = array( @@ -56,7 +54,7 @@ public function process(ContainerBuilder $container) } } if (!isset($tags[0]['namespace'])) { - $tags[0]['namespace'] = $this->getNamespace($namespaceSuffix, $id); + $tags[0]['namespace'] = $this->getNamespace($seed, $id); } if (isset($tags[0]['clearer'])) { $clearer = strtolower($tags[0]['clearer']); @@ -88,9 +86,9 @@ public function process(ContainerBuilder $container) } } - private function getNamespace($namespaceSuffix, $id) + private function getNamespace($seed, $id) { - return substr(str_replace('/', '-', base64_encode(hash('sha256', $id.$namespaceSuffix, true))), 0, 10); + return substr(str_replace('/', '-', base64_encode(hash('sha256', $id.$seed, true))), 0, 10); } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolClearerPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolClearerPassTest.php index 62a41962316e2..38a2d38761e3b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolClearerPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolClearerPassTest.php @@ -24,6 +24,10 @@ class CachePoolClearerPassTest extends \PHPUnit_Framework_TestCase public function testPoolRefsAreWeak() { $container = new ContainerBuilder(); + $container->setParameter('kernel.debug', false); + $container->setParameter('kernel.name', 'app'); + $container->setParameter('kernel.environment', 'prod'); + $container->setParameter('kernel.root_dir', 'foo'); $publicPool = new Definition(); $publicPool->addArgument('namespace'); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php index 53cb95837f7e8..192e1493d0c38 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/CachePoolPassTest.php @@ -29,6 +29,10 @@ protected function setUp() public function testNamespaceArgumentIsReplaced() { $container = new ContainerBuilder(); + $container->setParameter('kernel.debug', false); + $container->setParameter('kernel.name', 'app'); + $container->setParameter('kernel.environment', 'prod'); + $container->setParameter('kernel.root_dir', 'foo'); $adapter = new Definition(); $adapter->setAbstract(true); $adapter->addTag('cache.pool'); @@ -41,12 +45,16 @@ public function testNamespaceArgumentIsReplaced() $this->cachePoolPass->process($container); - $this->assertSame('kRFqMp5odS', $cachePool->getArgument(0)); + $this->assertSame('C42Pcl9VBJ', $cachePool->getArgument(0)); } public function testArgsAreReplaced() { $container = new ContainerBuilder(); + $container->setParameter('kernel.debug', false); + $container->setParameter('kernel.name', 'app'); + $container->setParameter('kernel.environment', 'prod'); + $container->setParameter('cache.prefix.seed', 'foo'); $cachePool = new Definition(); $cachePool->addTag('cache.pool', array( 'provider' => 'foobar', @@ -61,7 +69,7 @@ public function testArgsAreReplaced() $this->assertInstanceOf(Reference::class, $cachePool->getArgument(0)); $this->assertSame('foobar', (string) $cachePool->getArgument(0)); - $this->assertSame('kRFqMp5odS', $cachePool->getArgument(1)); + $this->assertSame('KO3xHaFEZU', $cachePool->getArgument(1)); $this->assertSame(3, $cachePool->getArgument(2)); } @@ -72,6 +80,10 @@ public function testArgsAreReplaced() public function testThrowsExceptionWhenCachePoolTagHasUnknownAttributes() { $container = new ContainerBuilder(); + $container->setParameter('kernel.debug', false); + $container->setParameter('kernel.name', 'app'); + $container->setParameter('kernel.environment', 'prod'); + $container->setParameter('kernel.root_dir', 'foo'); $adapter = new Definition(); $adapter->setAbstract(true); $adapter->addTag('cache.pool'); From 0af433b01f6d0b7870fc20e752e313c4eae0b8a0 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Sat, 19 Nov 2016 11:21:18 +0000 Subject: [PATCH 47/56] [DI] Initialize properties before method calls --- .../DependencyInjection/ContainerBuilder.php | 8 ++++---- .../DependencyInjection/Dumper/PhpDumper.php | 6 +++--- .../Tests/ContainerBuilderTest.php | 14 ++++++++++++++ .../Tests/Dumper/PhpDumperTest.php | 19 +++++++++++++++++++ .../Tests/Fixtures/includes/classes.php | 17 +++++++++++++++++ .../Tests/Fixtures/php/services9.php | 6 +++--- .../Tests/Fixtures/php/services9_compiled.php | 6 +++--- 7 files changed, 63 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 7c9f5a243190a..9313370004b2b 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -902,15 +902,15 @@ public function createService(Definition $definition, $id, $tryProxy = true) $this->shareService($definition, $service, $id); } - foreach ($definition->getMethodCalls() as $call) { - $this->callMethod($service, $call); - } - $properties = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties()))); foreach ($properties as $name => $value) { $service->$name = $value; } + foreach ($definition->getMethodCalls() as $call) { + $this->callMethod($service, $call); + } + if ($callable = $definition->getConfigurator()) { if (is_array($callable)) { $callable[0] = $parameterBag->resolveValue($callable[0]); diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 37c3275444bcc..2f7a01bc081d4 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -335,8 +335,8 @@ private function addServiceInlinedDefinitions($id, $definition) $code .= $this->addNewInstance($id, $sDefinition, '$'.$name, ' = '); if (!$this->hasReference($id, $sDefinition->getMethodCalls(), true) && !$this->hasReference($id, $sDefinition->getProperties(), true)) { - $code .= $this->addServiceMethodCalls(null, $sDefinition, $name); $code .= $this->addServiceProperties(null, $sDefinition, $name); + $code .= $this->addServiceMethodCalls(null, $sDefinition, $name); $code .= $this->addServiceConfigurator(null, $sDefinition, $name); } @@ -507,8 +507,8 @@ private function addServiceInlinedDefinitionsSetup($id, Definition $definition) } $name = (string) $this->definitionVariables->offsetGet($iDefinition); - $code .= $this->addServiceMethodCalls(null, $iDefinition, $name); $code .= $this->addServiceProperties(null, $iDefinition, $name); + $code .= $this->addServiceMethodCalls(null, $iDefinition, $name); $code .= $this->addServiceConfigurator(null, $iDefinition, $name); } @@ -663,8 +663,8 @@ private function addService($id, Definition $definition) $this->addServiceInlinedDefinitions($id, $definition). $this->addServiceInstance($id, $definition). $this->addServiceInlinedDefinitionsSetup($id, $definition). - $this->addServiceMethodCalls($id, $definition). $this->addServiceProperties($id, $definition). + $this->addServiceMethodCalls($id, $definition). $this->addServiceConfigurator($id, $definition). $this->addServiceReturn($id, $definition) ; diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 8f8c8b179f790..16e8ae19d244b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -798,6 +798,20 @@ public function testLazyLoadedService() $this->assertTrue($classInList); } + + public function testInitializePropertiesBeforeMethodCalls() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass'); + $container->register('bar', 'MethodCallClass') + ->setProperty('simple', 'bar') + ->setProperty('complex', new Reference('foo')) + ->addMethodCall('callMe'); + + $container->compile(); + + $this->assertTrue($container->get('bar')->callPassed(), '->compile() initializes properties before method calls'); + } } class FooClass diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 3d9570d4dbcef..72215e8c486a5 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -267,4 +267,23 @@ public function testInlinedDefinitionReferencingServiceContainer() $dumper = new PhpDumper($container); $this->assertStringEqualsFile(self::$fixturesPath.'/php/services13.php', $dumper->dump(), '->dump() dumps inline definitions which reference service_container'); } + + public function testInitializePropertiesBeforeMethodCalls() + { + require_once self::$fixturesPath.'/includes/classes.php'; + + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass'); + $container->register('bar', 'MethodCallClass') + ->setProperty('simple', 'bar') + ->setProperty('complex', new Reference('foo')) + ->addMethodCall('callMe'); + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls'))); + + $container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls(); + $this->assertTrue($container->get('bar')->callPassed(), '->dump() initializes properties before method calls'); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php index 70c3d275b8898..48b687c1f4e53 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php @@ -59,3 +59,20 @@ public function __construct(BarClass $bar) $this->bar = $bar; } } + +class MethodCallClass +{ + public $simple; + public $complex; + private $callPassed = false; + + public function callMe() + { + $this->callPassed = is_scalar($this->simple) && is_object($this->complex); + } + + public function callPassed() + { + return $this->callPassed; + } +} diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php index abdfcbce3a55a..ce8930b8ddeba 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php @@ -170,11 +170,11 @@ protected function getFooService() $this->services['foo'] = $instance = \Bar\FooClass::getInstance('foo', $a, array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'foobar' => $this->getParameter('foo')), true, $this); - $instance->setBar($this->get('bar')); - $instance->initialize(); $instance->foo = 'bar'; $instance->moo = $a; $instance->qux = array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'foobar' => $this->getParameter('foo')); + $instance->setBar($this->get('bar')); + $instance->initialize(); sc_configure($instance); return $instance; @@ -333,8 +333,8 @@ protected function getInlinedService() { $this->services['inlined'] = $instance = new \Bar(); - $instance->setBaz($this->get('baz')); $instance->pub = 'pub'; + $instance->setBaz($this->get('baz')); return $instance; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php index 6ee0d40f5652e..559560fa6da60 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -179,11 +179,11 @@ protected function getFooService() $this->services['foo'] = $instance = \Bar\FooClass::getInstance('foo', $a, array('bar' => 'foo is bar', 'foobar' => 'bar'), true, $this); - $instance->setBar($this->get('bar')); - $instance->initialize(); $instance->foo = 'bar'; $instance->moo = $a; $instance->qux = array('bar' => 'foo is bar', 'foobar' => 'bar'); + $instance->setBar($this->get('bar')); + $instance->initialize(); sc_configure($instance); return $instance; @@ -230,8 +230,8 @@ protected function getFooWithInlineService() $this->services['foo_with_inline'] = $instance = new \Foo(); - $a->setBaz($this->get('baz')); $a->pub = 'pub'; + $a->setBaz($this->get('baz')); $instance->setBar($a); From c17a85beff05e6b1255fe7bfe14beade27315f94 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 25 Nov 2016 10:58:59 +0100 Subject: [PATCH 48/56] [HttpFoundation] Add links to RFC-7231 --- src/Symfony/Component/HttpFoundation/Request.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index cdaa57e0e6ff6..888e5fdc010d3 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1466,6 +1466,8 @@ public function isMethod($method) /** * Checks whether the method is safe or not. * + * @see https://tools.ietf.org/html/rfc7231#section-4.2.1 + * * @param bool $andCacheable Adds the additional condition that the method should be cacheable. True by default. * * @return bool @@ -1478,6 +1480,8 @@ public function isMethodSafe(/* $andCacheable = true */) /** * Checks whether the method is cacheable or not. * + * @see https://tools.ietf.org/html/rfc7231#section-4.2.3 + * * @return bool */ public function isMethodCacheable() From 25a629419a86bb1f8344ad5c5f18a4ef038e6ebd Mon Sep 17 00:00:00 2001 From: Alexandru Bucur Date: Fri, 25 Nov 2016 10:30:34 +0200 Subject: [PATCH 49/56] Update documentation link to the component Update documentation link to the component since it has standalone examples --- src/Symfony/Component/Validator/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/README.md b/src/Symfony/Component/Validator/README.md index 9dfbffb3f545a..3ccb2901adeac 100644 --- a/src/Symfony/Component/Validator/README.md +++ b/src/Symfony/Component/Validator/README.md @@ -7,7 +7,7 @@ The Validator component provides tools to validate values following the Resources --------- - * [Documentation](https://symfony.com/doc/current/book/validation.html) + * [Documentation](https://symfony.com/doc/current/components/validator.html) * [Contributing](https://symfony.com/doc/current/contributing/index.html) * [Report issues](https://github.com/symfony/symfony/issues) and [send Pull Requests](https://github.com/symfony/symfony/pulls) From cf333f32c567a759cd583025e63849c776eddd6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1chym=20Tou=C5=A1ek?= Date: Tue, 1 Nov 2016 12:50:51 +0100 Subject: [PATCH 50/56] [FrameworkBundle] Improve performance of ControllerNameParser --- .../Controller/ControllerNameParser.php | 5 +++-- .../Routing/DelegatingLoader.php | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php index 374d0eba10ff6..989dc8cd23d7c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php @@ -46,11 +46,12 @@ public function __construct(KernelInterface $kernel) */ public function parse($controller) { - $originalController = $controller; - if (3 !== count($parts = explode(':', $controller))) { + $parts = explode(':', $controller); + if (3 !== count($parts) || in_array('', $parts, true)) { throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid "a:b:c" controller string.', $controller)); } + $originalController = $controller; list($bundle, $controller, $action) = $parts; $controller = str_replace('/', '\\', $controller); $bundles = array(); diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php b/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php index 801149372af99..22f658ee7d5cb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php +++ b/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php @@ -21,7 +21,7 @@ * DelegatingLoader delegates route loading to other loaders using a loader resolver. * * This implementation resolves the _controller attribute from the short notation - * to the fully-qualified form (from a:b:c to class:method). + * to the fully-qualified form (from a:b:c to class::method). * * @author Fabien Potencier */ @@ -85,15 +85,18 @@ public function load($resource, $type = null) $this->loading = false; foreach ($collection->all() as $route) { - if ($controller = $route->getDefault('_controller')) { - try { - $controller = $this->parser->parse($controller); - } catch (\InvalidArgumentException $e) { - // unable to optimize unknown notation - } + $controller = $route->getDefault('_controller'); + if (!$controller) { + continue; + } - $route->setDefault('_controller', $controller); + try { + $controller = $this->parser->parse($controller); + } catch (\InvalidArgumentException $e) { + // unable to optimize unknown notation } + + $route->setDefault('_controller', $controller); } return $collection; From 73fbd085f184a97de3400e4bbf05b0ed139d5ec6 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Thu, 10 Nov 2016 15:01:21 +0100 Subject: [PATCH 51/56] [Routing] Fail properly when a route parameter name cannot be used as a PCRE subpattern name --- .../Component/Routing/RouteCompiler.php | 24 +++++++++++++++---- .../Routing/Tests/RouteCompilerTest.php | 16 ++++++++++--- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Routing/RouteCompiler.php b/src/Symfony/Component/Routing/RouteCompiler.php index f6637da666b82..1ce18ceb6607c 100644 --- a/src/Symfony/Component/Routing/RouteCompiler.php +++ b/src/Symfony/Component/Routing/RouteCompiler.php @@ -28,12 +28,22 @@ class RouteCompiler implements RouteCompilerInterface */ const SEPARATORS = '/,;.:-_~+*=@|'; + /** + * The maximum supported length of a PCRE subpattern name + * http://pcre.org/current/doc/html/pcre2pattern.html#SEC16. + * + * @var int + * + * @internal + */ + const VARIABLE_MAXIMUM_LENGTH = 32; + /** * {@inheritdoc} * * @throws \LogicException If a variable is referenced more than once - * @throws \DomainException If a variable name is numeric because PHP raises an error for such - * subpatterns in PCRE and thus would break matching, e.g. "(?P<123>.+)". + * @throws \DomainException If a variable name starts with a digit or if it is too long to be successfully used as + * a PCRE subpattern. */ public static function compile(Route $route) { @@ -95,13 +105,19 @@ private static function compilePattern(Route $route, $pattern, $isHost) $precedingChar = strlen($precedingText) > 0 ? substr($precedingText, -1) : ''; $isSeparator = '' !== $precedingChar && false !== strpos(static::SEPARATORS, $precedingChar); - if (is_numeric($varName)) { - throw new \DomainException(sprintf('Variable name "%s" cannot be numeric in route pattern "%s". Please use a different name.', $varName, $pattern)); + // A PCRE subpattern name must start with a non-digit. Also a PHP variable cannot start with a digit so the + // variable would not be usable as a Controller action argument. + if (preg_match('/^\d/', $varName)) { + throw new \DomainException(sprintf('Variable name "%s" cannot start with a digit in route pattern "%s". Please use a different name.', $varName, $pattern)); } if (in_array($varName, $variables)) { throw new \LogicException(sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $pattern, $varName)); } + if (strlen($varName) > self::VARIABLE_MAXIMUM_LENGTH) { + throw new \DomainException(sprintf('Variable name "%s" cannot be longer than %s characters in route pattern "%s". Please use a shorter name.', $varName, self::VARIABLE_MAXIMUM_LENGTH, $pattern)); + } + if ($isSeparator && strlen($precedingText) > 1) { $tokens[] = array('text', substr($precedingText, 0, -1)); } elseif (!$isSeparator && strlen($precedingText) > 0) { diff --git a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php index b4b4f45a8379f..f08b9688a921d 100644 --- a/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php +++ b/src/Symfony/Component/Routing/Tests/RouteCompilerTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Routing\Tests; use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCompiler; class RouteCompilerTest extends \PHPUnit_Framework_TestCase { @@ -176,16 +177,16 @@ public function testRouteWithSameVariableTwice() } /** - * @dataProvider getNumericVariableNames + * @dataProvider getVariableNamesStartingWithADigit * @expectedException \DomainException */ - public function testRouteWithNumericVariableName($name) + public function testRouteWithVariableNameStartingWithADigit($name) { $route = new Route('/{'.$name.'}'); $route->compile(); } - public function getNumericVariableNames() + public function getVariableNamesStartingWithADigit() { return array( array('09'), @@ -264,4 +265,13 @@ public function provideCompileWithHostData() ), ); } + + /** + * @expectedException \DomainException + */ + public function testRouteWithTooLongVariableName() + { + $route = new Route(sprintf('/{%s}', str_repeat('a', RouteCompiler::VARIABLE_MAXIMUM_LENGTH + 1))); + $route->compile(); + } } From 62a195884929ab3e694bf24228540541914c263c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 25 Nov 2016 21:20:19 +0100 Subject: [PATCH 52/56] [Cache] Mark FilesystemAdapterTrait as internal --- .../Component/Cache/Adapter/FilesystemAdapterTrait.php | 2 ++ src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Cache/Adapter/FilesystemAdapterTrait.php b/src/Symfony/Component/Cache/Adapter/FilesystemAdapterTrait.php index faf6e50f0f948..2f6e43e6379fa 100644 --- a/src/Symfony/Component/Cache/Adapter/FilesystemAdapterTrait.php +++ b/src/Symfony/Component/Cache/Adapter/FilesystemAdapterTrait.php @@ -15,6 +15,8 @@ /** * @author Nicolas Grekas + * + * @internal */ trait FilesystemAdapterTrait { diff --git a/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php b/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php index 4bc80ee30022e..c3cbd3bef7e54 100644 --- a/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php +++ b/src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php @@ -28,8 +28,6 @@ public function testDefaultLifeTime() { if (isset($this->skippedTests[__FUNCTION__])) { $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - - return; } $cache = $this->createCachePool(2); @@ -51,8 +49,6 @@ public function testNotUnserializable() { if (isset($this->skippedTests[__FUNCTION__])) { $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - - return; } $cache = $this->createCachePool(); From 2699009770ab5fc6b198d879acede4780efab08b Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Fri, 25 Nov 2016 23:28:18 +0100 Subject: [PATCH 53/56] [HttpFoundation] Fix test ensuring isMethodSafe() checks cacheable --- src/Symfony/Component/HttpFoundation/Tests/RequestTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index ad06622696298..74f058923f13b 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -1951,7 +1951,7 @@ public function methodSafeProvider() public function testMethodSafeChecksCacheable() { $request = new Request(); - $request->setMethod('OPTION'); + $request->setMethod('OPTIONS'); $this->assertFalse($request->isMethodSafe()); } From 9287b527832864e1622e1dbbf1fbb3a7da11ee0f Mon Sep 17 00:00:00 2001 From: Julien Falque Date: Fri, 25 Nov 2016 20:30:18 +0100 Subject: [PATCH 54/56] Fix tests that do not trigger any depreciation --- src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php index a8977312bdae7..0d873732636a9 100644 --- a/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php +++ b/src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php @@ -25,8 +25,8 @@ class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener private $skippedFile = false; private $wasSkipped = array(); private $isSkipped = array(); - private $expectedDeprecations; - private $gatheredDeprecations; + private $expectedDeprecations = array(); + private $gatheredDeprecations = array(); private $previousErrorHandler; /** @@ -181,7 +181,8 @@ public function endTest(\PHPUnit_Framework_Test $test, $time) $test->getTestResultObject()->addFailure($test, $e, $time); } - $this->expectedDeprecations = $this->gatheredDeprecations = $this->previousErrorHandler = null; + $this->expectedDeprecations = $this->gatheredDeprecations = array(); + $this->previousErrorHandler = null; } if (-2 < $this->state && $test instanceof \PHPUnit_Framework_TestCase) { $groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName(false)); From 6f04b220ac123a251e5b8a29aff9ec1f9215a28a Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 26 Nov 2016 20:45:52 -0800 Subject: [PATCH 55/56] updated CHANGELOG for 3.2.0-RC2 --- CHANGELOG-3.2.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/CHANGELOG-3.2.md b/CHANGELOG-3.2.md index b1fe6f167c120..b2de770775c93 100644 --- a/CHANGELOG-3.2.md +++ b/CHANGELOG-3.2.md @@ -7,6 +7,33 @@ 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.0-RC2 (2016-11-27) + + * bug #20601 [FrameworkBundle] Don't rely on any parent definition for "cache.annotations" (nicolas-grekas) + * bug #20638 Fix legacy tests that do not trigger any depreciation (julienfalque) + * bug #20374 [FrameworkBundle] Improve performance of ControllerNameParser (enumag) + * bug #20474 [Routing] Fail properly when a route parameter name cannot be used as a PCRE subpattern name (fancyweb) + * bug #20616 [Bridge/Doctrine] Use cache.prefix.seed parameter for generating cache namespace (nicolas-grekas) + * bug #20566 [DI] Initialize properties before method calls (ro0NL) + * bug #20583 [Workflow] Fixed graphviz dumper for state machine (lyrixx) + * bug #20621 [HttpKernel] Fix exception when serializing request attributes (nicolas-grekas) + * bug #20609 [DI] Fixed custom services definition BC break introduced in ec7e70fb… (kiler129) + * bug #20598 [DI] Aliases should preserve the aliased invalid behavior (nicolas-grekas) + * bug #20600 [Process] Fix process continuing after reached timeout using getIterator() (chalasr) + * bug #20603 [HttpKernel] Deprecate checking for cacheable HTTP methods in Request::isMethodSafe() (nicolas-grekas) + * bug #20602 [HttpKernel] Revert BC breaking change of Request::isMethodSafe() (nicolas-grekas) + * bug #20610 [FrameworkBundle] Add framework.cache.prefix_seed for predictible cache key prefixes (nicolas-grekas) + * bug #20595 [WebProfilerBundle] Fix deprecated uses of profiler_dump (nicolas-grekas) + * bug #20589 [SecurityBundle] Fix FirewallConfig nullable arguments (ogizanagi) + * bug #20590 [DI] Allow null as default env value (sroze) + * bug #20499 [Doctrine][Form] support large integers (xabbuh) + * bug #20559 [FrameworkBundle] Avoid warming up the validator cache for non-existent class (Seldaek) + * bug #20576 [Process] Do feat test before enabling TTY mode (nicolas-grekas) + * bug #20577 [FrameworkBundle] Mark cache.default_*_provider services private (nicolas-grekas) + * bug #20550 [YAML] Fix processing timestamp strings with timezone (myesain) + * bug #20543 [DI] Fix error when trying to resolve a DefinitionDecorator (nicolas-grekas) + * bug #20544 [PhpUnitBridge] Fix time-sensitive tests that use data providers (julienfalque) + * 3.2.0-RC1 (2016-11-17) * feature #20533 [DI] Revert "deprecate get() for uncompiled container builders" (nicolas-grekas) From 42d6eac045d567e31a8da1f0915da5398ee0c02a Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 26 Nov 2016 20:46:10 -0800 Subject: [PATCH 56/56] updated VERSION for 3.2.0-RC2 --- 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 f1013f23c61b2..0bd98579b5a7a 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.0-DEV'; + const VERSION = '3.2.0-RC2'; const VERSION_ID = 30200; const MAJOR_VERSION = 3; const MINOR_VERSION = 2; const RELEASE_VERSION = 0; - const EXTRA_VERSION = 'DEV'; + const EXTRA_VERSION = 'RC2'; const END_OF_MAINTENANCE = '07/2017'; const END_OF_LIFE = '01/2018';