Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 27 |
|
0.00% |
0 / 6 |
CRAP | |
0.00% |
0 / 1 |
ResultDuplicator | |
0.00% |
0 / 27 |
|
0.00% |
0 / 6 |
156 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
add | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
20 | |||
merge | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
getUniqueQueries | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getResult | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
sortResult | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 |
1 | <?php |
2 | |
3 | namespace Flow\Data\Utils; |
4 | |
5 | use Flow\Data\ObjectManager; |
6 | use Flow\Exception\InvalidParameterException; |
7 | |
8 | // Better name? |
9 | // Add query arrays with a multi-dimensional position |
10 | // Merge results with their query value |
11 | // Get back result array with same positions as the original query |
12 | // Maintains merge ordering |
13 | class ResultDuplicator { |
14 | /** |
15 | * Maps from the query array to its position in the query array |
16 | * |
17 | * @var string[] |
18 | */ |
19 | protected $queryKeys; |
20 | |
21 | /** |
22 | * @var int |
23 | */ |
24 | protected $dimensions; |
25 | |
26 | /** |
27 | * @var MultiDimArray |
28 | */ |
29 | protected $desiredOrder; |
30 | |
31 | /** |
32 | * @var MultiDimArray |
33 | */ |
34 | protected $queryMap; |
35 | |
36 | /** |
37 | * @var MultiDimArray |
38 | */ |
39 | protected $result; |
40 | |
41 | /** |
42 | * @var array |
43 | */ |
44 | protected $queries = []; |
45 | |
46 | /** |
47 | * @param string[] $queryKeys |
48 | * @param int $dimensions |
49 | */ |
50 | public function __construct( array $queryKeys, $dimensions ) { |
51 | $this->queryKeys = $queryKeys; |
52 | $this->dimensions = $dimensions; |
53 | $this->desiredOrder = new MultiDimArray; |
54 | $this->queryMap = new MultiDimArray; |
55 | $this->result = new MultiDimArray; |
56 | } |
57 | |
58 | /** |
59 | * Add a query and its position. Positions must be unique. |
60 | * @param array $query |
61 | * @param int|int[] $position |
62 | * @throws InvalidParameterException |
63 | */ |
64 | public function add( $query, $position ) { |
65 | $dim = count( (array)$position ); |
66 | if ( $dim !== $this->dimensions ) { |
67 | throw new InvalidParameterException( "Expected position with {$this->dimensions} dimensions, received $dim" ); |
68 | } |
69 | $query = ObjectManager::splitFromRow( $query, $this->queryKeys ); |
70 | if ( $query === null ) { |
71 | // the queryKeys are either unset or null, and not indexable |
72 | // TODO: what should happen here? |
73 | return; |
74 | } |
75 | $this->desiredOrder[$position] = $query; |
76 | if ( !isset( $this->queryMap[$query] ) ) { |
77 | $this->queries[] = $query; |
78 | $this->queryMap[$query] = true; |
79 | } |
80 | } |
81 | |
82 | /** |
83 | * merge a query into the result set |
84 | * @param array $query |
85 | * @param array $result |
86 | */ |
87 | public function merge( array $query, array $result ) { |
88 | $query = ObjectManager::splitFromRow( $query, $this->queryKeys ); |
89 | if ( $query === null ) { |
90 | // the queryKeys are either unset or null, and not indexable |
91 | // TODO: what should happen here? |
92 | return; |
93 | } |
94 | $this->result[$query] = $result; |
95 | } |
96 | |
97 | public function getUniqueQueries() { |
98 | return $this->queries; |
99 | } |
100 | |
101 | public function getResult() { |
102 | return self::sortResult( $this->desiredOrder->all(), $this->result, $this->dimensions ); |
103 | } |
104 | |
105 | /** |
106 | * merge() wasn't necessarily called in the same order as add(), this walks back through |
107 | * the results to put them in the desired order with the correct keys. |
108 | * @param array $order |
109 | * @param MultiDimArray $result |
110 | * @param int $dimensions |
111 | * @return array |
112 | */ |
113 | public static function sortResult( array $order, MultiDimArray $result, $dimensions ) { |
114 | $final = []; |
115 | foreach ( $order as $position => $query ) { |
116 | if ( $dimensions > 1 ) { |
117 | $final[$position] = self::sortResult( $query, $result, $dimensions - 1 ); |
118 | } else { |
119 | $final[$position] = $result[$query] ?? null; |
120 | } |
121 | } |
122 | return $final; |
123 | } |
124 | } |