1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @link https://github.com/old-town/workflow-zf2-toolkit |
4
|
|
|
* @author Malofeykin Andrey <[email protected]> |
5
|
|
|
*/ |
6
|
|
|
namespace OldTown\Workflow\ZF2\Toolkit\WorkflowRunParams; |
7
|
|
|
|
8
|
|
|
use Zend\EventManager\AbstractListenerAggregate; |
9
|
|
|
use Zend\EventManager\EventManagerInterface; |
10
|
|
|
use OldTown\Workflow\ZF2\Dispatch\RunParamsHandler\RouteHandler; |
11
|
|
|
use OldTown\Workflow\ZF2\Dispatch\RunParamsHandler\RouteHandler\ResolveEntryIdEventInterface; |
12
|
|
|
use OldTown\Workflow\ZF2\Toolkit\EntryToObjects\EntryToObjectsService; |
13
|
|
|
use OldTown\Workflow\ZF2\Toolkit\Options\ModuleOptions; |
14
|
|
|
use Zend\Mvc\MvcEvent; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Class EntryIdResolver |
18
|
|
|
* |
19
|
|
|
* @package OldTown\Workflow\ZF2\Toolkit\WorkflowRunParams |
20
|
|
|
*/ |
21
|
|
|
class EntryIdResolver extends AbstractListenerAggregate |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* Имя параметра в конфиги модуля, по которому можно получить имя менеджера wf |
25
|
|
|
* |
26
|
|
|
* @var string |
27
|
|
|
*/ |
28
|
|
|
const WORKFLOW_MANAGER_NAME = 'workflowManagerName'; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Имя параметра в конфиге модуля, по которому можно получить имя wf |
32
|
|
|
* |
33
|
|
|
* @var string |
34
|
|
|
*/ |
35
|
|
|
const WORKFLOW_NAME = 'workflowName'; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Имя параметра в конфиге модуля, по которому можно конфиг описывающий какие классы и какие имена параметров роуетера |
39
|
|
|
* используется, для получения entryId |
40
|
|
|
* |
41
|
|
|
* @var string |
42
|
|
|
*/ |
43
|
|
|
const MAP = 'map'; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Имя параметра в карте(@see const MAP), по которому можно получить класс сущности |
47
|
|
|
* |
48
|
|
|
* @var string |
49
|
|
|
*/ |
50
|
|
|
const ENTITY_CLASS_NAME = 'entityClassName'; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Имя параметра в карте(@see const MAP), по которому можно получить имя параметра роутера содержащего id сущности |
54
|
|
|
* |
55
|
|
|
* @var string |
56
|
|
|
*/ |
57
|
|
|
const ROUTER_PARAM_NAME = 'routerParamName'; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Сервис реализующий функционал, для привязки процессов wf и информации о объектаъ |
61
|
|
|
* |
62
|
|
|
* @var EntryToObjectsService |
63
|
|
|
*/ |
64
|
|
|
protected $entryToObjectsService; |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Настройки модуля |
68
|
|
|
* |
69
|
|
|
* @var ModuleOptions |
70
|
|
|
*/ |
71
|
|
|
protected $moduleOptions; |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Индекс для маппинга |
75
|
|
|
* |
76
|
|
|
* @var null|array |
77
|
|
|
*/ |
78
|
|
|
protected $indexMetadata; |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* @var MvcEvent |
82
|
|
|
*/ |
83
|
|
|
protected $mvcEvent; |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* EntryIdResolver constructor. |
87
|
|
|
* |
88
|
|
|
* @param array $options |
89
|
|
|
*/ |
90
|
|
|
public function __construct(array $options = []) |
91
|
|
|
{ |
92
|
|
|
$initOptions = [ |
93
|
|
|
array_key_exists('entryToObjectsService', $options) ? $options['entryToObjectsService'] : null, |
94
|
|
|
array_key_exists('moduleOptions', $options) ? $options['moduleOptions'] : null, |
95
|
|
|
array_key_exists('mvcEvent', $options) ? $options['mvcEvent'] : null |
96
|
|
|
]; |
97
|
|
|
call_user_func_array([$this, 'init'], $initOptions); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* @param EntryToObjectsService $entryToObjectsService |
102
|
|
|
* @param ModuleOptions $moduleOptions |
103
|
|
|
* @param MvcEvent $mvcEvent |
104
|
|
|
*/ |
105
|
|
|
protected function init( |
106
|
|
|
EntryToObjectsService $entryToObjectsService, |
107
|
|
|
ModuleOptions $moduleOptions, |
108
|
|
|
MvcEvent $mvcEvent |
109
|
|
|
) { |
110
|
|
|
$this->setEntryToObjectsService($entryToObjectsService); |
111
|
|
|
$this->setModuleOptions($moduleOptions); |
112
|
|
|
$this->setMvcEvent($mvcEvent); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* @param EventManagerInterface $events |
117
|
|
|
*/ |
118
|
|
|
public function attach(EventManagerInterface $events) |
119
|
|
|
{ |
120
|
|
|
$events->getSharedManager()->attach(RouteHandler::class, ResolveEntryIdEventInterface::RESOLVE_ENTRY_ID_EVENT, [$this, 'onResolveEntryId'], 80); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Обработчик содержащий логику получения entryId |
125
|
|
|
* |
126
|
|
|
* @param ResolveEntryIdEventInterface $resolveEntryIdEvent |
127
|
|
|
* |
128
|
|
|
* |
129
|
|
|
* @return null|string |
130
|
|
|
* |
131
|
|
|
* @throws \OldTown\Workflow\ZF2\Toolkit\EntryToObjects\Exception\InvalidGetEntryByObjectsInfoException |
132
|
|
|
* @throws \OldTown\Workflow\ZF2\Toolkit\WorkflowRunParams\Exception\InvalidWorkflowEntryToObjectMetadataException |
133
|
|
|
* @throws \Zend\Serializer\Exception\ExceptionInterface |
134
|
|
|
*/ |
135
|
|
|
public function onResolveEntryId(ResolveEntryIdEventInterface $resolveEntryIdEvent) |
136
|
|
|
{ |
137
|
|
|
$index = $this->getIndexMetadata(); |
138
|
|
|
|
139
|
|
|
$managerName = $resolveEntryIdEvent->getManagerName(); |
140
|
|
|
if (!array_key_exists($managerName, $index)) { |
141
|
|
|
return null; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
$workflowName = $resolveEntryIdEvent->getWorkflowName(); |
145
|
|
|
if (!array_key_exists($workflowName, $index[$managerName]) || !is_array($index[$managerName][$workflowName])) { |
146
|
|
|
return null; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
$routeMatch = $this->getMvcEvent()->getRouteMatch(); |
150
|
|
|
$objectsInfo = []; |
151
|
|
|
foreach ($index[$managerName][$workflowName] as $entityClassName => $routerParamName) { |
152
|
|
|
$entityId = $routeMatch->getParam($routerParamName, null); |
153
|
|
|
if (null === $entityId) { |
154
|
|
|
return null; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
$objectsInfo[$entityClassName] = $entityId; |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
$entry = $this->getEntryToObjectsService()->getEntryByObjectsInfo($managerName, $workflowName, $objectsInfo); |
161
|
|
|
|
162
|
|
|
if (null === $entry) { |
163
|
|
|
return null; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
return $entry->getId(); |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* @return array|null |
171
|
|
|
* |
172
|
|
|
* @throws Exception\InvalidWorkflowEntryToObjectMetadataException |
173
|
|
|
*/ |
174
|
|
|
public function getIndexMetadata() |
175
|
|
|
{ |
176
|
|
|
if (null !== $this->indexMetadata) { |
177
|
|
|
return $this->indexMetadata; |
178
|
|
|
} |
179
|
|
|
$metadata = $this->getModuleOptions()->getWorkflowEntryToObjectMetadata(); |
180
|
|
|
|
181
|
|
|
$index = []; |
182
|
|
|
foreach ($metadata as $metadataItem) { |
183
|
|
View Code Duplication |
if (!array_key_exists(static::WORKFLOW_MANAGER_NAME, $metadataItem)) { |
|
|
|
|
184
|
|
|
$errMsg = sprintf('there is no option %s', static::WORKFLOW_MANAGER_NAME); |
185
|
|
|
throw new Exception\InvalidWorkflowEntryToObjectMetadataException($errMsg); |
186
|
|
|
} |
187
|
|
|
$workflowManagerName = $metadataItem[static::WORKFLOW_MANAGER_NAME]; |
188
|
|
|
|
189
|
|
View Code Duplication |
if (!array_key_exists(static::WORKFLOW_NAME, $metadataItem)) { |
|
|
|
|
190
|
|
|
$errMsg = sprintf('there is no option %s', static::WORKFLOW_NAME); |
191
|
|
|
throw new Exception\InvalidWorkflowEntryToObjectMetadataException($errMsg); |
192
|
|
|
} |
193
|
|
|
$workflowName = $metadataItem[static::WORKFLOW_NAME]; |
194
|
|
|
|
195
|
|
View Code Duplication |
if (!array_key_exists(static::MAP, $metadataItem)) { |
|
|
|
|
196
|
|
|
$errMsg = sprintf('there is no option %s', static::MAP); |
197
|
|
|
throw new Exception\InvalidWorkflowEntryToObjectMetadataException($errMsg); |
198
|
|
|
} |
199
|
|
View Code Duplication |
if (!is_array($metadataItem[static::MAP])) { |
|
|
|
|
200
|
|
|
$errMsg = sprintf('option %s is not array', static::MAP); |
201
|
|
|
throw new Exception\InvalidWorkflowEntryToObjectMetadataException($errMsg); |
202
|
|
|
} |
203
|
|
|
$map = $metadataItem[static::MAP]; |
204
|
|
|
|
205
|
|
|
if (!array_key_exists($workflowManagerName, $index)) { |
206
|
|
|
$index[$workflowManagerName] = []; |
207
|
|
|
} |
208
|
|
|
if (!array_key_exists($workflowName, $index[$workflowManagerName])) { |
209
|
|
|
$index[$workflowManagerName][$workflowName] = []; |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
foreach ($map as $mapItem) { |
213
|
|
View Code Duplication |
if (!array_key_exists(static::ENTITY_CLASS_NAME, $mapItem)) { |
|
|
|
|
214
|
|
|
$errMsg = sprintf('there is no option %s', static::ENTITY_CLASS_NAME); |
215
|
|
|
throw new Exception\InvalidWorkflowEntryToObjectMetadataException($errMsg); |
216
|
|
|
} |
217
|
|
|
$entityClassName = $mapItem[static::ENTITY_CLASS_NAME]; |
218
|
|
|
|
219
|
|
|
if (array_key_exists($entityClassName, $index[$workflowManagerName][$workflowName])) { |
220
|
|
|
$errMsg = sprintf('Metadata for entities already exist %s', $mapItem[static::ENTITY_CLASS_NAME]); |
221
|
|
|
throw new Exception\InvalidWorkflowEntryToObjectMetadataException($errMsg); |
222
|
|
|
} |
223
|
|
|
|
224
|
|
View Code Duplication |
if (!array_key_exists(static::ROUTER_PARAM_NAME, $mapItem)) { |
|
|
|
|
225
|
|
|
$errMsg = sprintf('there is no option %s', static::ROUTER_PARAM_NAME); |
226
|
|
|
throw new Exception\InvalidWorkflowEntryToObjectMetadataException($errMsg); |
227
|
|
|
} |
228
|
|
|
$routerParamName = $mapItem[static::ROUTER_PARAM_NAME]; |
229
|
|
|
|
230
|
|
|
$index[$workflowManagerName][$workflowName][$entityClassName] = $routerParamName; |
231
|
|
|
} |
232
|
|
|
} |
233
|
|
|
$this->indexMetadata = $index; |
234
|
|
|
|
235
|
|
|
return $this->indexMetadata; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
/** |
239
|
|
|
* @param array|null $indexMetadata |
240
|
|
|
* |
241
|
|
|
* @return $this |
242
|
|
|
*/ |
243
|
|
|
public function setIndexMetadata(array $indexMetadata = null) |
244
|
|
|
{ |
245
|
|
|
$this->indexMetadata = $indexMetadata; |
246
|
|
|
|
247
|
|
|
return $this; |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
|
251
|
|
|
/** |
252
|
|
|
* Сервис реализующий функционал, для привязки процессов wf и информации о объектаъ |
253
|
|
|
* |
254
|
|
|
* @return EntryToObjectsService |
255
|
|
|
*/ |
256
|
|
|
public function getEntryToObjectsService() |
257
|
|
|
{ |
258
|
|
|
return $this->entryToObjectsService; |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* Устанавливает сервис реализующий функционал, для привязки процессов wf и информации о объектаъ |
263
|
|
|
* |
264
|
|
|
* @param EntryToObjectsService $entryToObjectsService |
265
|
|
|
* |
266
|
|
|
* @return $this |
267
|
|
|
*/ |
268
|
|
|
public function setEntryToObjectsService(EntryToObjectsService $entryToObjectsService) |
269
|
|
|
{ |
270
|
|
|
$this->entryToObjectsService = $entryToObjectsService; |
271
|
|
|
|
272
|
|
|
return $this; |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* Настройки модуля |
277
|
|
|
* |
278
|
|
|
* @return ModuleOptions |
279
|
|
|
*/ |
280
|
|
|
public function getModuleOptions() |
281
|
|
|
{ |
282
|
|
|
return $this->moduleOptions; |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
/** |
286
|
|
|
* Устанавливает настройки модуля |
287
|
|
|
* |
288
|
|
|
* @param ModuleOptions $moduleOptions |
289
|
|
|
* |
290
|
|
|
* @return $this |
291
|
|
|
*/ |
292
|
|
|
public function setModuleOptions(ModuleOptions $moduleOptions) |
293
|
|
|
{ |
294
|
|
|
$this->moduleOptions = $moduleOptions; |
295
|
|
|
|
296
|
|
|
return $this; |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* @return MvcEvent |
301
|
|
|
*/ |
302
|
|
|
public function getMvcEvent() |
303
|
|
|
{ |
304
|
|
|
return $this->mvcEvent; |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
/** |
308
|
|
|
* @param MvcEvent $mvcEvent |
309
|
|
|
* |
310
|
|
|
* @return $this |
311
|
|
|
*/ |
312
|
|
|
public function setMvcEvent(MvcEvent $mvcEvent) |
313
|
|
|
{ |
314
|
|
|
$this->mvcEvent = $mvcEvent; |
315
|
|
|
|
316
|
|
|
return $this; |
317
|
|
|
} |
318
|
|
|
} |
319
|
|
|
|
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.