vendor/doctrine/mongodb-odm-bundle/Repository/ContainerRepositoryFactory.php line 50

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Doctrine\Bundle\MongoDBBundle\Repository;
  4. use Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
  5. use Doctrine\ODM\MongoDB\DocumentManager;
  6. use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
  7. use Doctrine\ODM\MongoDB\Repository\DocumentRepository;
  8. use Doctrine\ODM\MongoDB\Repository\GridFSRepository;
  9. use Doctrine\ODM\MongoDB\Repository\RepositoryFactory;
  10. use Doctrine\Persistence\ObjectRepository;
  11. use Psr\Container\ContainerInterface;
  12. use RuntimeException;
  13. use function class_exists;
  14. use function is_a;
  15. use function spl_object_hash;
  16. use function sprintf;
  17. /**
  18.  * Fetches repositories from the container or falls back to normal creation.
  19.  */
  20. final class ContainerRepositoryFactory implements RepositoryFactory
  21. {
  22.     /** @var array<string, ObjectRepository> */
  23.     private $managedRepositories = [];
  24.     /** @var ContainerInterface|null */
  25.     private $container;
  26.     /**
  27.      * @param ContainerInterface $container A service locator containing the repositories
  28.      */
  29.     public function __construct(ContainerInterface $container)
  30.     {
  31.         $this->container $container;
  32.     }
  33.     /**
  34.      * @psalm-param class-string<T> $documentName
  35.      *
  36.      * @psalm-return ObjectRepository<T>
  37.      *
  38.      * @template T of object
  39.      */
  40.     public function getRepository(DocumentManager $documentManagerstring $documentName): ObjectRepository
  41.     {
  42.         $metadata             $documentManager->getClassMetadata($documentName);
  43.         $customRepositoryName $metadata->customRepositoryClassName;
  44.         if ($customRepositoryName !== null) {
  45.             // fetch from the container
  46.             if ($this->container && $this->container->has($customRepositoryName)) {
  47.                 /** @var ObjectRepository<T> $repository */
  48.                 $repository $this->container->get($customRepositoryName);
  49.                 if (! $repository instanceof DocumentRepository) {
  50.                     throw new RuntimeException(sprintf('The service "%s" must extend DocumentRepository (or a base class, like ServiceDocumentRepository).'$customRepositoryName));
  51.                 }
  52.                 return $repository;
  53.             }
  54.             // if not in the container but the class/id implements the interface, throw an error
  55.             if (is_a($customRepositoryNameServiceDocumentRepositoryInterface::class, true)) {
  56.                 throw new RuntimeException(sprintf('The "%s" document repository implements "%s", but its service could not be found. Make sure the service exists and is tagged with "%s".'$customRepositoryNameServiceDocumentRepositoryInterface::class, ServiceRepositoryCompilerPass::REPOSITORY_SERVICE_TAG));
  57.             }
  58.             if (! class_exists($customRepositoryName)) {
  59.                 throw new RuntimeException(sprintf('The "%s" document 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));
  60.             }
  61.             // allow the repository to be created below
  62.         }
  63.         return $this->getOrCreateRepository($documentManager$metadata);
  64.     }
  65.     /**
  66.      * @psalm-param ClassMetadata<T> $metadata
  67.      *
  68.      * @psalm-return ObjectRepository<T>
  69.      *
  70.      * @template T of object
  71.      */
  72.     private function getOrCreateRepository(DocumentManager $documentManagerClassMetadata $metadata): ObjectRepository
  73.     {
  74.         $repositoryHash $metadata->getName() . spl_object_hash($documentManager);
  75.         if (isset($this->managedRepositories[$repositoryHash])) {
  76.             /** @psalm-var ObjectRepository<T> */
  77.             return $this->managedRepositories[$repositoryHash];
  78.         }
  79.         if ($metadata->customRepositoryClassName) {
  80.             $repositoryClassName $metadata->customRepositoryClassName;
  81.         } elseif ($metadata->isFile) {
  82.             /** @psalm-var class-string<GridFSRepository<T>> $repositoryClassName */
  83.             $repositoryClassName $documentManager->getConfiguration()->getDefaultGridFSRepositoryClassName();
  84.         } else {
  85.             /** @psalm-var class-string<ObjectRepository<T>> $repositoryClassName */
  86.             $repositoryClassName $documentManager->getConfiguration()->getDefaultDocumentRepositoryClassName();
  87.         }
  88.         return $this->managedRepositories[$repositoryHash] = new $repositoryClassName($documentManager$documentManager->getUnitOfWork(), $metadata);
  89.     }
  90. }