PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
tablepress / libraries / vendor / PhpSpreadsheet / Calculation / Engine / ArrayArgumentProcessor.php

ArrayArgumentProcessor.php in TablePress – Tables in WordPress made easy 3.4, at libraries/vendor/PhpSpreadsheet/Calculation/Engine/ArrayArgumentProcessor.php

188 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TablePress\PhpOffice\PhpSpreadsheet\Calculation\Engine;
4
5 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Exception;
6 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Functions;
7
8 class ArrayArgumentProcessor
9 {
10 private static ArrayArgumentHelper $arrayArgumentHelper;
11
12 /** @return mixed[]
13 * @param mixed ...$arguments */
14 public static function processArguments(
15 ArrayArgumentHelper $arrayArgumentHelper,
16 callable $method,
17 ...$arguments
18 ): array {
19 self::$arrayArgumentHelper = $arrayArgumentHelper;
20
21 if (self::$arrayArgumentHelper->hasArrayArgument() === false) {
22 return [$method(...$arguments)];
23 }
24
25 if (self::$arrayArgumentHelper->arrayArguments() === 1) {
26 $nthArgument = self::$arrayArgumentHelper->getFirstArrayArgumentNumber();
27
28 return self::evaluateNthArgumentAsArray($method, $nthArgument, ...$arguments);
29 }
30
31 $singleRowVectorIndex = self::$arrayArgumentHelper->getSingleRowVector();
32 $singleColumnVectorIndex = self::$arrayArgumentHelper->getSingleColumnVector();
33
34 if ($singleRowVectorIndex !== null && $singleColumnVectorIndex !== null) {
35 // Basic logic for a single row vector and a single column vector
36 return self::evaluateVectorPair($method, $singleRowVectorIndex, $singleColumnVectorIndex, ...$arguments);
37 }
38
39 $matrixPair = self::$arrayArgumentHelper->getMatrixPair();
40 if ($matrixPair !== []) {
41 if (
42 (self::$arrayArgumentHelper->isVector($matrixPair[0]) === true
43 && self::$arrayArgumentHelper->isVector($matrixPair[1]) === false)
44 || (self::$arrayArgumentHelper->isVector($matrixPair[0]) === false
45 && self::$arrayArgumentHelper->isVector($matrixPair[1]) === true)
46 ) {
47 // Logic for a matrix and a vector (row or column)
48 return self::evaluateVectorMatrixPair($method, $matrixPair, ...$arguments);
49 }
50
51 // Logic for matrix/matrix, column vector/column vector or row vector/row vector
52 return self::evaluateMatrixPair($method, $matrixPair, ...$arguments);
53 }
54
55 // Still need to work out the logic for more than two array arguments,
56 // For the moment, we're throwing an Exception when we initialise the ArrayArgumentHelper
57 return ['#VALUE!'];
58 }
59
60 /**
61 * @param int[] $matrixIndexes
62 *
63 * @return mixed[]
64 * @param mixed ...$arguments
65 */
66 private static function evaluateVectorMatrixPair(callable $method, array $matrixIndexes, ...$arguments): array
67 {
68 if (array_pop($matrixIndexes) === null) {
69 throw new Exception('empty array 2');
70 }
71 $matrix2 = array_pop($matrixIndexes);
72 /** @var mixed[][] $matrixValues2 */
73 $matrixValues2 = $arguments[$matrix2];
74 if (array_pop($matrixIndexes) === null) {
75 throw new Exception('empty array 1');
76 }
77 $matrix1 = array_pop($matrixIndexes);
78 /** @var mixed[][] $matrixValues1 */
79 $matrixValues1 = $arguments[$matrix1];
80
81 /** @var non-empty-array<int> */
82 $matrix12 = [$matrix1, $matrix2];
83 $rows = min(array_map(\Closure::fromCallable([self::$arrayArgumentHelper, 'rowCount']), $matrix12));
84 $columns = min(array_map(\Closure::fromCallable([self::$arrayArgumentHelper, 'columnCount']), $matrix12));
85
86 if ($rows === 1) {
87 $rows = max(array_map(\Closure::fromCallable([self::$arrayArgumentHelper, 'rowCount']), $matrix12));
88 }
89 if ($columns === 1) {
90 $columns = max(array_map(\Closure::fromCallable([self::$arrayArgumentHelper, 'columnCount']), $matrix12));
91 }
92
93 $result = [];
94 for ($rowIndex = 0; $rowIndex < $rows; ++$rowIndex) {
95 for ($columnIndex = 0; $columnIndex < $columns; ++$columnIndex) {
96 $rowIndex1 = self::$arrayArgumentHelper->isRowVector($matrix1) ? 0 : $rowIndex;
97 $columnIndex1 = self::$arrayArgumentHelper->isColumnVector($matrix1) ? 0 : $columnIndex;
98 $value1 = $matrixValues1[$rowIndex1][$columnIndex1];
99 $rowIndex2 = self::$arrayArgumentHelper->isRowVector($matrix2) ? 0 : $rowIndex;
100 $columnIndex2 = self::$arrayArgumentHelper->isColumnVector($matrix2) ? 0 : $columnIndex;
101 $value2 = $matrixValues2[$rowIndex2][$columnIndex2];
102 $arguments[$matrix1] = $value1;
103 $arguments[$matrix2] = $value2;
104
105 $result[$rowIndex][$columnIndex] = $method(...$arguments);
106 }
107 }
108
109 return $result;
110 }
111
112 /**
113 * @param array<int|string> $matrixIndexes
114 *
115 * @return mixed[]
116 * @param mixed ...$arguments
117 */
118 private static function evaluateMatrixPair(callable $method, array $matrixIndexes, ...$arguments): array
119 {
120 $matrix2 = array_pop($matrixIndexes);
121 /** @var mixed[][] $matrixValues2 */
122 $matrixValues2 = $arguments[$matrix2];
123 $matrix1 = array_pop($matrixIndexes);
124 /** @var mixed[][] $matrixValues1 */
125 $matrixValues1 = $arguments[$matrix1];
126
127 $result = [];
128 foreach ($matrixValues1 as $rowIndex => $row) {
129 foreach ($row as $columnIndex => $value1) {
130 if (isset($matrixValues2[$rowIndex][$columnIndex]) === false) {
131 continue;
132 }
133
134 $value2 = $matrixValues2[$rowIndex][$columnIndex];
135 $arguments[$matrix1] = $value1;
136 $arguments[$matrix2] = $value2;
137
138 $result[$rowIndex][$columnIndex] = $method(...$arguments);
139 }
140 }
141
142 return $result;
143 }
144
145 /** @return mixed[]
146 * @param mixed ...$arguments */
147 private static function evaluateVectorPair(callable $method, int $rowIndex, int $columnIndex, ...$arguments): array
148 {
149 $rowVector = Functions::flattenArray($arguments[$rowIndex]);
150 $columnVector = Functions::flattenArray($arguments[$columnIndex]);
151
152 $result = [];
153 foreach ($columnVector as $column) {
154 $rowResults = [];
155 foreach ($rowVector as $row) {
156 $arguments[$rowIndex] = $row;
157 $arguments[$columnIndex] = $column;
158
159 $rowResults[] = $method(...$arguments);
160 }
161 $result[] = $rowResults;
162 }
163
164 return $result;
165 }
166
167 /**
168 * Note, offset is from 1 (for the first argument) rather than from 0.
169 *
170 * @return mixed[]
171 * @param mixed ...$arguments
172 */
173 private static function evaluateNthArgumentAsArray(callable $method, int $nthArgument, ...$arguments): array
174 {
175 $values = array_slice($arguments, $nthArgument - 1, 1);
176 /** @var mixed[] $values */
177 $values = array_pop($values);
178
179 $result = [];
180 foreach ($values as $value) {
181 $arguments[$nthArgument - 1] = $value;
182 $result[] = $method(...$arguments);
183 }
184
185 return $result;
186 }
187 }
188