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
|
|
|
|