This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * @link https://github.com/old-town/workflow-zf2-dispatch |
||
4 | * @author Malofeykin Andrey <[email protected]> |
||
5 | */ |
||
6 | namespace OldTown\Workflow\ZF2\Dispatch\RunParamsHandler; |
||
7 | |||
8 | use OldTown\Workflow\ZF2\ServiceEngine\WorkflowServiceInterface; |
||
9 | use Zend\EventManager\AbstractListenerAggregate; |
||
10 | use Zend\EventManager\EventManagerAwareTrait; |
||
11 | use Zend\EventManager\EventManagerInterface; |
||
12 | use OldTown\Workflow\ZF2\Dispatch\Dispatcher\Dispatcher; |
||
13 | use OldTown\Workflow\ZF2\Dispatch\Dispatcher\WorkflowDispatchEventInterface; |
||
14 | use OldTown\Workflow\ZF2\Dispatch\Dispatcher\RunWorkflowParam; |
||
15 | use OldTown\Workflow\ZF2\Dispatch\Metadata\ReaderInterface; |
||
16 | use Zend\Mvc\Controller\AbstractController; |
||
17 | use OldTown\Workflow\ZF2\Dispatch\Metadata\Target\RunParams\MetadataInterface; |
||
18 | use OldTown\Workflow\ZF2\Dispatch\RunParamsHandler\RouteHandler\ResolveEntryIdEvent; |
||
19 | use OldTown\Workflow\ZF2\Dispatch\RunParamsHandler\RouteHandler\ResolveEntryIdEventInterface; |
||
20 | use ReflectionClass; |
||
21 | use Zend\Log\LoggerInterface; |
||
22 | |||
23 | /** |
||
24 | * Class RouteHandler |
||
25 | * |
||
26 | * @package OldTown\Workflow\ZF2\Dispatch\RunParamsHandler |
||
27 | */ |
||
28 | class RouteHandler extends AbstractListenerAggregate |
||
29 | { |
||
30 | use EventManagerAwareTrait; |
||
31 | |||
32 | /** |
||
33 | * Адаптер для чтения метаданных |
||
34 | * |
||
35 | * @var ReaderInterface |
||
36 | */ |
||
37 | protected $metadataReader; |
||
38 | |||
39 | /** |
||
40 | * Имя класса событие, бросаемого когда требуется определить entryId |
||
41 | * |
||
42 | * @var string |
||
43 | */ |
||
44 | protected $resolveEntryIdEventClassName = ResolveEntryIdEvent::class; |
||
45 | |||
46 | /** |
||
47 | * Сервис для работы с workflow |
||
48 | * |
||
49 | * @var WorkflowServiceInterface |
||
50 | */ |
||
51 | protected $workflowService; |
||
52 | |||
53 | /** |
||
54 | * Логер |
||
55 | * |
||
56 | * @var LoggerInterface |
||
57 | */ |
||
58 | protected $log; |
||
59 | |||
60 | /** |
||
61 | * RouteHandler constructor. |
||
62 | * |
||
63 | * @param array $options |
||
64 | */ |
||
65 | public function __construct(array $options = []) |
||
66 | { |
||
67 | $initOptions = [ |
||
68 | array_key_exists('metadataReader', $options) ? $options['metadataReader'] : null, |
||
69 | array_key_exists('workflowService', $options) ? $options['workflowService'] : null, |
||
70 | array_key_exists('log', $options) ? $options['log'] : null, |
||
71 | ]; |
||
72 | call_user_func_array([$this, 'init'], $initOptions); |
||
73 | } |
||
74 | |||
75 | /** |
||
76 | * @param ReaderInterface $metadataReader |
||
77 | * @param WorkflowServiceInterface $workflowService |
||
78 | * @param LoggerInterface $log |
||
79 | */ |
||
80 | protected function init(ReaderInterface $metadataReader, WorkflowServiceInterface $workflowService, LoggerInterface $log) |
||
81 | { |
||
82 | $this->setMetadataReader($metadataReader); |
||
83 | $this->setWorkflowService($workflowService); |
||
84 | $this->setLog($log); |
||
85 | } |
||
86 | |||
87 | /** |
||
88 | * @param EventManagerInterface $events |
||
89 | */ |
||
90 | public function attach(EventManagerInterface $events, $priority = 1) |
||
91 | { |
||
92 | $events->getSharedManager()->attach(Dispatcher::class, WorkflowDispatchEventInterface::METADATA_WORKFLOW_TO_RUN_EVENT, [$this, 'onMetadataWorkflowToRun'], 80); |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * Получение метаданных для запуска workflow |
||
97 | * |
||
98 | * @param WorkflowDispatchEventInterface $e |
||
99 | * |
||
100 | * @return RunWorkflowParam|null |
||
101 | * |
||
102 | * @throws Exception\InvalidMetadataException |
||
103 | * @throws Exception\ResolveEntryIdEventException |
||
104 | * @throws Exception\InvalidWorkflowManagerAliasException |
||
105 | * @throws Exception\RuntimeException |
||
106 | */ |
||
107 | public function onMetadataWorkflowToRun(WorkflowDispatchEventInterface $e) |
||
108 | { |
||
109 | $mvcEvent = $e->getMvcEvent(); |
||
110 | $controller = $mvcEvent->getTarget(); |
||
111 | if (!$controller instanceof AbstractController) { |
||
112 | return null; |
||
113 | } |
||
114 | |||
115 | $routeMatch = $mvcEvent->getRouteMatch(); |
||
116 | if (!$routeMatch) { |
||
117 | return null; |
||
118 | } |
||
119 | |||
120 | $action = $routeMatch->getParam('action', 'not-found'); |
||
121 | $actionMethod = AbstractController::getMethodFromAction($action); |
||
122 | |||
123 | if (!method_exists($controller, $actionMethod)) { |
||
124 | return null; |
||
125 | } |
||
126 | |||
127 | $controllerClassName = get_class($controller); |
||
128 | |||
129 | $metadata = $this->getMetadataReader()->loadMetadataForAction($controllerClassName, $actionMethod); |
||
130 | |||
131 | View Code Duplication | if (!$metadata instanceof MetadataInterface) { |
|
0 ignored issues
–
show
|
|||
132 | $errMsg = sprintf('Metadata not implement %s', MetadataInterface::class); |
||
133 | throw new Exception\InvalidMetadataException($errMsg); |
||
134 | } |
||
135 | |||
136 | $workflowManagerNameParam = $metadata->getWorkflowManagerNameRouterParam(); |
||
137 | $workflowManagerNameFromRoute = $routeMatch->getParam($workflowManagerNameParam, null); |
||
138 | |||
139 | $workflowManagerAliasParam = $metadata->getWorkflowManagerAliasRouterParam(); |
||
140 | $workflowManagerAlias = $routeMatch->getParam($workflowManagerAliasParam, null); |
||
141 | |||
142 | $workflowManagerName = $workflowManagerNameFromRoute; |
||
143 | if (null !== $workflowManagerAlias) { |
||
144 | $workflowService = $this->getWorkflowService(); |
||
145 | if (!$workflowService->hasWorkflowManagerAlias($workflowManagerAlias)) { |
||
146 | $errMsg = sprintf('Invalid workflow manager alias: %s', $workflowManagerAlias); |
||
147 | throw new Exception\InvalidWorkflowManagerAliasException($errMsg); |
||
148 | } |
||
149 | |||
150 | $workflowManagerNameByAlias = $workflowService->getManagerNameByAlias($workflowManagerAlias); |
||
151 | |||
152 | if (null !== $workflowManagerNameFromRoute && $workflowManagerNameFromRoute !== $workflowManagerNameByAlias) { |
||
153 | $errMsg = sprintf( |
||
154 | 'Name collision workflow manager.The name of the alias: %s. The name of the router: %s', |
||
155 | $workflowManagerNameByAlias, |
||
156 | $workflowManagerNameFromRoute |
||
157 | ); |
||
158 | throw new Exception\RuntimeException($errMsg); |
||
159 | } |
||
160 | $workflowManagerName = $workflowManagerNameByAlias; |
||
161 | } |
||
162 | |||
163 | $workflowActionNameParam = $metadata->getWorkflowActionNameRouterParam(); |
||
164 | $workflowActionName = $routeMatch->getParam($workflowActionNameParam, null); |
||
165 | |||
166 | if (null === $workflowManagerName || null === $workflowActionName) { |
||
167 | $this->getLog()->debug('Metadata Workflow to start not found', [ |
||
168 | 'workflowManagerNameFromRoute' => $workflowManagerNameFromRoute, |
||
169 | 'workflowManagerAlias' => $workflowManagerAlias, |
||
170 | 'workflowManagerName' => $workflowManagerName, |
||
171 | 'workflowActionName' => $workflowActionName |
||
172 | ]); |
||
173 | return null; |
||
174 | } |
||
175 | |||
176 | $runType = $e->getMetadata()->getWorkflowRunType(); |
||
177 | |||
178 | $workflowNameParam = $metadata->getWorkflowNameRouterParam(); |
||
179 | $workflowName = $routeMatch->getParam($workflowNameParam, null); |
||
180 | |||
181 | $runWorkflowParam = new RunWorkflowParam(); |
||
182 | $runWorkflowParam->setRunType($runType); |
||
183 | $runWorkflowParam->setManagerName($workflowManagerName); |
||
184 | $runWorkflowParam->setActionName($workflowActionName); |
||
185 | |||
186 | if (RunWorkflowParam::WORKFLOW_RUN_INITIALIZE === $runType && null !== $workflowName) { |
||
187 | $runWorkflowParam->setWorkflowName($workflowName); |
||
188 | |||
189 | return $runWorkflowParam; |
||
190 | } |
||
191 | |||
192 | |||
193 | if (RunWorkflowParam::WORKFLOW_RUN_TYPE_DO_ACTION === $runType) { |
||
194 | $event = $this->resolveEntryIdEventFactory(); |
||
195 | $event->setWorkflowDispatchEvent($e); |
||
196 | $event->setRunType($runType); |
||
197 | $event->setActionName($workflowActionName); |
||
198 | $event->setManagerName($workflowManagerName); |
||
199 | $event->setWorkflowName($workflowName); |
||
200 | $event->setManagerAlias($workflowManagerAlias); |
||
201 | |||
202 | |||
203 | $resolveEntryIdResults = $this->getEventManager()->trigger(ResolveEntryIdEventInterface::RESOLVE_ENTRY_ID_EVENT, $event, function ($item) { |
||
204 | return is_numeric($item); |
||
205 | }); |
||
206 | $resolveEntryIdResult = $resolveEntryIdResults->last(); |
||
207 | |||
208 | if (is_numeric($resolveEntryIdResult)) { |
||
209 | $runWorkflowParam->setEntryId($resolveEntryIdResult); |
||
210 | |||
211 | return $runWorkflowParam; |
||
212 | } |
||
213 | } |
||
214 | |||
215 | |||
216 | return null; |
||
217 | } |
||
218 | |||
219 | /** |
||
220 | * Подписчики по умолчанию |
||
221 | * |
||
222 | * @return void |
||
223 | */ |
||
224 | public function attachDefaultListeners() |
||
225 | { |
||
226 | $this->getEventManager()->attach(ResolveEntryIdEventInterface::RESOLVE_ENTRY_ID_EVENT, [$this, 'onResolveEntryIdHandler']); |
||
227 | } |
||
228 | |||
229 | /** |
||
230 | * Определение entryId на основе параметров роута |
||
231 | * |
||
232 | * @param ResolveEntryIdEventInterface $event |
||
233 | * |
||
234 | * @return integer|null |
||
235 | * |
||
236 | * @throws Exception\InvalidMetadataException |
||
237 | */ |
||
238 | public function onResolveEntryIdHandler(ResolveEntryIdEventInterface $event) |
||
239 | { |
||
240 | $this->getLog()->info('Getting the value "entryId" to run the Workflow based on the router settings'); |
||
241 | |||
242 | $mvcEvent = $event->getWorkflowDispatchEvent()->getMvcEvent(); |
||
243 | $controller = $mvcEvent->getTarget(); |
||
244 | if (!$controller instanceof AbstractController) { |
||
245 | $this->getLog()->notice( |
||
246 | 'Unable to get the value of "entryId" to start the workflow. No controller object in the property "target" MvcEvent.' |
||
247 | ); |
||
248 | return null; |
||
249 | } |
||
250 | |||
251 | $routeMatch = $mvcEvent->getRouteMatch(); |
||
252 | if (!$routeMatch) { |
||
253 | return null; |
||
254 | } |
||
255 | |||
256 | $action = $routeMatch->getParam('action', 'not-found'); |
||
257 | $actionMethod = AbstractController::getMethodFromAction($action); |
||
258 | |||
259 | if (!method_exists($controller, $actionMethod)) { |
||
260 | $this->getLog()->notice( |
||
261 | 'Unable to get the value of "entryId" to start the workflow. Do not set RouteMatch' |
||
262 | ); |
||
263 | return null; |
||
264 | } |
||
265 | |||
266 | $controllerClassName = get_class($controller); |
||
267 | $metadata = $this->getMetadataReader()->loadMetadataForAction($controllerClassName, $actionMethod); |
||
268 | |||
269 | View Code Duplication | if (!$metadata instanceof MetadataInterface) { |
|
0 ignored issues
–
show
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. ![]() |
|||
270 | $errMsg = sprintf('Metadata not implement %s', MetadataInterface::class); |
||
271 | throw new Exception\InvalidMetadataException($errMsg); |
||
272 | } |
||
273 | |||
274 | $entryIdParam = $metadata->getEntryIdRouterParam(); |
||
275 | $entryId = $routeMatch->getParam($entryIdParam, null); |
||
276 | |||
277 | $this->getLog()->info( |
||
278 | 'Meaning "entryId" to run the Workflow based on the router settings', |
||
279 | [ |
||
280 | 'entryId' => $entryId |
||
281 | ] |
||
282 | ); |
||
283 | |||
284 | return $entryId; |
||
285 | } |
||
286 | |||
287 | |||
288 | /** |
||
289 | * @return ReaderInterface |
||
290 | */ |
||
291 | public function getMetadataReader() |
||
292 | { |
||
293 | return $this->metadataReader; |
||
294 | } |
||
295 | |||
296 | /** |
||
297 | * @param ReaderInterface $metadataReader |
||
298 | * |
||
299 | * @return $this |
||
300 | */ |
||
301 | public function setMetadataReader(ReaderInterface $metadataReader) |
||
302 | { |
||
303 | $this->metadataReader = $metadataReader; |
||
304 | |||
305 | return $this; |
||
306 | } |
||
307 | |||
308 | /** |
||
309 | * Имя класса событие, бросаемого когда требуется определить entryId |
||
310 | * |
||
311 | * @return string |
||
312 | */ |
||
313 | public function getResolveEntryIdEventClassName() |
||
314 | { |
||
315 | return $this->resolveEntryIdEventClassName; |
||
316 | } |
||
317 | |||
318 | /** |
||
319 | * Устанавливает имя класса событие, бросаемого когда требуется определить entryId |
||
320 | * |
||
321 | * @param string $resolveEntryIdEventClassName |
||
322 | * |
||
323 | * @return $this |
||
324 | */ |
||
325 | public function setResolveEntryIdEventClassName($resolveEntryIdEventClassName) |
||
326 | { |
||
327 | $this->resolveEntryIdEventClassName = $resolveEntryIdEventClassName; |
||
328 | |||
329 | return $this; |
||
330 | } |
||
331 | |||
332 | /** |
||
333 | * Фабрика для создания объекта события бросаемого когда нужно определить значение entryId |
||
334 | * |
||
335 | * @return ResolveEntryIdEventInterface |
||
336 | * |
||
337 | * @throws Exception\ResolveEntryIdEventException |
||
338 | */ |
||
339 | public function resolveEntryIdEventFactory() |
||
340 | { |
||
341 | $className = $this->getResolveEntryIdEventClassName(); |
||
342 | |||
343 | $r = new ReflectionClass($className); |
||
344 | $event = $r->newInstance(); |
||
345 | |||
346 | if (!$event instanceof ResolveEntryIdEventInterface) { |
||
347 | $errMsg = sprintf('ResolveEntryIdEvent not implement %s', ResolveEntryIdEventInterface::class); |
||
348 | throw new Exception\ResolveEntryIdEventException($errMsg); |
||
349 | } |
||
350 | |||
351 | return $event; |
||
352 | } |
||
353 | |||
354 | /** |
||
355 | * Устанавливает логер |
||
356 | * |
||
357 | * @return LoggerInterface |
||
358 | */ |
||
359 | public function getLog() |
||
360 | { |
||
361 | return $this->log; |
||
362 | } |
||
363 | |||
364 | /** |
||
365 | * Возвращает логер |
||
366 | * |
||
367 | * @param LoggerInterface $log |
||
368 | * |
||
369 | * @return $this |
||
370 | */ |
||
371 | public function setLog(LoggerInterface $log) |
||
372 | { |
||
373 | $this->log = $log; |
||
374 | |||
375 | return $this; |
||
376 | } |
||
377 | |||
378 | /** |
||
379 | * Сервис для работы с workflow |
||
380 | * |
||
381 | * @return WorkflowServiceInterface |
||
382 | */ |
||
383 | public function getWorkflowService() |
||
384 | { |
||
385 | return $this->workflowService; |
||
386 | } |
||
387 | |||
388 | /** |
||
389 | * Устанавливает сервис для работы с workflow |
||
390 | * |
||
391 | * @param WorkflowServiceInterface $workflowService |
||
392 | * |
||
393 | * @return $this |
||
394 | */ |
||
395 | public function setWorkflowService(WorkflowServiceInterface $workflowService) |
||
396 | { |
||
397 | $this->workflowService = $workflowService; |
||
398 | |||
399 | return $this; |
||
400 | } |
||
401 | } |
||
402 |
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.