welcome back to dyb-tech

This commit is contained in:
Daniel Guzman
2024-05-18 02:28:01 +02:00
parent 9513cdba09
commit 9f30bc98c7
6149 changed files with 668407 additions and 0 deletions
@@ -0,0 +1,111 @@
<?php
namespace Doctrine\Bundle\DoctrineBundle\Repository;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Repository\RepositoryFactory;
use Doctrine\Persistence\ObjectRepository;
use Psr\Container\ContainerInterface;
use RuntimeException;
use function class_exists;
use function get_debug_type;
use function is_a;
use function spl_object_hash;
use function sprintf;
use function trigger_deprecation;
/**
* Fetches repositories from the container or falls back to normal creation.
*/
final class ContainerRepositoryFactory implements RepositoryFactory
{
use RepositoryFactoryCompatibility;
/** @var array<string, ObjectRepository> */
private array $managedRepositories = [];
private ContainerInterface $container;
/** @param ContainerInterface $container A service locator containing the repositories */
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
/**
* @param class-string<T> $entityName
*
* @return ObjectRepository<T>
* @psalm-return ($strictTypeCheck is true ? EntityRepository<T> : ObjectRepository<T>)
*
* @template T of object
*/
private function doGetRepository(EntityManagerInterface $entityManager, string $entityName, bool $strictTypeCheck): ObjectRepository
{
$metadata = $entityManager->getClassMetadata($entityName);
$repositoryServiceId = $metadata->customRepositoryClassName;
$customRepositoryName = $metadata->customRepositoryClassName;
if ($customRepositoryName !== null) {
// fetch from the container
if ($this->container->has($customRepositoryName)) {
$repository = $this->container->get($customRepositoryName);
if (! $repository instanceof EntityRepository && $strictTypeCheck) {
throw new RuntimeException(sprintf('The service "%s" must extend EntityRepository (e.g. by extending ServiceEntityRepository), "%s" given.', $repositoryServiceId, get_debug_type($repository)));
}
if (! $repository instanceof ObjectRepository) {
throw new RuntimeException(sprintf('The service "%s" must implement ObjectRepository (or extend a base class, like ServiceEntityRepository), "%s" given.', $repositoryServiceId, get_debug_type($repository)));
}
if (! $repository instanceof EntityRepository) {
trigger_deprecation('doctrine/doctrine-bundle', '2.11', 'The service "%s" of type "%s" should extend "%s", not doing so is deprecated.', $repositoryServiceId, get_debug_type($repository), EntityRepository::class);
}
/** @psalm-var ObjectRepository<T> */
return $repository;
}
// if not in the container but the class/id implements the interface, throw an error
if (is_a($customRepositoryName, ServiceEntityRepositoryInterface::class, true)) {
throw new RuntimeException(sprintf('The "%s" entity repository implements "%s", but its service could not be found. Make sure the service exists and is tagged with "%s".', $customRepositoryName, ServiceEntityRepositoryInterface::class, ServiceRepositoryCompilerPass::REPOSITORY_SERVICE_TAG));
}
if (! class_exists($customRepositoryName)) {
throw new RuntimeException(sprintf('The "%s" entity has a repositoryClass set to "%s", but this is not a valid class. Check your class naming. If this is meant to be a service id, make sure this service exists and is tagged with "%s".', $metadata->name, $customRepositoryName, ServiceRepositoryCompilerPass::REPOSITORY_SERVICE_TAG));
}
// allow the repository to be created below
}
return $this->getOrCreateRepository($entityManager, $metadata);
}
/**
* @param ClassMetadata<TEntity> $metadata
*
* @return ObjectRepository<TEntity>
*
* @template TEntity of object
*/
private function getOrCreateRepository(
EntityManagerInterface $entityManager,
ClassMetadata $metadata
): ObjectRepository {
$repositoryHash = $metadata->getName() . spl_object_hash($entityManager);
if (isset($this->managedRepositories[$repositoryHash])) {
/** @psalm-var ObjectRepository<TEntity> */
return $this->managedRepositories[$repositoryHash];
}
$repositoryClassName = $metadata->customRepositoryClassName ?: $entityManager->getConfiguration()->getDefaultRepositoryClassName();
/** @psalm-var ObjectRepository<TEntity> */
return $this->managedRepositories[$repositoryHash] = new $repositoryClassName($entityManager, $metadata);
}
}
@@ -0,0 +1,82 @@
<?php
namespace Doctrine\Bundle\DoctrineBundle\Repository;
use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use LogicException;
use Symfony\Component\VarExporter\LazyObjectInterface;
use function debug_backtrace;
use function sprintf;
use const DEBUG_BACKTRACE_IGNORE_ARGS;
/**
* @internal Extend {@see ServiceEntityRepository} instead.
*
* @template T of object
* @template-extends EntityRepository<T>
*/
class LazyServiceEntityRepository extends EntityRepository implements ServiceEntityRepositoryInterface
{
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)
{
$this->registry = $registry;
$this->entityClass = $entityClass;
if ($this instanceof LazyObjectInterface) {
$this->initialize();
return;
}
unset($this->_em);
unset($this->_class);
unset($this->_entityName);
}
/** @return mixed */
public function __get(string $name)
{
$this->initialize();
$scope = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['class'] ?? null;
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 entitys metadata.',
$this->entityClass,
));
}
parent::__construct($manager, $manager->getClassMetadata($this->entityClass));
}
}
@@ -0,0 +1,43 @@
<?php
namespace Doctrine\Bundle\DoctrineBundle\Repository;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Repository\RepositoryFactory;
use Doctrine\Persistence\ObjectRepository;
use ReflectionMethod;
if ((new ReflectionMethod(RepositoryFactory::class, 'getRepository'))->hasReturnType()) {
// ORM >= 3
/** @internal */
trait RepositoryFactoryCompatibility
{
/**
* Gets the repository for an entity class.
*
* @param class-string<T> $entityName
*
* @return EntityRepository<T>
*
* @template T of object
*
* @psalm-suppress MethodSignatureMismatch
*/
public function getRepository(EntityManagerInterface $entityManager, string $entityName): EntityRepository
{
return $this->doGetRepository($entityManager, $entityName, true);
}
}
} else {
// ORM 2
/** @internal */
trait RepositoryFactoryCompatibility
{
/** {@inheritDoc} */
public function getRepository(EntityManagerInterface $entityManager, $entityName): ObjectRepository
{
return $this->doGetRepository($entityManager, $entityName, false);
}
}
}
@@ -0,0 +1,53 @@
<?php
namespace Doctrine\Bundle\DoctrineBundle\Repository;
use Doctrine\ORM\EntityRepository;
use function property_exists;
if (property_exists(EntityRepository::class, '_entityName')) {
// 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
/**
* 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 ServiceEntityRepositoryProxy<T>
*/
class ServiceEntityRepository extends ServiceEntityRepositoryProxy
{
}
}
@@ -0,0 +1,10 @@
<?php
namespace Doctrine\Bundle\DoctrineBundle\Repository;
/**
* This interface signals that your repository should be loaded from the container.
*/
interface ServiceEntityRepositoryInterface
{
}
@@ -0,0 +1,138 @@
<?php
declare(strict_types=1);
namespace Doctrine\Bundle\DoctrineBundle\Repository;
use Doctrine\Common\Collections\AbstractLazyCollection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Selectable;
use Doctrine\DBAL\LockMode;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use LogicException;
use Symfony\Component\VarExporter\LazyObjectInterface;
use function sprintf;
/**
* @internal Extend {@see ServiceEntityRepository} instead.
*
* @template T of object
* @template-extends EntityRepository<T>
*/
class ServiceEntityRepositoryProxy extends EntityRepository implements ServiceEntityRepositoryInterface
{
private ?EntityRepository $repository = null;
/** @param class-string<T> $entityClass The class name of the entity this repository manages */
public function __construct(
private readonly ManagerRegistry $registry,
private readonly string $entityClass,
) {
if (! $this instanceof LazyObjectInterface) {
return;
}
$this->repository = $this->resolveRepository();
}
/** @psalm-suppress MethodSignatureMismatch This proxy is used only in combination with newer parent class */
public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder
{
return ($this->repository ??= $this->resolveRepository())
->createQueryBuilder($alias, $indexBy);
}
/** @psalm-suppress MethodSignatureMismatch This proxy is used only in combination with newer parent class */
public function createResultSetMappingBuilder(string $alias): ResultSetMappingBuilder
{
return ($this->repository ??= $this->resolveRepository())
->createResultSetMappingBuilder($alias);
}
/** @psalm-suppress MethodSignatureMismatch This proxy is used only in combination with newer parent class */
public function find(mixed $id, LockMode|int|null $lockMode = null, int|null $lockVersion = null): object|null
{
/** @psalm-suppress InvalidReturnStatement This proxy is used only in combination with newer parent class */
return ($this->repository ??= $this->resolveRepository())
->find($id, $lockMode, $lockVersion);
}
/**
* {@inheritDoc}
*
* @psalm-suppress InvalidReturnStatement This proxy is used only in combination with newer parent class
* @psalm-suppress MethodSignatureMismatch This proxy is used only in combination with newer parent class
* @psalm-suppress InvalidReturnType This proxy is used only in combination with newer parent class
*/
public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array
{
return ($this->repository ??= $this->resolveRepository())
->findBy($criteria, $orderBy, $limit, $offset);
}
/** {@inheritDoc} */
public function findOneBy(array $criteria, ?array $orderBy = null): object|null
{
/** @psalm-suppress InvalidReturnStatement This proxy is used only in combination with newer parent class */
return ($this->repository ??= $this->resolveRepository())
->findOneBy($criteria, $orderBy);
}
/** {@inheritDoc} */
public function count(array $criteria = []): int
{
return ($this->repository ??= $this->resolveRepository())->count($criteria);
}
/**
* {@inheritDoc}
*
* @psalm-suppress MethodSignatureMismatch This proxy is used only in combination with newer parent class
*/
public function __call(string $method, array $arguments): mixed
{
return ($this->repository ??= $this->resolveRepository())->$method(...$arguments);
}
protected function getEntityName(): string
{
return ($this->repository ??= $this->resolveRepository())->getEntityName();
}
protected function getEntityManager(): EntityManagerInterface
{
return ($this->repository ??= $this->resolveRepository())->getEntityManager();
}
/** @psalm-suppress InvalidReturnType This proxy is used only in combination with newer parent class */
protected function getClassMetadata(): ClassMetadata
{
/** @psalm-suppress InvalidReturnStatement This proxy is used only in combination with newer parent class */
return ($this->repository ??= $this->resolveRepository())->getClassMetadata();
}
public function matching(Criteria $criteria): AbstractLazyCollection&Selectable
{
return ($this->repository ??= $this->resolveRepository())->matching($criteria);
}
private function resolveRepository(): EntityRepository
{
$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 entitys metadata.',
$this->entityClass,
));
}
return new EntityRepository($manager, $manager->getClassMetadata($this->entityClass));
}
}