@@ -34,8 +34,6 @@ final class StructuredReference implements Operand
34
34
35
35
private string $ tableName ;
36
36
37
- private Table $ table ;
38
-
39
37
private string $ reference ;
40
38
41
39
private ?int $ headersRow ;
@@ -104,16 +102,16 @@ private function getTableStructure(Cell $cell): void
104
102
preg_match (self ::TABLE_REFERENCE , $ this ->value , $ matches );
105
103
106
104
$ this ->tableName = $ matches [1 ];
107
- $ this -> table = ($ this ->tableName === '' )
105
+ $ table = ($ this ->tableName === '' )
108
106
? $ this ->getTableForCell ($ cell )
109
107
: $ this ->getTableByName ($ cell );
110
108
$ this ->reference = $ matches [2 ];
111
- $ tableRange = Coordinate::getRangeBoundaries ($ this -> table ->getRange ());
109
+ $ tableRange = Coordinate::getRangeBoundaries ($ table ->getRange ());
112
110
113
- $ this ->headersRow = ($ this -> table ->getShowHeaderRow ()) ? (int ) $ tableRange [0 ][1 ] : null ;
114
- $ this ->firstDataRow = ($ this -> table ->getShowHeaderRow ()) ? (int ) $ tableRange [0 ][1 ] + 1 : $ tableRange [0 ][1 ];
115
- $ this ->totalsRow = ($ this -> table ->getShowTotalsRow ()) ? (int ) $ tableRange [1 ][1 ] : null ;
116
- $ this ->lastDataRow = ($ this -> table ->getShowTotalsRow ()) ? (int ) $ tableRange [1 ][1 ] - 1 : $ tableRange [1 ][1 ];
111
+ $ this ->headersRow = ($ table ->getShowHeaderRow ()) ? (int ) $ tableRange [0 ][1 ] : null ;
112
+ $ this ->firstDataRow = ($ table ->getShowHeaderRow ()) ? (int ) $ tableRange [0 ][1 ] + 1 : $ tableRange [0 ][1 ];
113
+ $ this ->totalsRow = ($ table ->getShowTotalsRow ()) ? (int ) $ tableRange [1 ][1 ] : null ;
114
+ $ this ->lastDataRow = ($ table ->getShowTotalsRow ()) ? (int ) $ tableRange [1 ][1 ] - 1 : $ tableRange [1 ][1 ];
117
115
118
116
$ this ->columns = $ this ->getColumns ($ cell , $ tableRange );
119
117
}
@@ -180,16 +178,18 @@ private function getRowReference(Cell $cell): string
180
178
foreach ($ this ->columns as $ columnId => $ columnName ) {
181
179
$ columnName = str_replace ("\u{a0}" , ' ' , $ columnName );
182
180
$ cellReference = $ columnId . $ cell ->getRow ();
181
+ $ pattern1 = '/\[ ' . preg_quote ($ columnName ) . '\]/miu ' ;
182
+ $ pattern2 = '/@ ' . preg_quote ($ columnName ) . '/miu ' ;
183
183
/** @var string $reference */
184
- if (stripos ( $ reference , ' [ ' . $ columnName . ' ] ' ) !== false ) {
185
- $ reference = preg_replace (' /\[ ' . preg_quote ( $ columnName ) . ' \]/miu ' , $ cellReference , $ reference );
186
- } elseif (stripos ( $ reference , $ columnName ) !== false ) {
187
- $ 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 );
188
188
}
189
189
}
190
190
191
191
/** @var string $reference */
192
- return $ this ->validateParsedReference (trim ($ reference , '[]@ ' ));
192
+ return $ this ->validateParsedReference (trim ($ reference , '[]@, ' ));
193
193
}
194
194
195
195
/**
@@ -202,43 +202,10 @@ private function getColumnReference(): string
202
202
$ startRow = ($ this ->totalsRow === null ) ? $ this ->lastDataRow : $ this ->totalsRow ;
203
203
$ endRow = ($ this ->headersRow === null ) ? $ this ->firstDataRow : $ this ->headersRow ;
204
204
205
- $ rowsSelected = false ;
206
- foreach (self ::ITEM_SPECIFIER_ROWS_SET as $ rowReference ) {
207
- /** @var string $reference */
208
- if (stripos ($ reference , '[ ' . $ rowReference . '] ' ) !== false ) {
209
- $ rowsSelected = true ;
210
- $ startRow = min ($ startRow , $ this ->getMinimumRow ($ rowReference ));
211
- $ endRow = max ($ endRow , $ this ->getMaximumRow ($ rowReference ));
212
- $ reference = preg_replace ('/\[ ' . $ rowReference . '\],/mui ' , '' , $ reference );
213
- }
214
- }
215
- if ($ rowsSelected === false ) {
216
- // If there isn't any Special Item Identifier specified, then the selection defaults to data rows only.
217
- $ startRow = $ this ->firstDataRow ;
218
- $ endRow = $ this ->lastDataRow ;
219
- }
205
+ [$ startRow , $ endRow ] = $ this ->getRowsForColumnReference ($ reference , $ startRow , $ endRow );
206
+ $ reference = $ this ->getColumnsForColumnReference ($ reference , $ startRow , $ endRow );
220
207
221
- $ columnsSelected = false ;
222
- foreach ($ this ->columns as $ columnId => $ columnName ) {
223
- $ columnName = str_replace ("\u{a0}" , ' ' , $ columnName );
224
- $ cellFrom = "{$ columnId }{$ startRow }" ;
225
- $ cellTo = "{$ columnId }{$ endRow }" ;
226
- $ cellReference = ($ cellFrom === $ cellTo ) ? $ cellFrom : "{$ cellFrom }: {$ cellTo }" ;
227
- /** @var string $reference */
228
- if (stripos ($ reference , '[ ' . $ columnName . '] ' ) !== false ) {
229
- $ columnsSelected = true ;
230
- $ reference = preg_replace ('/\[ ' . preg_quote ($ columnName ) . '\]/miu ' , $ cellReference , $ reference );
231
- } elseif (stripos ($ reference , $ columnName ) !== false ) {
232
- $ reference = preg_replace ('/@ ' . preg_quote ($ columnName ) . '/miu ' , $ cellReference , $ reference );
233
- $ columnsSelected = true ;
234
- }
235
- }
236
- if ($ columnsSelected === false ) {
237
- return $ this ->fullData ($ startRow , $ endRow );
238
- }
239
-
240
- /** @var string $reference */
241
- $ reference = trim ($ reference , '[]@ ' );
208
+ $ reference = trim ($ reference , '[]@, ' );
242
209
if (substr_count ($ reference , ': ' ) > 1 ) {
243
210
$ cells = explode (': ' , $ reference );
244
211
$ firstCell = array_shift ($ cells );
@@ -284,6 +251,8 @@ private function getMinimumRow(string $reference): int
284
251
case self ::ITEM_SPECIFIER_TOTALS :
285
252
return $ this ->totalsRow ?? $ this ->lastDataRow ;
286
253
}
254
+
255
+ return $ this ->headersRow ?? $ this ->firstDataRow ;
287
256
}
288
257
289
258
private function getMaximumRow (string $ reference ): int
@@ -297,10 +266,59 @@ private function getMaximumRow(string $reference): int
297
266
case self ::ITEM_SPECIFIER_TOTALS :
298
267
return $ this ->totalsRow ?? $ this ->lastDataRow ;
299
268
}
269
+
270
+ return $ this ->totalsRow ?? $ this ->lastDataRow ;
300
271
}
301
272
302
273
public function value (): string
303
274
{
304
275
return $ this ->value ;
305
276
}
277
+
278
+ /**
279
+ * @return array<int, int>
280
+ */
281
+ private function getRowsForColumnReference (string &$ reference , int $ startRow , int $ endRow ): array
282
+ {
283
+ $ rowsSelected = false ;
284
+ foreach (self ::ITEM_SPECIFIER_ROWS_SET as $ rowReference ) {
285
+ $ pattern = '/\[ ' . $ rowReference . '\]/mui ' ;
286
+ /** @var string $reference */
287
+ if (preg_match ($ pattern , $ reference ) === 1 ) {
288
+ $ rowsSelected = true ;
289
+ $ startRow = min ($ startRow , $ this ->getMinimumRow ($ rowReference ));
290
+ $ endRow = max ($ endRow , $ this ->getMaximumRow ($ rowReference ));
291
+ $ reference = preg_replace ($ pattern , '' , $ reference );
292
+ }
293
+ }
294
+ if ($ rowsSelected === false ) {
295
+ // If there isn't any Special Item Identifier specified, then the selection defaults to data rows only.
296
+ $ startRow = $ this ->firstDataRow ;
297
+ $ endRow = $ this ->lastDataRow ;
298
+ }
299
+
300
+ return [$ startRow , $ endRow ];
301
+ }
302
+
303
+ private function getColumnsForColumnReference (string $ reference , int $ startRow , int $ endRow ): string
304
+ {
305
+ $ columnsSelected = false ;
306
+ foreach ($ this ->columns as $ columnId => $ columnName ) {
307
+ $ columnName = str_replace ("\u{a0}" , ' ' , $ columnName );
308
+ $ cellFrom = "{$ columnId }{$ startRow }" ;
309
+ $ cellTo = "{$ columnId }{$ endRow }" ;
310
+ $ cellReference = ($ cellFrom === $ cellTo ) ? $ cellFrom : "{$ cellFrom }: {$ cellTo }" ;
311
+ $ pattern = '/\[ ' . preg_quote ($ columnName ) . '\]/mui ' ;
312
+ if (preg_match ($ pattern , $ reference ) === 1 ) {
313
+ $ columnsSelected = true ;
314
+ $ reference = preg_replace ($ pattern , $ cellReference , $ reference );
315
+ }
316
+ /** @var string $reference */
317
+ }
318
+ if ($ columnsSelected === false ) {
319
+ return $ this ->fullData ($ startRow , $ endRow );
320
+ }
321
+
322
+ return $ reference ;
323
+ }
306
324
}
0 commit comments