Completed
Push — master ( 74c3c7...591b88 )
by Eric
08:09
created

RepositoryFactory   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 93
Duplicated Lines 17.2 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
c 1
b 0
f 0
lcom 1
cbo 3
dl 16
loc 93
ccs 31
cts 31
cp 1
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getRepository() 0 11 2
A createRepository() 16 16 2
A createResourceRepository() 0 12 3
A resolveResource() 0 8 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/*
4
 * This file is part of the Lug package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Lug\Component\Resource\Repository\Doctrine\ORM;
13
14
use Doctrine\Common\Persistence\ObjectRepository;
15
use Doctrine\ORM\EntityManagerInterface;
16
use Doctrine\ORM\Mapping\ClassMetadata;
17
use Doctrine\ORM\Repository\RepositoryFactory as RepositoryFactoryInterface;
18
use Lug\Component\Registry\Model\RegistryInterface;
19
use Lug\Component\Resource\Model\ResourceInterface;
20
use Lug\Component\Resource\Repository\RepositoryInterface as BaseRepositoryInterface;
21
22
/**
23
 * @author GeLo <[email protected]>
24
 */
25
class RepositoryFactory implements RepositoryFactoryInterface
26
{
27
    /**
28
     * @var RegistryInterface
29
     */
30
    private $resourceRegistry;
31
32
    /**
33
     * @var ObjectRepository[]
34
     */
35
    private $cache = [];
36
37
    /**
38
     * @param RegistryInterface $resourceRegistry
39
     */
40 9
    public function __construct(RegistryInterface $resourceRegistry)
41
    {
42 9
        $this->resourceRegistry = $resourceRegistry;
43 9
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48 5
    public function getRepository(EntityManagerInterface $entityManager, $entityName)
49
    {
50 5
        $metadata = $entityManager->getClassMetadata($entityName);
51 5
        $hash = $metadata->getName().spl_object_hash($entityManager);
52
53 5
        if (isset($this->cache[$hash])) {
54 5
            return $this->cache[$hash];
55
        }
56
57 5
        return $this->cache[$hash] = $this->createRepository($entityManager, $entityName);
58
    }
59
60
    /**
61
     * @param EntityManagerInterface $entityManager
62
     * @param string                 $entityName
63
     *
64
     * @return ObjectRepository
65
     */
66 5 View Code Duplication
    protected function createRepository(EntityManagerInterface $entityManager, $entityName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
67
    {
68 5
        $metadata = $entityManager->getClassMetadata($entityName);
69 5
        $repository = $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...
70
71 5
        if ($repository === null) {
72 2
            $repository = $entityManager->getConfiguration()->getDefaultRepositoryClassName();
73 2
        }
74
75 5
        return $this->createResourceRepository(
76 5
            $repository,
77 5
            $entityManager,
78 5
            $metadata,
0 ignored issues
show
Compatibility introduced by
$metadata of type object<Doctrine\Common\P...\Mapping\ClassMetadata> is not a sub-type of object<Doctrine\ORM\Mapping\ClassMetadata>. It seems like you assume a concrete implementation of the interface Doctrine\Common\Persistence\Mapping\ClassMetadata to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
79 5
            $this->resolveResource($metadata->getName())
80 5
        );
81
    }
82
83
    /**
84
     * @param string                 $class
85
     * @param EntityManagerInterface $entityManager
86
     * @param ClassMetadata          $metadata
87
     * @param ResourceInterface|null $resource
88
     *
89
     * @return ObjectRepository
90
     */
91 4
    protected function createResourceRepository(
92
        $class,
93
        EntityManagerInterface $entityManager,
94
        ClassMetadata $metadata,
95
        ResourceInterface $resource = null
96
    ) {
97 4
        if ($resource !== null && is_a($class, BaseRepositoryInterface::class, true)) {
98 2
            return new $class($entityManager, $metadata, $resource);
99
        }
100
101 2
        return new $class($entityManager, $metadata);
102
    }
103
104
    /**
105
     * @param string $class
106
     *
107
     * @return ResourceInterface|null
108
     */
109 5
    private function resolveResource($class)
110
    {
111 5
        foreach ($this->resourceRegistry as $resource) {
112 3
            if ($resource->getModel() === $class) {
113 3
                return $resource;
114
            }
115 2
        }
116 2
    }
117
}
118