GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

RouteHandler::onMetadataWorkflowToRun()   D
last analyzed

Complexity

Conditions 15
Paths 16

Size

Total Lines 111
Code Lines 69

Duplication

Lines 4
Ratio 3.6 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 4
loc 111
rs 4.9121
cc 15
eloc 69
nc 16
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
Duplication introduced by
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.

Loading history...
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
Duplication introduced by
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.

Loading history...
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