Completed
Pull Request — master (#727)
by
unknown
02:10
created

ContainerRepositoryFactory   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 46
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 6
lcom 1
cbo 4
dl 0
loc 46
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B getRepository() 0 28 5
1
<?php
2
3
/*
4
 * This file is part of the Doctrine Bundle
5
 *
6
 * The code was originally distributed inside the Symfony framework.
7
 *
8
 * (c) Fabien Potencier <[email protected]>
9
 * (c) Doctrine Project, Benjamin Eberlei <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Doctrine\Bundle\DoctrineBundle\Repository;
16
17
use Doctrine\ORM\EntityManagerInterface;
18
use Doctrine\ORM\EntityRepository;
19
use Doctrine\ORM\Repository\RepositoryFactory;
20
use Psr\Container\ContainerInterface;
21
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
22
23
/**
24
 * A custom repository factory that fetches repositories from the container.
25
 *
26
 * @author Ryan Weaver <[email protected]>
27
 */
28
class ContainerRepositoryFactory implements RepositoryFactory
29
{
30
    private $managedRepositories = [];
31
32
    private $container;
33
34
    /**
35
     * @param ContainerInterface $container A service locator containing the repositories
36
     */
37
    public function __construct(ContainerInterface $container)
38
    {
39
        $this->container = $container;
40
    }
41
42
    /**
43
     * {@inheritDoc}
44
     */
45
    public function getRepository(EntityManagerInterface $entityManager, $entityName)
46
    {
47
        $metadata = $entityManager->getClassMetadata($entityName);
48
        $repositoryServiceId = $metadata->customRepositoryClassName;
0 ignored issues
show
Bug introduced by
Accessing customRepositoryClassName on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
49
50
        if (null !== $repositoryServiceId) {
51
            if (!$this->container->has($metadata->customRepositoryClassName)) {
0 ignored issues
show
Bug introduced by
Accessing customRepositoryClassName on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
52
                throw new \RuntimeException(sprintf('Could not find the repository service for the "%s" entity. Make sure the "%s" service exists and is tagged with "%s".', $entityName, $repositoryServiceId, ServiceRepositoryCompilerPass::REPOSITORY_SERVICE_TAG));
53
            }
54
55
            $repository = $this->container->get($metadata->customRepositoryClassName);
0 ignored issues
show
Bug introduced by
Accessing customRepositoryClassName on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
56
57
            if (!$repository instanceof EntityRepository) {
58
                throw new \RuntimeException(sprintf('The service "%s" must extend EntityRepository (or a base class, like ServiceEntityRepository).', $repositoryServiceId));
59
            }
60
61
            return $repository;
62
        }
63
64
        $repositoryHash = $metadata->getName() . spl_object_hash($entityManager);
65
        if (isset($this->managedRepositories[$repositoryHash])) {
66
            return $this->managedRepositories[$repositoryHash];
67
        }
68
69
        $repositoryClassName = $entityManager->getConfiguration()->getDefaultRepositoryClassName();
70
71
        return $this->managedRepositories[$repositoryHash] = new $repositoryClassName($entityManager, $metadata);
72
    }
73
}
74