diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 692cccd4..f14b3ed5 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5190,11 +5190,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Shared/StringHelper.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:countCharacters\\(\\) should return int but returns int\\|false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/StringHelper.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:formatNumber\\(\\) should return string but returns array\\|string\\.$#" count: 1 @@ -6970,11 +6965,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php - - - message: "#^Parameter \\#1 \\$ascii of function chr expects int, float given\\.$#" - count: 3 - path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php - - message: "#^Parameter \\#1 \\$bitmap of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Worksheet\\:\\:processBitmap\\(\\) expects string, mixed given\\.$#" count: 1 @@ -7640,11 +7630,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - message: "#^Parameter \\#3 \\$namespace of method XMLWriter\\:\\:startElementNs\\(\\) expects string, null given\\.$#" - count: 8 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - message: "#^Parameter \\#3 \\$stringTable of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeSheetData\\(\\) expects array\\, array\\\\|null given\\.$#" count: 1 diff --git a/phpstan-conditional.php b/phpstan-conditional.php index a673d523..5501039b 100644 --- a/phpstan-conditional.php +++ b/phpstan-conditional.php @@ -3,7 +3,7 @@ $config = []; if (PHP_VERSION_ID < 80000) { - // Change of signature in PHP 8.0 + // GdImage not available before PHP8 $config['parameters']['ignoreErrors'][] = [ 'message' => '~^Method .* has invalid return type GdImage\.$~', 'path' => __DIR__ . '/src/PhpSpreadsheet/Shared/Drawing.php', @@ -34,6 +34,18 @@ if (PHP_VERSION_ID < 80000) { 'path' => __DIR__ . '/src/PhpSpreadsheet/Writer/Xls/Worksheet.php', 'count' => 1, ]; + // Erroneous analysis by Phpstan before PHP8 - 3rd parameter is nullable + $config['parameters']['ignoreErrors'][] = [ + 'message' => '#^Parameter \\#3 \\$namespace of method XMLWriter\\:\\:startElementNs\\(\\) expects string, null given\\.$#', + 'path' => __DIR__ . '/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php', + 'count' => 8, + ]; + // Erroneous analysis by Phpstan before PHP8 - mb_strlen does not return false + $config['parameters']['ignoreErrors'][] = [ + 'message' => '#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:countCharacters\\(\\) should return int but returns int\\|false\\.$#', + 'path' => __DIR__ . '/src/PhpSpreadsheet/Shared/StringHelper.php', + 'count' => 1, + ]; } return $config; diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Current.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Current.php index 7a70978e..d23ce37b 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Current.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Current.php @@ -27,9 +27,9 @@ class Current public static function today() { $dti = new DateTimeImmutable(); - $dateArray = date_parse($dti->format('c')); + $dateArray = Helpers::dateParse($dti->format('c')); - return is_array($dateArray) ? Helpers::returnIn3FormatsArray($dateArray, true) : Functions::VALUE(); + return Helpers::dateParseSucceeded($dateArray) ? Helpers::returnIn3FormatsArray($dateArray, true) : Functions::VALUE(); } /** @@ -52,8 +52,8 @@ class Current public static function now() { $dti = new DateTimeImmutable(); - $dateArray = date_parse($dti->format('c')); + $dateArray = Helpers::dateParse($dti->format('c')); - return is_array($dateArray) ? Helpers::returnIn3FormatsArray($dateArray) : Functions::VALUE(); + return Helpers::dateParseSucceeded($dateArray) ? Helpers::returnIn3FormatsArray($dateArray) : Functions::VALUE(); } } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php index d8e88a21..3b215506 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php @@ -92,13 +92,11 @@ class DateValue /** * Parse date. - * - * @return array|bool */ - private static function setUpArray(string $dateValue, DateTimeImmutable $dti) + private static function setUpArray(string $dateValue, DateTimeImmutable $dti): array { - $PHPDateArray = date_parse($dateValue); - if (($PHPDateArray === false) || ($PHPDateArray['error_count'] > 0)) { + $PHPDateArray = Helpers::dateParse($dateValue); + if (!Helpers::dateParseSucceeded($PHPDateArray)) { // If original count was 1, we've already returned. // If it was 2, we added another. // Therefore, neither of the first 2 stroks below can fail. @@ -106,9 +104,9 @@ class DateValue $testVal2 = strtok('- '); $testVal3 = strtok('- ') ?: $dti->format('Y'); Helpers::adjustYear((string) $testVal1, (string) $testVal2, $testVal3); - $PHPDateArray = date_parse($testVal1 . '-' . $testVal2 . '-' . $testVal3); - if (($PHPDateArray === false) || ($PHPDateArray['error_count'] > 0)) { - $PHPDateArray = date_parse($testVal2 . '-' . $testVal1 . '-' . $testVal3); + $PHPDateArray = Helpers::dateParse($testVal1 . '-' . $testVal2 . '-' . $testVal3); + if (!Helpers::dateParseSucceeded($PHPDateArray)) { + $PHPDateArray = Helpers::dateParse($testVal2 . '-' . $testVal1 . '-' . $testVal3); } } @@ -118,15 +116,13 @@ class DateValue /** * Final results. * - * @param array|bool $PHPDateArray - * * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag */ - private static function finalResults($PHPDateArray, DateTimeImmutable $dti, int $baseYear) + private static function finalResults(array $PHPDateArray, DateTimeImmutable $dti, int $baseYear) { $retValue = Functions::Value(); - if (is_array($PHPDateArray) && $PHPDateArray['error_count'] == 0) { + if (Helpers::dateParseSucceeded($PHPDateArray)) { // Execute function Helpers::replaceIfEmpty($PHPDateArray['year'], $dti->format('Y')); if ($PHPDateArray['year'] < $baseYear) { diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php index 9503401c..55ce13f1 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php @@ -282,4 +282,25 @@ class Helpers $PHPDateObject->modify($mod); } } + + public static function dateParse(string $string): array + { + return self::forceArray(date_parse($string)); + } + + public static function dateParseSucceeded(array $dateArray): bool + { + return $dateArray['error_count'] === 0; + } + + /** + * Despite documentation, date_parse probably never returns false. + * Just in case, this routine helps guarantee it. + * + * @param array|false $dateArray + */ + private static function forceArray($dateArray): array + { + return is_array($dateArray) ? $dateArray : ['error_count' => 1]; + } } diff --git a/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php b/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php index 2a294344..c9645e66 100644 --- a/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php +++ b/src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php @@ -40,11 +40,17 @@ class TimeValue $timeValue = implode(':', $arraySplit); } - $PHPDateArray = date_parse($timeValue); + $PHPDateArray = Helpers::dateParse($timeValue); $retValue = Functions::VALUE(); - if (($PHPDateArray !== false) && ($PHPDateArray['error_count'] == 0)) { + if (Helpers::dateParseSucceeded($PHPDateArray)) { + /** @var int */ + $hour = $PHPDateArray['hour']; + /** @var int */ + $minute = $PHPDateArray['minute']; + /** @var int */ + $second = $PHPDateArray['second']; // OpenOffice-specific code removed - it works just like Excel - $excelDateValue = SharedDateHelper::formattedPHPToExcel(1900, 1, 1, $PHPDateArray['hour'], $PHPDateArray['minute'], $PHPDateArray['second']) - 1; + $excelDateValue = SharedDateHelper::formattedPHPToExcel(1900, 1, 1, $hour, $minute, $second) - 1; $retType = Functions::getReturnDateType(); if ($retType === Functions::RETURNDATE_EXCEL) { diff --git a/src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php b/src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php index 9129dd32..1dd0bcd8 100644 --- a/src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php +++ b/src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php @@ -52,8 +52,10 @@ class NumberFormatter $number = floor($numberFloat / $divisor); $mask = substr_replace($mask, $blockValue, $offset, $size); } + /** @var string */ + $numberString = $number; if ($number > 0) { - $mask = substr_replace($mask, $number, $offset, 0); + $mask = substr_replace($mask, $numberString, $offset, 0); } $result = $mask; } diff --git a/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php b/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php index 19a3d1e2..91acbb7b 100644 --- a/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php +++ b/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php @@ -102,7 +102,7 @@ class MemoryDrawing extends BaseDrawing $transparent = imagecolortransparent($this->imageResource); if ($transparent >= 0) { $rgb = imagecolorsforindex($this->imageResource, $transparent); - if ($rgb === false) { + if (empty($rgb)) { throw new Exception('Could not get image colors'); } diff --git a/src/PhpSpreadsheet/Writer/Xls/Worksheet.php b/src/PhpSpreadsheet/Writer/Xls/Worksheet.php index 77ec5de9..2387ceb0 100644 --- a/src/PhpSpreadsheet/Writer/Xls/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xls/Worksheet.php @@ -2388,7 +2388,7 @@ class Worksheet extends BIFFwriter for ($i = 0; $i < $width; ++$i) { $color = imagecolorsforindex($image, imagecolorat($image, $i, $j)); foreach (['red', 'green', 'blue'] as $key) { - $color[$key] = $color[$key] + round((255 - $color[$key]) * $color['alpha'] / 127); + $color[$key] = $color[$key] + (int) round((255 - $color[$key]) * $color['alpha'] / 127); } $data .= chr($color['blue']) . chr($color['green']) . chr($color['red']); }