diff --git a/composer.json b/composer.json index 5c8ac1a2aa..99e66b2eea 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=7.2.5", "ext-xml": "*", - "friendsofphp/proxy-manager-lts": "^1.0", + "friendsofphp/proxy-manager-lts": "^1.0.2", "doctrine/event-manager": "~1.0", "doctrine/persistence": "^2", "twig/twig": "^2.10|^3.0", diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index 070347d853..a4ce339a7c 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -11,7 +11,7 @@ namespace Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper; -use ProxyManager\Generator\ClassGenerator; +use Laminas\Code\Generator\ClassGenerator; use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface; diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php index 1dee20d7a3..19a9bdd512 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php @@ -48,7 +48,7 @@ class SunnyInterface_%s implements \ProxyManager\Proxy\VirtualProxyInterface, \S static $reflection; $reflection = $reflection ?? new \ReflectionClass(__CLASS__); - $instance%w= $reflection->newInstanceWithoutConstructor(); + $instance = $reflection->newInstanceWithoutConstructor(); $instance->initializer%s = $initializer; @@ -73,48 +73,114 @@ class SunnyInterface_%s implements \ProxyManager\Proxy\VirtualProxyInterface, \S return $this->valueHolder%s->$name; } - $targetObject = $this->valueHolder%s; + $realInstanceReflection = new \ReflectionClass(__CLASS__); - $backtrace = debug_backtrace(false%S); - trigger_error( - sprintf( - 'Undefined property: %s::$%s in %s on line %s', - __CLASS__, - $name, - $backtrace[0]['file'], - $backtrace[0]['line'] - ), - \E_USER_NOTICE - ); - return $targetObject->$name; + if (! $realInstanceReflection->hasProperty($name)) { + $targetObject = $this->valueHolder%s; + + $backtrace = debug_backtrace(false, 1); + trigger_error( + sprintf( + 'Undefined property: %%s::$%%s in %%s on line %%s', + $realInstanceReflection->getName(), + $name, + $backtrace[0]['file'], + $backtrace[0]['line'] + ), + \E_USER_NOTICE + ); + return $targetObject->$name; + } + + $targetObject = $this->valueHolder%s; + $accessor = function & () use ($targetObject, $name) { + return $targetObject->$name; + }; + $backtrace = debug_backtrace(true, 2); + $scopeObject = isset($backtrace[1]['object']) ? $backtrace[1]['object'] : new \ProxyManager\Stub\EmptyClassStub(); + $accessor = $accessor->bindTo($scopeObject, get_class($scopeObject)); + $returnValue = & $accessor(); + + return $returnValue; } public function __set($name, $value) { $this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, '__set', array('name' => $name, 'value' => $value), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; - $targetObject = $this->valueHolder%s; + $realInstanceReflection = new \ReflectionClass(__CLASS__); - $targetObject->$name = $value;%wreturn $targetObject->$name; + if (! $realInstanceReflection->hasProperty($name)) { + $targetObject = $this->valueHolder%s; + + $targetObject->$name = $value; + + return $targetObject->$name; + } + + $targetObject = $this->valueHolder%s; + $accessor = function & () use ($targetObject, $name, $value) { + $targetObject->$name = $value; + + return $targetObject->$name; + }; + $backtrace = debug_backtrace(true, 2); + $scopeObject = isset($backtrace[1]['object']) ? $backtrace[1]['object'] : new \ProxyManager\Stub\EmptyClassStub(); + $accessor = $accessor->bindTo($scopeObject, get_class($scopeObject)); + $returnValue = & $accessor(); + + return $returnValue; } public function __isset($name) { $this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, '__isset', array('name' => $name), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; - $targetObject = $this->valueHolder%s; + $realInstanceReflection = new \ReflectionClass(__CLASS__); - return isset($targetObject->$name); + if (! $realInstanceReflection->hasProperty($name)) { + $targetObject = $this->valueHolder%s; + + return isset($targetObject->$name); + } + + $targetObject = $this->valueHolder%s; + $accessor = function () use ($targetObject, $name) { + return isset($targetObject->$name); + }; + $backtrace = debug_backtrace(true, 2); + $scopeObject = isset($backtrace[1]['object']) ? $backtrace[1]['object'] : new \ProxyManager\Stub\EmptyClassStub(); + $accessor = $accessor->bindTo($scopeObject, get_class($scopeObject)); + $returnValue = $accessor(); + + return $returnValue; } public function __unset($name) { $this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, '__unset', array('name' => $name), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; - $targetObject = $this->valueHolder%s; + $realInstanceReflection = new \ReflectionClass(__CLASS__); - unset($targetObject->$name); -%a } + if (! $realInstanceReflection->hasProperty($name)) { + $targetObject = $this->valueHolder%s; + + unset($targetObject->$name); + + return; + } + + $targetObject = $this->valueHolder%s; + $accessor = function () use ($targetObject, $name) { + unset($targetObject->$name); + + return; + }; + $backtrace = debug_backtrace(true, 2); + $scopeObject = isset($backtrace[1]['object']) ? $backtrace[1]['object'] : new \ProxyManager\Stub\EmptyClassStub(); + $accessor = $accessor->bindTo($scopeObject, get_class($scopeObject)); + $accessor(); + } public function __clone() { diff --git a/src/Symfony/Bridge/ProxyManager/composer.json b/src/Symfony/Bridge/ProxyManager/composer.json index ae8aa90e7d..99872089f0 100644 --- a/src/Symfony/Bridge/ProxyManager/composer.json +++ b/src/Symfony/Bridge/ProxyManager/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=7.2.5", "composer/package-versions-deprecated": "^1.8", - "friendsofphp/proxy-manager-lts": "^1.0", + "friendsofphp/proxy-manager-lts": "^1.0.2", "symfony/dependency-injection": "^5.0" }, "require-dev": { diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php index 8b728bc81c..ce4e66ca04 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php @@ -14,6 +14,7 @@ namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor; use Symfony\Component\Console\Exception\LogicException; use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\AbstractArgument; use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -393,6 +394,10 @@ class JsonDescriptor extends Descriptor ]; } + if ($value instanceof AbstractArgument) { + return ['type' => 'abstract', 'text' => $value->getText()]; + } + if ($value instanceof ArgumentInterface) { return $this->describeValue($value->getValues(), $omitTags, $showArguments); } diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php index 5e73580537..33566f7f3e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php @@ -16,6 +16,7 @@ use Symfony\Component\Console\Helper\Dumper; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\AbstractArgument; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; @@ -347,6 +348,8 @@ class TextDescriptor extends Descriptor $argumentsInformation[] = sprintf('Service locator (%d element(s))', \count($argument->getValues())); } elseif ($argument instanceof Definition) { $argumentsInformation[] = 'Inlined Service'; + } elseif ($argument instanceof AbstractArgument) { + $argumentsInformation[] = sprintf('Abstract argument (%s)', $argument->getText()); } else { $argumentsInformation[] = \is_array($argument) ? sprintf('Array (%d element(s))', \count($argument)) : $argument; } diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php index 86574b3f19..38780ec135 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php @@ -14,6 +14,7 @@ namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor; use Symfony\Component\Console\Exception\LogicException; use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\AbstractArgument; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; @@ -409,6 +410,9 @@ class XmlDescriptor extends Descriptor } } elseif ($argument instanceof Definition) { $argumentXML->appendChild($dom->importNode($this->getContainerDefinitionDocument($argument, null, false, true)->childNodes->item(0), true)); + } elseif ($argument instanceof AbstractArgument) { + $argumentXML->setAttribute('type', 'abstract'); + $argumentXML->appendChild(new \DOMText($argument->getText())); } elseif (\is_array($argument)) { $argumentXML->setAttribute('type', 'collection'); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php index 1da970371a..50cd4a4e46 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor; use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\AbstractArgument; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -146,6 +147,7 @@ class ObjectsProvider new Reference('definition_1'), new Reference('.definition_2'), ])) + ->addArgument(new AbstractArgument('placeholder')) ->setFactory(['Full\\Qualified\\FactoryClass', 'get']), '.definition_2' => $definition2 ->setPublic(false) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.json index e07b137438..8835a17d6f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.json +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.json @@ -60,7 +60,11 @@ "type": "service", "id": ".definition_2" } - ] + ], + { + "type": "abstract", + "text": "placeholder" + } ], "file": null, "factory_class": "Full\\Qualified\\FactoryClass", diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.xml index 061bb5d6ef..3a51fa1646 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.xml @@ -22,6 +22,7 @@ + placeholder diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.json index 209557d5ba..769679c6d2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.json +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.json @@ -58,7 +58,11 @@ "type": "service", "id": ".definition_2" } - ] + ], + { + "type": "abstract", + "text": "placeholder" + } ], "file": null, "factory_class": "Full\\Qualified\\FactoryClass", diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.txt b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.txt index 2e9dc9771c..af3410f83d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.txt +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.txt @@ -1,24 +1,25 @@ - ---------------- ----------------------------- -  Option   Value  - ---------------- ----------------------------- - Service ID - - Class Full\Qualified\Class1 - Tags - - Public yes - Synthetic no - Lazy yes - Shared yes - Abstract yes - Autowired no - Autoconfigured no - Factory Class Full\Qualified\FactoryClass - Factory Method get - Arguments Service(.definition_2)  - %parameter%  - Inlined Service  - Array (3 element(s))  - Iterator (2 element(s))  - - Service(definition_1)  - - Service(.definition_2) - ---------------- ----------------------------- + ---------------- --------------------------------- +  Option   Value  + ---------------- --------------------------------- + Service ID - + Class Full\Qualified\Class1 + Tags - + Public yes + Synthetic no + Lazy yes + Shared yes + Abstract yes + Autowired no + Autoconfigured no + Factory Class Full\Qualified\FactoryClass + Factory Method get + Arguments Service(.definition_2)  + %parameter%  + Inlined Service  + Array (3 element(s))  + Iterator (2 element(s))  + - Service(definition_1)  + - Service(.definition_2)  + Abstract argument (placeholder) + ---------------- --------------------------------- diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.xml index c3a099c152..b71fe8e144 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.xml @@ -20,4 +20,5 @@ + placeholder diff --git a/src/Symfony/Component/Finder/Tests/FinderTest.php b/src/Symfony/Component/Finder/Tests/FinderTest.php index e26aef1666..d41879d13b 100644 --- a/src/Symfony/Component/Finder/Tests/FinderTest.php +++ b/src/Symfony/Component/Finder/Tests/FinderTest.php @@ -631,7 +631,7 @@ class FinderTest extends Iterator\RealIteratorTestCase { $finder = $this->buildFinder(); $this->assertSame($finder, $finder->sortByName()); - $this->assertIterator($this->toAbsolute([ + $this->assertOrderedIterator($this->toAbsolute([ 'foo', 'foo bar', 'foo/bar.tmp', @@ -654,14 +654,12 @@ class FinderTest extends Iterator\RealIteratorTestCase { $finder = $this->buildFinder(); $this->assertSame($finder, $finder->sortByType()); - $this->assertIterator($this->toAbsolute([ + $this->assertOrderedIterator($this->toAbsolute([ 'foo', - 'foo bar', - 'toto', - 'foo/bar.tmp', - 'test.php', - 'test.py', 'qux', + 'toto', + 'foo bar', + 'foo/bar.tmp', 'qux/baz_100_1.py', 'qux/baz_1_2.py', 'qux_0_1.php', @@ -670,6 +668,8 @@ class FinderTest extends Iterator\RealIteratorTestCase 'qux_10_2.php', 'qux_12_0.php', 'qux_2_0.php', + 'test.php', + 'test.py', ]), $finder->in(self::$tmpDir)->getIterator()); } @@ -770,19 +770,19 @@ class FinderTest extends Iterator\RealIteratorTestCase { $finder = $this->buildFinder(); $this->assertSame($finder, $finder->sortByName(true)); - $this->assertIterator($this->toAbsolute([ + $this->assertOrderedIterator($this->toAbsolute([ 'foo', - 'foo bar', 'foo/bar.tmp', + 'foo bar', 'qux', - 'qux/baz_100_1.py', 'qux/baz_1_2.py', + 'qux/baz_100_1.py', 'qux_0_1.php', - 'qux_1000_1.php', - 'qux_1002_0.php', + 'qux_2_0.php', 'qux_10_2.php', 'qux_12_0.php', - 'qux_2_0.php', + 'qux_1000_1.php', + 'qux_1002_0.php', 'test.php', 'test.py', 'toto', @@ -790,7 +790,7 @@ class FinderTest extends Iterator\RealIteratorTestCase $finder = $this->buildFinder(); $this->assertSame($finder, $finder->sortByName(false)); - $this->assertIterator($this->toAbsolute([ + $this->assertOrderedIterator($this->toAbsolute([ 'foo', 'foo bar', 'foo/bar.tmp', @@ -813,13 +813,10 @@ class FinderTest extends Iterator\RealIteratorTestCase { $finder = $this->buildFinder(); $this->assertSame($finder, $finder->sort(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealPath(), $b->getRealPath()); })); - $this->assertIterator($this->toAbsolute([ + $this->assertOrderedIterator($this->toAbsolute([ 'foo', 'foo bar', 'foo/bar.tmp', - 'test.php', - 'test.py', - 'toto', 'qux', 'qux/baz_100_1.py', 'qux/baz_1_2.py', @@ -829,6 +826,9 @@ class FinderTest extends Iterator\RealIteratorTestCase 'qux_10_2.php', 'qux_12_0.php', 'qux_2_0.php', + 'test.php', + 'test.py', + 'toto', ]), $finder->in(self::$tmpDir)->getIterator()); } diff --git a/src/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php b/src/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php index a59d0cbe8e..7f567b99b6 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Profiler/FileProfilerStorageTest.php @@ -213,26 +213,25 @@ class FileProfilerStorageTest extends TestCase public function testStoreTime() { - $dt = new \DateTime('now'); - $start = $dt->getTimestamp(); + $start = $now = time(); for ($i = 0; $i < 3; ++$i) { - $dt->modify('+1 minute'); + $now += 60; $profile = new Profile('time_'.$i); $profile->setIp('127.0.0.1'); $profile->setUrl('http://foo.bar'); - $profile->setTime($dt->getTimestamp()); + $profile->setTime($now); $profile->setMethod('GET'); $this->storage->write($profile); } - $records = $this->storage->find('', '', 3, 'GET', $start, time() + 3 * 60); + $records = $this->storage->find('', '', 3, 'GET', $start, $start + 3 * 60); $this->assertCount(3, $records, '->find() returns all previously added records'); $this->assertEquals('time_2', $records[0]['token'], '->find() returns records ordered by time in descendant order'); $this->assertEquals('time_1', $records[1]['token'], '->find() returns records ordered by time in descendant order'); $this->assertEquals('time_0', $records[2]['token'], '->find() returns records ordered by time in descendant order'); - $records = $this->storage->find('', '', 3, 'GET', $start, time() + 2 * 60); + $records = $this->storage->find('', '', 3, 'GET', $start, $start + 2 * 60); $this->assertCount(2, $records, '->find() should return only first two of the previously added records'); }