vendor/doctrine/doctrine-bundle/Repository/ContainerRepositoryFactory.php line 42

Open in your IDE?
  1. <?php
  2. namespace Doctrine\Bundle\DoctrineBundle\Repository;
  3. use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
  4. use Doctrine\Common\Persistence\ObjectRepository;
  5. use Doctrine\ORM\EntityManagerInterface;
  6. use Doctrine\ORM\Mapping\ClassMetadata;
  7. use Doctrine\ORM\Repository\RepositoryFactory;
  8. use InvalidArgumentException;
  9. use Psr\Container\ContainerInterface;
  10. use RuntimeException;
  11. /**
  12.  * Fetches repositories from the container or falls back to normal creation.
  13.  */
  14. final class ContainerRepositoryFactory implements RepositoryFactory {
  15.     /** @var ObjectRepository[] */
  16.     private $managedRepositories = [];
  17.     /** @var ContainerInterface|null */
  18.     private $container;
  19.     /**
  20.      * @param ContainerInterface $container A service locator containing the repositories
  21.      */
  22.     public function __construct(ContainerInterface $container null) {
  23.         // When DoctrineBundle requires Symfony 3.3+, this can be removed
  24.         // and the $container argument can become required.
  25.         if ($container === null) {
  26.             throw new InvalidArgumentException(sprintf('The first argument of %s::__construct() is required on Symfony 3.3 or higher.'self::class));
  27.         }
  28.         $this->container $container;
  29.     }
  30.     /**
  31.      * {@inheritdoc}
  32.      */
  33.     public function getRepository(EntityManagerInterface $entityManager$entityName) {
  34.         $metadata $entityManager->getClassMetadata($entityName);
  35.         $repositoryServiceId $metadata->customRepositoryClassName;
  36.         $customRepositoryName $metadata->customRepositoryClassName;
  37.         if ($customRepositoryName !== null) {
  38.             // fetch from the container
  39.             if ($this->container && $this->container->has($customRepositoryName)) {
  40.                 $repository $this->container->get($customRepositoryName);
  41.                 if (!$repository instanceof ObjectRepository) {
  42.                     throw new RuntimeException(sprintf('The service "%s" must implement ObjectRepository (or extend a base class, like ServiceEntityRepository).'$repositoryServiceId));
  43.                 }
  44.                 return $repository;
  45.             }
  46.             // if not in the container but the class/id implements the interface, throw an error
  47.             if (is_a($customRepositoryNameServiceEntityRepositoryInterface::class, true)) {
  48.                 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".'$customRepositoryNameServiceEntityRepositoryInterface::class, ServiceRepositoryCompilerPass::REPOSITORY_SERVICE_TAG));
  49.             }
  50.             if (!class_exists($customRepositoryName)) {
  51.                 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$customRepositoryNameServiceRepositoryCompilerPass::REPOSITORY_SERVICE_TAG));
  52.             }
  53.             // allow the repository to be created below
  54.         }
  55.         return $this->getOrCreateRepository($entityManager$metadata);
  56.     }
  57.     private function getOrCreateRepository(EntityManagerInterface $entityManagerClassMetadata $metadata) {
  58.         $repositoryHash $metadata->getName() . spl_object_hash($entityManager);
  59.         if (isset($this->managedRepositories[$repositoryHash])) {
  60.             return $this->managedRepositories[$repositoryHash];
  61.         }
  62.         $repositoryClassName $metadata->customRepositoryClassName ?: $entityManager->getConfiguration()->getDefaultRepositoryClassName();
  63.         return $this->managedRepositories[$repositoryHash] = new $repositoryClassName($entityManager$metadata);
  64.     }
  65. }