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'; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy