ValueListFetcher::fetchChildren()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 9
nc 3
nop 2
dl 0
loc 16
ccs 0
cts 9
cp 0
crap 12
rs 9.9666
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Remorhaz\JSON\Path\Runtime;
6
7
use Remorhaz\JSON\Data\Value\ArrayValueInterface;
8
use Remorhaz\JSON\Path\Value\EvaluatedValueInterface;
9
use Remorhaz\JSON\Path\Value\EvaluatedValueList;
10
use Remorhaz\JSON\Path\Value\EvaluatedValueListInterface;
11
use Remorhaz\JSON\Data\Value\NodeValueInterface;
12
use Remorhaz\JSON\Path\Value\NodeValueList;
13
use Remorhaz\JSON\Path\Value\NodeValueListBuilder;
14
use Remorhaz\JSON\Path\Value\NodeValueListInterface;
15
16
final class ValueListFetcher implements ValueListFetcherInterface
17
{
18
19
    private $valueFetcher;
20
21
    public function __construct(ValueFetcherInterface $valueFetcher)
22
    {
23
        $this->valueFetcher = $valueFetcher;
24
    }
25
26
    /**
27
     * @param NodeValueListInterface $source
28
     * @param Matcher\ChildMatcherInterface $matcher
29
     * @return NodeValueListInterface
30
     */
31
    public function fetchChildren(
32
        NodeValueListInterface $source,
33
        Matcher\ChildMatcherInterface $matcher
34
    ): NodeValueListInterface {
35
        $nodesBuilder = new NodeValueListBuilder();
36
        foreach ($source->getValues() as $sourceIndex => $sourceValue) {
37
            $children = $this
38
                ->valueFetcher
39
                ->createChildrenIterator($matcher, $sourceValue);
40
            $outerIndex = $source->getIndexMap()->getOuterIndex($sourceIndex);
41
            foreach ($children as $child) {
42
                $nodesBuilder->addValue($child, $outerIndex);
43
            }
44
        }
45
46
        return $nodesBuilder->build();
47
    }
48
49
    public function fetchChildrenDeep(
50
        NodeValueListInterface $source,
51
        Matcher\ChildMatcherInterface $matcher
52
    ): NodeValueListInterface {
53
        $nodesBuilder = new NodeValueListBuilder();
54
        foreach ($source->getValues() as $sourceIndex => $sourceValue) {
55
            $children = $this
56
                ->valueFetcher
57
                ->createDeepChildrenIterator($matcher, $sourceValue);
58
            $outerIndex = $source->getIndexMap()->getOuterIndex($sourceIndex);
59
            foreach ($children as $child) {
60
                $nodesBuilder->addValue($child, $outerIndex);
61
            }
62
        }
63
64
        return $nodesBuilder->build();
65
    }
66
67
    public function merge(NodeValueListInterface ...$sources): NodeValueListInterface
68
    {
69
        $nodesBuilder = new NodeValueListBuilder();
70
        foreach ($sources as $source) {
71
            foreach ($source->getValues() as $innerIndex => $value) {
72
                $nodesBuilder->addValue(
73
                    $value,
74
                    $source->getIndexMap()->getOuterIndex($innerIndex),
75
                );
76
            }
77
        }
78
79
        return $nodesBuilder->build();
80
    }
81
82
    public function fetchFilterContext(NodeValueListInterface $source): NodeValueListInterface
83
    {
84
        $nodesBuilder = new NodeValueListBuilder();
85
        foreach ($source->getValues() as $sourceIndex => $sourceValue) {
86
            if (!$sourceValue instanceof NodeValueInterface) {
87
                throw new Exception\InvalidContextValueException($sourceValue);
88
            }
89
            $outerIndex = $source->getIndexMap()->getOuterIndex($sourceIndex);
90
            $children = $sourceValue instanceof ArrayValueInterface
91
                ? $this
92
                    ->valueFetcher
93
                    ->createChildrenIterator(new Matcher\AnyChildMatcher(), $sourceValue)
94
                : [$sourceValue];
95
            foreach ($children as $child) {
96
                $nodesBuilder->addValue($child, $outerIndex);
97
            }
98
        }
99
100
        return $nodesBuilder->build();
101
    }
102
103
    public function fetchFilteredValues(
104
        NodeValueListInterface $values,
105
        EvaluatedValueListInterface $results
106
    ): NodeValueListInterface {
107
        if (!$values->getIndexMap()->isCompatible($results->getIndexMap())) {
108
            throw new Exception\IndexMapMatchFailedException($values, $results);
109
        }
110
        $valueIndex = 0;
111
        $valueMap = [];
112
        foreach ($results->getIndexMap()->getOuterIndexes() as $innerIndex => $outerIndex) {
113
            if (isset($outerIndex)) {
114
                $valueMap[$innerIndex] = $valueIndex++;
115
            }
116
        }
117
        $nodesBuilder = new NodeValueListBuilder();
118
        foreach ($values->getValues() as $index => $value) {
119
            if (!isset($valueMap[$index])) {
120
                continue;
121
            }
122
            $evaluatedValue = $results->getValue($valueMap[$index]);
123
            if (!$evaluatedValue instanceof EvaluatedValueInterface) {
124
                throw new Exception\InvalidFilterValueException($evaluatedValue);
125
            }
126
            if (!$evaluatedValue->getData()) {
127
                continue;
128
            }
129
            $nodesBuilder->addValue(
130
                $value,
131
                $values->getIndexMap()->getOuterIndex($index)
132
            );
133
        }
134
135
        return $nodesBuilder->build();
136
    }
137
138
    public function splitFilterContext(NodeValueListInterface $values): NodeValueListInterface
139
    {
140
        return new NodeValueList(
141
            $values->getIndexMap()->split(),
142
            ...$values->getValues(),
143
        );
144
    }
145
146
    public function joinFilterResults(
147
        EvaluatedValueListInterface $evaluatedValues,
148
        NodeValueListInterface $contextValues
149
    ): EvaluatedValueListInterface {
150
        return new EvaluatedValueList(
151
            $evaluatedValues->getIndexMap()->join($contextValues->getIndexMap()),
152
            ...$evaluatedValues->getResults()
153
        );
154
    }
155
}
156