DeleteElementMutation::__invoke()   B
last analyzed

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