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