33namespace PhpOffice \PhpSpreadsheet \Cell ;
44
55use PhpOffice \PhpSpreadsheet \Exception ;
6+ use PhpOffice \PhpSpreadsheet \Shared \StringHelper ;
67use PhpOffice \PhpSpreadsheet \Worksheet \Validations ;
78use PhpOffice \PhpSpreadsheet \Worksheet \Worksheet ;
89
@@ -162,7 +163,7 @@ public static function splitRange(string $range): array
162163 /**
163164 * Build range from coordinate strings.
164165 *
165- * @param array $range Array containing one or more arrays containing one or two coordinate strings
166+ * @param mixed[] $range Array containing one or more arrays containing one or two coordinate strings
166167 *
167168 * @return string String representation of $pRange
168169 */
@@ -187,7 +188,7 @@ public static function buildRange(array $range): string
187188 *
188189 * @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3)
189190 *
190- * @return array Range coordinates [Start Cell, End Cell]
191+ * @return array{array{int, int}, array{int, int}} Range coordinates [Start Cell, End Cell]
191192 * where Start Cell and End Cell are arrays (Column Number, Row Number)
192193 */
193194 public static function rangeBoundaries (string $ range ): array
@@ -224,6 +225,8 @@ public static function rangeBoundaries(string $range): array
224225 // Translate column into index
225226 $ rangeStart [0 ] = self ::columnIndexFromString ($ rangeStart [0 ]);
226227 $ rangeEnd [0 ] = self ::columnIndexFromString ($ rangeEnd [0 ]);
228+ $ rangeStart [1 ] = (int ) $ rangeStart [1 ];
229+ $ rangeEnd [1 ] = (int ) $ rangeEnd [1 ];
227230
228231 return [$ rangeStart , $ rangeEnd ];
229232 }
@@ -233,7 +236,7 @@ public static function rangeBoundaries(string $range): array
233236 *
234237 * @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3)
235238 *
236- * @return array Range dimension (width, height)
239+ * @return array{int, int} Range dimension (width, height)
237240 */
238241 public static function rangeDimension (string $ range ): array
239242 {
@@ -248,7 +251,7 @@ public static function rangeDimension(string $range): array
248251 *
249252 * @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3)
250253 *
251- * @return array Range coordinates [Start Cell, End Cell]
254+ * @return array{array{string, int}, array{string, int}} Range coordinates [Start Cell, End Cell]
252255 * where Start Cell and End Cell are arrays [Column ID, Row Number]
253256 */
254257 public static function getRangeBoundaries (string $ range ): array
@@ -267,7 +270,7 @@ public static function getRangeBoundaries(string $range): array
267270 *
268271 * @param string $reference Coordinate or Range (e.g. A1:A1, B2, B:C, 2:3)
269272 *
270- * @return array reference data
273+ * @return array{type: string, firstCoordinate?: string, secondCoordinate?: string, coordinate?: string, worksheet?: string, localReference?: string} reference data
271274 */
272275 private static function validateReferenceAndGetData ($ reference ): array
273276 {
@@ -331,7 +334,13 @@ public static function coordinateIsInsideRange(string $range, string $coordinate
331334 }
332335 }
333336
337+ if (!isset ($ rangeData ['localReference ' ])) {
338+ return false ;
339+ }
334340 $ boundaries = self ::rangeBoundaries ($ rangeData ['localReference ' ]);
341+ if (!isset ($ coordinateData ['localReference ' ])) {
342+ return false ;
343+ }
335344 $ coordinates = self ::indexesFromString ($ coordinateData ['localReference ' ]);
336345
337346 $ columnIsInside = $ boundaries [0 ][0 ] <= $ coordinates [0 ] && $ coordinates [0 ] <= $ boundaries [1 ][0 ];
@@ -358,6 +367,7 @@ public static function columnIndexFromString(?string $columnAddress): int
358367 // Using a lookup cache adds a slight memory overhead, but boosts speed
359368 // caching using a static within the method is faster than a class static,
360369 // though it's additional memory overhead
370+ /** @var int[] */
361371 static $ indexCache = [];
362372 $ columnAddress = $ columnAddress ?? '' ;
363373
@@ -367,6 +377,7 @@ public static function columnIndexFromString(?string $columnAddress): int
367377 // It's surprising how costly the strtoupper() and ord() calls actually are, so we use a lookup array
368378 // rather than use ord() and make it case insensitive to get rid of the strtoupper() as well.
369379 // Because it's a static, there's no significant memory overhead either.
380+ /** @var array<string, int> */
370381 static $ columnLookup = [
371382 'A ' => 1 , 'B ' => 2 , 'C ' => 3 , 'D ' => 4 , 'E ' => 5 , 'F ' => 6 , 'G ' => 7 , 'H ' => 8 , 'I ' => 9 , 'J ' => 10 ,
372383 'K ' => 11 , 'L ' => 12 , 'M ' => 13 , 'N ' => 14 , 'O ' => 15 , 'P ' => 16 , 'Q ' => 17 , 'R ' => 18 , 'S ' => 19 ,
@@ -402,23 +413,25 @@ public static function columnIndexFromString(?string $columnAddress): int
402413 );
403414 }
404415
416+ private const LOOKUP_CACHE = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ ' ;
417+
405418 /**
406419 * String from column index.
407420 *
408421 * @param int|numeric-string $columnIndex Column index (A = 1)
409422 */
410423 public static function stringFromColumnIndex (int |string $ columnIndex ): string
411424 {
425+ /** @var string[] */
412426 static $ indexCache = [];
413- static $ lookupCache = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ ' ;
414427
415428 if (!isset ($ indexCache [$ columnIndex ])) {
416429 $ indexValue = $ columnIndex ;
417430 $ base26 = '' ;
418431 do {
419432 $ characterValue = ($ indexValue % 26 ) ?: 26 ;
420433 $ indexValue = ($ indexValue - $ characterValue ) / 26 ;
421- $ base26 = $ lookupCache [$ characterValue ] . $ base26 ;
434+ $ base26 = self :: LOOKUP_CACHE [$ characterValue ] . $ base26 ;
422435 } while ($ indexValue > 0 );
423436 $ indexCache [$ columnIndex ] = $ base26 ;
424437 }
@@ -431,7 +444,7 @@ public static function stringFromColumnIndex(int|string $columnIndex): string
431444 *
432445 * @param string $cellRange Range: e.g. 'A1' or 'A1:C10' or 'A1:E10,A20:E25' or 'A1:E5 C3:G7' or 'A1:C1,A3:C3 B1:C3'
433446 *
434- * @return array Array containing single cell references
447+ * @return string[] Array containing single cell references
435448 */
436449 public static function extractAllCellReferencesInRange (string $ cellRange ): array
437450 {
@@ -452,23 +465,35 @@ public static function extractAllCellReferencesInRange(string $cellRange): array
452465
453466 $ cells = [];
454467 foreach ($ ranges as $ range ) {
468+ /** @var string $range */
455469 $ cells [] = self ::getReferencesForCellBlock ($ range );
456470 }
457471
472+ /** @var mixed[] */
458473 $ cells = self ::processRangeSetOperators ($ operators , $ cells );
459474
460475 if (empty ($ cells )) {
461476 return [];
462477 }
463478
464- $ cellList = array_merge (...$ cells );
479+ /** @var string[] */
480+ $ cellList = array_merge (...$ cells ); //* @phpstan-ignore-line
481+ // Unsure how to satisfy phpstan in line above
465482
466- return array_map (
467- fn ($ cellAddress ) => ($ worksheet !== '' ) ? "{$ quoted }{$ worksheet }{$ quoted }! {$ cellAddress }" : $ cellAddress ,
483+ $ retVal = array_map (
484+ fn (string $ cellAddress ) => ($ worksheet !== '' ) ? "{$ quoted }{$ worksheet }{$ quoted }! {$ cellAddress }" : $ cellAddress ,
468485 self ::sortCellReferenceArray ($ cellList )
469486 );
487+
488+ return $ retVal ;
470489 }
471490
491+ /**
492+ * @param mixed[] $operators
493+ * @param mixed[][] $cells
494+ *
495+ * @return mixed[]
496+ */
472497 private static function processRangeSetOperators (array $ operators , array $ cells ): array
473498 {
474499 $ operatorCount = count ($ operators );
@@ -489,6 +514,11 @@ private static function processRangeSetOperators(array $operators, array $cells)
489514 return $ cells ;
490515 }
491516
517+ /**
518+ * @param string[] $cellList
519+ *
520+ * @return string[]
521+ */
492522 private static function sortCellReferenceArray (array $ cellList ): array
493523 {
494524 // Sort the result by column and row
@@ -497,6 +527,7 @@ private static function sortCellReferenceArray(array $cellList): array
497527 $ column = '' ;
498528 $ row = 0 ;
499529 sscanf ($ coordinate , '%[A-Z]%d ' , $ column , $ row );
530+ /** @var int $row */
500531 $ key = (--$ row * 16384 ) + self ::columnIndexFromString ((string ) $ column );
501532 $ sortKeys [$ key ] = $ coordinate ;
502533 }
@@ -548,7 +579,7 @@ public static function resolveUnionAndIntersection(string $cellBlock, string $im
548579 *
549580 * @param string $cellBlock A cell range e.g. A4:B5
550581 *
551- * @return array All individual cells in that range
582+ * @return string[] All individual cells in that range
552583 */
553584 private static function getReferencesForCellBlock (string $ cellBlock ): array
554585 {
@@ -585,6 +616,8 @@ private static function getReferencesForCellBlock(string $cellBlock): array
585616
586617 // Loop cells
587618 while ($ currentColumnIndex < $ endColumnIndex ) {
619+ /** @var int $currentRow */
620+ /** @var int $endRow */
588621 while ($ currentRow <= $ endRow ) {
589622 $ returnValue [] = self ::stringFromColumnIndex ($ currentColumnIndex ) . $ currentRow ;
590623 ++$ currentRow ;
@@ -610,9 +643,9 @@ private static function getReferencesForCellBlock(string $cellBlock): array
610643 *
611644 * [ 'A1:A3' => 'x', 'A4' => 'y' ]
612645 *
613- * @param array $coordinateCollection associative array mapping coordinates to values
646+ * @param array<string, mixed> $coordinateCollection associative array mapping coordinates to values
614647 *
615- * @return array associative array mapping coordinate ranges to valuea
648+ * @return array<string, mixed> associative array mapping coordinate ranges to valuea
616649 */
617650 public static function mergeRangesInCollection (array $ coordinateCollection ): array
618651 {
@@ -628,7 +661,7 @@ public static function mergeRangesInCollection(array $coordinateCollection): arr
628661
629662 [$ column , $ row ] = self ::coordinateFromString ($ coord );
630663 $ row = (int ) (ltrim ($ row , '$ ' ));
631- $ hashCode = $ column . '- ' . ((is_object ($ value ) && method_exists ($ value , 'getHashCode ' )) ? $ value ->getHashCode () : $ value );
664+ $ hashCode = $ column . '- ' . StringHelper:: convertToString ((is_object ($ value ) && method_exists ($ value , 'getHashCode ' )) ? $ value ->getHashCode () : $ value );
632665
633666 if (!isset ($ hashedValues [$ hashCode ])) {
634667 $ hashedValues [$ hashCode ] = (object ) [
@@ -687,7 +720,7 @@ public static function mergeRangesInCollection(array $coordinateCollection): arr
687720 * Get the individual cell blocks from a range string, removing any $ characters.
688721 * then splitting by operators and returning an array with ranges and operators.
689722 *
690- * @return array []
723+ * @return mixed[] []
691724 */
692725 private static function getCellBlocksFromRangeString (string $ rangeString ): array
693726 {
0 commit comments