Collector::processEvent()   D
last analyzed

Complexity

Conditions 19
Paths 28

Size

Total Lines 54
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 26.3208

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 19
eloc 40
c 2
b 1
f 0
nc 28
nop 1
dl 0
loc 54
ccs 24
cts 33
cp 0.7272
crap 26.3208
rs 4.5166

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
declare(strict_types=1);
3
4
namespace JsonDecodeStream\Collector;
5
6
use JsonDecodeStream\Event;
7
use JsonDecodeStream\Exception\CollectorException;
8
use JsonDecodeStream\Exception\SelectorException;
9
use stdClass;
10
11
class Collector implements CollectorInterface
12
{
13
    /** @var string */
14
    protected $selector;
15
    /** @var bool */
16
    protected $objectsAsAssocArrays;
17
18
    /** @var null|array|stdClass */
19
    protected $current = null;
20
    /** @var array|array[]|stdClass[] */
21
    protected $stack = [];
22
    /** @var null|string */
23
    protected $key = null;
24
    /** @var string[]|null[] */
25
    protected $keyStack = [];
26
27 13
    public function __construct(string $selector = null, bool $objectsAsAssocArrays = false)
28
    {
29 13
        $this->selector = $selector;
30 13
        $this->objectsAsAssocArrays = $objectsAsAssocArrays;
31 13
    }
32
33
    /**
34
     * @param Event $event
35
     * @return array|null
36
     * @throws CollectorException
37
     * @throws SelectorException
38
     */
39 13
    public function processEvent(Event $event)
40
    {
41 13
        if ($this->selector !== null && !$event->matchPath($this->selector)) {
42 9
            return null;
43
        }
44
45 13
        switch ($event->getId()) {
46
            case Event::KEY:
47 6
                $this->key = $event->getValue();
48 6
                break;
49
50
            case Event::VALUE:
51 13
                if ($this->current === null) {
52 7
                    return [ $event->getPath(), $event->getValue() ];
53 7
                } elseif ($this->key !== null && $this->hasKeyInCurrent($this->key)) {
54
                    throw CollectorException::duplicatedKey($this->key, $event);
55
                } else {
56 7
                    $this->setInCurrent($event->getValue(), $this->key);
57
                }
58 7
                break;
59
60
            case Event::OBJECT_START:
61
            case Event::ARRAY_START:
62 7
                if ($this->current !== null) {
63
                    $this->stack[] = $this->current;
64
                    $this->keyStack[] = $this->key;
65
                }
66 7
                if ($event->getId() == Event::OBJECT_START) {
67 6
                    $this->current = $this->objectsAsAssocArrays ? [] : new stdClass();
68 2
                } elseif ($event->getId() == Event::ARRAY_START) {
69 2
                    $this->current = [];
70
                }
71 7
                $this->key = null;
72 7
                break;
73
74
            case Event::OBJECT_END:
75
            case Event::ARRAY_END:
76 7
                $finished = $this->current;
77 7
                if (!empty($this->stack)) {
78
                    $this->current = array_pop($this->stack);
79
                    $this->key = array_pop($this->keyStack);
80
                    if ($this->key !== null && $this->hasKeyInCurrent($this->key)) {
81
                        throw CollectorException::duplicatedKey($this->key, $event);
82
                    }
83
                    $this->setInCurrent($finished, $this->key);
84
                } else {
85 7
                    $this->current = null;
86 7
                    $this->key = null;
87 7
                    return [ $event->getPath(), $finished ];
88
                }
89
                break;
90
        }
91
92 7
        return null;
93
    }
94
95 6
    protected function hasKeyInCurrent($key)
96
    {
97 6
        if ($key === null) {
98
            return false;
99
        }
100 6
        if (is_object($this->current)) {
101 6
            return isset($this->current->{$key});
102
        } elseif (is_array($this->current)) {
103
            return isset($this->current[$key]);
104
        } else {
105
            return false;
106
        }
107
    }
108
109 7
    protected function setInCurrent($value, $key = null)
110
    {
111 7
        if (is_object($this->current)) {
112 6
            $this->current->{$key} = $value;
113 2
        } elseif (is_array($this->current) && $key === null) {
114 2
            $this->current[] = $value;
115
        } elseif (is_array($this->current)) {
116
            $this->current[$key] = $value;
117
        }
118 7
    }
119
}
120