From 178a0f73b7d3ee78c04e51fbf77b2f2bfec02f4b Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Thu, 20 Jul 2017 19:10:01 -0400 Subject: [PATCH 01/16] Fixing a bug where if a core class was autowired, autowiring tried to autowire optional args as if they were required --- .../Compiler/AutowirePass.php | 6 ++++++ .../Tests/Compiler/AutowirePassTest.php | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php index 055347b6f8..a59444fcac 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @@ -273,6 +273,12 @@ class AutowirePass extends AbstractRecursivePass // no default value? Then fail if (!$parameter->isDefaultValueAvailable()) { + // For core classes, isDefaultValueAvailable() can + // be false when isOptional() returns true. If the + // argument *is* optional, allow it to be missing + if ($parameter->isOptional()) { + continue; + } throw new AutowiringFailedException($this->currentId, sprintf('Cannot autowire service "%s": argument "$%s" of method "%s()" must have a type-hint or be given a value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method)); } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php index 76cf290283..c78c3499c8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php @@ -512,6 +512,23 @@ class AutowirePassTest extends TestCase ); } + public function testOptionalArgsNoRequiredForCoreClasses() + { + $container = new ContainerBuilder(); + + $container->register('pdo_service', \PDO::class) + ->addArgument('sqlite:/foo.db') + ->setAutowired(true); + + (new AutowirePass())->process($container); + + $definition = $container->getDefinition('pdo_service'); + $this->assertEquals( + array('sqlite:/foo.db'), + $definition->getArguments() + ); + } + public function testSetterInjection() { $container = new ContainerBuilder(); From ef1e50802ed4af6e4d59688d4facd84925327ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Wed, 19 Jul 2017 13:44:58 +0200 Subject: [PATCH 02/16] [WebProfilerBundle] Display trace and context in the logger profiler --- .../views/Collector/logger.html.twig | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig index 373233afa8..6e92022a44 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/logger.html.twig @@ -224,31 +224,33 @@ {% endmacro %} {% macro render_log_message(category, log_index, log) %} - {% if log.context.exception.trace is defined %} + {% set has_context = log.context is defined and log.context is not empty %} + {% set has_trace = log.context.exception.trace is defined %} + + {% if not has_context %} + {{ profiler_dump_log(log.message) }} + {% else %} {{ profiler_dump_log(log.message, log.context) }} - {% set context_id = 'context-' ~ category ~ '-' ~ log_index %} +
+ {% set context_id = 'context-' ~ category ~ '-' ~ log_index %} + Show context -
-
+
+ {{ profiler_dump(log.context, maxDepth=1) }} +
+ + {% if has_trace %} +
{{ profiler_dump(log.context.exception.trace, maxDepth=1) }}
- - {% elseif log.context is defined and log.context is not empty %} - {{ profiler_dump_log(log.message, log.context) }} - - {% set context_id = 'context-' ~ category ~ '-' ~ log_index %} - - - {% else %} - {{ profiler_dump_log(log.message) }} + {% endif %} {% endif %} {% endmacro %} From 52e2821597fdeb32363e02301e650cf25e7785e6 Mon Sep 17 00:00:00 2001 From: David Badura Date: Fri, 21 Jul 2017 19:43:13 +0200 Subject: [PATCH 03/16] Router: allow HEAD method to be defined first --- .../Routing/Matcher/Dumper/PhpMatcherDumper.php | 2 +- .../Routing/Tests/Fixtures/dumper/url_matcher4.php | 11 +++++++++++ .../Tests/Matcher/Dumper/PhpMatcherDumperTest.php | 9 +++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php index 8eae68c4c2..1397bac448 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -307,7 +307,7 @@ EOF; if (in_array('GET', $methods)) { // Since we treat HEAD requests like GET requests we don't need to match it. $methodVariable = 'canonicalMethod'; - $methods = array_filter($methods, function ($method) { return 'HEAD' !== $method; }); + $methods = array_values(array_filter($methods, function ($method) { return 'HEAD' !== $method; })); } if (1 === count($methods)) { diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher4.php b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher4.php index b90e49af89..c638dca2a5 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher4.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher4.php @@ -57,6 +57,17 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher } not_head_and_get: + // get_and_head + if ('/get_and_head' === $pathinfo) { + if ('GET' !== $canonicalMethod) { + $allow[] = 'GET'; + goto not_get_and_head; + } + + return array('_route' => 'get_and_head'); + } + not_get_and_head: + // post_and_head if ('/post_and_get' === $pathinfo) { if (!in_array($requestMethod, array('POST', 'HEAD'))) { diff --git a/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php b/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php index 9d4f086be7..4fb65f4a11 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php @@ -297,6 +297,15 @@ class PhpMatcherDumperTest extends TestCase array(), '', array(), + array('HEAD', 'GET') + )); + $headMatchCasesCollection->add('get_and_head', new Route( + '/get_and_head', + array(), + array(), + array(), + '', + array(), array('GET', 'HEAD') )); $headMatchCasesCollection->add('post_and_head', new Route( From 1ba95738fb3cc240acb98f2a2e3391759dbf2034 Mon Sep 17 00:00:00 2001 From: Christopher Parotat Date: Sat, 22 Jul 2017 01:40:13 +0200 Subject: [PATCH 04/16] [Validator] Fix IbanValidator for ukrainian IBANs The ukrainian bank identifier consists of six digits and not letters. Also fix the broken links to the current SWIFT IBAN registry pdf. --- .../Component/Validator/Constraints/IbanValidator.php | 4 ++-- .../Validator/Tests/Constraints/IbanValidatorTest.php | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/IbanValidator.php b/src/Symfony/Component/Validator/Constraints/IbanValidator.php index ae4eb112b7..20300b00ab 100644 --- a/src/Symfony/Component/Validator/Constraints/IbanValidator.php +++ b/src/Symfony/Component/Validator/Constraints/IbanValidator.php @@ -34,7 +34,7 @@ class IbanValidator extends ConstraintValidator * a BBAN (Basic Bank Account Number) which has a fixed length per country and, * included within it, a bank identifier with a fixed position and a fixed length per country * - * @see http://www.swift.com/dsp/resources/documents/IBAN_Registry.pdf + * @see https://www.swift.com/sites/default/files/resources/iban_registry.pdf * * @var array */ @@ -130,7 +130,7 @@ class IbanValidator extends ConstraintValidator 'TL' => 'TL\d{2}\d{3}\d{14}\d{2}', // Timor-Leste 'TN' => 'TN59\d{2}\d{3}\d{13}\d{2}', // Tunisia 'TR' => 'TR\d{2}\d{5}[\dA-Z]{1}[\dA-Z]{16}', // Turkey - 'UA' => 'UA\d{2}[A-Z]{6}[\dA-Z]{19}', // Ukraine + 'UA' => 'UA\d{2}\d{6}[\dA-Z]{19}', // Ukraine 'VG' => 'VG\d{2}[A-Z]{4}\d{16}', // Virgin Islands, British 'WF' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // Wallis and Futuna Islands 'XK' => 'XK\d{2}\d{4}\d{10}\d{2}', // Republic of Kosovo diff --git a/src/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php index e9deb11de4..f16dafd827 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/IbanValidatorTest.php @@ -118,7 +118,7 @@ class IbanValidatorTest extends AbstractConstraintValidatorTest //Extended country list //http://www.nordea.com/Our+services/International+products+and+services/Cash+Management/IBAN+countries/908462.html - // http://www.swift.com/dsp/resources/documents/IBAN_Registry.pdf + // https://www.swift.com/sites/default/files/resources/iban_registry.pdf array('AO06000600000100037131174'), //Angola array('AZ21NABZ00000000137010001944'), //Azerbaijan array('BH29BMAG1299123456BH00'), //Bahrain @@ -156,6 +156,7 @@ class IbanValidatorTest extends AbstractConstraintValidatorTest array('TL380080012345678910157'), //Timor-Leste array('TN5914207207100707129648'), //Tunisia array('TR330006100519786457841326'), //Turkey + array('UA213223130000026007233566001'), //Ukraine array('AE260211000000230064016'), //United Arab Emirates ); } @@ -268,6 +269,7 @@ class IbanValidatorTest extends AbstractConstraintValidatorTest array('TL3800800123456789101571'), //Timor-Leste array('TN59142072071007071296481'), //Tunisia array('TR3300061005197864578413261'), //Turkey + array('UA21AAAA1300000260072335660012'), //Ukraine array('AE2602110000002300640161'), //United Arab Emirates ); } @@ -377,6 +379,7 @@ class IbanValidatorTest extends AbstractConstraintValidatorTest array('TL380080012345678910158'), //Timor-Leste array('TN5914207207100707129649'), //Tunisia array('TR330006100519786457841327'), //Turkey + array('UA213223130000026007233566002'), //Ukraine array('AE260211000000230064017'), //United Arab Emirates ); } From 7816f3b7c700d2e90b6d23d023fd63e685a5e6ff Mon Sep 17 00:00:00 2001 From: Valentin Date: Thu, 1 Jun 2017 23:44:40 +0300 Subject: [PATCH 05/16] [DoctrineBridge][PropertyInfo] Added support for Doctrine Embeddables --- .../PropertyInfo/DoctrineExtractor.php | 16 ++++++++- .../PropertyInfo/DoctrineExtractorTest.php | 36 +++++++++++++++++++ .../Fixtures/DoctrineEmbeddable.php | 28 +++++++++++++++ .../Fixtures/DoctrineWithEmbedded.php | 36 +++++++++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineEmbeddable.php create mode 100644 src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineWithEmbedded.php diff --git a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php index aba31792f9..200cc582d4 100644 --- a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php +++ b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php @@ -50,7 +50,17 @@ class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeE return; } - return array_merge($metadata->getFieldNames(), $metadata->getAssociationNames()); + $properties = array_merge($metadata->getFieldNames(), $metadata->getAssociationNames()); + + if ($metadata instanceof ClassMetadataInfo && class_exists('Doctrine\ORM\Mapping\Embedded') && $metadata->embeddedClasses) { + $properties = array_filter($properties, function ($property) { + return false === strpos($property, '.'); + }); + + $properties = array_merge($properties, array_keys($metadata->embeddedClasses)); + } + + return $properties; } /** @@ -105,6 +115,10 @@ class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeE )); } + if ($metadata instanceof ClassMetadataInfo && class_exists('Doctrine\ORM\Mapping\Embedded') && isset($metadata->embeddedClasses[$property])) { + return array(new Type(Type::BUILTIN_TYPE_OBJECT, false, $metadata->embeddedClasses[$property]['class'])); + } + if ($metadata->hasField($property)) { $typeOfField = $metadata->getTypeOfField($property); $nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property); diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php index 2224517db6..ecbfbbe32c 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php @@ -62,6 +62,21 @@ class DoctrineExtractorTest extends \PHPUnit_Framework_TestCase ); } + public function testGetPropertiesWithEmbedded() + { + if (!class_exists('Doctrine\ORM\Mapping\Embedded')) { + $this->markTestSkipped('@Embedded is not available in Doctrine ORM lower than 2.5.'); + } + + $this->assertEquals( + array( + 'id', + 'embedded', + ), + $this->extractor->getProperties('Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineWithEmbedded') + ); + } + /** * @dataProvider typesProvider */ @@ -70,6 +85,27 @@ class DoctrineExtractorTest extends \PHPUnit_Framework_TestCase $this->assertEquals($type, $this->extractor->getTypes('Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy', $property, array())); } + public function testExtractWithEmbedded() + { + if (!class_exists('Doctrine\ORM\Mapping\Embedded')) { + $this->markTestSkipped('@Embedded is not available in Doctrine ORM lower than 2.5.'); + } + + $expectedTypes = array(new Type( + Type::BUILTIN_TYPE_OBJECT, + false, + 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineEmbeddable' + )); + + $actualTypes = $this->extractor->getTypes( + 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineWithEmbedded', + 'embedded', + array() + ); + + $this->assertEquals($expectedTypes, $actualTypes); + } + public function typesProvider() { return array( diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineEmbeddable.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineEmbeddable.php new file mode 100644 index 0000000000..a00856ed73 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineEmbeddable.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures; + +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Embeddable; + +/** + * @Embeddable + * + * @author Udaltsov Valentin + */ +class DoctrineEmbeddable +{ + /** + * @Column(type="string") + */ + protected $field; +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineWithEmbedded.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineWithEmbedded.php new file mode 100644 index 0000000000..a1e011338f --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineWithEmbedded.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures; + +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\Embedded; + +/** + * @Entity + * + * @author Udaltsov Valentin + */ +class DoctrineWithEmbedded +{ + /** + * @Id + * @Column(type="smallint") + */ + public $id; + + /** + * @Embedded(class="DoctrineEmbeddable") + */ + protected $embedded; +} From 445c56aa3ea152ae51906782abbf76ff707a02db Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Sat, 22 Jul 2017 20:45:32 +0200 Subject: [PATCH 06/16] Remove unused mocks/vars --- .../FrameworkBundle/Tests/Command/RouterDebugCommandTest.php | 4 ---- .../FrameworkBundle/Tests/Command/RouterMatchCommandTest.php | 4 ---- .../Tests/Functional/ConfigDebugCommandTest.php | 2 +- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterDebugCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterDebugCommandTest.php index 597082485a..a8ef3cd421 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterDebugCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterDebugCommandTest.php @@ -71,10 +71,6 @@ class RouterDebugCommandTest extends TestCase ->will($this->returnValue($routeCollection)) ; - $loader = $this->getMockBuilder('Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader') - ->disableOriginalConstructor() - ->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock(); $container ->expects($this->once()) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php index 384bd7ca53..fe77fa5703 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/RouterMatchCommandTest.php @@ -70,10 +70,6 @@ class RouterMatchCommandTest extends TestCase ->will($this->returnValue($requestContext)) ; - $loader = $this->getMockBuilder('Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader') - ->disableOriginalConstructor() - ->getMock(); - $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock(); $container ->expects($this->atLeastOnce()) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ConfigDebugCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ConfigDebugCommandTest.php index 5b40325e08..a98879938d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ConfigDebugCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ConfigDebugCommandTest.php @@ -61,7 +61,7 @@ class ConfigDebugCommandTest extends WebTestCase public function testDumpUndefinedBundleOption() { $tester = $this->createCommandTester(); - $ret = $tester->execute(array('name' => 'TestBundle', 'path' => 'foo')); + $tester->execute(array('name' => 'TestBundle', 'path' => 'foo')); $this->assertContains('Unable to find configuration for "test.foo"', $tester->getDisplay()); } From 07ff4dd163486baade30b767a5d56d84e7540b31 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Sat, 22 Jul 2017 20:52:59 +0200 Subject: [PATCH 07/16] Remove unused prop + added @deprecated --- .../Tests/Functional/CachePoolClearCommandTest.php | 2 -- .../SecurityBundle/Command/UserPasswordEncoderCommand.php | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolClearCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolClearCommandTest.php index 59949dfdfd..c4ea8e3974 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolClearCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/CachePoolClearCommandTest.php @@ -19,8 +19,6 @@ use Symfony\Component\Console\Tester\CommandTester; */ class CachePoolClearCommandTest extends WebTestCase { - private $application; - protected function setUp() { static::bootKernel(array('test_case' => 'CachePoolClear', 'root_config' => 'config.yml')); diff --git a/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php b/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php index 6c3f032749..2e1fc2ef50 100644 --- a/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php +++ b/src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php @@ -48,6 +48,8 @@ class UserPasswordEncoderCommand extends ContainerAwareCommand /** * {@inheritdoc} + * + * @deprecated since version 3.3, to be removed in 4.0 */ protected function getContainer() { From cccc88f738b64d09739bb6a4365855827c63f16b Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 21 Jul 2017 14:42:57 +0200 Subject: [PATCH 08/16] [Cache] Handle unserialization failures for Memcached --- src/Symfony/Component/Cache/Traits/MemcachedTrait.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php index 8139d31fa9..c2832946f9 100644 --- a/src/Symfony/Component/Cache/Traits/MemcachedTrait.php +++ b/src/Symfony/Component/Cache/Traits/MemcachedTrait.php @@ -26,6 +26,7 @@ trait MemcachedTrait 'persistent_id' => null, 'username' => null, 'password' => null, + 'serializer' => 'php', ); private $client; @@ -194,7 +195,14 @@ trait MemcachedTrait */ protected function doFetch(array $ids) { - return $this->checkResultCode($this->client->getMulti($ids)); + $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback'); + try { + return $this->checkResultCode($this->client->getMulti($ids)); + } catch (\Error $e) { + throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()); + } finally { + ini_set('unserialize_callback_func', $unserializeCallbackHandler); + } } /** From 70cc4e86f4d32f3b2d51d23f7d2b2076fc11fe09 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 23 Jul 2017 11:15:20 +0200 Subject: [PATCH 09/16] [DI] Fix test --- .../Tests/Compiler/AutowirePassTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php index c78c3499c8..757db3f229 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php @@ -516,15 +516,15 @@ class AutowirePassTest extends TestCase { $container = new ContainerBuilder(); - $container->register('pdo_service', \PDO::class) - ->addArgument('sqlite:/foo.db') + $container->register('foo', \SplFileObject::class) + ->addArgument('foo.txt') ->setAutowired(true); (new AutowirePass())->process($container); - $definition = $container->getDefinition('pdo_service'); + $definition = $container->getDefinition('foo'); $this->assertEquals( - array('sqlite:/foo.db'), + array('foo.txt'), $definition->getArguments() ); } From 9fd425ea141e8812241d67ccba3effe5ecfa0f2e Mon Sep 17 00:00:00 2001 From: Guilhem Niot Date: Sun, 23 Jul 2017 14:40:01 +0200 Subject: [PATCH 10/16] Suggest using quotes instead of Yaml::PARSE_KEYS_AS_STRINGS --- UPGRADE-3.3.md | 13 +++++-------- UPGRADE-4.0.md | 18 ++++++++---------- src/Symfony/Component/Yaml/CHANGELOG.md | 13 +++++-------- src/Symfony/Component/Yaml/Inline.php | 2 +- src/Symfony/Component/Yaml/Parser.php | 2 +- .../Component/Yaml/Tests/InlineTest.php | 2 +- .../Component/Yaml/Tests/ParserTest.php | 4 ++-- 7 files changed, 23 insertions(+), 31 deletions(-) diff --git a/UPGRADE-3.3.md b/UPGRADE-3.3.md index b8d2524654..e43c365e6c 100644 --- a/UPGRADE-3.3.md +++ b/UPGRADE-3.3.md @@ -365,8 +365,7 @@ Yaml * Deprecated support for implicitly parsing non-string mapping keys as strings. Mapping keys that are no strings will lead to a `ParseException` in Symfony - 4.0. Use the `PARSE_KEYS_AS_STRINGS` flag to opt-in for keys to be parsed as - strings. + 4.0. Use quotes to opt-in for keys to be parsed as strings. Before: @@ -374,7 +373,6 @@ Yaml $yaml = << Date: Sun, 23 Jul 2017 18:14:03 +0300 Subject: [PATCH 11/16] Removed references for non existent validator constraints --- .../Form/Extension/Validator/ValidatorTypeGuesser.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php b/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php index c90443a9dc..4a5ed4d69e 100644 --- a/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php +++ b/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php @@ -151,8 +151,6 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface case 'Symfony\Component\Validator\Constraints\Count': return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CollectionType', array(), Guess::LOW_CONFIDENCE); - case 'Symfony\Component\Validator\Constraints\True': - case 'Symfony\Component\Validator\Constraints\False': case 'Symfony\Component\Validator\Constraints\IsTrue': case 'Symfony\Component\Validator\Constraints\IsFalse': return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CheckboxType', array(), Guess::MEDIUM_CONFIDENCE); @@ -171,7 +169,6 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface switch (get_class($constraint)) { case 'Symfony\Component\Validator\Constraints\NotNull': case 'Symfony\Component\Validator\Constraints\NotBlank': - case 'Symfony\Component\Validator\Constraints\True': case 'Symfony\Component\Validator\Constraints\IsTrue': return new ValueGuess(true, Guess::HIGH_CONFIDENCE); } From fe48ab1f8bb33dc33059510760a82ade7735d87f Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Mon, 24 Jul 2017 20:55:44 +0200 Subject: [PATCH 12/16] [Form] Static call TimezoneType::getTimezones --- src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php b/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php index beb83dde4f..486f0a28e4 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/TimezoneType.php @@ -66,7 +66,7 @@ class TimezoneType extends AbstractType implements ChoiceLoaderInterface return $this->choiceList; } - return $this->choiceList = new ArrayChoiceList($this->getTimezones(), $value); + return $this->choiceList = new ArrayChoiceList(self::getTimezones(), $value); } /** From 973b2d39730a64613ee0e3f0d6a312f9cddc81cb Mon Sep 17 00:00:00 2001 From: fmarchalemisys <30406081+fmarchalemisys@users.noreply.github.com> Date: Mon, 24 Jul 2017 16:01:47 +0200 Subject: [PATCH 13/16] [Form][TwigBridge] Don't render _method in form_rest() for a child form --- .../Bridge/Twig/Resources/views/Form/form_div_layout.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig index 0a52cc5110..a27c81dd49 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig @@ -303,7 +303,7 @@ {% endif %} {%- endfor %} - {% if not form.methodRendered %} + {% if not form.methodRendered and form.parent is null %} {%- do form.setMethodRendered() -%} {% set method = method|upper %} {%- if method in ["GET", "POST"] -%} From f3da6cf6a2d09c860b419572a30d2cd20c73c1d9 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 24 Jul 2017 22:27:32 +0200 Subject: [PATCH 14/16] [DI] Fix using private services in expressions --- .../Compiler/AnalyzeServiceReferencesPass.php | 28 +++++++ .../DependencyInjection/Dumper/PhpDumper.php | 10 ++- .../ExpressionLanguage.php | 4 +- .../ExpressionLanguageProvider.php | 9 +- .../Tests/Dumper/PhpDumperTest.php | 16 ++++ .../Tests/Fixtures/php/services9.php | 2 +- .../Tests/Fixtures/php/services9_compiled.php | 2 +- .../php/services_private_in_expression.php | 83 +++++++++++++++++++ 8 files changed, 148 insertions(+), 6 deletions(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_in_expression.php diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php index 717fc378e4..68b2a02172 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php @@ -12,8 +12,10 @@ namespace Symfony\Component\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\ExpressionLanguage; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\ExpressionLanguage\Expression; /** * Run this pass before passes that need to know more about the relation of @@ -32,6 +34,7 @@ class AnalyzeServiceReferencesPass implements RepeatablePassInterface private $currentDefinition; private $repeatedPass; private $onlyConstructorArguments; + private $expressionLanguage; /** * @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls @@ -97,6 +100,8 @@ class AnalyzeServiceReferencesPass implements RepeatablePassInterface foreach ($arguments as $argument) { if (is_array($argument)) { $this->processArguments($argument); + } elseif ($argument instanceof Expression) { + $this->getExpressionLanguage()->compile((string) $argument, array('this' => 'container')); } elseif ($argument instanceof Reference) { $this->graph->connect( $this->currentId, @@ -143,4 +148,27 @@ class AnalyzeServiceReferencesPass implements RepeatablePassInterface return $id; } + + private function getExpressionLanguage() + { + if (null === $this->expressionLanguage) { + $providers = $this->container->getExpressionLanguageProviders(); + $this->expressionLanguage = new ExpressionLanguage(null, $providers, function ($arg) { + if ('""' === substr_replace($arg, '', 1, -1)) { + $id = stripcslashes(substr($arg, 1, -1)); + + $this->graph->connect( + $this->currentId, + $this->currentDefinition, + $this->getDefinitionId($id), + $this->getDefinition($id) + ); + } + + return sprintf('$this->get(%s)', $arg); + }); + } + + return $this->expressionLanguage; + } } diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 19b1ba17c7..c43b677883 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1597,7 +1597,15 @@ EOF; throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); } $providers = $this->container->getExpressionLanguageProviders(); - $this->expressionLanguage = new ExpressionLanguage(null, $providers); + $this->expressionLanguage = new ExpressionLanguage(null, $providers, function ($arg) { + $id = '""' === substr_replace($arg, '', 1, -1) ? stripcslashes(substr($arg, 1, -1)) : null; + + if (null !== $id && ($this->container->hasAlias($id) || $this->container->hasDefinition($id))) { + return $this->getServiceCall($id); + } + + return sprintf('$this->get(%s)', $arg); + }); if ($this->container->isTrackingResources()) { foreach ($providers as $provider) { diff --git a/src/Symfony/Component/DependencyInjection/ExpressionLanguage.php b/src/Symfony/Component/DependencyInjection/ExpressionLanguage.php index d80985fa67..051d41b84b 100644 --- a/src/Symfony/Component/DependencyInjection/ExpressionLanguage.php +++ b/src/Symfony/Component/DependencyInjection/ExpressionLanguage.php @@ -25,10 +25,10 @@ class ExpressionLanguage extends BaseExpressionLanguage /** * {@inheritdoc} */ - public function __construct($cache = null, array $providers = array()) + public function __construct($cache = null, array $providers = array(), callable $serviceCompiler = null) { // prepend the default provider to let users override it easily - array_unshift($providers, new ExpressionLanguageProvider()); + array_unshift($providers, new ExpressionLanguageProvider($serviceCompiler)); parent::__construct($cache, $providers); } diff --git a/src/Symfony/Component/DependencyInjection/ExpressionLanguageProvider.php b/src/Symfony/Component/DependencyInjection/ExpressionLanguageProvider.php index ce6d69522e..e2084aa85d 100644 --- a/src/Symfony/Component/DependencyInjection/ExpressionLanguageProvider.php +++ b/src/Symfony/Component/DependencyInjection/ExpressionLanguageProvider.php @@ -24,10 +24,17 @@ use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; */ class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface { + private $serviceCompiler; + + public function __construct(callable $serviceCompiler = null) + { + $this->serviceCompiler = $serviceCompiler; + } + public function getFunctions() { return array( - new ExpressionFunction('service', function ($arg) { + new ExpressionFunction('service', $this->serviceCompiler ?: function ($arg) { return sprintf('$this->get(%s)', $arg); }, function (array $variables, $value) { return $variables['container']->get($value); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 2ff01d120b..179650df46 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -425,6 +425,22 @@ class PhpDumperTest extends TestCase $this->assertInstanceOf('BazClass', $container->get('bar')->getBaz()); } + public function testExpressionReferencingPrivateService() + { + $container = new ContainerBuilder(); + $container->register('private_bar', 'stdClass') + ->setPublic(false); + $container->register('private_foo', 'stdClass') + ->setPublic(false); + $container->register('public_foo', 'stdClass') + ->addArgument(new Expression('service("private_foo")')); + + $container->compile(); + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_private_in_expression.php', $dumper->dump()); + } + public function testDumpHandlesLiteralClassWithRootNamespace() { $container = new ContainerBuilder(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php index 306375d1b5..0f5789fef3 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9.php @@ -306,7 +306,7 @@ class ProjectServiceContainer extends Container if ($this->has('foobaz')) { $instance->setBar($this->get('foobaz', ContainerInterface::NULL_ON_INVALID_REFERENCE)); } - $instance->setBar(($this->get("foo")->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default")))); + $instance->setBar(($this->get('foo')->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default")))); 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 f8b263c2a0..751b76c852 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -299,7 +299,7 @@ class ProjectServiceContainer extends Container $instance->setBar($this->get('foo')); $instance->setBar(NULL); - $instance->setBar(($this->get("foo")->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default")))); + $instance->setBar(($this->get('foo')->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default")))); return $instance; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_in_expression.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_in_expression.php new file mode 100644 index 0000000000..a50653f55b --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_private_in_expression.php @@ -0,0 +1,83 @@ +services = array(); + $this->methodMap = array( + 'private_foo' => 'getPrivateFooService', + 'public_foo' => 'getPublicFooService', + ); + $this->privates = array( + 'private_foo' => true, + ); + + $this->aliases = array(); + } + + /** + * {@inheritdoc} + */ + public function compile() + { + throw new LogicException('You cannot compile a dumped frozen container.'); + } + + /** + * {@inheritdoc} + */ + public function isFrozen() + { + return true; + } + + /** + * Gets the 'public_foo' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return \stdClass A stdClass instance + */ + protected function getPublicFooService() + { + return $this->services['public_foo'] = new \stdClass(${($_ = isset($this->services['private_foo']) ? $this->services['private_foo'] : $this->getPrivateFooService()) && false ?: '_'}); + } + + /** + * Gets the 'private_foo' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * This service is private. + * If you want to be able to request this service from the container directly, + * make it public, otherwise you might end up with broken code. + * + * @return \stdClass A stdClass instance + */ + protected function getPrivateFooService() + { + return $this->services['private_foo'] = new \stdClass(); + } +} From 3c2f5f7a248fb8675e9d5259714eae388eb81e4d Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 25 Jul 2017 16:01:38 +0200 Subject: [PATCH 15/16] [VarDumper] Adapt to php 7.2 changes --- .../Component/VarDumper/Caster/Caster.php | 2 +- .../VarDumper/Tests/CliDumperTest.php | 47 +++++++++++++++---- .../VarDumper/Tests/VarClonerTest.php | 2 +- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Caster/Caster.php b/src/Symfony/Component/VarDumper/Caster/Caster.php index db052c8498..4123870043 100644 --- a/src/Symfony/Component/VarDumper/Caster/Caster.php +++ b/src/Symfony/Component/VarDumper/Caster/Caster.php @@ -54,7 +54,7 @@ class Caster if ($a) { $p = array_keys($a); foreach ($p as $i => $k) { - if (isset($k[0]) && "\0" !== $k[0] && !$reflector->hasProperty($k)) { + if (isset($k[0]) ? "\0" !== $k[0] && !$reflector->hasProperty($k) : \PHP_VERSION_ID >= 70200) { $p[$i] = self::PREFIX_DYNAMIC.$k; } elseif (isset($k[16]) && "\0" === $k[16] && 0 === strpos($k, "\0class@anonymous\0")) { $p[$i] = "\0".$reflector->getParentClass().'@anonymous'.strrchr($k, "\0"); diff --git a/src/Symfony/Component/VarDumper/Tests/CliDumperTest.php b/src/Symfony/Component/VarDumper/Tests/CliDumperTest.php index f8acf0d562..ebf5eed35e 100644 --- a/src/Symfony/Component/VarDumper/Tests/CliDumperTest.php +++ b/src/Symfony/Component/VarDumper/Tests/CliDumperTest.php @@ -141,8 +141,22 @@ EOTXT $var[] = &$v; $var[''] = 2; - $this->assertDumpMatchesFormat( - <<<'EOTXT' + if (\PHP_VERSION_ID >= 70200) { + $this->assertDumpMatchesFormat( + <<<'EOTXT' +array:4 [ + 0 => {} + 1 => &1 null + 2 => &1 null + "" => 2 +] +EOTXT + , + $var + ); + } else { + $this->assertDumpMatchesFormat( + <<<'EOTXT' array:4 [ "0" => {} "1" => &1 null @@ -150,9 +164,10 @@ array:4 [ "" => 2 ] EOTXT - , - $var - ); + , + $var + ); + } } public function testObjectCast() @@ -160,16 +175,28 @@ EOTXT $var = (object) array(1 => 1); $var->{1} = 2; - $this->assertDumpMatchesFormat( - <<<'EOTXT' + if (\PHP_VERSION_ID >= 70200) { + $this->assertDumpMatchesFormat( + <<<'EOTXT' +{ + +"1": 2 +} +EOTXT + , + $var + ); + } else { + $this->assertDumpMatchesFormat( + <<<'EOTXT' { +1: 1 +"1": 2 } EOTXT - , - $var - ); + , + $var + ); + } } public function testClosedResource() diff --git a/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php b/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php index 8ca59bdddf..6e98d6ecbc 100644 --- a/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php +++ b/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php @@ -203,7 +203,7 @@ object(Symfony\Component\VarDumper\Cloner\Data)#%i (4) { EOTXT; ob_start(); var_dump($clone); - $this->assertStringMatchesFormat($expected, ob_get_clean()); + $this->assertStringMatchesFormat(\PHP_VERSION_ID >= 70200 ? str_replace('"1"', '1', $expected) : $expected, ob_get_clean()); } public function testCaster() From eebae7ec7124def32d8d9153da4e4b174219885c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 26 Jul 2017 08:11:54 +0200 Subject: [PATCH 16/16] [DI] use assertStringEqualsFile when possible --- .../DependencyInjection/Tests/Dumper/PhpDumperTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 1ce5b7b999..e238649361 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -119,13 +119,13 @@ class PhpDumperTest extends TestCase // without compilation $container = include self::$fixturesPath.'/containers/container9.php'; $dumper = new PhpDumper($container); - $this->assertEquals(str_replace('%path%', str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9.php')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services9.php', str_replace(str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), '%path%', $dumper->dump()), '->dump() dumps services'); // with compilation $container = include self::$fixturesPath.'/containers/container9.php'; $container->compile(); $dumper = new PhpDumper($container); - $this->assertEquals(str_replace('%path%', str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9_compiled.php')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services9_compiled.php', str_replace(str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), '%path%', $dumper->dump()), '->dump() dumps services'); $dumper = new PhpDumper($container = new ContainerBuilder()); $container->register('foo', 'FooClass')->addArgument(new \stdClass()); @@ -145,7 +145,7 @@ class PhpDumperTest extends TestCase { $container = include self::$fixturesPath.'/containers/container20.php'; $dumper = new PhpDumper($container); - $this->assertEquals(str_replace('%path%', str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services20.php')), $dumper->dump(), '->dump() dumps services'); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services20.php', str_replace(str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), '%path%', $dumper->dump()), '->dump() dumps services'); } public function testServicesWithAnonymousFactories()