diff --git a/.github/composer-config.json b/.github/composer-config.json index 2bdec1a826251..77add3dcc3b23 100644 --- a/.github/composer-config.json +++ b/.github/composer-config.json @@ -6,7 +6,6 @@ "symfony/http-kernel": "source", "symfony/messenger": "source", "symfony/notifier": "source", - "symfony/proxy-manager-bridge": "source", "symfony/translation": "source", "symfony/validator": "source", "*": "dist" diff --git a/UPGRADE-7.0.md b/UPGRADE-7.0.md index 5a9e8a2ba6435..f87b0113cf1f5 100644 --- a/UPGRADE-7.0.md +++ b/UPGRADE-7.0.md @@ -5,6 +5,11 @@ Symfony 6.4 and Symfony 7.0 will be released simultaneously at the end of Novemb release process, both versions will have the same features, but Symfony 7.0 won't include any deprecated features. To upgrade, make sure to resolve all deprecation notices. +ProxyManagerBridge +------------------ + + * Remove the bridge, use VarExporter's lazy objects instead + SecurityBundle -------------- diff --git a/composer.json b/composer.json index 7456ddd64e7c4..fd47788784b80 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,6 @@ "php": ">=8.2", "composer-runtime-api": ">=2.1", "ext-xml": "*", - "friendsofphp/proxy-manager-lts": "^1.0.2", "doctrine/event-manager": "^1.2|^2", "doctrine/persistence": "^2|^3", "twig/twig": "^2.13|^3.0.4", @@ -93,7 +92,6 @@ "symfony/process": "self.version", "symfony/property-access": "self.version", "symfony/property-info": "self.version", - "symfony/proxy-manager-bridge": "self.version", "symfony/rate-limiter": "self.version", "symfony/remote-event": "self.version", "symfony/routing": "self.version", @@ -181,7 +179,6 @@ "psr-4": { "Symfony\\Bridge\\Doctrine\\": "src/Symfony/Bridge/Doctrine/", "Symfony\\Bridge\\Monolog\\": "src/Symfony/Bridge/Monolog/", - "Symfony\\Bridge\\ProxyManager\\": "src/Symfony/Bridge/ProxyManager/", "Symfony\\Bridge\\Twig\\": "src/Symfony/Bridge/Twig/", "Symfony\\Bundle\\": "src/Symfony/Bundle/", "Symfony\\Component\\": "src/Symfony/Component/" diff --git a/src/Symfony/Bridge/Doctrine/Tests/LegacyManagerRegistryTest.php b/src/Symfony/Bridge/Doctrine/Tests/LegacyManagerRegistryTest.php deleted file mode 100644 index 7e525e35b1db4..0000000000000 --- a/src/Symfony/Bridge/Doctrine/Tests/LegacyManagerRegistryTest.php +++ /dev/null @@ -1,137 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\Doctrine\Tests; - -use PHPUnit\Framework\TestCase; -use ProxyManager\Proxy\LazyLoadingInterface; -use ProxyManager\Proxy\ValueHolderInterface; -use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper; -use Symfony\Bridge\ProxyManager\Tests\LazyProxy\Dumper\PhpDumperTest; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\DependencyInjection\Dumper\PhpDumper; -use Symfony\Component\Filesystem\Filesystem; - -/** - * @group legacy - */ -class LegacyManagerRegistryTest extends TestCase -{ - public static function setUpBeforeClass(): void - { - $test = new PhpDumperTest(); - $test->testDumpContainerWithProxyServiceWillShareProxies(); - } - - public function testResetService() - { - $container = new \LazyServiceProjectServiceContainer(); - - $registry = new TestManagerRegistry('name', [], ['defaultManager' => 'foo'], 'defaultConnection', 'defaultManager', 'proxyInterfaceName'); - $registry->setTestContainer($container); - - $foo = $container->get('foo'); - $foo->bar = 123; - $this->assertTrue(isset($foo->bar)); - - $registry->resetManager(); - - $this->assertSame($foo, $container->get('foo')); - $this->assertInstanceOf(\stdClass::class, $foo); - $this->assertFalse(property_exists($foo, 'bar')); - } - - /** - * When performing an entity manager lazy service reset, the reset operations may re-use the container - * to create a "fresh" service: when doing so, it can happen that the "fresh" service is itself a proxy. - * - * Because of that, the proxy will be populated with a wrapped value that is itself a proxy: repeating - * the reset operation keeps increasing this nesting until the application eventually runs into stack - * overflow or memory overflow operations, which can happen for long-running processes that rely on - * services that are reset very often. - */ - public function testResetServiceWillNotNestFurtherLazyServicesWithinEachOther() - { - // This test scenario only applies to containers composed as a set of generated sources - $this->dumpLazyServiceProjectAsFilesServiceContainer(); - - /** @var ContainerInterface $container */ - $container = new \LazyServiceProjectAsFilesServiceContainer(); - - $registry = new TestManagerRegistry( - 'irrelevant', - [], - ['defaultManager' => 'foo'], - 'irrelevant', - 'defaultManager', - 'irrelevant' - ); - $registry->setTestContainer($container); - - $service = $container->get('foo'); - - self::assertInstanceOf(\stdClass::class, $service); - self::assertInstanceOf(LazyLoadingInterface::class, $service); - self::assertInstanceOf(ValueHolderInterface::class, $service); - self::assertFalse($service->isProxyInitialized()); - - $service->initializeProxy(); - - self::assertTrue($container->initialized('foo')); - self::assertTrue($service->isProxyInitialized()); - - $registry->resetManager(); - $service->initializeProxy(); - - $wrappedValue = $service->getWrappedValueHolderValue(); - self::assertInstanceOf(\stdClass::class, $wrappedValue); - self::assertNotInstanceOf(LazyLoadingInterface::class, $wrappedValue); - self::assertNotInstanceOf(ValueHolderInterface::class, $wrappedValue); - } - - private function dumpLazyServiceProjectAsFilesServiceContainer() - { - if (class_exists(\LazyServiceProjectAsFilesServiceContainer::class, false)) { - return; - } - - $container = new ContainerBuilder(); - - $container->register('foo', \stdClass::class) - ->setPublic(true) - ->setLazy(true); - $container->compile(); - - $fileSystem = new Filesystem(); - - $temporaryPath = $fileSystem->tempnam(sys_get_temp_dir(), 'symfonyManagerRegistryTest'); - $fileSystem->remove($temporaryPath); - $fileSystem->mkdir($temporaryPath); - - $dumper = new PhpDumper($container); - - $dumper->setProxyDumper(new ProxyDumper()); - $containerFiles = $dumper->dump([ - 'class' => 'LazyServiceProjectAsFilesServiceContainer', - 'as_files' => true, - ]); - - array_walk( - $containerFiles, - static function (string $containerSources, string $fileName) use ($temporaryPath): void { - (new Filesystem())->dumpFile($temporaryPath.'/'.$fileName, $containerSources); - } - ); - - require $temporaryPath.'/LazyServiceProjectAsFilesServiceContainer.php'; - } -} diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index 2f5db399c9832..9564433d50ddc 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -36,7 +36,6 @@ "symfony/messenger": "^6.4|^7.0", "symfony/property-access": "^6.4|^7.0", "symfony/property-info": "^6.4|^7.0", - "symfony/proxy-manager-bridge": "^6.4|^7.0", "symfony/security-core": "^6.4|^7.0", "symfony/stopwatch": "^6.4|^7.0", "symfony/translation": "^6.4|^7.0", diff --git a/src/Symfony/Bridge/ProxyManager/.gitattributes b/src/Symfony/Bridge/ProxyManager/.gitattributes deleted file mode 100644 index 84c7add058fb5..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/.gitattributes +++ /dev/null @@ -1,4 +0,0 @@ -/Tests export-ignore -/phpunit.xml.dist export-ignore -/.gitattributes export-ignore -/.gitignore export-ignore diff --git a/src/Symfony/Bridge/ProxyManager/.gitignore b/src/Symfony/Bridge/ProxyManager/.gitignore deleted file mode 100644 index c49a5d8df5c65..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -vendor/ -composer.lock -phpunit.xml diff --git a/src/Symfony/Bridge/ProxyManager/CHANGELOG.md b/src/Symfony/Bridge/ProxyManager/CHANGELOG.md deleted file mode 100644 index 5ba6cdaf730a1..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/CHANGELOG.md +++ /dev/null @@ -1,22 +0,0 @@ -CHANGELOG -========= - -6.3 ---- - - * Deprecate the bridge - -4.2.0 ------ - - * allowed creating lazy-proxies from interfaces - -3.3.0 ------ - - * [BC BREAK] The `ProxyDumper` class is now final - -2.3.0 ------ - - * First introduction of `Symfony\Bridge\ProxyManager` diff --git a/src/Symfony/Bridge/ProxyManager/Internal/LazyLoadingFactoryTrait.php b/src/Symfony/Bridge/ProxyManager/Internal/LazyLoadingFactoryTrait.php deleted file mode 100644 index cabff29b3c5ec..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/Internal/LazyLoadingFactoryTrait.php +++ /dev/null @@ -1,33 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\ProxyManager\Internal; - -use ProxyManager\Configuration; - -/** - * @internal - */ -trait LazyLoadingFactoryTrait -{ - private readonly ProxyGenerator $generator; - - public function __construct(Configuration $config, ProxyGenerator $generator) - { - parent::__construct($config); - $this->generator = $generator; - } - - public function getGenerator(): ProxyGenerator - { - return $this->generator; - } -} diff --git a/src/Symfony/Bridge/ProxyManager/Internal/ProxyGenerator.php b/src/Symfony/Bridge/ProxyManager/Internal/ProxyGenerator.php deleted file mode 100644 index 26c95448eb2bb..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/Internal/ProxyGenerator.php +++ /dev/null @@ -1,86 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\ProxyManager\Internal; - -use Laminas\Code\Generator\ClassGenerator; -use ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator; -use ProxyManager\ProxyGenerator\ProxyGeneratorInterface; -use Symfony\Component\DependencyInjection\Definition; - -/** - * @internal - */ -class ProxyGenerator implements ProxyGeneratorInterface -{ - public function generate(\ReflectionClass $originalClass, ClassGenerator $classGenerator, array $proxyOptions = []): void - { - (new LazyLoadingValueHolderGenerator())->generate($originalClass, $classGenerator, $proxyOptions); - - foreach ($classGenerator->getMethods() as $method) { - if (str_starts_with($originalClass->getFilename(), __FILE__)) { - $method->setBody(str_replace(var_export($originalClass->name, true), '__CLASS__', $method->getBody())); - } - } - - if (str_starts_with($originalClass->getFilename(), __FILE__)) { - $interfaces = $classGenerator->getImplementedInterfaces(); - array_pop($interfaces); - $classGenerator->setImplementedInterfaces(array_merge($interfaces, $originalClass->getInterfaceNames())); - } - } - - public function getProxifiedClass(Definition $definition): ?string - { - if (!$definition->hasTag('proxy')) { - if (!($class = $definition->getClass()) || !(class_exists($class) || interface_exists($class, false))) { - return null; - } - - return (new \ReflectionClass($class))->name; - } - if (!$definition->isLazy()) { - throw new \InvalidArgumentException(sprintf('Invalid definition for service of class "%s": setting the "proxy" tag on a service requires it to be "lazy".', $definition->getClass())); - } - $tags = $definition->getTag('proxy'); - if (!isset($tags[0]['interface'])) { - throw new \InvalidArgumentException(sprintf('Invalid definition for service of class "%s": the "interface" attribute is missing on the "proxy" tag.', $definition->getClass())); - } - if (1 === \count($tags)) { - return class_exists($tags[0]['interface']) || interface_exists($tags[0]['interface'], false) ? $tags[0]['interface'] : null; - } - - $proxyInterface = 'LazyProxy'; - $interfaces = ''; - foreach ($tags as $tag) { - if (!isset($tag['interface'])) { - throw new \InvalidArgumentException(sprintf('Invalid definition for service of class "%s": the "interface" attribute is missing on a "proxy" tag.', $definition->getClass())); - } - if (!interface_exists($tag['interface'])) { - throw new \InvalidArgumentException(sprintf('Invalid definition for service of class "%s": several "proxy" tags found but "%s" is not an interface.', $definition->getClass(), $tag['interface'])); - } - - $proxyInterface .= '\\'.$tag['interface']; - $interfaces .= ', \\'.$tag['interface']; - } - - if (!interface_exists($proxyInterface)) { - $i = strrpos($proxyInterface, '\\'); - $namespace = substr($proxyInterface, 0, $i); - $interface = substr($proxyInterface, 1 + $i); - $interfaces = substr($interfaces, 2); - - eval("namespace {$namespace}; interface {$interface} extends {$interfaces} {}"); - } - - return $proxyInterface; - } -} diff --git a/src/Symfony/Bridge/ProxyManager/LICENSE b/src/Symfony/Bridge/ProxyManager/LICENSE deleted file mode 100644 index 0138f8f071351..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2004-present Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/RuntimeInstantiator.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/RuntimeInstantiator.php deleted file mode 100644 index 590dc2108e372..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/RuntimeInstantiator.php +++ /dev/null @@ -1,65 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\ProxyManager\LazyProxy\Instantiator; - -use ProxyManager\Configuration; -use ProxyManager\Factory\LazyLoadingValueHolderFactory; -use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; -use ProxyManager\Proxy\LazyLoadingInterface; -use Symfony\Bridge\ProxyManager\Internal\LazyLoadingFactoryTrait; -use Symfony\Bridge\ProxyManager\Internal\ProxyGenerator; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface; - -trigger_deprecation('symfony/proxy-manager-bridge', '6.3', 'The "symfony/proxy-manager-bridge" package is deprecated and can be removed from your dependencies.'); - -/** - * Runtime lazy loading proxy generator. - * - * @author Marco Pivetta - * - * @deprecated since Symfony 6.3 - */ -class RuntimeInstantiator implements InstantiatorInterface -{ - private Configuration $config; - private ProxyGenerator $generator; - - public function __construct() - { - $this->config = new Configuration(); - $this->config->setGeneratorStrategy(new EvaluatingGeneratorStrategy()); - $this->generator = new ProxyGenerator(); - } - - public function instantiateProxy(ContainerInterface $container, Definition $definition, string $id, callable $realInstantiator): object - { - $proxifiedClass = new \ReflectionClass($this->generator->getProxifiedClass($definition)); - - $factory = new class($this->config, $this->generator) extends LazyLoadingValueHolderFactory { - use LazyLoadingFactoryTrait; - }; - - $initializer = static function (&$wrappedInstance, LazyLoadingInterface $proxy) use ($realInstantiator) { - $wrappedInstance = $realInstantiator(); - $proxy->setProxyInitializer(null); - - return true; - }; - - return $factory->createProxy($proxifiedClass->name, $initializer, [ - 'fluentSafe' => $definition->hasTag('proxy'), - 'skipDestructor' => true, - ]); - } -} diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php deleted file mode 100644 index 3747d896bccd9..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ /dev/null @@ -1,104 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper; - -use Laminas\Code\Generator\ClassGenerator; -use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy; -use Symfony\Bridge\ProxyManager\Internal\ProxyGenerator; -use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface; - -trigger_deprecation('symfony/proxy-manager-bridge', '6.3', 'The "symfony/proxy-manager-bridge" package is deprecated and can be removed from your dependencies.'); - -/** - * Generates dumped PHP code of proxies via reflection. - * - * @author Marco Pivetta - * - * @deprecated since Symfony 6.3 - * - * @final - */ -class ProxyDumper implements DumperInterface -{ - private string $salt; - private ProxyGenerator $proxyGenerator; - private BaseGeneratorStrategy $classGenerator; - - public function __construct(string $salt = '') - { - $this->salt = $salt; - $this->proxyGenerator = new ProxyGenerator(); - $this->classGenerator = new BaseGeneratorStrategy(); - } - - public function isProxyCandidate(Definition $definition, bool &$asGhostObject = null, string $id = null): bool - { - $asGhostObject = false; - - return ($definition->isLazy() || $definition->hasTag('proxy')) && $this->proxyGenerator->getProxifiedClass($definition); - } - - public function getProxyFactoryCode(Definition $definition, string $id, string $factoryCode): string - { - $instantiation = 'return'; - - if ($definition->isShared()) { - $instantiation .= sprintf(' $container->%s[%s] =', $definition->isPublic() && !$definition->isPrivate() ? 'services' : 'privates', var_export($id, true)); - } - - $proxifiedClass = new \ReflectionClass($this->proxyGenerator->getProxifiedClass($definition)); - $proxyClass = $this->getProxyClassName($proxifiedClass->name); - - return <<createProxy('$proxyClass', static fn () => \\$proxyClass::staticProxyConstructor( - static function (&\$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface \$proxy) use (\$container) { - \$wrappedInstance = $factoryCode; - - \$proxy->setProxyInitializer(null); - - return true; - } - )); - } - - -EOF; - } - - public function getProxyCode(Definition $definition, string $id = null): string - { - $code = $this->classGenerator->generate($this->generateProxyClass($definition)); - $code = preg_replace('/^(class [^ ]++ extends )([^\\\\])/', '$1\\\\$2', $code); - - return $code; - } - - private function getProxyClassName(string $class): string - { - return preg_replace('/^.*\\\\/', '', $class).'_'.substr(hash('sha256', $class.$this->salt), -7); - } - - private function generateProxyClass(Definition $definition): ClassGenerator - { - $class = $this->proxyGenerator->getProxifiedClass($definition); - $generatedClass = new ClassGenerator($this->getProxyClassName($class)); - - $this->proxyGenerator->generate(new \ReflectionClass($class), $generatedClass, [ - 'fluentSafe' => $definition->hasTag('proxy'), - 'skipDestructor' => true, - ]); - - return $generatedClass; - } -} diff --git a/src/Symfony/Bridge/ProxyManager/README.md b/src/Symfony/Bridge/ProxyManager/README.md deleted file mode 100644 index ff6c6b2f76505..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/README.md +++ /dev/null @@ -1,15 +0,0 @@ -ProxyManager Bridge -=================== - -The ProxyManager bridge provides integration for [ProxyManager][1] with various -Symfony components. - -Resources ---------- - - * [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) - in the [main Symfony repository](https://github.com/symfony/symfony) - -[1]: https://github.com/FriendsOfPHP/proxy-manager-lts diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/ContainerBuilderTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/ContainerBuilderTest.php deleted file mode 100644 index dbe5795cb3447..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/ContainerBuilderTest.php +++ /dev/null @@ -1,62 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\ProxyManager\Tests\LazyProxy; - -require_once __DIR__.'/Fixtures/includes/foo.php'; - -use PHPUnit\Framework\TestCase; -use ProxyManager\Proxy\LazyLoadingInterface; -use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator; -use Symfony\Component\DependencyInjection\ContainerBuilder; - -/** - * Integration tests for {@see \Symfony\Component\DependencyInjection\ContainerBuilder} combined - * with the ProxyManager bridge. - * - * @author Marco Pivetta - * - * @group legacy - */ -class ContainerBuilderTest extends TestCase -{ - public function testCreateProxyServiceWithRuntimeInstantiator() - { - $builder = new ContainerBuilder(); - $builder->setProxyInstantiator(new RuntimeInstantiator()); - - $builder->register('foo1', \ProxyManagerBridgeFooClass::class)->setFile(__DIR__.'/Fixtures/includes/foo.php')->setPublic(true); - $builder->getDefinition('foo1')->setLazy(true)->addTag('proxy', ['interface' => \ProxyManagerBridgeFooClass::class]); - - $builder->compile(); - - /* @var $foo1 \ProxyManager\Proxy\LazyLoadingInterface|\ProxyManager\Proxy\ValueHolderInterface */ - $foo1 = $builder->get('foo1'); - - $foo1->__destruct(); - $this->assertSame(0, $foo1::$destructorCount); - - $this->assertSame($foo1, $builder->get('foo1'), 'The same proxy is retrieved on multiple subsequent calls'); - $this->assertInstanceOf(\ProxyManagerBridgeFooClass::class, $foo1); - $this->assertInstanceOf(LazyLoadingInterface::class, $foo1); - $this->assertFalse($foo1->isProxyInitialized()); - - $foo1->initializeProxy(); - - $this->assertSame($foo1, $builder->get('foo1'), 'The same proxy is retrieved after initialization'); - $this->assertTrue($foo1->isProxyInitialized()); - $this->assertInstanceOf(\ProxyManagerBridgeFooClass::class, $foo1->getWrappedValueHolderValue()); - $this->assertNotInstanceOf(LazyLoadingInterface::class, $foo1->getWrappedValueHolderValue()); - - $foo1->__destruct(); - $this->assertSame(1, $foo1::$destructorCount); - } -} diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Dumper/PhpDumperTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Dumper/PhpDumperTest.php deleted file mode 100644 index 32992796c0ebf..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Dumper/PhpDumperTest.php +++ /dev/null @@ -1,76 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\ProxyManager\Tests\LazyProxy\Dumper; - -use PHPUnit\Framework\TestCase; -use ProxyManager\Proxy\LazyLoadingInterface; -use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Dumper\PhpDumper; - -/** - * Integration tests for {@see \Symfony\Component\DependencyInjection\Dumper\PhpDumper} combined - * with the ProxyManager bridge. - * - * @author Marco Pivetta - * - * @group legacy - */ -class PhpDumperTest extends TestCase -{ - public function testDumpContainerWithProxyService() - { - $this->assertStringMatchesFormatFile( - __DIR__.'/../Fixtures/php/lazy_service_structure.txt', - $this->dumpLazyServiceProjectServiceContainer(), - '->dump() does generate proxy lazy loading logic.' - ); - } - - /** - * Verifies that the generated container retrieves the same proxy instance on multiple subsequent requests. - */ - public function testDumpContainerWithProxyServiceWillShareProxies() - { - if (!class_exists(\LazyServiceProjectServiceContainer::class, false)) { - eval('?>'.$this->dumpLazyServiceProjectServiceContainer()); - } - - $container = new \LazyServiceProjectServiceContainer(); - - $proxy = $container->get('foo'); - $this->assertInstanceOf(\stdClass::class, $proxy); - $this->assertInstanceOf(LazyLoadingInterface::class, $proxy); - $this->assertSame($proxy, $container->get('foo')); - - $this->assertFalse($proxy->isProxyInitialized()); - - $proxy->initializeProxy(); - - $this->assertTrue($proxy->isProxyInitialized()); - $this->assertSame($proxy, $container->get('foo')); - } - - private function dumpLazyServiceProjectServiceContainer() - { - $container = new ContainerBuilder(); - - $container->register('foo', \stdClass::class)->setPublic(true); - $container->getDefinition('foo')->setLazy(true)->addTag('proxy', ['interface' => \stdClass::class]); - $container->compile(); - - $dumper = new PhpDumper($container); - $dumper->setProxyDumper(new ProxyDumper()); - - return $dumper->dump(['class' => 'LazyServiceProjectServiceContainer']); - } -} diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/includes/foo.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/includes/foo.php deleted file mode 100644 index 435e9a4d77bff..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/includes/foo.php +++ /dev/null @@ -1,48 +0,0 @@ -arguments = $arguments; - } - - public static function getInstance($arguments = []) - { - $obj = new self($arguments); - $obj->called = true; - - return $obj; - } - - public function initialize() - { - $this->initialized = true; - } - - public function configure() - { - $this->configured = true; - } - - public function setBar($value = null) - { - $this->bar = $value; - } - - public function __destruct() - { - ++self::$destructorCount; - } -} diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/php/lazy_service_structure.txt b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/php/lazy_service_structure.txt deleted file mode 100644 index ad7a803cb6e8a..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Fixtures/php/lazy_service_structure.txt +++ /dev/null @@ -1,25 +0,0 @@ -services['foo'] = $container->createProxy('stdClass_%s', static fn () => %S\stdClass_%s( - static function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($container) { - $wrappedInstance = self::getFooService($container, false); - - $proxy->setProxyInitializer(null); - - return true; - } - )); - } - - return new \stdClass(); - } -} - -class stdClass_%s extends \stdClass implements \ProxyManager\%s -{%a}%A diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Instantiator/RuntimeInstantiatorTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Instantiator/RuntimeInstantiatorTest.php deleted file mode 100644 index 15190df1d308b..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/Instantiator/RuntimeInstantiatorTest.php +++ /dev/null @@ -1,58 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\ProxyManager\Tests\LazyProxy\Instantiator; - -use PHPUnit\Framework\TestCase; -use ProxyManager\Proxy\LazyLoadingInterface; -use ProxyManager\Proxy\ValueHolderInterface; -use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\DependencyInjection\Definition; - -/** - * Tests for {@see \Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator}. - * - * @author Marco Pivetta - * - * @group legacy - */ -class RuntimeInstantiatorTest extends TestCase -{ - /** - * @var RuntimeInstantiator - */ - protected $instantiator; - - protected function setUp(): void - { - $this->instantiator = new RuntimeInstantiator(); - } - - public function testInstantiateProxy() - { - $instance = new \stdClass(); - $container = $this->createMock(ContainerInterface::class); - $definition = new Definition('stdClass'); - $instantiator = fn () => $instance; - - /* @var $proxy LazyLoadingInterface|ValueHolderInterface */ - $proxy = $this->instantiator->instantiateProxy($container, $definition, 'foo', $instantiator); - - $this->assertInstanceOf(LazyLoadingInterface::class, $proxy); - $this->assertInstanceOf(ValueHolderInterface::class, $proxy); - $this->assertFalse($proxy->isProxyInitialized()); - - $proxy->initializeProxy(); - - $this->assertSame($instance, $proxy->getWrappedValueHolderValue()); - } -} diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-factory.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-factory.php deleted file mode 100644 index c0399ae3340f3..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-factory.php +++ /dev/null @@ -1,33 +0,0 @@ -privates['foo'] = $container->createProxy('SunnyInterface_1eff735', static fn () => \SunnyInterface_1eff735::staticProxyConstructor( - static function (&$wrappedInstance, \ProxyManager\Proxy\LazyLoadingInterface $proxy) use ($container) { - $wrappedInstance = $container->getFooService(false); - - $proxy->setProxyInitializer(null); - - return true; - } - )); - } - - return new Symfony\Bridge\ProxyManager\Tests\LazyProxy\PhpDumper\DummyClass(); - } - - protected function createProxy($class, \Closure $factory) - { - $this->proxyClass = $class; - - return $factory(); - } -}; 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 deleted file mode 100644 index 19a9bdd5125d3..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/Fixtures/proxy-implem.php +++ /dev/null @@ -1,227 +0,0 @@ -initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, 'dummy', array(), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; - - if ($this->valueHolder%s === $returnValue = $this->valueHolder%s->dummy()) { - return $this; - } - - return $returnValue; - } - - public function & dummyRef() - { - $this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, 'dummyRef', array(), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; - - if ($this->valueHolder%s === $returnValue = & $this->valueHolder%s->dummyRef()) { - return $this; - } - - return $returnValue; - } - - public function sunny() - { - $this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, 'sunny', array(), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; - - if ($this->valueHolder%s === $returnValue = $this->valueHolder%s->sunny()) { - return $this; - } - - return $returnValue; - } - - public static function staticProxyConstructor($initializer) - { - static $reflection; - - $reflection = $reflection ?? new \ReflectionClass(__CLASS__); - $instance = $reflection->newInstanceWithoutConstructor(); - - $instance->initializer%s = $initializer; - - return $instance; - } - - public function __construct() - { - static $reflection; - - if (! $this->valueHolder%s) { - $reflection = $reflection ?? new \ReflectionClass(__CLASS__); - $this->valueHolder%s = $reflection->newInstanceWithoutConstructor(); - } - } - - public function & __get($name) - { - $this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, '__get', ['name' => $name], $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; - - if (isset(self::$publicProperties%s[$name])) { - return $this->valueHolder%s->$name; - } - - $realInstanceReflection = new \ReflectionClass(__CLASS__); - - 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; - - $realInstanceReflection = new \ReflectionClass(__CLASS__); - - 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; - - $realInstanceReflection = new \ReflectionClass(__CLASS__); - - 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; - - $realInstanceReflection = new \ReflectionClass(__CLASS__); - - 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() - { - $this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, '__clone', array(), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; - - $this->valueHolder%s = clone $this->valueHolder%s; - } - - public function __sleep() - { - $this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, '__sleep', array(), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; - - return array('valueHolder%s'); - } - - public function __wakeup() - { - } - - public function setProxyInitializer(\Closure $initializer = null)%S - { - $this->initializer%s = $initializer; - } - - public function getProxyInitializer()%S - { - return $this->initializer%s; - } - - public function initializeProxy() : bool - { - return $this->initializer%s && ($this->initializer%s->__invoke($valueHolder%s, $this, 'initializeProxy', array(), $this->initializer%s) || 1) && $this->valueHolder%s = $valueHolder%s; - } - - public function isProxyInitialized() : bool - { - return null !== $this->valueHolder%s; - } - - public function getWrappedValueHolderValue()%S - { - return $this->valueHolder%s; - }%w -} diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php deleted file mode 100644 index 3652275c2bb65..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php +++ /dev/null @@ -1,221 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\ProxyManager\Tests\LazyProxy\PhpDumper; - -use PHPUnit\Framework\TestCase; -use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper; -use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface; - -/** - * Tests for {@see \Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper}. - * - * @author Marco Pivetta - * - * @group legacy - */ -class ProxyDumperTest extends TestCase -{ - /** - * @var ProxyDumper - */ - protected $dumper; - - protected function setUp(): void - { - $this->dumper = new ProxyDumper(); - } - - /** - * @dataProvider getProxyCandidates - */ - public function testIsProxyCandidate(Definition $definition, bool $expected) - { - $this->assertSame($expected, $this->dumper->isProxyCandidate($definition)); - } - - public function testGetProxyCode() - { - $definition = new Definition(__CLASS__); - - $definition->setLazy(true); - - $code = $this->dumper->getProxyCode($definition); - - $this->assertStringMatchesFormat( - '%Aclass ProxyDumperTest%aextends%w' - .'\Symfony\Bridge\ProxyManager\Tests\LazyProxy\PhpDumper\ProxyDumperTest%a', - $code - ); - } - - public function testDeterministicProxyCode() - { - $definition = new Definition(__CLASS__); - $definition->setLazy(true); - - $this->assertSame($this->dumper->getProxyCode($definition), $this->dumper->getProxyCode($definition)); - } - - public function testGetProxyFactoryCode() - { - $definition = new Definition(__CLASS__); - - $definition->setLazy(true); - - $code = $this->dumper->getProxyFactoryCode($definition, 'foo', '$container->getFoo2Service(false)'); - - $this->assertStringMatchesFormat( - '%A$wrappedInstance = $container->getFoo2Service(false);%w$proxy->setProxyInitializer(null);%A', - $code - ); - } - - /** - * @dataProvider getPrivatePublicDefinitions - */ - public function testCorrectAssigning(Definition $definition, $access) - { - $definition->setLazy(true); - - $code = $this->dumper->getProxyFactoryCode($definition, 'foo', '$container->getFoo2Service(false)'); - - $this->assertStringMatchesFormat('%A$container->'.$access.'[\'foo\'] = %A', $code); - } - - public static function getPrivatePublicDefinitions() - { - return [ - [ - (new Definition(__CLASS__)) - ->setPublic(false), - 'privates', - ], - [ - (new Definition(__CLASS__)) - ->setPublic(true), - 'services', - ], - ]; - } - - public function testGetProxyFactoryCodeForInterface() - { - $class = DummyClass::class; - $definition = new Definition($class); - - $definition->setLazy(true); - $definition->addTag('proxy', ['interface' => DummyInterface::class]); - $definition->addTag('proxy', ['interface' => SunnyInterface::class]); - - $implem = "dumper->getProxyCode($definition); - $factory = $this->dumper->getProxyFactoryCode($definition, 'foo', '$container->getFooService(false)'); - $factory = <<proxyClass = \$class; - - return \$factory(); - } -}; - -EOPHP; - - $implem = preg_replace('#\n /\*\*.*?\*/#s', '', $implem); - $implem = str_replace("array(\n \n );", "[\n \n ];", $implem); - - $this->assertStringMatchesFormatFile(__DIR__.'/Fixtures/proxy-implem.php', $implem); - $this->assertStringEqualsFile(__DIR__.'/Fixtures/proxy-factory.php', $factory); - - eval(preg_replace('/^<\?php/', '', $implem)); - $factory = require __DIR__.'/Fixtures/proxy-factory.php'; - - $foo = $factory->getFooService(); - - $this->assertInstanceof($factory->proxyClass, $foo); - $this->assertInstanceof(DummyInterface::class, $foo); - $this->assertInstanceof(SunnyInterface::class, $foo); - $this->assertNotInstanceof(DummyClass::class, $foo); - $this->assertSame($foo, $foo->dummy()); - - $foo->dynamicProp = 123; - $this->assertSame(123, @$foo->dynamicProp); - } - - public static function getProxyCandidates(): array - { - $definitions = [ - [new Definition(__CLASS__), true], - [new Definition('stdClass'), true], - [new Definition(DumperInterface::class), true], - [new Definition(uniqid('foo', true)), false], - [new Definition(), false], - ]; - - array_map( - function ($definition) { - $definition[0]->setLazy(true); - }, - $definitions - ); - - return $definitions; - } -} - -#[\AllowDynamicProperties] -final class DummyClass implements DummyInterface, SunnyInterface -{ - private $ref; - - public function dummy() - { - return $this; - } - - public function sunny() - { - } - - public function &dummyRef() - { - return $this->ref; - } -} - -interface DummyInterface -{ - public function dummy(); - - public function &dummyRef(); -} - -interface SunnyInterface -{ - public function dummy(); - - public function sunny(); -} diff --git a/src/Symfony/Bridge/ProxyManager/composer.json b/src/Symfony/Bridge/ProxyManager/composer.json deleted file mode 100644 index c556198968ec6..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/composer.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "symfony/proxy-manager-bridge", - "type": "symfony-bridge", - "description": "Provides integration for ProxyManager with various Symfony components", - "keywords": [], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=8.2", - "friendsofphp/proxy-manager-lts": "^1.0.2", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/deprecation-contracts": "^2.5|^3" - }, - "require-dev": { - "symfony/config": "^6.4|^7.0" - }, - "autoload": { - "psr-4": { "Symfony\\Bridge\\ProxyManager\\": "" }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "minimum-stability": "dev" -} diff --git a/src/Symfony/Bridge/ProxyManager/phpunit.xml.dist b/src/Symfony/Bridge/ProxyManager/phpunit.xml.dist deleted file mode 100644 index d93048d2cbe15..0000000000000 --- a/src/Symfony/Bridge/ProxyManager/phpunit.xml.dist +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - ./Tests/ - - - - - - ./ - - - ./Resources - ./Tests - ./vendor - - - diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json index b04061e7b20e5..9096088af003c 100644 --- a/src/Symfony/Component/DependencyInjection/composer.json +++ b/src/Symfony/Component/DependencyInjection/composer.json @@ -31,7 +31,6 @@ "ext-psr": "<1.1|>=2", "symfony/config": "<6.4", "symfony/finder": "<6.4", - "symfony/proxy-manager-bridge": "<6.4", "symfony/yaml": "<6.4" }, "provide": { 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