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 / LookupRef / ChooseRowsEtc.php

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

264 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\LookupRef;
4
5 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Functions;
6 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
7
8 class ChooseRowsEtc
9 {
10 /**
11 * Transpose 2-dimensional array.
12 * See https://stackoverflow.com/questions/797251/transposing-multidimensional-arrays-in-php
13 * especially the comment from user17994717.
14 *
15 * @param mixed[] $array
16 *
17 * @return mixed[]
18 */
19 public static function transpose(array $array): array
20 {
21 return empty($array) ? [] : (array_map((count($array) === 1) ? (fn ($x) => [$x]) : null, ...$array)); // @phpstan-ignore argument.type (phstan is wrong), argument.type (phpstan is wrong)
22 }
23
24 /** @return mixed[]
25 * @param mixed $array */
26 private static function arrayValues($array): array
27 {
28 return is_array($array) ? array_values($array) : [$array];
29 }
30
31 /**
32 * CHOOSECOLS.
33 *
34 * @param mixed $input expecting two-dimensional array
35 *
36 * @return mixed[]|string
37 * @param mixed ...$args
38 */
39 public static function chooseCols($input, ...$args)
40 {
41 if (!is_array($input)) {
42 $input = [[$input]];
43 }
44 $retval = self::chooseRows(self::transpose($input), ...$args);
45
46 return is_array($retval) ? self::transpose($retval) : $retval;
47 }
48
49 /**
50 * CHOOSEROWS.
51 *
52 * @param mixed $input expecting two-dimensional array
53 *
54 * @return mixed[]|string
55 * @param mixed ...$args
56 */
57 public static function chooseRows($input, ...$args)
58 {
59 if (!is_array($input)) {
60 $input = [[$input]];
61 }
62 $inputArray = [[]]; // no row 0
63 $numRows = 0;
64 foreach ($input as $inputRow) {
65 $inputArray[] = self::arrayValues($inputRow);
66 ++$numRows;
67 }
68 $outputArray = [];
69 foreach (Functions::flattenArray2(...$args) as $arg) {
70 if (!is_numeric($arg)) {
71 return ExcelError::VALUE();
72 }
73 $index = (int) $arg;
74 if ($index < 0) {
75 $index += $numRows + 1;
76 }
77 if ($index <= 0 || $index > $numRows) {
78 return ExcelError::VALUE();
79 }
80 $outputArray[] = $inputArray[$index];
81 }
82
83 return $outputArray;
84 }
85
86 /**
87 * @param mixed[] $array
88 *
89 * @return mixed[]|string
90 * @param mixed $offset
91 */
92 private static function dropRows(array $array, $offset)
93 {
94 if ($offset === null) {
95 return $array;
96 }
97 if (!is_numeric($offset)) {
98 return ExcelError::VALUE();
99 }
100 $offset = (int) $offset;
101 $count = count($array);
102 if (abs($offset) >= $count) {
103 // In theory, this should be #CALC!, but Excel treats
104 // #CALC! as corrupt, and it's not worth figuring out why
105 return ExcelError::VALUE();
106 }
107 if ($offset === 0) {
108 return $array;
109 }
110 if ($offset > 0) {
111 return array_slice($array, $offset);
112 }
113
114 return array_slice($array, 0, $count + $offset);
115 }
116
117 /**
118 * DROP.
119 *
120 * @param mixed $input expect two-dimensional array
121 *
122 * @return mixed[]|string
123 * @param mixed $rows
124 * @param mixed $columns
125 */
126 public static function drop($input, $rows = null, $columns = null)
127 {
128 if (!is_array($input)) {
129 $input = [[$input]];
130 }
131 $inputArray = []; // no row 0
132 foreach ($input as $inputRow) {
133 $inputArray[] = self::arrayValues($inputRow);
134 }
135 $outputArray1 = self::dropRows($inputArray, $rows);
136 if (is_string($outputArray1)) {
137 return $outputArray1;
138 }
139 $outputArray2 = self::transpose($outputArray1);
140 $outputArray3 = self::dropRows($outputArray2, $columns);
141 if (is_string($outputArray3)) {
142 return $outputArray3;
143 }
144
145 return self::transpose($outputArray3);
146 }
147
148 /**
149 * @param mixed[] $array
150 *
151 * @return mixed[]|string
152 * @param mixed $offset
153 */
154 private static function takeRows(array $array, $offset)
155 {
156 if ($offset === null) {
157 return $array;
158 }
159 if (!is_numeric($offset)) {
160 return ExcelError::VALUE();
161 }
162 $offset = (int) $offset;
163 if ($offset === 0) {
164 // should be #CALC! - see above
165 return ExcelError::VALUE();
166 }
167 $count = count($array);
168 if (abs($offset) >= $count) {
169 return $array;
170 }
171 if ($offset > 0) {
172 return array_slice($array, 0, $offset);
173 }
174
175 return array_slice($array, $count + $offset);
176 }
177
178 /**
179 * TAKE.
180 *
181 * @param mixed $input expecting two-dimensional array
182 *
183 * @return mixed[]|string
184 * @param mixed $rows
185 * @param mixed $columns
186 */
187 public static function take($input, $rows, $columns = null)
188 {
189 if (!is_array($input)) {
190 $input = [[$input]];
191 }
192 if ($rows === null && $columns === null) {
193 return $input;
194 }
195 $inputArray = [];
196 foreach ($input as $inputRow) {
197 $inputArray[] = self::arrayValues($inputRow);
198 }
199 $outputArray1 = self::takeRows($inputArray, $rows);
200 if (is_string($outputArray1)) {
201 return $outputArray1;
202 }
203 $outputArray2 = self::transpose($outputArray1);
204 $outputArray3 = self::takeRows($outputArray2, $columns);
205 if (is_string($outputArray3)) {
206 return $outputArray3;
207 }
208
209 return self::transpose($outputArray3);
210 }
211
212 /**
213 * EXPAND.
214 *
215 * @param mixed $input expecting two-dimensional array
216 *
217 * @return mixed[]|string
218 * @param mixed $rows
219 * @param mixed $columns
220 * @param mixed $pad
221 */
222 public static function expand($input, $rows, $columns = null, $pad = '#N/A')
223 {
224 if (!is_array($input)) {
225 $input = [[$input]];
226 }
227 if ($rows === null && $columns === null) {
228 return $input;
229 }
230 $numRows = count($input);
231 $rows ??= $numRows;
232 if (!is_numeric($rows)) {
233 return ExcelError::VALUE();
234 }
235 $rows = (int) $rows;
236 if ($rows < count($input)) {
237 return ExcelError::VALUE();
238 }
239 $numCols = 0;
240 foreach ($input as $inputRow) {
241 $numCols = max($numCols, is_array($inputRow) ? count($inputRow) : 1);
242 }
243 $columns ??= $numCols;
244 if (!is_numeric($columns)) {
245 return ExcelError::VALUE();
246 }
247 $columns = (int) $columns;
248 if ($columns < $numCols) {
249 return ExcelError::VALUE();
250 }
251 $inputArray = [];
252 foreach ($input as $inputRow) {
253 $inputArray[] = array_pad(self::arrayValues($inputRow), $columns, $pad);
254 }
255 $outputArray = [];
256 $padRow = array_pad([], $columns, $pad);
257 for ($count = 0; $count < $rows; ++$count) {
258 $outputArray[] = ($count >= $numRows) ? $padRow : $inputArray[$count];
259 }
260
261 return $outputArray;
262 }
263 }
264