Completed
Push — master ( 0cdf45...d59ceb )
by Edward
04:37
created

Fetcher::fetchElements()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 5
c 0
b 0
f 0
nc 3
nop 2
dl 0
loc 10
ccs 0
cts 6
cp 0
crap 12
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace Remorhaz\JSON\Path\Runtime;
5
6
use Remorhaz\JSON\Data\Value\ArrayValueInterface;
7
use Remorhaz\JSON\Path\Value\EvaluatedValueInterface;
8
use Remorhaz\JSON\Path\Value\EvaluatedValueListInterface;
9
use Remorhaz\JSON\Data\Value\NodeValueInterface;
10
use Remorhaz\JSON\Path\Value\NodeValueListBuilder;
11
use Remorhaz\JSON\Path\Value\NodeValueListInterface;
12
use Remorhaz\JSON\Data\Iterator\ValueIteratorFactory;
13
use Remorhaz\JSON\Path\Value\ValueListInterface;
14
15
final class Fetcher
16
{
17
18
    private $valueIteratorFactory;
19
20
    private $valueFetcher;
21
22
    public function __construct(ValueIteratorFactory $valueIteratorFactory, ValueFetcherInterface $valueFetcher)
23
    {
24
        $this->valueIteratorFactory = $valueIteratorFactory;
25
        $this->valueFetcher = $valueFetcher;
26
    }
27
28
    /**
29
     * @param NodeValueListInterface $source
30
     * @param Matcher\ChildMatcherInterface ...$matcherList
31
     * @return NodeValueListInterface
32
     */
33
    public function fetchChildren(
34
        NodeValueListInterface $source,
35
        Matcher\ChildMatcherInterface ...$matcherList
36
    ): NodeValueListInterface {
37
        $nodesBuilder = new NodeValueListBuilder;
38
        foreach ($source->getValues() as $sourceIndex => $sourceValue) {
39
            $matcher = $matcherList[$sourceIndex];
40
            $children = $this
41
                ->valueFetcher
42
                ->fetchValueChildren($matcher, $sourceValue);
43
            $outerIndex = $source->getIndexMap()->getOuterIndex($sourceIndex);
44
            foreach ($children as $child) {
45
                $nodesBuilder->addValue($child, $outerIndex);
46
            }
47
        }
48
49
        return $nodesBuilder->build();
50
    }
51
52
    public function fetchDeepChildren(
53
        Matcher\ChildMatcherInterface $matcher,
54
        NodeValueListInterface $source
55
    ): NodeValueListInterface {
56
        $nodesBuilder = new NodeValueListBuilder;
57
        foreach ($source->getValues() as $sourceIndex => $sourceValue) {
58
            $children = $this
59
                ->valueFetcher
60
                ->fetchValueDeepChildren($matcher, $sourceValue);
61
            $outerIndex = $source->getIndexMap()->getOuterIndex($sourceIndex);
62
            foreach ($children as $child) {
63
                $nodesBuilder->addValue($child, $outerIndex);
64
            }
65
        }
66
67
        return $nodesBuilder->build();
68
    }
69
70
    public function fetchFilterContext(NodeValueListInterface $source): NodeValueListInterface
71
    {
72
        $nodesBuilder = new NodeValueListBuilder;
73
        foreach ($source->getValues() as $sourceIndex => $sourceValue) {
74
            if (!$sourceValue instanceof NodeValueInterface) {
75
                throw new Exception\InvalidContextValueException($sourceValue);
76
            }
77
            $outerIndex = $source->getIndexMap()->getOuterIndex($sourceIndex);
78
            $children = $sourceValue instanceof ArrayValueInterface
79
                ? $this
80
                    ->valueFetcher
81
                    ->fetchValueChildren(new Matcher\AnyChildMatcher, $sourceValue)
82
                : [$sourceValue];
83
            foreach ($children as $child) {
84
                $nodesBuilder->addValue($child, $outerIndex);
85
            }
86
        }
87
88
        return $nodesBuilder->build();
89
    }
90
91
    public function fetchFilteredValues(
92
        EvaluatedValueListInterface $results,
93
        NodeValueListInterface $values
94
    ): NodeValueListInterface {
95
        if (!$values->getIndexMap()->equals($results->getIndexMap())) {
96
            throw new Exception\IndexMapMatchFailedException($values, $results);
97
        }
98
        $nodesBuilder = new NodeValueListBuilder;
99
        foreach ($values->getValues() as $index => $value) {
100
            $evaluatedValue = $results->getValue($index);
101
            if (!$evaluatedValue instanceof EvaluatedValueInterface) {
102
                throw new Exception\InvalidFilterValueException($evaluatedValue);
103
            }
104
            if (!$evaluatedValue->getData()) {
105
                continue;
106
            }
107
            $nodesBuilder->addValue(
108
                $value,
109
                $values->getIndexMap()->getOuterIndex($index)
110
            );
111
        }
112
113
        return $nodesBuilder->build();
114
    }
115
116
    /**
117
     * @param ValueListInterface $valueList
118
     * @return int[][]
119
     */
120
    public function fetchIndice(ValueListInterface $valueList): array
121
    {
122
        $result = [];
123
        foreach ($valueList->getValues() as $valueIndex => $value) {
124
            if (!$value instanceof ArrayValueInterface) {
125
                $result[$valueIndex] = [];
126
                continue;
127
            }
128
129
            $indice = [];
130
            $elementIterator = $this->valueIteratorFactory->createArrayIterator($value->createIterator());
131
            foreach ($elementIterator as $index => $element) {
132
                $indice[] = $index;
133
            }
134
            $result[$valueIndex] = $indice;
135
        }
136
137
        return $result;
138
    }
139
}
140