Skip to content

Commit

Permalink
[VarExporter] generate __doUnserialize() method in ProxyHelper::gener…
Browse files Browse the repository at this point in the history
…ateLazyProxy()
  • Loading branch information
nikophil committed Jun 24, 2024
1 parent 792ca83 commit f9a0606
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
27 changes: 26 additions & 1 deletion ProxyHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,35 @@ public static function generateLazyProxy(?\ReflectionClass $class, array $interf
$body = $methods ? "\n".implode("\n\n", $methods)."\n" : '';
$propertyScopes = $class ? self::exportPropertyScopes($class->name) : '[]';

if (
$class?->hasMethod('__unserialize')
&& !$class->getMethod('__unserialize')->getParameters()[0]->getType()
) {
// fix contravariance type problem when $class declares a `__unserialize()` method without typehint.
$lazyProxyTraitStatement = <<<EOPHP
use \Symfony\Component\VarExporter\LazyProxyTrait {
__unserialize as private __doUnserialize;
}
EOPHP;

$body .= <<<EOPHP
public function __unserialize(\$data): void
{
\$this->__doUnserialize(\$data);
}
EOPHP;
} else {
$lazyProxyTraitStatement = <<<EOPHP
use \Symfony\Component\VarExporter\LazyProxyTrait;
EOPHP;
}

return <<<EOPHP
{$parent} implements \\{$interfaces}
{
use \Symfony\Component\VarExporter\LazyProxyTrait;
{$lazyProxyTraitStatement}
private const LAZY_OBJECT_PROPERTY_SCOPES = {$propertyScopes};
{$body}}
Expand Down
45 changes: 45 additions & 0 deletions Tests/ProxyHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,50 @@ class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class);
$this->assertSame($expected, ProxyHelper::generateLazyProxy(null, [new \ReflectionClass(TestForProxyHelperInterface1::class), new \ReflectionClass(TestForProxyHelperInterface2::class)]));
}

/**
* @dataProvider classWithUnserializeMagicMethodProvider
*/
public function testGenerateLazyProxyForClassWithUnserializeMagicMethod(object $obj, string $expected)
{
$this->assertStringContainsString($expected, ProxyHelper::generateLazyProxy(new \ReflectionClass($obj::class)));
}

public static function classWithUnserializeMagicMethodProvider(): iterable
{
yield 'not type hinted __unserialize method' => [new class() {
public function __unserialize($array)
{
}
}, <<<'EOPHP'
implements \Symfony\Component\VarExporter\LazyObjectInterface
{
use \Symfony\Component\VarExporter\LazyProxyTrait {
__unserialize as private __doUnserialize;
}
private const LAZY_OBJECT_PROPERTY_SCOPES = [];
public function __unserialize($data): void
{
$this->__doUnserialize($data);
}
}
EOPHP];
yield 'type hinted __unserialize method' => [new class() {
public function __unserialize(array $array)
{
}
}, <<<'EOPHP'
implements \Symfony\Component\VarExporter\LazyObjectInterface
{
use \Symfony\Component\VarExporter\LazyProxyTrait;
private const LAZY_OBJECT_PROPERTY_SCOPES = [];
}
EOPHP];
}
public function testAttributes()
{
$expected = <<<'EOPHP'
Expand All @@ -182,6 +226,7 @@ public function foo(#[\SensitiveParameter, AnotherAttribute] $a): int
{
}
});

$this->assertStringContainsString($expected, ProxyHelper::generateLazyProxy($class));
}

Expand Down

0 comments on commit f9a0606

Please sign in to comment.