Passed
Push — master ( 3a32e2...77143f )
by Edward
04:21
created

Query::getSource()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace Remorhaz\JSON\Pointer\Query;
5
6
use Remorhaz\JSON\Data\Value\ArrayValueInterface;
7
use Remorhaz\JSON\Data\Value\NodeValueInterface;
8
use Remorhaz\JSON\Data\Value\ObjectValueInterface;
9
use Remorhaz\JSON\Data\Value\ScalarValueInterface;
10
use Remorhaz\JSON\Pointer\Locator\IndexReferenceInterface;
11
use Remorhaz\JSON\Pointer\Locator\LocatorInterface;
12
use Remorhaz\JSON\Pointer\Locator\NextIndexReferenceInterface;
13
14
final class Query implements QueryInterface
15
{
16
17
    private $source;
18
19
    private $locator;
20
21 2
    public function __construct(string $source, LocatorInterface $locator)
22
    {
23 2
        $this->source = $source;
24 2
        $this->locator = $locator;
25 2
    }
26
27 1
    public function __invoke(NodeValueInterface $rootNode): QueryResultInterface
28
    {
29 1
        $node = $rootNode;
30 1
        $parentNode = null;
31 1
        $lastReference = null;
32 1
        foreach ($this->locator->references() as $listedReference) {
33 1
            if ($listedReference->isLast()) {
34 1
                $lastReference = $listedReference->getReference();
35
            }
36 1
            if ($node instanceof ScalarValueInterface) {
37
                return new QueryResult($this->source);
38
            }
39
40 1
            if ($node instanceof ArrayValueInterface) {
41
                $reference = $listedReference->getReference();
42
                switch (true) {
43
                    case $reference instanceof IndexReferenceInterface:
44
                        $key = $reference->getElementIndex();
45
                        break;
46
47
                    case $reference instanceof NextIndexReferenceInterface:
48
                        $key = null;
49
                        break;
50
51
                    default:
52
                        return new QueryResult($this->source);
53
                }
54
                $lastIndex = null;
55
                foreach ($node->createChildIterator() as $index => $element) {
56
                    $lastIndex = $index;
57
                    if ($index === $key) {
58
                        $parentNode = $node;
59
                        $node = $element;
60
                        continue 2;
61
                    }
62
                }
63
64
                if (isset($key) && $key != $lastIndex + 1) {
65
                    return new QueryResult($this->source);
66
                }
67
68
                return new QueryResult(
69
                    $this->source,
70
                    null,
71
                    $listedReference->isLast() ? $node : null,
72
                    $lastReference,
73
                );
74
            }
75
76 1
            if ($node instanceof ObjectValueInterface) {
77 1
                $key = $listedReference->getReference()->getPropertyName();
78 1
                foreach ($node->createChildIterator() as $name => $property) {
79 1
                    if ($name == $key) {
80 1
                        $parentNode = $node;
81 1
                        $node = $property;
82 1
                        continue 2;
83
                    }
84
                }
85
86
                return new QueryResult(
87
                    $this->source,
88
                    null,
89
                    $listedReference->isLast() ? $node : null,
90
                    $lastReference,
91
                );
92
            }
93
        }
94
95 1
        return new QueryResult($this->source, $node, $parentNode, $lastReference);
96
    }
97
98 1
    public function getSource(): string
99
    {
100 1
        return $this->source;
101
    }
102
}
103