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.

ActionDescriptor   C
last analyzed

Complexity

Total Complexity 59

Size/Duplication

Total Lines 515
Duplicated Lines 13.01 %

Coupling/Cohesion

Components 1
Dependencies 14

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 59
c 1
b 0
f 0
lcom 1
cbo 14
dl 67
loc 515
ccs 241
cts 241
cp 1
rs 5.849

22 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 2
F init() 30 99 16
A getAutoExecute() 0 4 1
A setAutoExecute() 0 6 1
A isCommon() 0 4 1
A setCommon() 0 6 1
A getView() 0 4 1
A setView() 0 6 1
A getValidators() 0 4 1
A getUnconditionalResult() 0 4 1
A setUnconditionalResult() 0 6 1
A getRestriction() 0 4 1
A setRestriction() 0 6 1
A getPostFunctions() 0 4 1
A getPreFunctions() 0 4 1
A getMetaAttributes() 0 4 1
A setMetaAttributes() 0 6 1
A isFinish() 0 4 1
A setFinish() 0 6 1
A getConditionalResults() 0 4 1
B validate() 0 28 5
F writeXml() 37 110 18

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ActionDescriptor often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ActionDescriptor, and based on these observations, apply Extract Interface, too.

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\InvalidDescriptorException;
10
use OldTown\Workflow\Exception\InvalidWorkflowDescriptorException;
11
use OldTown\Workflow\Exception\InvalidWriteWorkflowException;
12
use SplObjectStorage;
13
use DOMDocument;
14
15
/**
16
 * Class ConditionDescriptor
17
 *
18
 * @package OldTown\Workflow\Loader
19
 */
20
class ActionDescriptor extends AbstractDescriptor
21
    implements
22
        Traits\NameInterface,
23
        ValidateDescriptorInterface,
24
        WriteXmlInterface
25
{
26
    use Traits\NameTrait, Traits\IdTrait;
27
28
    /**
29
     * @var ConditionalResultDescriptor[]|SplObjectStorage
30
     */
31
    protected $conditionalResults;
32
33
    /**
34
     * @var FunctionDescriptor[]|SplObjectStorage
35
     */
36
    protected $postFunctions;
37
38
    /**
39
     * @var FunctionDescriptor[]|SplObjectStorage
40
     */
41
    protected $preFunctions;
42
43
    /**
44
     * @var ValidatorDescriptor[]|SplObjectStorage
45
     */
46
    protected $validators;
47
48
    /**
49
     * @var array
50
     */
51
    protected $metaAttributes = [];
52
53
    /**
54
     * @var RestrictionDescriptor
55
     */
56
    protected $restriction;
57
58
    /**
59
     * @var ResultDescriptor
60
     */
61
    protected $unconditionalResult;
62
63
    /**
64
     * @var string
65
     */
66
    protected $view;
67
68
    /**
69
     * @var bool
70
     */
71
    protected $autoExecute = false;
72
73
    /**
74
     * @var bool
75
     */
76
    protected $common = false;
77
78
    /**
79
     * @var bool
80
     */
81
    protected $finish = false;
82
83
    /**
84
     * @param $element
85
     * @throws InvalidWorkflowDescriptorException
86
     */
87 78
    public function __construct(DOMElement $element = null)
88
    {
89 78
        $this->validators = new SplObjectStorage();
90 78
        $this->preFunctions = new SplObjectStorage();
91 78
        $this->conditionalResults = new SplObjectStorage();
92 78
        $this->postFunctions = new SplObjectStorage();
93
94 78
        parent::__construct($element);
95
96 78
        if (null !== $element) {
97 75
            $this->init($element);
98 74
        }
99 77
    }
100
101
    /**
102
     * @param DOMElement $action
103
     *
104
     * @return void
105
     * @throws InvalidWorkflowDescriptorException
106
     */
107 75
    protected function init(DOMElement $action)
108
    {
109 75
        $this->parseId($action);
110 75
        $this->parseName($action);
111
112 75
        if ($action->hasAttribute('view')) {
113 2
            $view = XmlUtil::getRequiredAttributeValue($action, 'view');
114 2
            $this->setView($view);
115 2
        }
116
117 75
        if ($action->hasAttribute('auto')) {
118 2
            $autoValue = XmlUtil::getRequiredAttributeValue($action, 'auto');
119 2
            $auto = strtolower($autoValue);
120 2
            $autoExecute = 'true' === $auto;
121 2
            $this->setAutoExecute($autoExecute);
122 2
        }
123
124 75
        if ($action->hasAttribute('finish')) {
125 2
            $finishValue = XmlUtil::getRequiredAttributeValue($action, 'finish');
126 2
            $finish = strtolower($finishValue);
127 2
            $finish = 'true' === $finish;
128 2
            $this->setFinish($finish);
129 2
        }
130
131 75
        $metaElements = XmlUtil::getChildElements($action, 'meta');
132 75
        $metaAttributes = [];
133 75 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...
134 1
            $value = XmlUtil::getText($meta);
135 1
            $name = XmlUtil::getRequiredAttributeValue($meta, 'name');
136
137 1
            $metaAttributes[$name] = $value;
138 75
        }
139 75
        $this->setMetaAttributes($metaAttributes);
140
141
        // set up validators -- OPTIONAL
142 75
        $v = XMLUtil::getChildElement($action, 'validators');
143 75 View Code Duplication
        if (null !== $v) {
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...
144 4
            $validators = XMLUtil::getChildElements($v, 'validator');
145 4
            foreach ($validators as $validator) {
146 4
                $validatorDescriptor = DescriptorFactory::getFactory()->createValidatorDescriptor($validator);
147 4
                $validatorDescriptor->setParent($this);
148 4
                $this->validators->attach($validatorDescriptor);
149 4
            }
150 4
        }
151
152
        // set up pre-functions -- OPTIONAL
153 75
        $pre = XMLUtil::getChildElement($action, 'pre-functions');
154 75 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...
155 13
            $preFunctions = XMLUtil::getChildElements($pre, 'function');
156 13
            foreach ($preFunctions as $preFunction) {
157 13
                $functionDescriptor = DescriptorFactory::getFactory()->createFunctionDescriptor($preFunction);
158 13
                $functionDescriptor->setParent($this);
159 13
                $this->preFunctions->attach($functionDescriptor);
160 13
            }
161 13
        }
162
163
        // set up results - REQUIRED
164 75
        $resultsElement = XMLUtil::getChildElement($action, 'results');
165 75
        if (!$resultsElement instanceof DOMElement) {
166 1
            $errMsg = 'Отсутствует обязательный блок results';
167 1
            throw new InvalidWorkflowDescriptorException($errMsg);
168
        }
169 74
        $results = XMLUtil::getChildElements($resultsElement, 'result');
170 74
        foreach ($results as $result) {
171 31
            $conditionalResultDescriptor = new ConditionalResultDescriptor($result);
172 31
            $conditionalResultDescriptor->setParent($this);
173 31
            $this->conditionalResults->attach($conditionalResultDescriptor);
174 74
        }
175
176 74
        $unconditionalResult = XMLUtil::getChildElement($resultsElement, 'unconditional-result');
177 74
        if (null !== $unconditionalResult) {
178 65
            $unconditionalResult = DescriptorFactory::getFactory()->createResultDescriptor($unconditionalResult);
179 65
            $unconditionalResult->setParent($this);
180 65
            $this->setUnconditionalResult($unconditionalResult);
181 65
        }
182
183
184
        // set up post-functions - OPTIONAL
185 74
        $post = XMLUtil::getChildElement($action, 'post-functions');
186 74 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...
187 12
            $postFunctions = XMLUtil::getChildElements($post, 'function');
188 12
            foreach ($postFunctions as $postFunction) {
189 12
                $functionDescriptor = DescriptorFactory::getFactory()->createFunctionDescriptor($postFunction);
190 12
                $functionDescriptor->setParent($this);
191 12
                $this->postFunctions->attach($functionDescriptor);
192 12
            }
193 12
        }
194
195
        // set up restrict-to - OPTIONAL
196 74
        $restrictElement = XMLUtil::getChildElement($action, 'restrict-to');
197 74
        if (null !== $restrictElement) {
198 20
            $restriction = new RestrictionDescriptor($restrictElement);
199
200 20
            if (null !== $restriction->getConditionsDescriptor()) {
201 20
                $restriction->setParent($this);
202 20
                $this->setRestriction($restriction);
203 20
            }
204 20
        }
205 74
    }
206
207
    /**
208
     * @return boolean
209
     */
210 15
    public function getAutoExecute()
211
    {
212 15
        return $this->autoExecute;
213
    }
214
215
    /**
216
     * @param boolean $autoExecute
217
     *
218
     * @return $this
219
     */
220 2
    public function setAutoExecute($autoExecute)
221
    {
222 2
        $this->autoExecute = (boolean)$autoExecute;
223
224 2
        return $this;
225
    }
226
227
    /**
228
     * @return boolean
229
     */
230 17
    public function isCommon()
231
    {
232 17
        return $this->common;
233
    }
234
235
    /**
236
     * @param boolean $common
237
     *
238
     * @return $this
239
     */
240 11
    public function setCommon($common)
241
    {
242 11
        $this->common = (boolean)$common;
243
244 11
        return $this;
245
    }
246
247
    /**
248
     * @return string
249
     */
250 15
    public function getView()
251
    {
252 15
        return $this->view;
253
    }
254
255
    /**
256
     * @param string $view
257
     *
258
     * @return $this
259
     */
260 2
    public function setView($view)
261
    {
262 2
        $this->view = (string)$view;
263
264 2
        return $this;
265
    }
266
267
    /**
268
     * @return ValidatorDescriptor[]|SplObjectStorage
269
     */
270 40
    public function getValidators()
271
    {
272 40
        return $this->validators;
273
    }
274
275
    /**
276
     * @return ResultDescriptor
277
     */
278 40
    public function getUnconditionalResult()
279
    {
280 40
        return $this->unconditionalResult;
281
    }
282
283
    /**
284
     * @param ResultDescriptor $unconditionalResult
285
     *
286
     * @return $this
287
     */
288 65
    public function setUnconditionalResult(ResultDescriptor $unconditionalResult)
289
    {
290 65
        $this->unconditionalResult = $unconditionalResult;
291
292 65
        return $this;
293
    }
294
295
    /**
296
     * @return RestrictionDescriptor
297
     */
298 40
    public function getRestriction()
299
    {
300 40
        return $this->restriction;
301
    }
302
303
    /**
304
     * @param RestrictionDescriptor $restriction
305
     *
306
     * @return $this
307
     */
308 20
    public function setRestriction(RestrictionDescriptor $restriction)
309
    {
310 20
        $this->restriction = $restriction;
311
312 20
        return $this;
313
    }
314
315
    /**
316
     * @return FunctionDescriptor[]|SplObjectStorage
317
     */
318 22
    public function getPostFunctions()
319
    {
320 22
        return $this->postFunctions;
321
    }
322
323
    /**
324
     * @return FunctionDescriptor[]|SplObjectStorage
325
     */
326 39
    public function getPreFunctions()
327
    {
328 39
        return $this->preFunctions;
329
    }
330
331
    /**
332
     * @return array
333
     */
334 15
    public function getMetaAttributes()
335
    {
336 15
        return $this->metaAttributes;
337
    }
338
339
    /**
340
     * @param array $metaAttributes
341
     *
342
     * @return $this
343
     */
344 75
    public function setMetaAttributes(array $metaAttributes = [])
345
    {
346 75
        $this->metaAttributes = $metaAttributes;
347
348 75
        return $this;
349
    }
350
351
    /**
352
     * @return boolean
353
     */
354 39
    public function isFinish()
355
    {
356 39
        return $this->finish;
357
    }
358
359
    /**
360
     * @param boolean $finish
361
     *
362
     * @return $this
363
     */
364 2
    public function setFinish($finish)
365
    {
366 2
        $this->finish = (boolean)$finish;
367
368 2
        return $this;
369
    }
370
371
    /**
372
     * @return SplObjectStorage|ConditionalResultDescriptor[]
373
     */
374 49
    public function getConditionalResults()
375
    {
376 49
        return $this->conditionalResults;
377
    }
378
379
380
    /**
381
     * Валидация дескриптора
382
     *
383
     * @return void
384
     * @throws InvalidWorkflowDescriptorException
385
     */
386 19
    public function validate()
387
    {
388 19
        $preFunctions = $this->getPreFunctions();
389 19
        $postFunctions = $this->getPostFunctions();
390 19
        $validators = $this->getValidators();
391 19
        $conditionalResults = $this->getConditionalResults();
392
393 19
        ValidationHelper::validate($preFunctions);
394 19
        ValidationHelper::validate($postFunctions);
395 19
        ValidationHelper::validate($validators);
396 19
        ValidationHelper::validate($conditionalResults);
397
398 19
        $unconditionalResult = $this->getUnconditionalResult();
399 19
        if (null === $unconditionalResult && $conditionalResults->count() > 0) {
400 1
            $name = (string)$this->getName();
401 1
            $errMsg = sprintf('Действие %s имеет условные условия, но не имеет запасного безусловного', $name);
402 1
            throw new InvalidWorkflowDescriptorException($errMsg);
403
        }
404
405 18
        $restrictions = $this->getRestriction();
406 18
        if ($restrictions !== null) {
407 12
            $restrictions->validate();
408 12
        }
409
410 18
        if ($unconditionalResult !== null) {
411 18
            $unconditionalResult->validate();
412 18
        }
413 18
    }
414
415
    /**
416
     * Создает DOMElement - эквивалентный состоянию дескриптора
417
     *
418
     * @param DOMDocument $dom
419
     *
420
     * @return DOMElement
421
     * @throws InvalidDescriptorException
422
     * @throws InvalidWriteWorkflowException
423
     */
424 17
    public function writeXml(DOMDocument $dom = null)
425
    {
426 17
        if (null === $dom) {
427 1
            $errMsg = 'Не передан DOMDocument';
428 1
            throw new InvalidWriteWorkflowException($errMsg);
429
        }
430 16
        $descriptor = $dom->createElement('action');
431
432 16
        if (!$this->hasId()) {
433 1
            $errMsg = 'Отсутствует атрибут id';
434 1
            throw new InvalidDescriptorException($errMsg);
435
        }
436 15
        $id = $this->getId();
437 15
        $descriptor->setAttribute('id', $id);
438
439 15
        $name = (string)$this->getName();
440 15
        $name = trim($name);
441 15
        if (strlen($name) > 0) {
442 15
            $nameEncode = XmlUtil::encode($name);
443 15
            $descriptor->setAttribute('name', $nameEncode);
444 15
        }
445
446 15
        $view = (string)$this->getView();
447 15
        $view = trim($view);
448 15
        if (strlen($view) > 0) {
449 1
            $viewEncode = XmlUtil::encode($view);
450 1
            $descriptor->setAttribute('view', $viewEncode);
451 1
        }
452
453 15
        if ($this->isFinish()) {
454 1
            $descriptor->setAttribute('finish', 'true');
455 1
        }
456
457 15
        if ($this->getAutoExecute()) {
458 1
            $descriptor->setAttribute('auto', 'true');
459 1
        }
460
461 15
        $metaAttributes = $this->getMetaAttributes();
462 15
        $baseMeta = $dom->createElement('meta');
463 15 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...
464 1
            $metaAttributeNameEncode = XmlUtil::encode($metaAttributeName);
465 1
            $metaAttributeValueEnEncode = XmlUtil::encode($metaAttributeValue);
466
467 1
            $metaElement = clone $baseMeta;
468 1
            $metaElement->setAttribute('name', $metaAttributeNameEncode);
469 1
            $metaValueElement = $dom->createTextNode($metaAttributeValueEnEncode);
470 1
            $metaElement->appendChild($metaValueElement);
471
472 1
            $descriptor->appendChild($metaElement);
473 15
        }
474
475
476 15
        $restrictions = $this->getRestriction();
477 15
        if ($restrictions !== null) {
478 12
            $restrictionsElement = $restrictions->writeXml($dom);
479 12
            if (null !== $restrictionsElement) {
480 12
                $descriptor->appendChild($restrictionsElement);
481 12
            }
482 12
        }
483
484 15
        $validators = $this->getValidators();
485 15 View Code Duplication
        if ($validators->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...
486 1
            $validatorsElement = $dom->createElement('validators');
487 1
            foreach ($validators as $validator) {
488 1
                $validatorElement = $validator->writeXml($dom);
489 1
                $validatorsElement->appendChild($validatorElement);
490 1
            }
491 1
            $descriptor->appendChild($validatorsElement);
492 1
        }
493
494 15
        $preFunctions = $this->getPreFunctions();
495 15 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...
496 12
            $preFunctionsElement = $dom->createElement('pre-functions');
497 12
            foreach ($preFunctions as $function) {
498 12
                $functionElement = $function->writeXml($dom);
499 12
                $preFunctionsElement->appendChild($functionElement);
500 12
            }
501
502 12
            $descriptor->appendChild($preFunctionsElement);
503 12
        }
504
505 15
        $resultsElement = $dom->createElement('results');
506 15
        $descriptor->appendChild($resultsElement);
507
508 15
        $conditionalResults = $this->getConditionalResults();
509 15
        foreach ($conditionalResults as $conditionalResult) {
510 12
            $conditionalResultElement = $conditionalResult->writeXml($dom);
511 12
            $resultsElement->appendChild($conditionalResultElement);
512 15
        }
513
514 15
        $unconditionalResult = $this->getUnconditionalResult();
515 15
        if ($unconditionalResult !== null) {
516 15
            $unconditionalResultElement = $unconditionalResult->writeXml($dom);
517 15
            $resultsElement->appendChild($unconditionalResultElement);
518 15
        }
519
520 15
        $postFunctions = $this->getPostFunctions();
521 15 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...
522 12
            $postFunctionsElement = $dom->createElement('post-functions');
523 12
            foreach ($postFunctions as $function) {
524 12
                $functionElement = $function->writeXml($dom);
525 12
                $postFunctionsElement->appendChild($functionElement);
526 12
            }
527
528 12
            $descriptor->appendChild($postFunctionsElement);
529 12
        }
530
531
532 15
        return $descriptor;
533 1
    }
534
}
535