|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
declare(strict_types=1); |
|
4
|
|
|
|
|
5
|
|
|
namespace Chubbyphp\DoctrineDbServiceProvider\Registry; |
|
6
|
|
|
|
|
7
|
|
|
use Doctrine\Common\Persistence\ManagerRegistry; |
|
8
|
|
|
use Doctrine\Common\Persistence\ObjectManager; |
|
9
|
|
|
use Doctrine\Common\Persistence\ObjectRepository; |
|
10
|
|
|
use Doctrine\Common\Persistence\Proxy; |
|
11
|
|
|
use Doctrine\DBAL\Connection; |
|
12
|
|
|
use Doctrine\ORM\EntityManagerInterface; |
|
13
|
|
|
use Doctrine\ORM\EntityRepository; |
|
14
|
|
|
use Doctrine\ORM\ORMException; |
|
15
|
|
|
use Pimple\Container; |
|
16
|
|
|
|
|
17
|
|
|
final class DoctrineOrmManagerRegistry implements ManagerRegistry |
|
18
|
|
|
{ |
|
19
|
|
|
/** |
|
20
|
|
|
* @var Container |
|
21
|
|
|
*/ |
|
22
|
|
|
private $container; |
|
23
|
|
|
|
|
24
|
|
|
/** |
|
25
|
|
|
* @var Container |
|
26
|
|
|
*/ |
|
27
|
|
|
private $connections; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* @var string |
|
31
|
|
|
*/ |
|
32
|
|
|
private $defaultConnectionName; |
|
33
|
|
|
|
|
34
|
|
|
/** |
|
35
|
|
|
* @var Container |
|
36
|
|
|
*/ |
|
37
|
|
|
private $originalEntityManagers; |
|
38
|
|
|
|
|
39
|
|
|
/** |
|
40
|
|
|
* @var array<string, EntityManagerInterface> |
|
41
|
|
|
*/ |
|
42
|
|
|
private $resetedManagers = []; |
|
43
|
|
|
|
|
44
|
|
|
/** |
|
45
|
|
|
* @var string |
|
46
|
|
|
*/ |
|
47
|
|
|
private $defaultManagerName; |
|
48
|
|
|
|
|
49
|
19 |
|
public function __construct(Container $container) |
|
50
|
|
|
{ |
|
51
|
19 |
|
$this->container = $container; |
|
52
|
19 |
|
} |
|
53
|
|
|
|
|
54
|
3 |
|
public function getDefaultConnectionName(): string |
|
55
|
|
|
{ |
|
56
|
3 |
|
$this->loadConnections(); |
|
57
|
|
|
|
|
58
|
3 |
|
return $this->defaultConnectionName; |
|
59
|
|
|
} |
|
60
|
|
|
|
|
61
|
|
|
/** |
|
62
|
|
|
* @param string|null $name |
|
63
|
|
|
* |
|
64
|
|
|
* @throws \InvalidArgumentException |
|
65
|
|
|
* |
|
66
|
|
|
* @return Connection |
|
67
|
|
|
*/ |
|
68
|
2 |
View Code Duplication |
public function getConnection($name = null): Connection |
|
|
|
|
|
|
69
|
|
|
{ |
|
70
|
2 |
|
$this->loadConnections(); |
|
71
|
|
|
|
|
72
|
2 |
|
$name = $name ?? $this->getDefaultConnectionName(); |
|
73
|
|
|
|
|
74
|
2 |
|
if (!isset($this->connections[$name])) { |
|
75
|
1 |
|
throw new \InvalidArgumentException(sprintf('Missing connection with name "%s".', $name)); |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
1 |
|
return $this->connections[$name]; |
|
79
|
|
|
} |
|
80
|
|
|
|
|
81
|
|
|
/** |
|
82
|
|
|
* @return array<string, Connection> |
|
|
|
|
|
|
83
|
|
|
*/ |
|
84
|
1 |
View Code Duplication |
public function getConnections(): array |
|
|
|
|
|
|
85
|
|
|
{ |
|
86
|
1 |
|
$this->loadConnections(); |
|
87
|
|
|
|
|
88
|
1 |
|
$connections = []; |
|
89
|
|
|
/** @var string $name */ |
|
90
|
1 |
|
foreach ($this->connections->keys() as $name) { |
|
91
|
|
|
/** @var Connection $connection */ |
|
92
|
1 |
|
$connection = $this->connections[$name]; |
|
93
|
1 |
|
$connections[$name] = $connection; |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
1 |
|
return $connections; |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
/** |
|
100
|
|
|
* @return array<string> |
|
101
|
|
|
*/ |
|
102
|
1 |
|
public function getConnectionNames(): array |
|
103
|
|
|
{ |
|
104
|
1 |
|
$this->loadConnections(); |
|
105
|
|
|
|
|
106
|
1 |
|
return $this->connections->keys(); |
|
107
|
|
|
} |
|
108
|
|
|
|
|
109
|
6 |
|
public function getDefaultManagerName(): string |
|
110
|
|
|
{ |
|
111
|
6 |
|
$this->loadManagers(); |
|
112
|
|
|
|
|
113
|
6 |
|
return $this->defaultManagerName; |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
/** |
|
117
|
|
|
* @param string|null $name |
|
118
|
|
|
* |
|
119
|
|
|
* @return EntityManagerInterface|ObjectManager |
|
120
|
|
|
*/ |
|
121
|
8 |
|
public function getManager($name = null): ObjectManager |
|
122
|
|
|
{ |
|
123
|
8 |
|
$this->loadManagers(); |
|
124
|
|
|
|
|
125
|
8 |
|
$name = $name ?? $this->getDefaultManagerName(); |
|
126
|
|
|
|
|
127
|
8 |
|
if (!isset($this->originalEntityManagers[$name])) { |
|
128
|
1 |
|
throw new \InvalidArgumentException(sprintf('Missing manager with name "%s".', $name)); |
|
129
|
|
|
} |
|
130
|
|
|
|
|
131
|
7 |
|
if (isset($this->resetedManagers[$name])) { |
|
132
|
1 |
|
return $this->resetedManagers[$name]; |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
6 |
|
return $this->originalEntityManagers[$name]; |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
/** |
|
139
|
|
|
* @return array<string, EntityManagerInterface>|array<string, ObjectManager> |
|
|
|
|
|
|
140
|
|
|
*/ |
|
141
|
2 |
|
public function getManagers(): array |
|
142
|
|
|
{ |
|
143
|
2 |
|
$this->loadManagers(); |
|
144
|
|
|
|
|
145
|
2 |
|
$entityManagers = []; |
|
146
|
|
|
/** @var string $name */ |
|
147
|
2 |
|
foreach ($this->originalEntityManagers->keys() as $name) { |
|
148
|
|
|
/* @var EntityManagerInterface $entityManager */ |
|
149
|
2 |
|
if (isset($this->resetedManagers[$name])) { |
|
150
|
1 |
|
$entityManager = $this->resetedManagers[$name]; |
|
151
|
|
|
} else { |
|
152
|
1 |
|
$entityManager = $this->originalEntityManagers[$name]; |
|
153
|
|
|
} |
|
154
|
|
|
|
|
155
|
2 |
|
$entityManagers[$name] = $entityManager; |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
2 |
|
return $entityManagers; |
|
159
|
|
|
} |
|
160
|
|
|
|
|
161
|
|
|
/** |
|
162
|
|
|
* @return array<string> |
|
163
|
|
|
*/ |
|
164
|
5 |
|
public function getManagerNames(): array |
|
165
|
|
|
{ |
|
166
|
5 |
|
$this->loadManagers(); |
|
167
|
|
|
|
|
168
|
5 |
|
return $this->originalEntityManagers->keys(); |
|
169
|
|
|
} |
|
170
|
|
|
|
|
171
|
|
|
/** |
|
172
|
|
|
* @param string|null $name |
|
173
|
|
|
* |
|
174
|
|
|
* @return EntityManagerInterface|ObjectManager |
|
175
|
|
|
*/ |
|
176
|
2 |
|
public function resetManager($name = null) |
|
177
|
|
|
{ |
|
178
|
2 |
|
$this->loadManagers(); |
|
179
|
|
|
|
|
180
|
2 |
|
$name = $name ?? $this->getDefaultManagerName(); |
|
181
|
|
|
|
|
182
|
2 |
|
if (!isset($this->originalEntityManagers[$name])) { |
|
183
|
1 |
|
throw new \InvalidArgumentException(sprintf('Missing manager with name "%s".', $name)); |
|
184
|
|
|
} |
|
185
|
|
|
|
|
186
|
|
|
/** @var EntityManagerInterface $originalEntityManager */ |
|
187
|
1 |
|
$originalEntityManager = $this->originalEntityManagers[$name]; |
|
188
|
|
|
|
|
189
|
|
|
/** @var callable $entityManagerFactory */ |
|
190
|
1 |
|
$entityManagerFactory = $this->container['doctrine.orm.em.factory']; |
|
191
|
|
|
|
|
192
|
|
|
/** @var EntityManagerInterface $entityManager */ |
|
193
|
1 |
|
$entityManager = $entityManagerFactory( |
|
194
|
1 |
|
$originalEntityManager->getConnection(), |
|
195
|
1 |
|
$originalEntityManager->getConfiguration(), |
|
196
|
1 |
|
$originalEntityManager->getEventManager() |
|
197
|
|
|
); |
|
198
|
|
|
|
|
199
|
1 |
|
$this->resetedManagers[$name] = $entityManager; |
|
200
|
|
|
|
|
201
|
1 |
|
return $entityManager; |
|
202
|
|
|
} |
|
203
|
|
|
|
|
204
|
|
|
/** |
|
205
|
|
|
* @param string $alias |
|
206
|
|
|
* |
|
207
|
|
|
* @throws ORMException |
|
208
|
|
|
* |
|
209
|
|
|
* @return string |
|
210
|
|
|
*/ |
|
211
|
2 |
|
public function getAliasNamespace($alias): string |
|
212
|
|
|
{ |
|
213
|
2 |
|
foreach ($this->getManagerNames() as $name) { |
|
214
|
|
|
try { |
|
215
|
|
|
/** @var EntityManagerInterface $entityManager */ |
|
216
|
2 |
|
$entityManager = $this->getManager($name); |
|
217
|
|
|
|
|
218
|
2 |
|
return $entityManager->getConfiguration()->getEntityNamespace($alias); |
|
219
|
1 |
|
} catch (ORMException $exception) { |
|
|
|
|
|
|
220
|
|
|
// throw the exception only if no manager can solve it |
|
221
|
|
|
} |
|
222
|
|
|
} |
|
223
|
1 |
|
throw ORMException::unknownEntityNamespace($alias); |
|
224
|
|
|
} |
|
225
|
|
|
|
|
226
|
|
|
/** |
|
227
|
|
|
* @param string $persistentObject |
|
228
|
|
|
* @param string|null $persistentManagerName |
|
229
|
|
|
* |
|
230
|
|
|
* @return EntityRepository|ObjectRepository |
|
231
|
|
|
*/ |
|
232
|
1 |
|
public function getRepository($persistentObject, $persistentManagerName = null): ObjectRepository |
|
233
|
|
|
{ |
|
234
|
1 |
|
return $this->getManager($persistentManagerName)->getRepository($persistentObject); |
|
235
|
|
|
} |
|
236
|
|
|
|
|
237
|
|
|
/** |
|
238
|
|
|
* @param string $class |
|
239
|
|
|
* |
|
240
|
|
|
* @return EntityManagerInterface|ObjectManager|null |
|
241
|
|
|
*/ |
|
242
|
2 |
|
public function getManagerForClass($class) |
|
243
|
|
|
{ |
|
244
|
2 |
|
$reflectionClass = new \ReflectionClass($class); |
|
245
|
2 |
|
if ($reflectionClass->implementsInterface(Proxy::class)) { |
|
246
|
|
|
/** @var \ReflectionClass $reflectionParentClass */ |
|
247
|
2 |
|
$reflectionParentClass = $reflectionClass->getParentClass(); |
|
248
|
2 |
|
$class = $reflectionParentClass->getName(); |
|
|
|
|
|
|
249
|
|
|
} |
|
250
|
|
|
|
|
251
|
2 |
|
foreach ($this->getManagerNames() as $name) { |
|
252
|
2 |
|
$entityManager = $this->getManager($name); |
|
253
|
2 |
|
if (!$entityManager->getMetadataFactory()->isTransient($class)) { |
|
254
|
2 |
|
return $entityManager; |
|
255
|
|
|
} |
|
256
|
|
|
} |
|
257
|
1 |
|
} |
|
258
|
|
|
|
|
259
|
5 |
View Code Duplication |
private function loadConnections(): void |
|
|
|
|
|
|
260
|
|
|
{ |
|
261
|
5 |
|
if (null === $this->connections) { |
|
262
|
5 |
|
$this->connections = $this->container['doctrine.dbal.dbs']; |
|
263
|
5 |
|
$this->defaultConnectionName = $this->container['doctrine.dbal.dbs.default']; |
|
264
|
|
|
} |
|
265
|
5 |
|
} |
|
266
|
|
|
|
|
267
|
14 |
|
private function loadManagers(): void |
|
268
|
|
|
{ |
|
269
|
14 |
|
if (null === $this->originalEntityManagers) { |
|
270
|
14 |
|
$this->originalEntityManagers = $this->container['doctrine.orm.ems']; |
|
271
|
14 |
|
$this->defaultManagerName = $this->container['doctrine.orm.ems.default']; |
|
272
|
|
|
} |
|
273
|
14 |
|
} |
|
274
|
|
|
} |
|
275
|
|
|
|
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.