Skip to content

Commit b4cd42d

Browse files
authored
Merge pull request PHPOffice#4380 from oleibman/stanbleed06
Phpstan Bleeding Edge Last: Reader
2 parents 0e8d0bf + 8013034 commit b4cd42d

File tree

21 files changed

+215
-348
lines changed

21 files changed

+215
-348
lines changed

phpstan-baseline.neon

Lines changed: 0 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,2 @@
11
parameters:
22
ignoreErrors:
3-
-
4-
message: "#^Parameter \\#2 \\$contents of static method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\:\\:guessEncodingTestNoBom\\(\\) expects string, string\\|false given\\.$#"
5-
count: 1
6-
path: src/PhpSpreadsheet/Reader/Csv.php
7-
8-
-
9-
message: "#^Call to function is_array\\(\\) with non\\-empty\\-list\\<string\\> will always evaluate to true\\.$#"
10-
count: 1
11-
path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
12-
13-
-
14-
message: "#^Strict comparison using \\!\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\IReadFilter and null will always evaluate to true\\.$#"
15-
count: 1
16-
path: src/PhpSpreadsheet/Reader/Gnumeric.php
17-
18-
-
19-
message: "#^Strict comparison using \\!\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension and null will always evaluate to true\\.$#"
20-
count: 2
21-
path: src/PhpSpreadsheet/Reader/Gnumeric.php
22-
23-
-
24-
message: "#^Strict comparison using \\!\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension and null will always evaluate to true\\.$#"
25-
count: 2
26-
path: src/PhpSpreadsheet/Reader/Gnumeric.php
27-
28-
-
29-
message: "#^Strict comparison using \\!\\=\\= between SimpleXMLElement and null will always evaluate to true\\.$#"
30-
count: 1
31-
path: src/PhpSpreadsheet/Reader/Gnumeric.php
32-
33-
-
34-
message: "#^Strict comparison using \\!\\=\\= between SimpleXMLElement and null will always evaluate to true\\.$#"
35-
count: 1
36-
path: src/PhpSpreadsheet/Reader/Gnumeric/Properties.php
37-
38-
-
39-
message: "#^Call to function is_string\\(\\) with string will always evaluate to true\\.$#"
40-
count: 1
41-
path: src/PhpSpreadsheet/Reader/Html.php
42-
43-
-
44-
message: "#^Offset 0 on non\\-empty\\-list\\<string\\> in isset\\(\\) always exists and is not nullable\\.$#"
45-
count: 1
46-
path: src/PhpSpreadsheet/Reader/Html.php
47-
48-
-
49-
message: "#^Parameter \\#4 \\$column of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:processDomElement\\(\\) expects string, float\\|int\\|string given\\.$#"
50-
count: 1
51-
path: src/PhpSpreadsheet/Reader/Html.php
52-
53-
-
54-
message: "#^Parameter &\\$column by\\-ref type of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:processDomElementTable\\(\\) expects string, \\(float\\|int\\|string\\) given\\.$#"
55-
count: 1
56-
path: src/PhpSpreadsheet/Reader/Html.php
57-
58-
-
59-
message: "#^Parameter &\\$column by\\-ref type of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:processDomElementThTd\\(\\) expects string, \\(float\\|int\\) given\\.$#"
60-
count: 1
61-
path: src/PhpSpreadsheet/Reader/Html.php
62-
63-
-
64-
message: "#^Parameter &\\$column by\\-ref type of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:processDomElementThTd\\(\\) expects string, float\\|int\\|string given\\.$#"
65-
count: 2
66-
path: src/PhpSpreadsheet/Reader/Html.php
67-
68-
-
69-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\:\\:getXmlName\\(\\) is marked as impure but does not have any side effects\\.$#"
70-
count: 1
71-
path: src/PhpSpreadsheet/Reader/Ods.php
72-
73-
-
74-
message: "#^Strict comparison using \\!\\=\\= between DOMNodeList\\<DOMElement\\> and null will always evaluate to true\\.$#"
75-
count: 1
76-
path: src/PhpSpreadsheet/Reader/Ods.php
77-
78-
-
79-
message: "#^Strict comparison using \\!\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\IReadFilter and null will always evaluate to true\\.$#"
80-
count: 1
81-
path: src/PhpSpreadsheet/Reader/Ods.php
82-
83-
-
84-
message: "#^Strict comparison using \\!\\=\\= between string and null will always evaluate to true\\.$#"
85-
count: 1
86-
path: src/PhpSpreadsheet/Reader/Ods.php
87-
88-
-
89-
message: "#^Strict comparison using \\!\\=\\= between \\(float\\|int\\) and string will always evaluate to true\\.$#"
90-
count: 1
91-
path: src/PhpSpreadsheet/Reader/Slk.php
92-
93-
-
94-
message: "#^Strict comparison using \\!\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\IReadFilter and null will always evaluate to true\\.$#"
95-
count: 10
96-
path: src/PhpSpreadsheet/Reader/Xls.php
97-
98-
-
99-
message: "#^Strict comparison using \\!\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\IReadFilter and null will always evaluate to true\\.$#"
100-
count: 1
101-
path: src/PhpSpreadsheet/Reader/Xls/LoadSpreadsheet.php
102-
103-
-
104-
message: "#^Strict comparison using \\!\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\IReadFilter and null will always evaluate to true\\.$#"
105-
count: 1
106-
path: src/PhpSpreadsheet/Reader/Xlsx.php
107-
108-
-
109-
message: "#^Strict comparison using \\!\\=\\= between SimpleXMLElement and false will always evaluate to true\\.$#"
110-
count: 1
111-
path: src/PhpSpreadsheet/Reader/Xlsx.php
112-
113-
-
114-
message: "#^Strict comparison using \\!\\=\\= between SimpleXMLElement and null will always evaluate to true\\.$#"
115-
count: 1
116-
path: src/PhpSpreadsheet/Reader/Xlsx.php
117-
118-
-
119-
message: "#^Strict comparison using \\!\\=\\= between mixed and null will always evaluate to true\\.$#"
120-
count: 1
121-
path: src/PhpSpreadsheet/Reader/Xlsx.php
122-
123-
-
124-
message: "#^Strict comparison using \\!\\=\\= between string and false will always evaluate to true\\.$#"
125-
count: 2
126-
path: src/PhpSpreadsheet/Reader/Xlsx.php
127-
128-
-
129-
message: "#^Strict comparison using \\!\\=\\= between SimpleXMLElement and null will always evaluate to true\\.$#"
130-
count: 1
131-
path: src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php
132-
133-
-
134-
message: "#^Strict comparison using \\!\\=\\= between mixed and null will always evaluate to true\\.$#"
135-
count: 1
136-
path: src/PhpSpreadsheet/Reader/Xlsx/WorkbookView.php
137-
138-
-
139-
message: "#^Strict comparison using \\!\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\IReadFilter and null will always evaluate to true\\.$#"
140-
count: 1
141-
path: src/PhpSpreadsheet/Reader/Xml.php

src/PhpSpreadsheet/Cell/AdvancedValueBinder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ public function bindValue(Cell $cell, mixed $value = null): bool
6161
if (preg_match(FormattedNumber::currencyMatcherRegexp(), (string) preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', $value), $matches, PREG_UNMATCHED_AS_NULL)) {
6262
// Convert value to number
6363
$sign = ($matches['PrefixedSign'] ?? $matches['PrefixedSign2'] ?? $matches['PostfixedSign']) ?? null;
64-
$currencyCode = $matches['PrefixedCurrency'] ?? $matches['PostfixedCurrency'];
64+
$currencyCode = $matches['PrefixedCurrency'] ?? $matches['PostfixedCurrency'] ?? '';
6565
/** @var string */
6666
$temp = str_replace([$decimalSeparatorNoPreg, $currencyCode, ' ', '-'], ['.', '', '', ''], (string) preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', $value));
6767
$value = (float) ($sign . trim($temp));
6868

69-
return $this->setCurrency($value, $cell, $currencyCode ?? '');
69+
return $this->setCurrency($value, $cell, $currencyCode);
7070
}
7171

7272
// Check for time without seconds e.g. '9:45', '09:45'

src/PhpSpreadsheet/Reader/Csv.php

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,6 @@ class Csv extends BaseReader
6969
*/
7070
private ?string $escapeCharacter = null;
7171

72-
/**
73-
* The character that will be supplied to fgetcsv
74-
* when escapeCharacter is null.
75-
* It is anticipated that it will conditionally be set
76-
* to null-string for Php9 and above.
77-
*/
78-
private static string $defaultEscapeCharacter = PHP_VERSION_ID < 90000 ? '\\' : '';
79-
8072
/**
8173
* Callback for setting defaults in construction.
8274
*
@@ -200,7 +192,7 @@ protected function inferSeparator(): void
200192
return;
201193
}
202194

203-
$inferenceEngine = new Delimiter($this->fileHandle, $this->escapeCharacter ?? self::$defaultEscapeCharacter, $this->enclosure);
195+
$inferenceEngine = new Delimiter($this->fileHandle, $this->getEscapeCharacter(), $this->enclosure);
204196

205197
// If number of lines is 0, nothing to infer : fall back to the default
206198
if ($inferenceEngine->linesCounted() === 0) {
@@ -323,10 +315,10 @@ public function setTestAutoDetect(bool $value): self
323315
return $this;
324316
}
325317

326-
private function setAutoDetect(?string $value): ?string
318+
private function setAutoDetect(?string $value, int $version = PHP_VERSION_ID): ?string
327319
{
328320
$retVal = null;
329-
if ($value !== null && $this->testAutodetect && PHP_VERSION_ID < 90000) {
321+
if ($value !== null && $this->testAutodetect && $version < 90000) {
330322
$retVal2 = @ini_set('auto_detect_line_endings', $value);
331323
if (is_string($retVal2)) {
332324
$retVal = $retVal2;
@@ -566,9 +558,9 @@ public function getContiguous(): bool
566558
* Not yet ready to mark deprecated in order to give users
567559
* a migration path.
568560
*/
569-
public function setEscapeCharacter(string $escapeCharacter): self
561+
public function setEscapeCharacter(string $escapeCharacter, int $version = PHP_VERSION_ID): self
570562
{
571-
if (PHP_VERSION_ID >= 90000 && $escapeCharacter !== '') {
563+
if ($version >= 90000 && $escapeCharacter !== '') {
572564
throw new ReaderException('Escape character must be null string for Php9+');
573565
}
574566

@@ -577,9 +569,9 @@ public function setEscapeCharacter(string $escapeCharacter): self
577569
return $this;
578570
}
579571

580-
public function getEscapeCharacter(): string
572+
public function getEscapeCharacter(int $version = PHP_VERSION_ID): string
581573
{
582-
return $this->escapeCharacter ?? self::$defaultEscapeCharacter;
574+
return $this->escapeCharacter ?? self::getDefaultEscapeCharacter($version);
583575
}
584576

585577
/**
@@ -628,7 +620,7 @@ private static function guessEncodingTestNoBom(string &$encoding, string &$conte
628620
private static function guessEncodingNoBom(string $filename): string
629621
{
630622
$encoding = '';
631-
$contents = file_get_contents($filename);
623+
$contents = (string) file_get_contents($filename);
632624
self::guessEncodingTestNoBom($encoding, $contents, self::UTF32BE_LF, 'UTF-32BE');
633625
self::guessEncodingTestNoBom($encoding, $contents, self::UTF32LE_LF, 'UTF-32LE');
634626
self::guessEncodingTestNoBom($encoding, $contents, self::UTF16BE_LF, 'UTF-16BE');
@@ -705,10 +697,11 @@ private static function getCsv(
705697
?int $length = null,
706698
string $separator = ',',
707699
string $enclosure = '"',
708-
?string $escape = null
700+
?string $escape = null,
701+
int $version = PHP_VERSION_ID
709702
): array|false {
710-
$escape = $escape ?? self::$defaultEscapeCharacter;
711-
if (PHP_VERSION_ID >= 80400 && $escape !== '') {
703+
$escape = $escape ?? self::getDefaultEscapeCharacter();
704+
if ($version >= 80400 && $escape !== '') {
712705
return @fgetcsv($stream, $length, $separator, $enclosure, $escape);
713706
}
714707

@@ -720,10 +713,11 @@ public static function affectedByPhp9(
720713
string $inputEncoding = 'UTF-8',
721714
?string $delimiter = null,
722715
string $enclosure = '"',
723-
string $escapeCharacter = '\\'
716+
string $escapeCharacter = '\\',
717+
int $version = PHP_VERSION_ID
724718
): bool {
725-
if (PHP_VERSION_ID < 70400 || PHP_VERSION_ID >= 90000) {
726-
throw new ReaderException('Function valid only for Php7.4 or Php8'); // @codeCoverageIgnore
719+
if ($version < 70400 || $version >= 90000) {
720+
throw new ReaderException('Function valid only for Php7.4 or Php8');
727721
}
728722
$reader1 = new self();
729723
$reader1->setInputEncoding($inputEncoding)
@@ -749,4 +743,15 @@ public static function affectedByPhp9(
749743

750744
return $array1 !== $array2;
751745
}
746+
747+
/**
748+
* The character that will be supplied to fgetcsv
749+
* when escapeCharacter is null.
750+
* It is anticipated that it will conditionally be set
751+
* to null-string for Php9 and above.
752+
*/
753+
private static function getDefaultEscapeCharacter(int $version = PHP_VERSION_ID): string
754+
{
755+
return $version < 90000 ? '\\' : '';
756+
}
752757
}

src/PhpSpreadsheet/Reader/Csv/Delimiter.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,11 @@ protected function countPotentialDelimiters(): void
5656
protected function countDelimiterValues(string $line, array $delimiterKeys): void
5757
{
5858
$splitString = str_split($line, 1);
59-
if (is_array($splitString)) {
60-
$distribution = array_count_values($splitString);
61-
$countLine = array_intersect_key($distribution, $delimiterKeys);
59+
$distribution = array_count_values($splitString);
60+
$countLine = array_intersect_key($distribution, $delimiterKeys);
6261

63-
foreach (self::POTENTIAL_DELIMETERS as $delimiter) {
64-
$this->counts[$delimiter][] = $countLine[$delimiter] ?? 0;
65-
}
62+
foreach (self::POTENTIAL_DELIMETERS as $delimiter) {
63+
$this->counts[$delimiter][] = $countLine[$delimiter] ?? 0;
6664
}
6765
}
6866

src/PhpSpreadsheet/Reader/Gnumeric.php

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,8 @@ public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Sp
302302
$column = Coordinate::stringFromColumnIndex($column + 1);
303303

304304
// Read cell?
305-
if ($this->getReadFilter() !== null) {
306-
if (!$this->getReadFilter()->readCell($column, $row, $worksheetName)) {
307-
continue;
308-
}
305+
if (!$this->getReadFilter()->readCell($column, $row, $worksheetName)) {
306+
continue;
309307
}
310308

311309
$this->loadCell($cell, $worksheetName, $cellAttributes, $column, $row);
@@ -380,32 +378,30 @@ private function processAutofilter(?SimpleXMLElement $sheet): void
380378
{
381379
if ($sheet !== null && isset($sheet->Filters)) {
382380
foreach ($sheet->Filters->Filter as $autofilter) {
383-
if ($autofilter !== null) {
384-
$attributes = $autofilter->attributes();
385-
if (isset($attributes['Area'])) {
386-
$this->spreadsheet->getActiveSheet()->setAutoFilter((string) $attributes['Area']);
387-
}
381+
$attributes = $autofilter->attributes();
382+
if (isset($attributes['Area'])) {
383+
$this->spreadsheet->getActiveSheet()->setAutoFilter((string) $attributes['Area']);
388384
}
389385
}
390386
}
391387
}
392388

393389
private function setColumnWidth(int $whichColumn, float $defaultWidth): void
394390
{
395-
$columnDimension = $this->spreadsheet->getActiveSheet()
396-
->getColumnDimension(Coordinate::stringFromColumnIndex($whichColumn + 1));
397-
if ($columnDimension !== null) {
398-
$columnDimension->setWidth($defaultWidth);
399-
}
391+
$this->spreadsheet->getActiveSheet()
392+
->getColumnDimension(
393+
Coordinate::stringFromColumnIndex($whichColumn + 1)
394+
)
395+
->setWidth($defaultWidth);
400396
}
401397

402398
private function setColumnInvisible(int $whichColumn): void
403399
{
404-
$columnDimension = $this->spreadsheet->getActiveSheet()
405-
->getColumnDimension(Coordinate::stringFromColumnIndex($whichColumn + 1));
406-
if ($columnDimension !== null) {
407-
$columnDimension->setVisible(false);
408-
}
400+
$this->spreadsheet->getActiveSheet()
401+
->getColumnDimension(
402+
Coordinate::stringFromColumnIndex($whichColumn + 1)
403+
)
404+
->setVisible(false);
409405
}
410406

411407
private function processColumnLoop(int $whichColumn, int $maxCol, ?SimpleXMLElement $columnOverride, float $defaultWidth): int
@@ -453,18 +449,18 @@ private function processColumnWidths(?SimpleXMLElement $sheet, int $maxCol): voi
453449

454450
private function setRowHeight(int $whichRow, float $defaultHeight): void
455451
{
456-
$rowDimension = $this->spreadsheet->getActiveSheet()->getRowDimension($whichRow);
457-
if ($rowDimension !== null) {
458-
$rowDimension->setRowHeight($defaultHeight);
459-
}
452+
$this->spreadsheet
453+
->getActiveSheet()
454+
->getRowDimension($whichRow)
455+
->setRowHeight($defaultHeight);
460456
}
461457

462458
private function setRowInvisible(int $whichRow): void
463459
{
464-
$rowDimension = $this->spreadsheet->getActiveSheet()->getRowDimension($whichRow);
465-
if ($rowDimension !== null) {
466-
$rowDimension->setVisible(false);
467-
}
460+
$this->spreadsheet
461+
->getActiveSheet()
462+
->getRowDimension($whichRow)
463+
->setVisible(false);
468464
}
469465

470466
private function processRowLoop(int $whichRow, int $maxRow, ?SimpleXMLElement $rowOverride, float $defaultHeight): int

0 commit comments

Comments
 (0)