Skip to content

Commit adff7a3

Browse files
committed
Make Structured Reference parsing case-insensitive, by switching from strpos to preg_match, allowing re-use of the pattern in preg_replace for convenience
1 parent adbc981 commit adff7a3

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

src/PhpSpreadsheet/Calculation/Engine/Operands/StructuredReference.php

+17-12
Original file line numberDiff line numberDiff line change
@@ -178,16 +178,18 @@ private function getRowReference(Cell $cell): string
178178
foreach ($this->columns as $columnId => $columnName) {
179179
$columnName = str_replace("\u{a0}", ' ', $columnName);
180180
$cellReference = $columnId . $cell->getRow();
181+
$pattern1 = '/\[' . preg_quote($columnName) . '\]/miu';
182+
$pattern2 = '/@' . preg_quote($columnName) . '/miu';
181183
/** @var string $reference */
182-
if (stripos($reference, "[{$columnName}]") !== false) {
183-
$reference = preg_replace('/\[' . preg_quote($columnName) . '\]/miu', $cellReference, $reference);
184-
} elseif (stripos($reference, "@{$columnName}") !== false) {
185-
$reference = preg_replace('/@' . preg_quote($columnName) . '/miu', $cellReference, $reference);
184+
if (preg_match($pattern1, $reference) === 1) {
185+
$reference = preg_replace($pattern1, $cellReference, $reference);
186+
} elseif (preg_match($pattern2, $reference) === 1) {
187+
$reference = preg_replace($pattern2, $cellReference, $reference);
186188
}
187189
}
188190

189191
/** @var string $reference */
190-
return $this->validateParsedReference(trim($reference, '[]@ '));
192+
return $this->validateParsedReference(trim($reference, '[]@, '));
191193
}
192194

193195
/**
@@ -208,17 +210,18 @@ private function getColumnReference(): string
208210
$cellFrom = "{$columnId}{$startRow}";
209211
$cellTo = "{$columnId}{$endRow}";
210212
$cellReference = ($cellFrom === $cellTo) ? $cellFrom : "{$cellFrom}:{$cellTo}";
213+
$pattern = '/\[' . preg_quote($columnName) . '\]/mui';
211214
/** @var string $reference */
212-
if (stripos($reference, "[{$columnName}]") !== false) {
215+
if (preg_match($pattern, $reference) === 1) {
213216
$columnsSelected = true;
214-
$reference = preg_replace('/\[' . preg_quote($columnName) . '\]/miu', $cellReference, $reference);
217+
$reference = preg_replace($pattern, $cellReference, $reference);
215218
}
216219
}
217220
if ($columnsSelected === false) {
218221
return $this->fullData($startRow, $endRow);
219222
}
220223

221-
$reference = trim($reference ?? '', '[]@ ');
224+
$reference = trim($reference ?? '', '[]@, ');
222225
if (substr_count($reference, ':') > 1) {
223226
$cells = explode(':', $reference);
224227
$firstCell = array_shift($cells);
@@ -237,6 +240,7 @@ private function validateParsedReference(string $reference): string
237240
{
238241
if (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . ':' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $reference) !== 1) {
239242
if (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/miu', $reference) !== 1) {
243+
240244
throw new Exception("Invalid Structured Reference {$this->reference} {$reference}");
241245
}
242246
}
@@ -265,7 +269,7 @@ private function getMinimumRow(string $reference): int
265269
return $this->totalsRow ?? $this->lastDataRow;
266270
}
267271

268-
return 1;
272+
return $this->headersRow ?? $this->firstDataRow;
269273
}
270274

271275
private function getMaximumRow(string $reference): int
@@ -280,7 +284,7 @@ private function getMaximumRow(string $reference): int
280284
return $this->totalsRow ?? $this->lastDataRow;
281285
}
282286

283-
return 1;
287+
return $this->totalsRow ?? $this->lastDataRow;
284288
}
285289

286290
public function value(): string
@@ -295,12 +299,13 @@ public function getRowsForColumnReference(string &$reference, int $startRow, int
295299
{
296300
$rowsSelected = false;
297301
foreach (self::ITEM_SPECIFIER_ROWS_SET as $rowReference) {
302+
$pattern = '/\[' . $rowReference . '\]/mui';
298303
/** @var string $reference */
299-
if (stripos($reference, "[{$rowReference}]") !== false) {
304+
if (preg_match($pattern, $reference) === 1) {
300305
$rowsSelected = true;
301306
$startRow = min($startRow, $this->getMinimumRow($rowReference));
302307
$endRow = max($endRow, $this->getMaximumRow($rowReference));
303-
$reference = preg_replace('/\[' . $rowReference . '\],/mui', '', $reference);
308+
$reference = preg_replace($pattern, '', $reference);
304309
}
305310
}
306311
if ($rowsSelected === false) {

0 commit comments

Comments
 (0)