Passed
Push — master ( 531553...9683f3 )
by Edward
04:25
created

DeleteElementMutation::__invoke()   B

Complexity

Conditions 8
Paths 18

Size

Total Lines 56
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 8
eloc 36
c 1
b 1
f 0
nc 18
nop 2
dl 0
loc 56
ccs 0
cts 31
cp 0
crap 72
rs 8.0995

How to fix   Long Method   

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
declare(strict_types=1);
3
4
namespace Remorhaz\JSON\Pointer\Processor\Mutator;
5
6
use ArrayIterator;
7
use Iterator;
8
use Remorhaz\JSON\Data\Event\AfterElementEvent;
9
use Remorhaz\JSON\Data\Event\AfterElementEventInterface;
10
use Remorhaz\JSON\Data\Event\BeforeElementEvent;
11
use Remorhaz\JSON\Data\Event\BeforeElementEventInterface;
12
use Remorhaz\JSON\Data\Event\EventInterface;
13
use Remorhaz\JSON\Data\Export\EventDecoder;
14
use Remorhaz\JSON\Data\Path\PathInterface;
15
use Remorhaz\JSON\Data\Walker\MutationInterface;
16
use Remorhaz\JSON\Data\Walker\ValueWalkerInterface;
17
18
final class DeleteElementMutation implements MutationInterface
19
{
20
21
    private $arrayPath;
22
23
    private $elementPath;
24
25
    private $elementIndex;
26
27
    private $elementCounter;
28
29
    private $eventDecoder;
30
31
    public function __construct(PathInterface $arrayPath, PathInterface $elementPath)
32
    {
33
        $this->arrayPath = $arrayPath;
34
        $this->elementPath = $elementPath;
35
        $this->eventDecoder = new EventDecoder;
36
    }
37
38
    public function __invoke(EventInterface $event, ValueWalkerInterface $valueWalker): Iterator
39
    {
40
        if ($this->elementPath->equals($event->getPath())) {
41
            if ($event instanceof AfterElementEventInterface) {
42
                $this->elementCounter = $event->getIndex();
43
            }
44
        }
45
        if ($this->elementPath->contains($event->getPath())) {
46
            return;
47
        }
48
        if (!$this->parentPathMatches($event)) {
49
            yield $event;
50
51
            return;
52
        }
53
54
        if (!isset($this->elementCounter)) {
55
            yield $event;
56
57
            return;
58
        }
59
60
        switch (true) {
61
            case $event instanceof BeforeElementEventInterface:
62
                yield new BeforeElementEvent(
63
                    $this->elementCounter,
64
                    $this
65
                        ->arrayPath
66
                        ->copyWithElement($this->elementCounter)
67
                );
68
69
                return;
70
71
            case $event instanceof AfterElementEventInterface:
72
                yield new AfterElementEvent(
73
                    $this->elementCounter,
74
                    $this
75
                        ->arrayPath
76
                        ->copyWithElement($this->elementCounter)
77
                );
78
                $this->elementCounter++;
79
80
                return;
81
82
            default:
83
                yield from $valueWalker->createEventIterator(
84
                    $this
85
                        ->eventDecoder
86
                        ->exportExistingEvents(new ArrayIterator([$event])),
87
                    $this
88
                        ->arrayPath
89
                        ->copyWithElement($this->elementCounter)
90
                );
91
        }
92
93
        return;
94
    }
95
96
    public function reset(): void
97
    {
98
        unset($this->elementIndex, $this->elementCounter);
99
    }
100
101
    private function parentPathMatches(EventInterface $event): bool
102
    {
103
        $pathElements = $event->getPath()->getElements();
104
        if (empty($pathElements)) {
105
            return false;
106
        }
107
108
        return $event
109
            ->getPath()
110
            ->copyParent()
111
            ->equals($this->arrayPath);
112
    }
113
}
114