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/**
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 */
15class 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}