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 / Indirect.php

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

131 lines 4.6 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 Exception;
6 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Calculation;
7 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Functions;
8 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
9 use TablePress\PhpOffice\PhpSpreadsheet\Cell\AddressRange;
10 use TablePress\PhpOffice\PhpSpreadsheet\Cell\Cell;
11 use TablePress\PhpOffice\PhpSpreadsheet\Cell\Coordinate;
12 use TablePress\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
13
14 class Indirect
15 {
16 /**
17 * Determine whether cell address is in A1 (true) or R1C1 (false) format.
18 *
19 * @param mixed $a1fmt Expect bool Helpers::CELLADDRESS_USE_A1 or CELLADDRESS_USE_R1C1,
20 * but can be provided as numeric which is cast to bool
21 */
22 private static function a1Format($a1fmt): bool
23 {
24 $a1fmt = Functions::flattenSingleValue($a1fmt);
25 if ($a1fmt === null) {
26 return Helpers::CELLADDRESS_USE_A1;
27 }
28 if (is_string($a1fmt)) {
29 throw new Exception(ExcelError::VALUE());
30 }
31
32 return (bool) $a1fmt;
33 }
34
35 /**
36 * Convert cellAddress to string, verify not null string.
37 *
38 * @param null|mixed[]|string $cellAddress
39 */
40 private static function validateAddress($cellAddress): string
41 {
42 $cellAddress = Functions::flattenSingleValue($cellAddress);
43 if (!is_string($cellAddress) || !$cellAddress) {
44 throw new Exception(ExcelError::REF());
45 }
46
47 return $cellAddress;
48 }
49
50 /**
51 * INDIRECT.
52 *
53 * Returns the reference specified by a text string.
54 * References are immediately evaluated to display their contents.
55 *
56 * Excel Function:
57 * =INDIRECT(cellAddress, bool) where the bool argument is optional
58 *
59 * @param mixed[]|string $cellAddress $cellAddress The cell address of the current cell (containing this formula)
60 * @param mixed $a1fmt Expect bool Helpers::CELLADDRESS_USE_A1 or CELLADDRESS_USE_R1C1,
61 * but can be provided as numeric which is cast to bool
62 * @param Cell $cell The current cell (containing this formula)
63 *
64 * @return mixed[]|string An array containing a cell or range of cells, or a string on error
65 */
66 public static function INDIRECT($cellAddress, $a1fmt, Cell $cell)
67 {
68 [$baseCol, $baseRow] = Coordinate::indexesFromString($cell->getCoordinate());
69
70 try {
71 $a1 = self::a1Format($a1fmt);
72 $cellAddress = self::validateAddress($cellAddress);
73 } catch (Exception $e) {
74 return $e->getMessage();
75 }
76
77 [$cellAddress, $worksheet, $sheetName] = Helpers::extractWorksheet($cellAddress, $cell);
78
79 if (preg_match('/^' . Calculation::CALCULATION_REGEXP_COLUMNRANGE_RELATIVE . '$/miu', $cellAddress, $matches)) {
80 $cellAddress = self::handleRowColumnRanges($worksheet, ...explode(':', $cellAddress));
81 } elseif (preg_match('/^' . Calculation::CALCULATION_REGEXP_ROWRANGE_RELATIVE . '$/miu', $cellAddress, $matches)) {
82 $cellAddress = self::handleRowColumnRanges($worksheet, ...explode(':', $cellAddress));
83 }
84
85 try {
86 [$cellAddress1, $cellAddress2, $cellAddress] = Helpers::extractCellAddresses($cellAddress, $a1, $cell->getWorkSheet(), $sheetName, $baseRow, $baseCol);
87 } catch (Exception $exception) {
88 return ExcelError::REF();
89 }
90
91 if (
92 (!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $cellAddress1, $matches))
93 || (($cellAddress2 !== null) && (!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $cellAddress2, $matches)))
94 ) {
95 return ExcelError::REF();
96 }
97
98 return self::extractRequiredCells($worksheet, $cellAddress);
99 }
100
101 /**
102 * Extract range values.
103 *
104 * @return mixed[] Array of values in range if range contains more than one element.
105 * Otherwise, a single value is returned.
106 */
107 private static function extractRequiredCells(?Worksheet $worksheet, string $cellAddress): array
108 {
109 return Calculation::getInstance(($nullsafeVariable1 = $worksheet) ? $nullsafeVariable1->getParent() : null)
110 ->extractCellRange($cellAddress, $worksheet, false, true);
111 }
112
113 private static function handleRowColumnRanges(?Worksheet $worksheet, string $start, string $end): string
114 {
115 // Being lazy, we're only checking a single row/column to get the max
116 if (ctype_digit($start) && $start <= AddressRange::MAX_ROW) {
117 // Max 16,384 columns for Excel2007
118 $endColRef = ($worksheet !== null) ? $worksheet->getHighestDataColumn((int) $start) : AddressRange::MAX_COLUMN;
119
120 return "A{$start}:{$endColRef}{$end}";
121 } elseif (ctype_alpha($start) && strlen($start) <= 3) {
122 // Max 1,048,576 rows for Excel2007
123 $endRowRef = ($worksheet !== null) ? $worksheet->getHighestDataRow($start) : AddressRange::MAX_ROW;
124
125 return "{$start}1:{$end}{$endRowRef}";
126 }
127
128 return "{$start}:{$end}";
129 }
130 }
131