Skip to content

Commit ebb04a8

Browse files
committed
More Phpstan Level 10 Prep - Writers
1 parent fb2cfed commit ebb04a8

31 files changed

+317
-125
lines changed

phpstan.neon.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ parameters:
2828
# Accept a bit anything for assert methods
2929
- '~^Parameter \#2 .* of static method PHPUnit\\Framework\\Assert\:\:assert\w+\(\) expects .*, .* given\.$~'
3030
#- '~Method .*rovider.* return type has no value type specified in iterable type array\.$~'
31+
#- '~Method .*rovider.* should return array but returns mixed\.$~'
3132
- identifier: missingType.iterableValue

src/PhpSpreadsheet/Cell/Coordinate.php

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PhpOffice\PhpSpreadsheet\Cell;
44

55
use PhpOffice\PhpSpreadsheet\Exception;
6+
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
67
use PhpOffice\PhpSpreadsheet\Worksheet\Validations;
78
use 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
{

src/PhpSpreadsheet/Chart/Chart.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ public function setBottomRightPosition(string $cellAddress = '', ?int $xOffset =
490490
/**
491491
* Get the bottom right position of the chart.
492492
*
493-
* @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell
493+
* @return array{cell: string, xOffset: int, yOffset:int} an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell
494494
*/
495495
public function getBottomRightPosition(): array
496496
{

src/PhpSpreadsheet/Chart/PlotArea.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class PlotArea
1717
* First is position in %.
1818
* Second is ChartColor.
1919
*
20-
* @var array[]
20+
* @var array<array{float, ChartColor}>
2121
*/
2222
private array $gradientFillStops = [];
2323

@@ -126,6 +126,7 @@ public function getNoFill(): bool
126126
return $this->noFill;
127127
}
128128

129+
/** @param array<array{float, ChartColor}> $gradientFillStops */
129130
public function setGradientFillProperties(array $gradientFillStops, ?float $gradientFillAngle): self
130131
{
131132
$this->gradientFillStops = $gradientFillStops;
@@ -144,6 +145,8 @@ public function getGradientFillAngle(): ?float
144145

145146
/**
146147
* Get gradientFillStops.
148+
*
149+
* @return array<array{float, ChartColor}>
147150
*/
148151
public function getGradientFillStops(): array
149152
{

src/PhpSpreadsheet/Chart/Title.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ public function __construct(array|RichText|string $caption = '', ?Layout $layout
4646

4747
/**
4848
* Get caption.
49+
*
50+
* @return array<RichText|string>|RichText|string
4951
*/
5052
public function getCaption(): array|RichText|string
5153
{

src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,8 @@ protected function loadSpreadsheetFromFile2(string $filename, Xls $xls): Spreads
628628
if (count($coordinateStrings) == 2) {
629629
[$firstColumn, $firstRow] = Coordinate::coordinateFromString($coordinateStrings[0]);
630630
[$lastColumn, $lastRow] = Coordinate::coordinateFromString($coordinateStrings[1]);
631+
$firstRow = (int) $firstRow;
632+
$lastRow = (int) $lastRow;
631633

632634
if ($firstColumn == 'A' && $lastColumn == 'IV') {
633635
// then we have repeating rows

src/PhpSpreadsheet/Reader/Xlsx.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1751,7 +1751,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet
17511751
$docSheet->getPageSetup()->setColumnsToRepeatAtLeft([$matches[1], $matches[2]]);
17521752
} elseif (preg_match('/!?(\d+)\:(\d+)$/', $range, $matches)) {
17531753
// check for repeating rows, e.g. '1:1' or '1:5'
1754-
$docSheet->getPageSetup()->setRowsToRepeatAtTop([$matches[1], $matches[2]]);
1754+
$docSheet->getPageSetup()->setRowsToRepeatAtTop([(int) $matches[1], (int) $matches[2]]);
17551755
}
17561756
}
17571757

src/PhpSpreadsheet/Worksheet/PageSetup.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,14 +208,14 @@ class PageSetup
208208
/**
209209
* Columns to repeat at left.
210210
*
211-
* @var array Containing start column and end column, empty array if option unset
211+
* @var array{string, string} Containing start column and end column, empty array if option unset
212212
*/
213213
private array $columnsToRepeatAtLeft = ['', ''];
214214

215215
/**
216216
* Rows to repeat at top.
217217
*
218-
* @var array Containing start row number and end row number, empty array if option unset
218+
* @var int[] Containing start row number and end row number, empty array if option unset
219219
*/
220220
private array $rowsToRepeatAtTop = [0, 0];
221221

@@ -443,7 +443,7 @@ public function isColumnsToRepeatAtLeftSet(): bool
443443
/**
444444
* Get Columns to repeat at left.
445445
*
446-
* @return array Containing start column and end column, empty array if option unset
446+
* @return array{string, string} Containing start column and end column, empty array if option unset
447447
*/
448448
public function getColumnsToRepeatAtLeft(): array
449449
{
@@ -453,7 +453,7 @@ public function getColumnsToRepeatAtLeft(): array
453453
/**
454454
* Set Columns to repeat at left.
455455
*
456-
* @param array $columnsToRepeatAtLeft Containing start column and end column, empty array if option unset
456+
* @param array{string, string} $columnsToRepeatAtLeft Containing start column and end column, empty array if option unset
457457
*
458458
* @return $this
459459
*/
@@ -496,7 +496,7 @@ public function isRowsToRepeatAtTopSet(): bool
496496
/**
497497
* Get Rows to repeat at top.
498498
*
499-
* @return array Containing start column and end column, empty array if option unset
499+
* @return int[] Containing start column and end column, empty array if option unset
500500
*/
501501
public function getRowsToRepeatAtTop(): array
502502
{
@@ -506,7 +506,7 @@ public function getRowsToRepeatAtTop(): array
506506
/**
507507
* Set Rows to repeat at top.
508508
*
509-
* @param array $rowsToRepeatAtTop Containing start column and end column, empty array if option unset
509+
* @param int[] $rowsToRepeatAtTop Containing start column and end column, empty array if option unset
510510
*
511511
* @return $this
512512
*/

src/PhpSpreadsheet/Writer/Csv.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ private static function elementToString(mixed $element): string
289289
* Write line to CSV file.
290290
*
291291
* @param resource $fileHandle PHP filehandle
292-
* @param array $values Array containing values in a row
292+
* @param mixed[] $values Array containing values in a row
293293
*/
294294
private function writeLine($fileHandle, array $values): void
295295
{

0 commit comments

Comments
 (0)