Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ResultDuplicator
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 6
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 add
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
20
 merge
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getUniqueQueries
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getResult
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 sortResult
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace Flow\Data\Utils;
4
5use Flow\Data\ObjectManager;
6use 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
13class 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}