-
-
Notifications
You must be signed in to change notification settings - Fork 505
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch proxies to LazyGhostTrait
#2700
base: 2.10.x
Are you sure you want to change the base?
Conversation
9bdb39c
to
a81c08c
Compare
LazyGhostTrait
LazyGhostTrait
use function substr; | ||
|
||
/** @internal */ | ||
class LazyGhostProxyClassNameResolver implements ClassNameResolver, ProxyClassNameResolver |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class is copied from Doctrine\ORM\Proxy\DefaultProxyClassNameResolver
.
* @template T of object | ||
* @template-extends Proxy<T> | ||
*/ | ||
interface InternalProxy extends Proxy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This interface is copied from Doctrine\ORM\Proxy\InternalProxy.
$proxyManagerConfiguration = new ProxyManagerConfiguration(); | ||
$proxyManagerConfiguration->setProxiesTargetDir($this->getProxyDir()); | ||
$proxyManagerConfiguration->setProxiesNamespace($this->getProxyNamespace()); | ||
|
||
switch ($this->getAutoGenerateProxyClasses()) { | ||
case self::AUTOGENERATE_FILE_NOT_EXISTS: | ||
$proxyManagerConfiguration->setGeneratorStrategy(new FileWriterGeneratorStrategy( | ||
new FileLocator($proxyManagerConfiguration->getProxiesTargetDir()), | ||
)); | ||
|
||
break; | ||
case self::AUTOGENERATE_EVAL: | ||
$proxyManagerConfiguration->setGeneratorStrategy(new EvaluatingGeneratorStrategy()); | ||
|
||
break; | ||
default: | ||
throw new InvalidArgumentException('Invalid proxy generation strategy given - only AUTOGENERATE_FILE_NOT_EXISTS and AUTOGENERATE_EVAL are supported.'); | ||
} | ||
|
||
return $proxyManagerConfiguration; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Creating ProxyManagerConfiguration
on-demand as the class is not required when LazyGhostObjects are used.
* | ||
* @internal | ||
*/ | ||
final class Autoloader |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class is copied from Doctrine\ORM\Proxy\Autoloader.
return static function (InternalProxy $proxy, mixed $identifier) use ($persister, $classMetadata, $factory): void { | ||
$original = $persister->load([$classMetadata->identifier => $identifier], $proxy); | ||
|
||
if (! $original && ! $factory->lifecycleEventManager->documentNotFound($proxy, $identifier)) { | ||
throw DocumentNotFoundException::documentNotFound($classMetadata->getName(), $identifier); | ||
} | ||
|
||
// phpcs:ignore SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed | ||
if ($proxy instanceof NotifyPropertyChanged) { | ||
$proxy->addPropertyChangedListener($factory->uow); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialization code copied from StaticProxyFactory
.
* | ||
* @template T of object | ||
*/ | ||
public function getProxy(ClassMetadata $metadata, $identifier): GhostObjectInterface; | ||
public function getProxy(ClassMetadata $metadata, $identifier): object; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The interface is modified, but child classes can be more restrictive. This is not a BC break for implementers of the interface, but it can be for users of the interface.
public static function isLazyObject(object $document): bool | ||
{ | ||
return $document instanceof InternalProxy || $document instanceof LazyLoadingInterface; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most test changes are related to check interfaces to assert if the class is a lazy proxy object. I wonder if this method should be in UOW.
Later, it will use ReflectionClass::getLazyInitializer()
to detect native lazy object.
|
||
/** | ||
* Generate proxy classes using Symfony VarExporter's LazyGhostTrait if true. | ||
* Otherwise, use ProxyManager's LazyLoadingGhostFactory (deprecated) | ||
*/ | ||
public function setUseLazyGhostObject(bool $flag): void | ||
{ | ||
if ($flag === false) { | ||
if (! class_exists(ProxyManagerConfiguration::class)) { | ||
throw new LogicException('Package "friendsofphp/proxy-manager-lts" is required to disable LazyGhostObject.'); | ||
} | ||
|
||
trigger_deprecation( | ||
'doctrine/mongodb-odm', | ||
'2.6', | ||
'Using "friendsofphp/proxy-manager-lts" is deprecated. Use "symfony/var-exporter" LazyGhostObjects instead.', | ||
); | ||
} | ||
|
||
$this->useLazyGhostObject = $flag; | ||
} | ||
|
||
public function isLazyGhostObjectEnabled(): bool | ||
{ | ||
return $this->useLazyGhostObject ?? true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use the same method names as the ORM: isLazyGhostObjectEnabled
and setLazyGhostObjectEnabled
?
lib/Doctrine/ODM/MongoDB/Proxy/Factory/LazyGhostProxyFactory.php
Outdated
Show resolved
Hide resolved
Considering the unchecked checkboxes in your initial PR description, is this a WIP? |
e69cd31
to
dbd1f1b
Compare
631e341
to
cbab97c
Compare
I've just rebased this PR. The bundle will need an update to register the autoloader. Regarding native lazy objects and prop hooks PR on ODM, I think the approaches are not conflicting this this PR. |
Summary
Use the
LazyGhostTrait
fromsymfony/var-exporter
to generate lazy proxy classes.LazyGhostProxyFactory
that implements theProxyFactory
interface and use it by defaultlazy-ghost-objects