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.
Completed
Push — master ( 138d30...5011e7 )
by Андрей
07:49
created

StepDescriptor::validate()   C

Complexity

Conditions 9
Paths 9

Size

Total Lines 48
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 48
rs 5.5102
cc 9
eloc 34
nc 9
nop 0
1
<?php
2
/**
3
 * @link    https://github.com/old-town/old-town-workflow
4
 * @author  Malofeykin Andrey  <[email protected]>
5
 */
6
namespace OldTown\Workflow\Loader;
7
8
use DOMElement;
9
use OldTown\Workflow\Exception\ArgumentNotNumericException;
10
use OldTown\Workflow\Exception\InvalidDescriptorException;
11
use OldTown\Workflow\Exception\InvalidParsingWorkflowException;
12
use OldTown\Workflow\Exception\InvalidWorkflowDescriptorException;
13
use OldTown\Workflow\Exception\InvalidWriteWorkflowException;
14
use SplObjectStorage;
15
use DOMDocument;
16
17
/**
18
 * Class ConditionDescriptor
19
 *
20
 * @package OldTown\Workflow\Loader
21
 */
22
class StepDescriptor extends AbstractDescriptor
23
    implements
24
        Traits\NameInterface,
25
        ValidateDescriptorInterface,
26
        WriteXmlInterface
27
{
28
    use Traits\NameTrait, Traits\IdTrait;
29
30
    /**
31
     * @var ActionDescriptor[]|SplObjectStorage
32
     */
33
    protected $actions;
34
35
    /**
36
     * Список id дейсвтия являющихся общими для всего workflow
37
     *
38
     * @var array
39
     */
40
    protected $commonActions = [];
41
42
    /**
43
     * @var FunctionDescriptor[]|SplObjectStorage
44
     */
45
    protected $postFunctions;
46
47
    /**
48
     * @var FunctionDescriptor[]|SplObjectStorage
49
     */
50
    protected $preFunctions;
51
52
    /**
53
     * @var PermissionDescriptor[]|SplObjectStorage
54
     */
55
    protected $permissions;
56
57
    /**
58
     * @var array
59
     */
60
    protected $metaAttributes = [];
61
62
    /**
63
     * Определяет есть ли действия для данного шага workflow
64
     *
65
     * @var bool
66
     */
67
    protected $hasActions = false;
68
69
70
    /**
71
     * @param DOMElement $element
72
     * @param AbstractDescriptor $parent
73
     *
74
     * @throws InvalidParsingWorkflowException
75
     */
76
    public function __construct(DOMElement $element = null, AbstractDescriptor $parent = null)
77
    {
78
        $this->preFunctions = new SplObjectStorage();
79
        $this->postFunctions = new SplObjectStorage();
80
        $this->actions = new SplObjectStorage();
81
        $this->permissions = new SplObjectStorage();
82
83
        parent::__construct($element);
84
85
        if (null !== $parent) {
86
            $this->setParent($parent);
87
        }
88
        if (null !== $element) {
89
            $this->init($element);
90
        }
91
    }
92
93
    /**
94
     * @param DOMElement $step
95
     *
96
     * @return void
97
     * @throws InvalidParsingWorkflowException
98
     */
99
    protected function init(DOMElement $step)
100
    {
101
        $this->parseId($step);
102
        $this->parseName($step);
103
104
105
        $metaElements = XmlUtil::getChildElements($step, 'meta');
106
        $metaAttributes = [];
107 View Code Duplication
        foreach ($metaElements as $meta) {
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...
108
            $value = XmlUtil::getText($meta);
109
            $name = XmlUtil::getRequiredAttributeValue($meta, 'name');
110
111
            $metaAttributes[$name] = $value;
112
        }
113
        $this->setMetaAttributes($metaAttributes);
114
115
        // set up pre-functions -- OPTIONAL
116
        $pre = XMLUtil::getChildElement($step, 'pre-functions');
117 View Code Duplication
        if (null !== $pre) {
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...
118
            $preFunctions = XMLUtil::getChildElements($pre, 'function');
119
            foreach ($preFunctions as $preFunction) {
120
                $functionDescriptor = DescriptorFactory::getFactory()->createFunctionDescriptor($preFunction);
121
                $functionDescriptor->setParent($this);
122
                $this->preFunctions->attach($functionDescriptor);
123
            }
124
        }
125
126
        // set up permissions - OPTIONAL
127
        $p = XMLUtil::getChildElement($step, 'external-permissions');
128 View Code Duplication
        if (null !== $p) {
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...
129
            $permissions = XMLUtil::getChildElements($p, 'permission');
130
            foreach ($permissions as $permission) {
131
                $permissionDescriptor = DescriptorFactory::getFactory()->createPermissionDescriptor($permission);
132
                $permissionDescriptor->setParent($this);
133
                $this->permissions->attach($permissionDescriptor);
134
            }
135
        }
136
137
        // set up actions - OPTIONAL
138
        $a = XMLUtil::getChildElement($step, 'actions');
139
        if (null !== $a) {
140
            $this->hasActions = true;
141
142
            $actions = XMLUtil::getChildElements($a, 'action');
143
            foreach ($actions as $action) {
144
                $actionDescriptor = DescriptorFactory::getFactory()->createActionDescriptor($action);
145
                $actionDescriptor->setParent($this);
146
                $this->actions->attach($actionDescriptor);
147
            }
148
149
            $commonActions = XMLUtil::getChildElements($a, 'common-action');
150
            /** @var WorkflowDescriptor $workflowDescriptor */
151
            $workflowDescriptor = $this->getParent();
152
            if (!$workflowDescriptor instanceof WorkflowDescriptor) {
153
                $errMsg = 'Отсутствует Workflow Descriptor';
154
                throw new InvalidParsingWorkflowException($errMsg);
155
            }
156
            foreach ($commonActions as $commonAction) {
157
                $actionId = XmlUtil::getRequiredAttributeValue($commonAction, 'id');
158
                $commonActionReference = $workflowDescriptor->getCommonAction($actionId);
159
160
                if ($commonActionReference !== null) {
161
                    $this->actions->attach($commonActionReference);
162
                }
163
                $this->commonActions[$actionId] = $actionId;
164
            }
165
        }
166
167
        // set up post-functions - OPTIONAL
168
169
        // set up post-functions - OPTIONAL
170
        $post = XMLUtil::getChildElement($step, 'post-functions');
171 View Code Duplication
        if (null !== $post) {
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...
172
            $postFunctions = XMLUtil::getChildElements($post, 'function');
173
            foreach ($postFunctions as $postFunction) {
174
                $functionDescriptor = DescriptorFactory::getFactory()->createFunctionDescriptor($postFunction);
175
                $functionDescriptor->setParent($this);
176
                $this->postFunctions->attach($functionDescriptor);
177
            }
178
        }
179
    }
180
181
    /**
182
     * Возвращает список id дейсвтий являющихся общим для всего workflow
183
     *
184
     * @return array
185
     */
186
    public function getCommonActions()
187
    {
188
        return $this->commonActions;
189
    }
190
191
192
    /**
193
     * @return FunctionDescriptor[]|SplObjectStorage
194
     */
195
    public function getPostFunctions()
196
    {
197
        return $this->postFunctions;
198
    }
199
200
    /**
201
     * @return FunctionDescriptor[]|SplObjectStorage
202
     */
203
    public function getPreFunctions()
204
    {
205
        return $this->preFunctions;
206
    }
207
208
    /**
209
     * @return array
210
     */
211
    public function getMetaAttributes()
212
    {
213
        return $this->metaAttributes;
214
    }
215
216
    /**
217
     * @param array $metaAttributes
218
     *
219
     * @return $this
220
     */
221
    public function setMetaAttributes(array $metaAttributes = [])
222
    {
223
        $this->metaAttributes = $metaAttributes;
224
225
        return $this;
226
    }
227
228
    /**
229
     * @return PermissionDescriptor[]|SplObjectStorage
230
     */
231
    public function getPermissions()
232
    {
233
        return $this->permissions;
234
    }
235
236
    /**
237
     * @return ActionDescriptor[]|SplObjectStorage
238
     */
239
    public function getActions()
240
    {
241
        return $this->actions;
242
    }
243
244
    /**
245
     * @param integer $id
246
     *
247
     * @return ActionDescriptor|null
248
     */
249
    public function getAction($id)
250
    {
251
        $id = (integer)$id;
252
        foreach ($this->actions as $action) {
253
            if ($id === $action->getId()) {
254
                return $action;
255
            }
256
        }
257
        return null;
258
    }
259
260
    /**
261
     * Удаляет действия для данного шага
262
     *
263
     * @return $this
264
     */
265
    public function removeActions()
266
    {
267
        $this->commonActions = [];
268
        $this->actions = new SplObjectStorage();
269
        $this->hasActions = false;
270
        return $this;
271
    }
272
273
    /**
274
     * @param integer $join
275
     * @return boolean
276
     *
277
     * @throws ArgumentNotNumericException
278
     */
279
    public function resultsInJoin($join)
280
    {
281
        if (!is_numeric($join)) {
282
            $errMsg = 'Аргумент должен быть числом';
283
            throw new ArgumentNotNumericException($errMsg);
284
        }
285
286
        $join = (integer)$join;
287
288
        $actions = $this->getActions();
289
290
        foreach ($actions as $actionDescriptor) {
291
            if ($join === $actionDescriptor->getUnconditionalResult()->getJoin()) {
292
                return true;
293
            }
294
295
            $results = $actionDescriptor->getConditionalResults();
296
            foreach ($results as $resultDescriptor) {
297
                if ($join === $resultDescriptor->getJoin()) {
298
                    return true;
299
                }
300
            }
301
        }
302
303
        return false;
304
    }
305
306
    /**
307
     * Возвращает флаг определяющий есть ли действия у данного шага
308
     *
309
     * @return boolean
310
     */
311
    public function getFlagHasActions()
312
    {
313
        return $this->hasActions;
314
    }
315
316
317
    /**
318
     * Валидация дескриптора
319
     *
320
     * @return void
321
     * @throws InvalidWorkflowDescriptorException
322
     */
323
    public function validate()
324
    {
325
        $commonActions = $this->getCommonActions();
326
        $actions = $this->getActions();
327
        $hasActions = $this->hasActions;
328
329
        if ($hasActions && 0 === count($commonActions) && 0 === $actions->count()) {
330
            $stepName = (string)$this->getName();
331
            $errMsg = sprintf('Шаг %s должен содержать одни действие или одно общее действие', $stepName);
332
            throw new InvalidWorkflowDescriptorException($errMsg);
333
        }
334
335
        if (-1 === $this->getId()) {
336
            $errMsg = 'В качестве id шага нельзя использовать -1, так как это зарезериврованное значение';
337
            throw new InvalidWorkflowDescriptorException($errMsg);
338
        }
339
340
        $preFunctions = $this->getPreFunctions();
341
        $postFunctions = $this->getPostFunctions();
342
        $actions = $this->getActions();
343
        $permissions = $this->getPermissions();
344
345
        ValidationHelper::validate($preFunctions);
346
        ValidationHelper::validate($postFunctions);
347
        ValidationHelper::validate($actions);
348
        ValidationHelper::validate($permissions);
349
350
        $workflowDescriptor = $this->getParent();
351
        if (!$workflowDescriptor instanceof WorkflowDescriptor) {
352
            $errMsg = sprintf('Родительский элемент для шага должен реализовывать %s', WorkflowDescriptor::class);
353
            throw new InvalidWorkflowDescriptorException($errMsg);
354
        }
355
        foreach ($commonActions as $actionId) {
356
            try {
357
                $commonActionReference = $workflowDescriptor->getCommonAction($actionId);
358
359
                if (null === $commonActionReference) {
360
                    $stepName = (string)$this->getName();
361
                    $errMsg = sprintf('Common-action %s указанное для шага %s не существует', $actionId, $stepName);
362
                    throw new InvalidWorkflowDescriptorException($errMsg);
363
                }
364
            } catch (\Exception $e) {
365
                $actionIdStr = (string)$actionId;
366
                $errMsg = sprintf('Некорректный id для common-action: id %s', $actionIdStr);
367
                throw  new InvalidWorkflowDescriptorException($errMsg, $e->getCode(), $e);
368
            }
369
        }
370
    }
371
372
373
    /**
374
     * Создает DOMElement - эквивалентный состоянию дескриптора
375
     *
376
     * @param DOMDocument $dom
377
     *
378
     * @return DOMElement|null
379
     * @throws InvalidDescriptorException
380
     * @throws InvalidWriteWorkflowException
381
     */
382
    public function writeXml(DOMDocument $dom = null)
383
    {
384
        if (null === $dom) {
385
            $errMsg = 'Не передан DOMDocument';
386
            throw new InvalidWriteWorkflowException($errMsg);
387
        }
388
        $descriptor = $dom->createElement('step');
389
390
        if (!$this->hasId()) {
391
            $errMsg = 'Отсутствует атрибут id';
392
            throw new InvalidDescriptorException($errMsg);
393
        }
394
        $id = $this->getId();
395
        $descriptor->setAttribute('id', $id);
396
397
        $name = (string)$this->getName();
398
        $name = trim($name);
399
        if (strlen($name) > 0) {
400
            $nameEncode = XmlUtil::encode($name);
401
            $descriptor->setAttribute('name', $nameEncode);
402
        }
403
404
405
        $metaAttributes = $this->getMetaAttributes();
406
        $baseMeta = $dom->createElement('meta');
407 View Code Duplication
        foreach ($metaAttributes as $metaAttributeName => $metaAttributeValue) {
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...
408
            $metaAttributeNameEncode = XmlUtil::encode($metaAttributeName);
409
            $metaAttributeValueEnEncode = XmlUtil::encode($metaAttributeValue);
410
411
            $metaElement = clone $baseMeta;
412
            $metaElement->setAttribute('name', $metaAttributeNameEncode);
413
            $metaValueElement = $dom->createTextNode($metaAttributeValueEnEncode);
414
            $metaElement->appendChild($metaValueElement);
415
416
            $descriptor->appendChild($metaElement);
417
        }
418
419
420
        $preFunctions = $this->getPreFunctions();
421 View Code Duplication
        if ($preFunctions->count() > 0) {
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...
422
            $preFunctionsElement = $dom->createElement('pre-functions');
423
            foreach ($preFunctions as $function) {
424
                $functionElement = $function->writeXml($dom);
425
                $preFunctionsElement->appendChild($functionElement);
426
            }
427
428
            $descriptor->appendChild($preFunctionsElement);
429
        }
430
431
432
        $permissions = $this->getPermissions();
433
        if ($permissions->count() > 0) {
434
            $permissionsElement = $dom->createElement('external-permissions');
435
            foreach ($permissions as $permission) {
436
                $permissionElement = $permission->writeXml($dom);
437
                $permissionsElement->appendChild($permissionElement);
438
            }
439
440
            $descriptor->appendChild($permissionsElement);
441
        }
442
443
        $actions = $this->getActions();
444
        $commonActions = $this->getCommonActions();
445
446
        if ($actions->count() > 0 || count($commonActions) > 0) {
447
            $actionsElement = $dom->createElement('actions');
448
449
            $commonActionElementBase = $dom->createElement('common-action');
450
            foreach ($commonActions as $commonActionId) {
451
                $commonActionElement = clone $commonActionElementBase;
452
                $commonActionElement->setAttribute('id', $commonActionId);
453
454
                $actionsElement->appendChild($commonActionElement);
455
            }
456
457
            foreach ($actions as $action) {
458
                if (!$action->isCommon()) {
459
                    $actionElement = $action->writeXml($dom);
460
                    $actionsElement->appendChild($actionElement);
461
                }
462
            }
463
464
            $descriptor->appendChild($actionsElement);
465
        }
466
467
        $postFunctions = $this->getPostFunctions();
468 View Code Duplication
        if ($postFunctions->count() > 0) {
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...
469
            $postFunctionsElement = $dom->createElement('post-functions');
470
            foreach ($postFunctions as $function) {
471
                $functionElement = $function->writeXml($dom);
472
                $postFunctionsElement->appendChild($functionElement);
473
            }
474
475
            $descriptor->appendChild($postFunctionsElement);
476
        }
477
478
479
        return $descriptor;
480
    }
481
}
482