Completed
Pull Request — master (#14)
by Pavel
03:32
created

EntityMetadataFactory::doLoadMetadata()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4.0879

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 14
cts 17
cp 0.8235
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 15
nc 6
nop 4
crap 4.0879
1
<?php
2
3
namespace Bankiru\Api\Doctrine;
4
5
use Bankiru\Api\Doctrine\Exception\MappingException;
6
use Bankiru\Api\Doctrine\Mapping\EntityMetadata;
7
use Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory;
8
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
9
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
10
use Doctrine\Common\Persistence\Mapping\ReflectionService;
11
use ReflectionException;
12
13
class EntityMetadataFactory extends AbstractClassMetadataFactory
14
{
15
    /** @var  EntityManager */
16
    private $manager;
17
    /** @var  MappingDriver */
18
    private $driver;
19
20
    /** @var string[] */
21
    private $aliases = [];
22
23
    public function registerAlias($namespaceAlias, $namespace)
24
    {
25
        if (array_key_exists($namespaceAlias, $this->aliases)) {
26
            throw new \LogicException(sprintf('Alias "%s" is already registered', $namespaceAlias));
27
        }
28
29
        $this->aliases[$namespaceAlias] = rtrim($namespace, '\\');
30
    }
31
32
    /**
33
     * @param EntityManager $manager
34
     */
35 18
    public function setEntityManager($manager)
36
    {
37 18
        $this->manager = $manager;
38 18
    }
39
40
    /** {@inheritdoc} */
41 18
    protected function initialize()
42
    {
43 18
        $this->driver      = $this->manager->getConfiguration()->getDriver();
44 18
        $this->initialized = true;
45 18
    }
46
47
    /**
48
     * {@inheritdoc}
49
     * @throws MappingException
50
     */
51
    protected function getFqcnFromAlias($namespaceAlias, $simpleClassName)
52
    {
53
        if (!array_key_exists($namespaceAlias, $this->aliases)) {
54
            throw MappingException::unknownAlias($namespaceAlias);
55
        }
56
57
        return $this->aliases[$namespaceAlias] . $simpleClassName;
58
    }
59
60
    /** {@inheritdoc} */
61 18
    protected function wakeupReflection(ClassMetadata $class, ReflectionService $reflService)
62
    {
63 18
        if (!($class instanceof EntityMetadata)) {
64
            throw new \LogicException('Metadata is not supported');
65
        }
66
67
        /** @var EntityMetadata $class */
68 18
        $class->wakeupReflection($reflService);
69 18
    }
70
71
    /**
72
     * Initializes Reflection after ClassMetadata was constructed.
73
     *
74
     * @param ClassMetadata     $class
75
     * @param ReflectionService $reflService
76
     *
77
     * @return void
78
     */
79 18
    protected function initializeReflection(ClassMetadata $class, ReflectionService $reflService)
80
    {
81 18
        if (!($class instanceof EntityMetadata)) {
82
            throw new \LogicException('Metadata is not supported');
83
        }
84
85
        /** @var EntityMetadata $class */
86 18
        $class->initializeReflection($reflService);
87 18
    }
88
89
    /**
90
     * Checks whether the class metadata is an entity.
91
     *
92
     * This method should return false for mapped superclasses or embedded classes.
93
     *
94
     * @param ClassMetadata $class
95
     *
96
     * @return boolean
97
     */
98 18
    protected function isEntity(ClassMetadata $class)
99
    {
100 18
        return true;
101
    }
102
103
    /**
104
     * Actually loads the metadata from the underlying metadata.
105
     *
106
     * @param EntityMetadata      $class
107
     * @param EntityMetadata|null $parent
108
     * @param bool                $rootEntityFound
109
     * @param array               $nonSuperclassParents    All parent class names
110
     *                                                     that are not marked as mapped superclasses.
111
     *
112
     * @return void
113
     * @throws MappingException
114
     */
115 18
    protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents)
116
    {
117
        /* @var $class EntityMetadata */
118
        /* @var $parent EntityMetadata */
119 18
        if ($parent) {
120 5
            $this->addInheritedFields($class, $parent);
121 5
            $this->addInheritedRelations($class, $parent);
122 5
            $class->setIdentifier($parent->identifier);
123 5
            $class->apiName        = $parent->apiName;
124 5
            $class->clientName     = $parent->clientName;
125 5
            $class->methodProvider = $parent->methodProvider;
126 5
            $class->generatorType  = $parent->generatorType;
127
128 5
            if ($parent->isMappedSuperclass) {
129
                $class->setCustomRepositoryClass($parent->repositoryClass);
130
            }
131 5
        }
132
133
        // Invoke driver
134
        try {
135 18
            $this->getDriver()->loadMetadataForClass($class->getName(), $class);
136 18
        } catch (ReflectionException $e) {
137
            throw MappingException::nonExistingClass($class->getName());
138
        }
139 18
    }
140
141
    /**
142
     * Returns the mapping driver implementation.
143
     *
144
     * @return \Doctrine\Common\Persistence\Mapping\Driver\MappingDriver
145
     */
146 18
    protected function getDriver()
147
    {
148 18
        return $this->driver;
149
    }
150
151
    /**
152
     * Creates a new ClassMetadata instance for the given class name.
153
     *
154
     * @param string $className
155
     *
156
     * @return ClassMetadata
157
     */
158 18
    protected function newClassMetadataInstance($className)
159
    {
160 18
        return new EntityMetadata($className);
161
    }
162
163
    /**
164
     * Adds inherited fields to the subclass mapping.
165
     *
166
     * @param EntityMetadata $subClass
167
     * @param EntityMetadata $parentClass
168
     *
169
     * @return void
170
     */
171 5
    private function addInheritedFields(EntityMetadata $subClass, EntityMetadata $parentClass)
172
    {
173 5 View Code Duplication
        foreach ($parentClass->fields as $mapping) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
174 5
            if (!isset($mapping['inherited']) && !$parentClass->isMappedSuperclass) {
175 5
                $mapping['inherited'] = $parentClass->name;
176 5
            }
177 5
            if (!isset($mapping['declared'])) {
178 5
                $mapping['declared'] = $parentClass->name;
179 5
            }
180 5
            $subClass->addInheritedFieldMapping($mapping);
181 5
        }
182 5
        foreach ($parentClass->reflFields as $name => $field) {
183 5
            $subClass->reflFields[$name] = $field;
184 5
        }
185 5
    }
186
187
    /**
188
     * Adds inherited association mappings to the subclass mapping.
189
     *
190
     * @param EntityMetadata $subClass
191
     * @param EntityMetadata $parentClass
192
     *
193
     * @return void
194
     *
195
     * @throws MappingException
196
     */
197 5
    private function addInheritedRelations(EntityMetadata $subClass, EntityMetadata $parentClass)
198
    {
199 5 View Code Duplication
        foreach ($parentClass->associations as $mapping) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
200 5
            if (!isset($mapping['inherited']) && !$parentClass->isMappedSuperclass) {
201 5
                $mapping['inherited'] = $parentClass->name;
202 5
            }
203 5
            if (!isset($mapping['declared'])) {
204 5
                $mapping['declared'] = $parentClass->name;
205 5
            }
206 5
            $subClass->addInheritedAssociationMapping($mapping);
207 5
        }
208 5
    }
209
}
210