Skip to content

Commit

Permalink
Stop extending proxy factory from doctrine/common
Browse files Browse the repository at this point in the history
Extending it no longer serves any purpose.
  • Loading branch information
greg0ire committed Oct 7, 2023
1 parent e0b53bf commit 4e3e8bd
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 171 deletions.
8 changes: 8 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Upgrade to 3.0

## BC BREAK: `Doctrine\ORM\Proxy\ProxyFactory` no longer extends abstract factory from `doctrine/common`

It is no longer possible to call methods, constants or properties inherited
from that class on a `ProxyFactory` instance.

`Doctrine\ORM\Proxy\ProxyFactory::createProxyDefinition()` and
`Doctrine\ORM\Proxy\ProxyFactory::resetUninitializedProxy()` are removed as well.

## BC BREAK: lazy ghosts are enabled unconditionally

`Doctrine\ORM\Configuration::setLazyGhostObjectEnabled()` and
Expand Down
150 changes: 7 additions & 143 deletions lib/Doctrine/ORM/Proxy/ProxyFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
namespace Doctrine\ORM\Proxy;

use Closure;
use Doctrine\Common\Proxy\AbstractProxyFactory;
use Doctrine\Common\Proxy\Proxy as CommonProxy;
use Doctrine\Common\Proxy\ProxyDefinition;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityNotFoundException;
use Doctrine\ORM\ORMInvalidArgumentException;
Expand All @@ -18,7 +15,6 @@
use Doctrine\Persistence\Proxy;
use ReflectionProperty;
use Symfony\Component\VarExporter\ProxyHelper;
use Throwable;

use function array_combine;
use function array_flip;
Expand Down Expand Up @@ -53,7 +49,7 @@
/**
* This factory is used to create proxy objects for entities at runtime.
*/
class ProxyFactory extends AbstractProxyFactory
class ProxyFactory
{
/**
* Never autogenerate a proxy and rely that it was generated by some
Expand Down Expand Up @@ -168,9 +164,12 @@ public function __construct(
}

/**
* {@inheritDoc}
* @param class-string $className
* @param array<mixed> $identifier
*
* @return InternalProxy
*/
public function getProxy($className, array $identifier)
public function getProxy(string $className, array $identifier)
{
$proxyFactory = $this->proxyFactories[$className] ?? $this->getProxyFactory($className);

Expand All @@ -187,7 +186,7 @@ public function getProxy($className, array $identifier)
*
* @return int Number of generated proxies.
*/
public function generateProxyClasses(array $classes, $proxyDir = null)
public function generateProxyClasses(array $classes, $proxyDir = null): int
{
$generated = 0;

Expand All @@ -207,108 +206,13 @@ public function generateProxyClasses(array $classes, $proxyDir = null)
return $generated;
}

/**
* {@inheritDoc}
*
* @deprecated ProxyFactory::resetUninitializedProxy() is deprecated and will be removed in version 3.0 of doctrine/orm.
*/
public function resetUninitializedProxy(CommonProxy $proxy)
{
return parent::resetUninitializedProxy($proxy);
}

protected function skipClass(ClassMetadata $metadata): bool
{
return $metadata->isMappedSuperclass
|| $metadata->isEmbeddedClass
|| $metadata->getReflectionClass()->isAbstract();
}

/**
* {@inheritDoc}
*
* @deprecated ProxyFactory::createProxyDefinition() is deprecated and will be removed in version 3.0 of doctrine/orm.
*/
protected function createProxyDefinition($className): ProxyDefinition
{
$classMetadata = $this->em->getClassMetadata($className);
$entityPersister = $this->uow->getEntityPersister($className);

$initializer = $this->createInitializer($classMetadata, $entityPersister);
$cloner = $this->createCloner($classMetadata, $entityPersister);

return new ProxyDefinition(
self::generateProxyClassName($className, $this->proxyNs),
$classMetadata->getIdentifierFieldNames(),
$classMetadata->getReflectionProperties(),
$initializer,
$cloner,
);
}

/**
* Creates a closure capable of initializing a proxy
*
* @deprecated ProxyFactory::createInitializer() is deprecated and will be removed in version 3.0 of doctrine/orm.
*
* @psalm-return Closure(CommonProxy):void
*
* @throws EntityNotFoundException
*/
private function createInitializer(ClassMetadata $classMetadata, EntityPersister $entityPersister): Closure
{
$wakeupProxy = $classMetadata->getReflectionClass()->hasMethod('__wakeup');

return function (CommonProxy $proxy) use ($entityPersister, $classMetadata, $wakeupProxy): void {
$initializer = $proxy->__getInitializer();
$cloner = $proxy->__getCloner();

$proxy->__setInitializer(null);
$proxy->__setCloner(null);

if ($proxy->__isInitialized()) {
return;
}

$properties = $proxy->__getLazyProperties();

foreach ($properties as $propertyName => $property) {
if (! isset($proxy->$propertyName)) {
$proxy->$propertyName = $properties[$propertyName];
}
}

$proxy->__setInitialized(true);

if ($wakeupProxy) {
$proxy->__wakeup();
}

$identifier = $classMetadata->getIdentifierValues($proxy);

try {
$entity = $entityPersister->loadById($identifier, $proxy);
} catch (Throwable $exception) {
$proxy->__setInitializer($initializer);
$proxy->__setCloner($cloner);
$proxy->__setInitialized(false);

throw $exception;
}

if ($entity === null) {
$proxy->__setInitializer($initializer);
$proxy->__setCloner($cloner);
$proxy->__setInitialized(false);

throw EntityNotFoundException::fromClassNameAndIdentifier(
$classMetadata->getName(),
$this->identifierFlattener->flattenIdentifier($classMetadata, $identifier),
);
}
};
}

/**
* Creates a closure capable of initializing a proxy
*
Expand Down Expand Up @@ -345,46 +249,6 @@ private function createLazyInitializer(ClassMetadata $classMetadata, EntityPersi
};
}

/**
* Creates a closure capable of finalizing state a cloned proxy
*
* @deprecated ProxyFactory::createCloner() is deprecated and will be removed in version 3.0 of doctrine/orm.
*
* @psalm-return Closure(CommonProxy):void
*
* @throws EntityNotFoundException
*/
private function createCloner(ClassMetadata $classMetadata, EntityPersister $entityPersister): Closure
{
return function (CommonProxy $proxy) use ($entityPersister, $classMetadata): void {
if ($proxy->__isInitialized()) {
return;
}

$proxy->__setInitialized(true);
$proxy->__setInitializer(null);

$class = $entityPersister->getClassMetadata();
$identifier = $classMetadata->getIdentifierValues($proxy);
$original = $entityPersister->loadById($identifier);

if ($original === null) {
throw EntityNotFoundException::fromClassNameAndIdentifier(
$classMetadata->getName(),
$this->identifierFlattener->flattenIdentifier($classMetadata, $identifier),
);
}

foreach ($class->getReflectionProperties() as $property) {
if (! $class->hasField($property->name) && ! $class->hasAssociation($property->name)) {
continue;
}

$property->setValue($proxy, $property->getValue($original));
}
};
}

private function getProxyFileName(string $className, string $baseDirectory): string
{
$baseDirectory = $baseDirectory ?: $this->proxyDir;
Expand Down
7 changes: 1 addition & 6 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,6 @@ parameters:
count: 1
path: lib/Doctrine/ORM/Proxy/ProxyFactory.php

-
message: "#^Call to an undefined method Doctrine\\\\Common\\\\Proxy\\\\Proxy\\:\\:__wakeup\\(\\)\\.$#"
count: 1
path: lib/Doctrine/ORM/Proxy/ProxyFactory.php

-
message: "#^Call to an undefined static method Doctrine\\\\ORM\\\\Proxy\\\\ProxyFactory\\:\\:createLazyGhost\\(\\)\\.$#"
count: 1
Expand All @@ -212,7 +207,7 @@ parameters:

-
message: "#^Parameter \\#1 \\$class of method Doctrine\\\\ORM\\\\Utility\\\\IdentifierFlattener\\:\\:flattenIdentifier\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata given\\.$#"
count: 3
count: 1
path: lib/Doctrine/ORM/Proxy/ProxyFactory.php

-
Expand Down
22 changes: 0 additions & 22 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -738,16 +738,7 @@
<file src="lib/Doctrine/ORM/Proxy/ProxyFactory.php">
<ArgumentTypeCoercion>
<code>$classMetadata</code>
<code>$classMetadata</code>
<code>$classMetadata</code>
</ArgumentTypeCoercion>
<DeprecatedMethod>
<code>createCloner</code>
<code>createInitializer</code>
</DeprecatedMethod>
<InvalidArgument>
<code><![CDATA[$classMetadata->getReflectionProperties()]]></code>
</InvalidArgument>
<InvalidNullableReturnType>
<code>Closure</code>
</InvalidNullableReturnType>
Expand All @@ -758,9 +749,6 @@
<code><![CDATA[$metadata->isEmbeddedClass]]></code>
<code><![CDATA[$metadata->isMappedSuperclass]]></code>
</NoInterfaceProperties>
<PossiblyNullArgument>
<code><![CDATA[$property->name]]></code>
</PossiblyNullArgument>
<NullableReturnStatement>
<code><![CDATA[$this->proxyFactories[$className] = $proxyFactory]]></code>
</NullableReturnStatement>
Expand All @@ -770,20 +758,10 @@
<PossiblyFalseOperand>
<code>$i</code>
</PossiblyFalseOperand>
<PossiblyNullPropertyFetch>
<code><![CDATA[$property->name]]></code>
</PossiblyNullPropertyFetch>
<PossiblyNullReference>
<code>getValue</code>
<code>setValue</code>
</PossiblyNullReference>
<TypeDoesNotContainType>
<code><![CDATA[$autoGenerate < 0]]></code>
<code><![CDATA[$autoGenerate > 4]]></code>
</TypeDoesNotContainType>
<UndefinedInterfaceMethod>
<code>__wakeup</code>
</UndefinedInterfaceMethod>
<UndefinedMethod>
<code><![CDATA[self::createLazyGhost(static function (InternalProxy $object) use ($initializer, &$proxy): void {
$initializer($object, $proxy);
Expand Down

0 comments on commit 4e3e8bd

Please sign in to comment.