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
|
20 |
|
public function setEntityManager($manager) |
36
|
|
|
{ |
37
|
20 |
|
$this->manager = $manager; |
38
|
20 |
|
} |
39
|
|
|
|
40
|
|
|
/** {@inheritdoc} */ |
41
|
20 |
|
protected function initialize() |
42
|
|
|
{ |
43
|
20 |
|
$this->driver = $this->manager->getConfiguration()->getDriver(); |
44
|
20 |
|
$this->initialized = true; |
45
|
20 |
|
} |
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
|
20 |
|
protected function wakeupReflection(ClassMetadata $class, ReflectionService $reflService) |
62
|
|
|
{ |
63
|
20 |
|
if (!($class instanceof EntityMetadata)) { |
64
|
|
|
throw new \LogicException('Metadata is not supported'); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** @var EntityMetadata $class */ |
68
|
20 |
|
$class->wakeupReflection($reflService); |
69
|
20 |
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Initializes Reflection after ClassMetadata was constructed. |
73
|
|
|
* |
74
|
|
|
* @param ClassMetadata $class |
75
|
|
|
* @param ReflectionService $reflService |
76
|
|
|
* |
77
|
|
|
* @return void |
78
|
|
|
*/ |
79
|
20 |
|
protected function initializeReflection(ClassMetadata $class, ReflectionService $reflService) |
80
|
|
|
{ |
81
|
20 |
|
if (!($class instanceof EntityMetadata)) { |
82
|
|
|
throw new \LogicException('Metadata is not supported'); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** @var EntityMetadata $class */ |
86
|
20 |
|
$class->initializeReflection($reflService); |
87
|
20 |
|
} |
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
|
20 |
|
protected function isEntity(ClassMetadata $class) |
99
|
|
|
{ |
100
|
20 |
|
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
|
20 |
|
protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents) |
116
|
|
|
{ |
117
|
|
|
/* @var $class EntityMetadata */ |
118
|
|
|
/* @var $parent EntityMetadata */ |
119
|
20 |
|
if ($parent) { |
120
|
5 |
|
$this->addInheritedFields($class, $parent); |
121
|
5 |
|
$this->addInheritedRelations($class, $parent); |
122
|
5 |
|
$class->setIdentifier($parent->identifier); |
123
|
5 |
|
$class->apiFactory = $parent->apiFactory; |
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
|
20 |
|
$this->getDriver()->loadMetadataForClass($class->getName(), $class); |
136
|
20 |
|
} catch (ReflectionException $e) { |
137
|
|
|
throw MappingException::nonExistingClass($class->getName()); |
138
|
|
|
} |
139
|
20 |
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Returns the mapping driver implementation. |
143
|
|
|
* |
144
|
|
|
* @return \Doctrine\Common\Persistence\Mapping\Driver\MappingDriver |
145
|
|
|
*/ |
146
|
20 |
|
protected function getDriver() |
147
|
|
|
{ |
148
|
20 |
|
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
|
20 |
|
protected function newClassMetadataInstance($className) |
159
|
|
|
{ |
160
|
20 |
|
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) { |
|
|
|
|
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) { |
|
|
|
|
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
|
|
|
|
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.