diff --git a/composer.lock b/composer.lock index 43c4aeaef..7140b853f 100644 --- a/composer.lock +++ b/composer.lock @@ -1803,16 +1803,16 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.21", + "version": "2.1.23", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "1ccf445757458c06a04eb3f803603cb118fe5fa6" + "reference": "a34502adbbd5c2366b5a97679848a5ace4f6f2f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/1ccf445757458c06a04eb3f803603cb118fe5fa6", - "reference": "1ccf445757458c06a04eb3f803603cb118fe5fa6", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a34502adbbd5c2366b5a97679848a5ace4f6f2f5", + "reference": "a34502adbbd5c2366b5a97679848a5ace4f6f2f5", "shasum": "" }, "require": { @@ -1857,7 +1857,7 @@ "type": "github" } ], - "time": "2025-07-28T19:35:08+00:00" + "time": "2025-09-10T11:42:22+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", @@ -5664,7 +5664,7 @@ "ext-zip": "*", "ext-zlib": "*" }, - "platform-dev": [], + "platform-dev": {}, "platform-overrides": { "php": "8.1.99" }, diff --git a/infra/LocaleGenerator.php b/infra/LocaleGenerator.php index 422c0c97f..d99eb8193 100644 --- a/infra/LocaleGenerator.php +++ b/infra/LocaleGenerator.php @@ -327,7 +327,7 @@ class LocaleGenerator foreach ($cells as $cell) { if ($cell->getValue() != '') { $this->log($cell->getRow() . ' -> ' . $cell->getValueString()); - $this->errorCodeMap[$cell->getValue()] = $cell->getRow(); + $this->errorCodeMap[$cell->getValueString()] = $cell->getRow(); } } } @@ -345,7 +345,7 @@ class LocaleGenerator if ($this->isFunctionCategoryEntry($cell)) { if (!empty($cell->getValue())) { $this->log('CATEGORY: ' . $cell->getValueString()); - $this->functionNameMap[$cell->getValue()] = $cell->getRow(); + $this->functionNameMap[$cell->getValueString()] = $cell->getRow(); } continue; @@ -356,7 +356,7 @@ class LocaleGenerator $this->functionNameMap[($cell->getValue() ? 'TRUE' : 'FALSE')] = $cell->getRow(); } else { $this->log($cell->getRow() . ' -> ' . $cell->getValueString()); - $this->functionNameMap[$cell->getValue()] = $cell->getRow(); + $this->functionNameMap[$cell->getValueString()] = $cell->getRow(); } } } diff --git a/samples/Wizards/NumberFormat/Currency.php b/samples/Wizards/NumberFormat/Currency.php index 1e1e53cc4..7484d012f 100644 --- a/samples/Wizards/NumberFormat/Currency.php +++ b/samples/Wizards/NumberFormat/Currency.php @@ -104,7 +104,7 @@ if (isset($_POST['submit'])) { $helper->log('Unrecognized currency symbol'); } else { try { - $negative = $negatives[$_POST['negative']] ?? CurrencyNegative::minus; + $negative = $negatives[$_POST['negative']] ?? CurrencyNegative::minus; //* @phpstan-ignore-line $wizard = new Wizard\Currency($_POST['currency'], (int) $_POST['decimals'], isset($_POST['thousands']), (bool) $_POST['position']); $wizard->setNegative($negative); $mask = $wizard->format(); @@ -118,7 +118,7 @@ if (isset($_POST['submit'])) { . ', Wizard\Currency::' . (((bool) $_POST['position']) ? 'LEADING_SYMBOL' : 'TRAILING_SYMBOL') . ');' ); - $helper->log('$wizard->setNegative(' . $negativesString[$_POST['negative']] . ');'); + $helper->log('$wizard->setNegative(' . $negativesString[$_POST['negative']] . ');'); //* @phpstan-ignore-line $helper->log('$mask = $wizard->format();'); $helper->log('
echo (string) $mask;'); $helper->log('
Mask:
'); diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 2e00977df..a210c88cd 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -1699,7 +1699,7 @@ class Calculation extends CalculationLocale return $this->raiseFormulaError($e->getMessage(), $e->getCode(), $e); } } - } elseif (!is_numeric($token) && !is_object($token) && isset($token, self::BINARY_OPERATORS[$token])) { + } elseif (!is_numeric($token) && !is_object($token) && isset($token, self::BINARY_OPERATORS[$token])) { //* @phpstan-ignore-line // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack // We must have two operands, error if we don't $operand2Data = $stack->pop(); @@ -2879,6 +2879,7 @@ class Calculation extends CalculationLocale if ($stack->count() > 0) { $o2 = $stack->last(); if ($o2) { + /** @var array{value: string} $o2 */ if (isset(self::CALCULATION_OPERATORS[$o2['value']])) { $retVal = (self::OPERATOR_PRECEDENCE[$opCharacter] ?? 0) <= self::OPERATOR_PRECEDENCE[$o2['value']]; } diff --git a/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentProcessor.php b/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentProcessor.php index 7004d0877..687ab1b46 100644 --- a/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentProcessor.php +++ b/src/PhpSpreadsheet/Calculation/Engine/ArrayArgumentProcessor.php @@ -102,7 +102,7 @@ class ArrayArgumentProcessor } /** - * @param mixed[] $matrixIndexes + * @param array $matrixIndexes * * @return mixed[] */ diff --git a/src/PhpSpreadsheet/Calculation/Engine/CyclicReferenceStack.php b/src/PhpSpreadsheet/Calculation/Engine/CyclicReferenceStack.php index f4806b477..c50fad654 100644 --- a/src/PhpSpreadsheet/Calculation/Engine/CyclicReferenceStack.php +++ b/src/PhpSpreadsheet/Calculation/Engine/CyclicReferenceStack.php @@ -21,8 +21,10 @@ class CyclicReferenceStack /** * Push a new entry onto the stack. + * + * @param int|string $value The value to test */ - public function push(mixed $value): void + public function push($value): void { $this->stack[$value] = $value; } @@ -38,9 +40,9 @@ class CyclicReferenceStack /** * Test to see if a specified entry exists on the stack. * - * @param mixed $value The value to test + * @param int|string $value The value to test */ - public function onStack(mixed $value): bool + public function onStack($value): bool { return isset($this->stack[$value]); } diff --git a/src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php b/src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php index 20cdd0697..287e841ca 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php @@ -135,14 +135,14 @@ class Matrix return self::extractRowValue($matrix, $rowKeys, $rowNum); } - $columnNum = $columnKeys[--$columnNum]; + $columnNum = $columnKeys[--$columnNum]; //* @phpstan-ignore-line if ($rowNum === 0) { return array_map( fn ($value): array => [$value], array_column($matrix, $columnNum) ); } - $rowNum = $rowKeys[--$rowNum]; + $rowNum = $rowKeys[--$rowNum]; //* @phpstan-ignore-line /** @var mixed[][] $matrix */ return $matrix[$rowNum][$columnNum]; @@ -159,7 +159,7 @@ class Matrix } $rowNum = $rowKeys[--$rowNum]; - $row = $matrix[$rowNum]; + $row = $matrix[$rowNum]; //* @phpstan-ignore-line if (is_array($row)) { return [$rowNum => $row]; } diff --git a/src/PhpSpreadsheet/Calculation/LookupRef/Sort.php b/src/PhpSpreadsheet/Calculation/LookupRef/Sort.php index 352f5c8cd..78a30a4d7 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef/Sort.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef/Sort.php @@ -335,6 +335,7 @@ class Sort extends LookupRefValidations // Building a new array in the correct (sorted) order works; but may be memory heavy for larger arrays $sortedArray = []; foreach ($sortVector as $index) { + /** @var int|string $index */ $sortedArray[] = $sortArray[$index]; } diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php b/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php index ab58add3a..47c2c9800 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php @@ -23,7 +23,7 @@ class Arabic /** * Recursively calculate the arabic value of a roman numeral. * - * @param mixed[] $roman + * @param string[] $roman */ private static function calculateArabic(array $roman, int &$sum = 0, int $subtract = 0): int { diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Averages.php b/src/PhpSpreadsheet/Calculation/Statistical/Averages.php index 55eb2ae80..588098277 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Averages.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Averages.php @@ -163,7 +163,7 @@ class Averages extends AggregateBase sort($aArgs, SORT_NUMERIC); $valueCount = $valueCount / 2; if ($valueCount == floor($valueCount)) { - $returnValue = ($aArgs[$valueCount--] + $aArgs[$valueCount]) / 2; + $returnValue = ($aArgs[$valueCount--] + $aArgs[$valueCount]) / 2; //* @phpstan-ignore-line } else { $valueCount = (int) floor($valueCount); $returnValue = $aArgs[$valueCount]; @@ -243,7 +243,7 @@ class Averages extends AggregateBase $maxfreqkey = $key; $maxfreqdatum = $datum; } elseif ($freq == $maxfreq) { - if ($frequencyArray[$key]['index'] < $frequencyArray[$maxfreqkey]['index']) { + if ($frequencyArray[$key]['index'] < $frequencyArray[$maxfreqkey]['index']) { //* @phpstan-ignore-line $maxfreqkey = $key; $maxfreqdatum = $datum; } diff --git a/src/PhpSpreadsheet/Chart/DataSeriesValues.php b/src/PhpSpreadsheet/Chart/DataSeriesValues.php index 78a2bbec3..f37893220 100644 --- a/src/PhpSpreadsheet/Chart/DataSeriesValues.php +++ b/src/PhpSpreadsheet/Chart/DataSeriesValues.php @@ -333,16 +333,12 @@ class DataSeriesValues extends Properties * Method for validating hex color. * * @param string $color value for color - * - * @return bool true if validation was successful */ - private function validateColor(string $color): bool + private function validateColor(string $color): void { if (!preg_match('/^[a-f0-9]{6}$/i', $color)) { throw new Exception(sprintf('Invalid hex color for chart series (color: "%s")', $color)); } - - return true; } /** diff --git a/src/PhpSpreadsheet/Reader/Xls.php b/src/PhpSpreadsheet/Reader/Xls.php index 3c1ac4f16..29384ff0a 100644 --- a/src/PhpSpreadsheet/Reader/Xls.php +++ b/src/PhpSpreadsheet/Reader/Xls.php @@ -140,7 +140,7 @@ class Xls extends XlsBase /** * REF structures. Only applies to BIFF8. * - * @var mixed[][] + * @var array */ protected array $ref; @@ -2022,8 +2022,8 @@ class Xls extends XlsBase // repeated option flags // OpenOffice.org documentation 5.21 - $option = ord($recordData[$pos]); /** @var int $pos */ + $option = ord($recordData[$pos]); ++$pos; /** @var int $limitpos */ diff --git a/src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php b/src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php index dda8aadb1..76e4235b8 100644 --- a/src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php +++ b/src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php @@ -549,6 +549,7 @@ class LoadSpreadsheet extends Xls foreach ($xls->sharedFormulaParts as $cell => $baseCell) { /** @var int $row */ [$column, $row] = Coordinate::coordinateFromString($cell); + /** @var string $baseCell */ if ($xls->getReadFilter()->readCell($column, $row, $xls->phpSheet->getTitle())) { /** @var string */ $temp = $xls->sharedFormulas[$baseCell]; diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index c7c171da2..f8a0b1132 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -1079,7 +1079,8 @@ class Xlsx extends BaseReader $childNode = $node->addChild('formula1'); if ($childNode !== null) { // null should never happen // see https://github.com/phpstan/phpstan/issues/8236 - $childNode[0] = (string) $item->formula1->children(Namespaces::DATA_VALIDATIONS2)->f; // @phpstan-ignore-line + // resolved with Phpstan 2.1.23 + $childNode[0] = (string) $item->formula1->children(Namespaces::DATA_VALIDATIONS2)->f; } } } diff --git a/src/PhpSpreadsheet/Reader/Xml/Style/Border.php b/src/PhpSpreadsheet/Reader/Xml/Style/Border.php index 349eaab60..8a5407d02 100644 --- a/src/PhpSpreadsheet/Reader/Xml/Style/Border.php +++ b/src/PhpSpreadsheet/Reader/Xml/Style/Border.php @@ -85,6 +85,7 @@ class Border extends StyleBase } } + /** @var int|string $borderPosition */ if ($borderPosition) { $style['borders'][$borderPosition] = $thisBorder; } elseif ($diagonalDirection) { @@ -99,6 +100,7 @@ class Border extends StyleBase /** @return mixed[] */ protected function parsePosition(string $borderStyleValue, string $diagonalDirection): array { + // TODO diagonalDirection seems to return int not string $borderStyleValue = strtolower($borderStyleValue); if (in_array($borderStyleValue, self::BORDER_POSITIONS)) { diff --git a/src/PhpSpreadsheet/Reader/Xml/Style/NumberFormat.php b/src/PhpSpreadsheet/Reader/Xml/Style/NumberFormat.php index e6fffe176..1ca825a54 100644 --- a/src/PhpSpreadsheet/Reader/Xml/Style/NumberFormat.php +++ b/src/PhpSpreadsheet/Reader/Xml/Style/NumberFormat.php @@ -15,7 +15,7 @@ class NumberFormat extends StyleBase $toFormats = ['-', ' ']; foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) { - $styleAttributeValue = str_replace($fromFormats, $toFormats, $styleAttributeValue); + $styleAttributeValue = str_replace($fromFormats, $toFormats, (string) $styleAttributeValue); switch ($styleAttributeValue) { case 'Short Date': diff --git a/src/PhpSpreadsheet/Style/Style.php b/src/PhpSpreadsheet/Style/Style.php index 089c9cccb..feac1cb95 100644 --- a/src/PhpSpreadsheet/Style/Style.php +++ b/src/PhpSpreadsheet/Style/Style.php @@ -400,6 +400,7 @@ class Style extends Supervisor } // Find existing style by hash. + /** @var string $styleHash */ $existingStyle = self::$cachedStyles['styleByHash'][$styleHash] ?? null; if (!$existingStyle) { diff --git a/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php b/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php index 1ee2eff54..441204ca6 100644 --- a/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php +++ b/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php @@ -274,7 +274,8 @@ class Rule throw new PhpSpreadsheetException('Invalid rule value for column AutoFilter Rule.'); } // Set the dateTime grouping that we've anticipated - $this->setGrouping(self::DATE_TIME_GROUPS[$grouping]); + // I have no idea what Phpstan is complaining about below + $this->setGrouping(self::DATE_TIME_GROUPS[$grouping]); // @phpstan-ignore-line } $this->value = $value; diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php index cd7c89a3d..7021d8292 100644 --- a/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -3005,6 +3005,7 @@ class Worksheet // Loop through rows foreach ($this->rangeToArrayYieldRows($range, $nullValue, $calculateFormulas, $formatData, $returnCellRef, $ignoreHidden, $reduceArrays) as $rowRef => $rowArray) { + /** @var int $rowRef */ $returnValue[$rowRef] = $rowArray; } @@ -3040,6 +3041,7 @@ class Worksheet foreach ($parts as $part) { // Loop through rows foreach ($this->rangeToArrayYieldRows($part, $nullValue, $calculateFormulas, $formatData, $returnCellRef, $ignoreHidden, $reduceArrays) as $rowRef => $rowArray) { + /** @var int $rowRef */ $returnValue[$rowRef] = $rowArray; } } diff --git a/src/PhpSpreadsheet/Writer/Html.php b/src/PhpSpreadsheet/Writer/Html.php index 8ebc4718e..27849bf37 100644 --- a/src/PhpSpreadsheet/Writer/Html.php +++ b/src/PhpSpreadsheet/Writer/Html.php @@ -2093,6 +2093,7 @@ class Html extends BaseWriter // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1 if (isset($this->isSpannedRow[$sheetIndex])) { foreach ($this->isSpannedRow[$sheetIndex] as $rowIndex) { + /** @var int $rowIndex */ $adjustedBaseCells = []; $c = -1; $e = $countColumns - 1; diff --git a/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php b/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php index 09ce162ca..608eadaf0 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/StringTable.php @@ -35,6 +35,7 @@ class StringTable extends WriterPart foreach ($worksheet->getCellCollection()->getCoordinates() as $coordinate) { /** @var Cell $cell */ $cell = $worksheet->getCellCollection()->get($coordinate); + /** @var null|int|RichText|string */ $cellValue = $cell->getValue(); if ( !is_object($cellValue) diff --git a/tests/PhpSpreadsheetTests/Issue1449Test.php b/tests/PhpSpreadsheetTests/Issue1449Test.php index d00b10f6e..211fe52fe 100644 --- a/tests/PhpSpreadsheetTests/Issue1449Test.php +++ b/tests/PhpSpreadsheetTests/Issue1449Test.php @@ -7,8 +7,7 @@ use PHPUnit\Framework\TestCase; class Issue1449Test extends TestCase { - /** @var bool */ - private $skipTests = true; + protected bool $skipTests = true; public function testDeleteColumns(): void { diff --git a/tests/PhpSpreadsheetTests/Reader/Gnumeric/GnumericStylesTest.php b/tests/PhpSpreadsheetTests/Reader/Gnumeric/GnumericStylesTest.php index 429a2ee86..19392acbf 100644 --- a/tests/PhpSpreadsheetTests/Reader/Gnumeric/GnumericStylesTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Gnumeric/GnumericStylesTest.php @@ -33,7 +33,6 @@ class GnumericStylesTest extends TestCase foreach ($expected as $key => $val) { $covered[$key] = 0; } - /** @var mixed[][] */ $tests = $this->providerBorderStyle(); foreach ($tests as $test) { $covered[$test[0]] = 1; @@ -88,7 +87,6 @@ class GnumericStylesTest extends TestCase foreach ($expected as $key => $val) { $covered[$key] = 0; } - /** @var mixed[][] */ $tests = $this->providerHorizontal(); foreach ($tests as $test) { $covered[$test[0]] = 1; @@ -117,7 +115,6 @@ class GnumericStylesTest extends TestCase foreach ($expected as $key => $val) { $covered[$key] = 0; } - /** @var mixed[][] */ $tests = $this->providerUnderline(); foreach ($tests as $test) { $covered[$test[0]] = 1; @@ -185,6 +182,7 @@ class GnumericStylesTest extends TestCase } } + /** @return array */ public static function providerBorderStyle(): array { return [ @@ -205,7 +203,7 @@ class GnumericStylesTest extends TestCase ]; } - /** @return string[][] */ + /** @return array */ public static function providerFillType(): array { return [ @@ -230,6 +228,7 @@ class GnumericStylesTest extends TestCase ]; } + /** @return array */ public static function providerHorizontal(): array { return [ @@ -243,6 +242,7 @@ class GnumericStylesTest extends TestCase ]; } + /** @return array */ public static function providerUnderline(): array { return [