Skip to content

Commit

Permalink
Don't rely on LazyProxyTrait in LazyServiceEntityRepository (#1727)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-grekas authored Nov 14, 2023
1 parent ca64ca7 commit 8c42712
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 107 deletions.
70 changes: 47 additions & 23 deletions Repository/LazyServiceEntityRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use LogicException;
use Symfony\Component\VarExporter\LazyGhostTrait;
use Symfony\Component\VarExporter\LazyObjectInterface;

use function debug_backtrace;
use function sprintf;

use const DEBUG_BACKTRACE_IGNORE_ARGS;

/**
* @internal Extend {@see ServiceEntityRepository} instead.
*
Expand All @@ -18,41 +20,63 @@
*/
class LazyServiceEntityRepository extends EntityRepository implements ServiceEntityRepositoryInterface
{
use LazyGhostTrait {
createLazyGhost as private;
}
private ManagerRegistry $registry;
private string $entityClass;

/**
* @param string $entityClass The class name of the entity this repository manages
* @psalm-param class-string<T> $entityClass
*/
public function __construct(ManagerRegistry $registry, string $entityClass)
{
$initializer = function ($instance, $property) use ($registry, $entityClass) {
$manager = $registry->getManagerForClass($entityClass);
$this->registry = $registry;
$this->entityClass = $entityClass;

if ($manager === null) {
throw new LogicException(sprintf(
'Could not find the entity manager for class "%s". Check your Doctrine configuration to make sure it is configured to load this entity’s metadata.',
$entityClass,
));
}
if ($this instanceof LazyObjectInterface) {
$this->initialize();

return;
}

parent::__construct($manager, $manager->getClassMetadata($entityClass));
unset($this->_em);
unset($this->_class);
unset($this->_entityName);
}

return $this->$property;
};
/** @return mixed */
public function __get(string $name)
{
$this->initialize();

if ($this instanceof LazyObjectInterface) {
$initializer($this, '_entityName');
$scope = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['class'] ?? null;

return;
return (function () use ($name) {
return $this->$name;
})->bindTo($this, $scope)();
}

public function __isset(string $name): bool
{
$this->initialize();

$scope = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['class'] ?? null;

return (function () use ($name) {
return isset($this->$name);
})->bindTo($this, $scope)();
}

private function initialize(): void
{
$manager = $this->registry->getManagerForClass($this->entityClass);

if ($manager === null) {
throw new LogicException(sprintf(
'Could not find the entity manager for class "%s". Check your Doctrine configuration to make sure it is configured to load this entity’s metadata.',
$this->entityClass,
));
}

self::createLazyGhost([
"\0*\0_em" => $initializer,
"\0*\0_class" => $initializer,
"\0*\0_entityName" => $initializer,
], null, $this);
parent::__construct($manager, $manager->getClassMetadata($this->entityClass));
}
}
38 changes: 0 additions & 38 deletions Repository/LegacyServiceEntityRepository.php

This file was deleted.

66 changes: 20 additions & 46 deletions Repository/ServiceEntityRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,30 @@
namespace Doctrine\Bundle\DoctrineBundle\Repository;

use Doctrine\ORM\EntityRepository;
use Symfony\Component\VarExporter\LazyGhostTrait;

use function property_exists;
use function trait_exists;

if (property_exists(EntityRepository::class, '_entityName')) {
if (trait_exists(LazyGhostTrait::class)) {
// ORM 2 with VarExporter
/**
* Optional EntityRepository base class with a simplified constructor (for autowiring).
*
* To use in your class, inject the "registry" service and call
* the parent constructor. For example:
*
* class YourEntityRepository extends ServiceEntityRepository
* {
* public function __construct(ManagerRegistry $registry)
* {
* parent::__construct($registry, YourEntity::class);
* }
* }
*
* @template T of object
* @template-extends LazyServiceEntityRepository<T>
*/
class ServiceEntityRepository extends LazyServiceEntityRepository
{
}
} else {
// ORM 2 without VarExporter
/**
* Optional EntityRepository base class with a simplified constructor (for autowiring).
*
* To use in your class, inject the "registry" service and call
* the parent constructor. For example:
*
* class YourEntityRepository extends ServiceEntityRepository
* {
* public function __construct(ManagerRegistry $registry)
* {
* parent::__construct($registry, YourEntity::class);
* }
* }
*
* @template T of object
* @template-extends LegacyServiceEntityRepository<T>
*/
class ServiceEntityRepository extends LegacyServiceEntityRepository
{
}
// ORM 2
/**
* Optional EntityRepository base class with a simplified constructor (for autowiring).
*
* To use in your class, inject the "registry" service and call
* the parent constructor. For example:
*
* class YourEntityRepository extends ServiceEntityRepository
* {
* public function __construct(ManagerRegistry $registry)
* {
* parent::__construct($registry, YourEntity::class);
* }
* }
*
* @template T of object
* @template-extends LazyServiceEntityRepository<T>
*/
class ServiceEntityRepository extends LazyServiceEntityRepository
{
}
} else {
// ORM 3
Expand Down

0 comments on commit 8c42712

Please sign in to comment.