1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @link https://github.com/nnx-framework/doctrine |
4
|
|
|
* @author Malofeykin Andrey <[email protected]> |
5
|
|
|
*/ |
6
|
|
|
namespace Nnx\Doctrine\Utils; |
7
|
|
|
|
8
|
|
|
use Nnx\Doctrine\Options\ModuleOptionsInterface; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* Class DoctrineOrmModuleConfig |
12
|
|
|
* |
13
|
|
|
* @package Nnx\Doctrine\Utils |
14
|
|
|
*/ |
15
|
|
|
class DoctrineOrmModuleConfig implements DoctrineOrmModuleConfigInterface |
16
|
|
|
{ |
17
|
|
|
/** |
18
|
|
|
* Префикс, с которого начинается имя сервиса, для получения ObjectManager'a доктрины |
19
|
|
|
* |
20
|
|
|
* @var string |
21
|
|
|
*/ |
22
|
|
|
const DOCTRINE_PREFIX = 'doctrine.entitymanager.'; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Конфигурация доктрины. |
26
|
|
|
* |
27
|
|
|
* @see https://github.com/doctrine/DoctrineORMModule/blob/0.10.0/config/module.config.php |
28
|
|
|
* |
29
|
|
|
* @var array |
30
|
|
|
*/ |
31
|
|
|
protected $doctrineConfig = []; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Ключем является имя ObjectManager'a значением либо массив содержащий имена неймспейсов в которых расположены |
35
|
|
|
* сущности данного ObjectManager, либо false, в случае если для данного ObjectManager невозможно получить список |
36
|
|
|
* неймспейсов |
37
|
|
|
* |
38
|
|
|
* @var array |
39
|
|
|
*/ |
40
|
|
|
protected $namespacesByObjectManagerCache = []; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Опции модуля |
44
|
|
|
* |
45
|
|
|
* @var ModuleOptionsInterface |
46
|
|
|
*/ |
47
|
|
|
protected $moduleOptions; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Список имен ObjectManager'ов |
51
|
|
|
* |
52
|
|
|
* @var array|null |
53
|
|
|
*/ |
54
|
|
|
protected $listObjectManagerName; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* Список соеденений |
58
|
|
|
* |
59
|
|
|
* @var array|null |
60
|
|
|
*/ |
61
|
|
|
protected $listConnectionName; |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* DoctrineOrmModuleConfig constructor. |
65
|
|
|
* |
66
|
|
|
* @param array $doctrineConfig |
67
|
|
|
* @param ModuleOptionsInterface $moduleOptions |
68
|
|
|
*/ |
69
|
|
|
public function __construct(array $doctrineConfig = [], ModuleOptionsInterface $moduleOptions) |
70
|
|
|
{ |
71
|
|
|
$this->setDoctrineConfig($doctrineConfig); |
72
|
|
|
$this->setModuleOptions($moduleOptions); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Возвращает конфигурацию доктрины. |
78
|
|
|
* |
79
|
|
|
* @return array |
80
|
|
|
*/ |
81
|
|
|
public function getDoctrineConfig() |
82
|
|
|
{ |
83
|
|
|
return $this->doctrineConfig; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Устанавливает конфигурацию доктрины. |
88
|
|
|
* |
89
|
|
|
* @param array $doctrineConfig |
90
|
|
|
* |
91
|
|
|
* @return $this |
92
|
|
|
*/ |
93
|
|
|
public function setDoctrineConfig(array $doctrineConfig = []) |
94
|
|
|
{ |
95
|
|
|
$this->doctrineConfig = $doctrineConfig; |
96
|
|
|
|
97
|
|
|
return $this; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Список ObjectManager'ов декларированных в настройках модуля DoctrineOrmModule |
102
|
|
|
* |
103
|
|
|
* @return array |
104
|
|
|
*/ |
105
|
|
View Code Duplication |
public function getListObjectManagerName() |
|
|
|
|
106
|
|
|
{ |
107
|
|
|
if ($this->listObjectManagerName) { |
108
|
|
|
return $this->listObjectManagerName; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
if (!$this->isValidDoctrineOrmModuleEntityManagerConfig()) { |
112
|
|
|
$this->listObjectManagerName = []; |
113
|
|
|
return $this->listObjectManagerName; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
$doctrineConfig = $this->getDoctrineConfig(); |
117
|
|
|
|
118
|
|
|
$listObjectManagerName = array_keys($doctrineConfig['entitymanager']); |
119
|
|
|
$prepareListObjectManagerName = array_map(function ($objectManagerName) { |
120
|
|
|
return 'doctrine.entitymanager.' . $objectManagerName; |
121
|
|
|
}, $listObjectManagerName); |
122
|
|
|
|
123
|
|
|
$this->listObjectManagerName = array_combine($listObjectManagerName, $prepareListObjectManagerName); |
124
|
|
|
|
125
|
|
|
return $this->listObjectManagerName; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Список соиденений декларированных в настройках модуля DoctrineOrmModule |
131
|
|
|
* |
132
|
|
|
* @return array |
133
|
|
|
*/ |
134
|
|
View Code Duplication |
public function getListConnectionName() |
|
|
|
|
135
|
|
|
{ |
136
|
|
|
if ($this->listConnectionName) { |
137
|
|
|
return $this->listConnectionName; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
if (!$this->isValidDoctrineOrmModuleEntityManagerConfig()) { |
141
|
|
|
$this->listConnectionName = []; |
142
|
|
|
return $this->listConnectionName; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
$doctrineConfig = $this->getDoctrineConfig(); |
146
|
|
|
|
147
|
|
|
$listConnectionName = array_keys($doctrineConfig['connection']); |
148
|
|
|
$prepareListConnectionName = array_map(function ($connectionName) { |
149
|
|
|
return 'doctrine.connection.' . $connectionName; |
150
|
|
|
}, $listConnectionName); |
151
|
|
|
|
152
|
|
|
$this->listConnectionName = array_combine($listConnectionName, $prepareListConnectionName); |
153
|
|
|
|
154
|
|
|
return $this->listConnectionName; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* @inheritdoc |
159
|
|
|
* |
160
|
|
|
* @param string $objectManagerServiceName |
161
|
|
|
* |
162
|
|
|
* @return boolean |
163
|
|
|
*/ |
164
|
|
|
public function hasNamespacesByObjectManager($objectManagerServiceName) |
165
|
|
|
{ |
166
|
|
|
if (array_key_exists($objectManagerServiceName, $this->namespacesByObjectManagerCache)) { |
167
|
|
|
return false !== $this->namespacesByObjectManagerCache[$objectManagerServiceName]; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
if (!$this->isValidDoctrineOrmModuleConfig()) { |
171
|
|
|
$this->namespacesByObjectManagerCache[$objectManagerServiceName] = false; |
172
|
|
|
return false; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
if (0 !== strpos($objectManagerServiceName, static::DOCTRINE_PREFIX)) { |
176
|
|
|
$this->namespacesByObjectManagerCache[$objectManagerServiceName] = false; |
177
|
|
|
return false; |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
$objectManagerName = substr($objectManagerServiceName, 23); |
181
|
|
|
|
182
|
|
|
$doctrineConfig = $this->getDoctrineConfig(); |
183
|
|
|
|
184
|
|
|
if (!array_key_exists($objectManagerName, $doctrineConfig['entitymanager'])) { |
185
|
|
|
$this->namespacesByObjectManagerCache[$objectManagerServiceName] = false; |
186
|
|
|
return false; |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
$omConfig = $doctrineConfig['entitymanager'][$objectManagerName]; |
190
|
|
|
|
191
|
|
|
if (!is_array($omConfig) || !array_key_exists('configuration', $omConfig) || !is_string($omConfig['configuration'])) { |
192
|
|
|
$this->namespacesByObjectManagerCache[$objectManagerServiceName] = false; |
193
|
|
|
return false; |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
$confName = $omConfig['configuration']; |
197
|
|
|
|
198
|
|
View Code Duplication |
if (!array_key_exists($confName, $doctrineConfig['configuration']) || !is_array($doctrineConfig['configuration'][$confName])) { |
|
|
|
|
199
|
|
|
$this->namespacesByObjectManagerCache[$objectManagerServiceName] = false; |
200
|
|
|
return false; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
$omConfiguration = $doctrineConfig['configuration'][$confName]; |
204
|
|
|
|
205
|
|
|
if (!array_key_exists('driver', $omConfiguration) || !is_string($omConfiguration['driver'])) { |
206
|
|
|
$this->namespacesByObjectManagerCache[$objectManagerServiceName] = false; |
207
|
|
|
return false; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
$driverName = $omConfiguration['driver']; |
211
|
|
|
|
212
|
|
View Code Duplication |
if (!array_key_exists($driverName, $doctrineConfig['driver']) || !is_array($doctrineConfig['driver'][$driverName])) { |
|
|
|
|
213
|
|
|
$this->namespacesByObjectManagerCache[$objectManagerServiceName] = false; |
214
|
|
|
return false; |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
$driverConfig = $doctrineConfig['driver'][$driverName]; |
218
|
|
|
|
219
|
|
View Code Duplication |
if (!array_key_exists('drivers', $driverConfig) || !is_array($driverConfig['drivers'])) { |
|
|
|
|
220
|
|
|
$this->namespacesByObjectManagerCache[$objectManagerServiceName] = false; |
221
|
|
|
return false; |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
$this->namespacesByObjectManagerCache[$objectManagerServiceName] = $this->buildIndexNamespaces($driverConfig['drivers']); |
225
|
|
|
|
226
|
|
|
return false !== $this->namespacesByObjectManagerCache[$objectManagerServiceName]; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* На основе секции drivers, для драйвера EntityManager'a doctrine строит индекс для работы с неймспейсами. |
231
|
|
|
* |
232
|
|
|
* Ключем явлеятся тот же ключ что и в $drivers, а значением часть неймспейса в котором распологаются все сущности модуля |
233
|
|
|
* |
234
|
|
|
* @param $drivers |
235
|
|
|
* |
236
|
|
|
* @return array |
237
|
|
|
*/ |
238
|
|
|
public function buildIndexNamespaces($drivers) |
239
|
|
|
{ |
240
|
|
|
$listNamespaces = array_keys($drivers); |
241
|
|
|
|
242
|
|
|
$moduleOptions = $this->getModuleOptions(); |
243
|
|
|
$entitySeparator = $moduleOptions->getEntitySeparator(); |
244
|
|
|
|
245
|
|
|
$index = []; |
246
|
|
|
foreach ($listNamespaces as $currentNamespace) { |
247
|
|
|
$prepareNamespace = rtrim($currentNamespace, '\\'); |
248
|
|
|
$normalizeNamespace = $prepareNamespace . '\\'; |
249
|
|
|
|
250
|
|
|
$normalizeNamespaceStack = explode($entitySeparator, $normalizeNamespace); |
251
|
|
|
|
252
|
|
|
$namespacePrefix = array_shift($normalizeNamespaceStack); |
253
|
|
|
$index[$currentNamespace] = $namespacePrefix . $entitySeparator; |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
return $index; |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* @inheritdoc |
261
|
|
|
* |
262
|
|
|
* @param $objectManagerServiceName |
263
|
|
|
* |
264
|
|
|
* @return array |
265
|
|
|
* |
266
|
|
|
* @throws Exception\EntityNamespacesNotFoundException |
267
|
|
|
*/ |
268
|
|
|
public function getNamespacesIndexByObjectManagerName($objectManagerServiceName) |
269
|
|
|
{ |
270
|
|
|
if (false === $this->hasNamespacesByObjectManager($objectManagerServiceName)) { |
271
|
|
|
$errMsh = sprintf('Entity namespaces not found for: %s', $objectManagerServiceName); |
272
|
|
|
throw new Exception\EntityNamespacesNotFoundException($errMsh); |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
return $this->namespacesByObjectManagerCache[$objectManagerServiceName]; |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
/** |
279
|
|
|
* Проверяет является ли структура конфига модуля DoctrineORMModule, подходящей для того что бы получить список |
280
|
|
|
* неймспейсов в которых распологаются сущности для работы заданного ObjectManager'a |
281
|
|
|
* |
282
|
|
|
* @return bool |
283
|
|
|
*/ |
284
|
|
|
public function isValidDoctrineOrmModuleConfig() |
285
|
|
|
{ |
286
|
|
|
$doctrineConfig = $this->getDoctrineConfig(); |
287
|
|
|
|
288
|
|
|
return $this->isValidDoctrineOrmModuleEntityManagerConfig() |
289
|
|
|
&& array_key_exists('configuration', $doctrineConfig) && is_array($doctrineConfig['configuration']) |
290
|
|
|
&& array_key_exists('driver', $doctrineConfig) && is_array($doctrineConfig['driver']); |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
/** |
294
|
|
|
* Проверяет есть ли в конфиги корректная секция описывающая настройки entitymanager |
295
|
|
|
* |
296
|
|
|
* @return bool |
297
|
|
|
*/ |
298
|
|
|
public function isValidDoctrineOrmModuleEntityManagerConfig() |
299
|
|
|
{ |
300
|
|
|
$doctrineConfig = $this->getDoctrineConfig(); |
301
|
|
|
|
302
|
|
|
return array_key_exists('entitymanager', $doctrineConfig) && is_array($doctrineConfig['entitymanager']); |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
/** |
306
|
|
|
* Возвращает опции модуля |
307
|
|
|
* |
308
|
|
|
* @return ModuleOptionsInterface |
309
|
|
|
*/ |
310
|
|
|
public function getModuleOptions() |
311
|
|
|
{ |
312
|
|
|
return $this->moduleOptions; |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* Устанавливает опции модуля |
317
|
|
|
* |
318
|
|
|
* @param ModuleOptionsInterface $moduleOptions |
319
|
|
|
* |
320
|
|
|
* @return $this |
321
|
|
|
*/ |
322
|
|
|
public function setModuleOptions(ModuleOptionsInterface $moduleOptions) |
323
|
|
|
{ |
324
|
|
|
$this->moduleOptions = $moduleOptions; |
325
|
|
|
|
326
|
|
|
return $this; |
327
|
|
|
} |
328
|
|
|
} |
329
|
|
|
|
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.