bug #39610 [ProxyManagerBridge] fix PHP notice, switch to "friendsofphp/proxy-manager-lts" (nicolas-grekas)
This PR was merged into the 4.4 branch. Discussion ---------- [ProxyManagerBridge] fix PHP notice, switch to "friendsofphp/proxy-manager-lts" | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #39089 | License | MIT | Doc PR | - I submitted the fix for #39089 on the origin library at https://github.com/Ocramius/ProxyManager/pull/646. Because of the [versioning policy](6d45615155/version-support.md (dependency-upgrades)
) in use at the origin library, this fix won't be available for PHP < 7.4. We usually resort to monkey-patching to workaround the policy and still ship the fix for 4.4 (which supports PHP >= 7.1). This time, and as explained in https://github.com/Ocramius/ProxyManager/issues/630, I propose to delegate the fix to [friendsofphp/proxy-manager-lts](https://github.com/FriendsOfPHP/proxy-manager-lts/). It already embeds the fix and a few others that allow us to remove most of the monkey-patching we had to accumulate over time. Commits -------389f5304c7
[ProxyManagerBridge] fix PHP notice, switch to "friendsofphp/proxy-manager-lts"
This commit is contained in:
commit
64cc4d8e7a
@ -18,6 +18,7 @@
|
||||
"require": {
|
||||
"php": ">=7.1.3",
|
||||
"ext-xml": "*",
|
||||
"friendsofphp/proxy-manager-lts": "^1.0",
|
||||
"doctrine/event-manager": "~1.0",
|
||||
"doctrine/persistence": "^1.3|^2",
|
||||
"twig/twig": "^1.41|^2.10|^3.0",
|
||||
@ -112,7 +113,6 @@
|
||||
"masterminds/html5": "^2.6",
|
||||
"monolog/monolog": "^1.25.1",
|
||||
"nyholm/psr7": "^1.0",
|
||||
"ocramius/proxy-manager": "^2.1",
|
||||
"paragonie/sodium_compat": "^1.8",
|
||||
"php-http/httplug": "^1.0|^2.0",
|
||||
"predis/predis": "~1.1",
|
||||
|
@ -48,7 +48,11 @@ class RuntimeInstantiator implements InstantiatorInterface
|
||||
$proxy->setProxyInitializer(null);
|
||||
|
||||
return true;
|
||||
}
|
||||
},
|
||||
[
|
||||
'fluentSafe' => $definition->hasTag('proxy'),
|
||||
'skipDestructor' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -11,87 +11,26 @@
|
||||
|
||||
namespace Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper;
|
||||
|
||||
use Laminas\Code\Generator\ClassGenerator;
|
||||
use ProxyManager\ProxyGenerator\LazyLoadingValueHolderGenerator as BaseGenerator;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Zend\Code\Generator\ClassGenerator;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class LazyLoadingValueHolderGenerator extends BaseGenerator
|
||||
{
|
||||
private $fluentSafe = false;
|
||||
|
||||
public function setFluentSafe(bool $fluentSafe)
|
||||
{
|
||||
$this->fluentSafe = $fluentSafe;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate(\ReflectionClass $originalClass, ClassGenerator $classGenerator): void
|
||||
public function generate(\ReflectionClass $originalClass, ClassGenerator $classGenerator, array $proxyOptions = []): void
|
||||
{
|
||||
parent::generate($originalClass, $classGenerator);
|
||||
parent::generate($originalClass, $classGenerator, $proxyOptions);
|
||||
|
||||
foreach ($classGenerator->getMethods() as $method) {
|
||||
$body = preg_replace(
|
||||
'/(\$this->initializer[0-9a-f]++) && \1->__invoke\(\$this->(valueHolder[0-9a-f]++), (.*?), \1\);/',
|
||||
'$1 && ($1->__invoke(\$$2, $3, $1) || 1) && $this->$2 = \$$2;',
|
||||
$method->getBody()
|
||||
);
|
||||
$body = str_replace('(new \ReflectionClass(get_class()))', '$reflection', $body);
|
||||
$body = str_replace('$reflection = $reflection ?: ', '$reflection = $reflection ?? ', $body);
|
||||
$body = str_replace('$reflection ?? $reflection = ', '$reflection ?? ', $body);
|
||||
|
||||
if ($originalClass->isInterface()) {
|
||||
$body = str_replace('get_parent_class($this)', var_export($originalClass->name, true), $body);
|
||||
$body = preg_replace_callback('/\n\n\$realInstanceReflection = [^{]++\{([^}]++)\}\n\n.*/s', function ($m) {
|
||||
$r = '';
|
||||
foreach (explode("\n", $m[1]) as $line) {
|
||||
$r .= "\n".substr($line, 4);
|
||||
if (0 === strpos($line, ' return ')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $r;
|
||||
}, $body);
|
||||
}
|
||||
|
||||
if ($this->fluentSafe) {
|
||||
$indent = $method->getIndentation();
|
||||
$method->setIndentation('');
|
||||
$code = $method->generate();
|
||||
if (null !== $docBlock = $method->getDocBlock()) {
|
||||
$code = substr($code, \strlen($docBlock->generate()));
|
||||
}
|
||||
$refAmp = (strpos($code, '&') ?: \PHP_INT_MAX) <= strpos($code, '(') ? '&' : '';
|
||||
$body = preg_replace(
|
||||
'/\nreturn (\$this->valueHolder[0-9a-f]++)(->[^;]++);$/',
|
||||
"\nif ($1 === \$returnValue = {$refAmp}$1$2) {\n \$returnValue = \$this;\n}\n\nreturn \$returnValue;",
|
||||
$body
|
||||
);
|
||||
$method->setIndentation($indent);
|
||||
}
|
||||
|
||||
if (0 === strpos($originalClass->getFilename(), __FILE__)) {
|
||||
$body = str_replace(var_export($originalClass->name, true), '__CLASS__', $body);
|
||||
$method->setBody(str_replace(var_export($originalClass->name, true), '__CLASS__', $method->getBody()));
|
||||
}
|
||||
|
||||
$method->setBody($body);
|
||||
}
|
||||
|
||||
if ($classGenerator->hasMethod('__destruct')) {
|
||||
$destructor = $classGenerator->getMethod('__destruct');
|
||||
$body = $destructor->getBody();
|
||||
$newBody = preg_replace('/^(\$this->initializer[a-zA-Z0-9]++) && .*;\n\nreturn (\$this->valueHolder)/', '$1 || $2', $body);
|
||||
|
||||
if ($body === $newBody) {
|
||||
throw new \UnexpectedValueException(sprintf('Unexpected lazy-proxy format generated for method "%s::__destruct()".', $originalClass->name));
|
||||
}
|
||||
|
||||
$destructor->setBody($newBody);
|
||||
}
|
||||
|
||||
if (0 === strpos($originalClass->getFilename(), __FILE__)) {
|
||||
|
@ -11,9 +11,7 @@
|
||||
|
||||
namespace Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper;
|
||||
|
||||
use ProxyManager\Exception\ExceptionInterface;
|
||||
use ProxyManager\Generator\ClassGenerator;
|
||||
use ProxyManager\Generator\MethodGenerator;
|
||||
use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface;
|
||||
@ -88,18 +86,6 @@ EOF;
|
||||
$code = $this->classGenerator->generate($this->generateProxyClass($definition));
|
||||
$code = preg_replace('/^(class [^ ]++ extends )([^\\\\])/', '$1\\\\$2', $code);
|
||||
|
||||
if (!method_exists(MethodGenerator::class, 'fromReflectionWithoutBodyAndDocBlock')) { // proxy-manager < 2.2
|
||||
$code = preg_replace(
|
||||
'/((?:\$(?:this|initializer|instance)->)?(?:publicProperties|initializer|valueHolder))[0-9a-f]++/',
|
||||
'${1}'.$this->getIdentifierSuffix($definition),
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
if (!is_subclass_of(ExceptionInterface::class, 'Throwable')) { // proxy-manager < 2.5
|
||||
$code = preg_replace('/ \\\\Closure::bind\(function ((?:& )?\(\$instance(?:, \$value)?\))/', ' \Closure::bind(static function \1', $code);
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
@ -118,8 +104,10 @@ EOF;
|
||||
$generatedClass = new ClassGenerator($this->getProxyClassName($definition));
|
||||
$class = $this->proxyGenerator->getProxifiedClass($definition);
|
||||
|
||||
$this->proxyGenerator->setFluentSafe($definition->hasTag('proxy'));
|
||||
$this->proxyGenerator->generate(new \ReflectionClass($class), $generatedClass);
|
||||
$this->proxyGenerator->generate(new \ReflectionClass($class), $generatedClass, [
|
||||
'fluentSafe' => $definition->hasTag('proxy'),
|
||||
'skipDestructor' => true,
|
||||
]);
|
||||
|
||||
return $generatedClass;
|
||||
}
|
||||
|
@ -11,4 +11,4 @@ Resources
|
||||
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
||||
in the [main Symfony repository](https://github.com/symfony/symfony)
|
||||
|
||||
[1]: https://github.com/Ocramius/ProxyManager
|
||||
[1]: https://github.com/FriendsOfPHP/proxy-manager-lts
|
||||
|
@ -16,7 +16,7 @@ class SunnyInterface_%s implements \ProxyManager\Proxy\VirtualProxyInterface, \S
|
||||
$this->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()) {
|
||||
$returnValue = $this;
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
@ -26,8 +26,8 @@ class SunnyInterface_%s implements \ProxyManager\Proxy\VirtualProxyInterface, \S
|
||||
{
|
||||
$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()) {
|
||||
$returnValue = $this;
|
||||
if ($this->valueHolder%s === $returnValue = & $this->valueHolder%s->dummyRef()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
@ -38,7 +38,7 @@ class SunnyInterface_%s implements \ProxyManager\Proxy\VirtualProxyInterface, \S
|
||||
$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()) {
|
||||
$returnValue = $this;
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
@ -96,7 +96,7 @@ class SunnyInterface_%s implements \ProxyManager\Proxy\VirtualProxyInterface, \S
|
||||
|
||||
$targetObject = $this->valueHolder%s;
|
||||
|
||||
return $targetObject->$name = $value;
|
||||
$targetObject->$name = $value; return $targetObject->$name;
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
|
@ -18,15 +18,12 @@
|
||||
"require": {
|
||||
"php": ">=7.1.3",
|
||||
"composer/package-versions-deprecated": "^1.8",
|
||||
"symfony/dependency-injection": "^4.0|^5.0",
|
||||
"ocramius/proxy-manager": "~2.1"
|
||||
"friendsofphp/proxy-manager-lts": "^1.0",
|
||||
"symfony/dependency-injection": "^4.0|^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/config": "^3.4|^4.0|^5.0"
|
||||
},
|
||||
"conflict": {
|
||||
"zendframework/zend-eventmanager": "2.6.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Bridge\\ProxyManager\\": "" },
|
||||
"exclude-from-classmap": [
|
||||
|
Reference in New Issue
Block a user