Skip to content

Commit aad91f1

Browse files
author
MarkBaker
committed
Merge branch 'master' into CSV-Reader-Dataype-casting-improvements
# Conflicts: # src/PhpSpreadsheet/Reader/Csv.php
2 parents 45ca934 + a7a48bf commit aad91f1

File tree

8 files changed

+252
-225
lines changed

8 files changed

+252
-225
lines changed

composer.lock

Lines changed: 77 additions & 70 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/topics/reading-and-writing-to-file.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,25 @@ $reader->setSheetIndex(5);
544544
$reader->loadIntoExisting("05featuredemo.csv", $spreadsheet);
545545
```
546546

547+
#### Line endings
548+
549+
Line endings for Unix (`\n`) and Windows (`\r\n`) are supported.
550+
551+
Mac line endings (`\r`) are supported as long as PHP itself
552+
supports them, which it does through release 8.0.
553+
Support for Mac line endings is deprecated for 8.1,
554+
and is scheduled to remain deprecated for all later PHP8 releases;
555+
PhpSpreadsheet will continue to support them for 8.*.
556+
Support is scheduled to be dropped with release 9;
557+
PhpSpreadsheet will then no longer handle CSV files
558+
with Mac line endings correctly.
559+
560+
You can suppress testing for Mac line endings as follows:
561+
```php
562+
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
563+
$reader->setTestAutoDetect(false);
564+
```
565+
547566
### \PhpOffice\PhpSpreadsheet\Writer\Csv
548567

549568
#### Writing a CSV file

phpstan-baseline.neon

Lines changed: 36 additions & 96 deletions
Large diffs are not rendered by default.

src/PhpSpreadsheet/Reader/Csv.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ class Csv extends BaseReader
8686
*/
8787
private static $constructorCallback;
8888

89+
/**
90+
* Attempt autodetect line endings (deprecated after PHP8.1)?
91+
*
92+
* @var bool
93+
*/
94+
private $testAutodetect = true;
95+
8996
/**
9097
* @var bool
9198
*/
@@ -281,10 +288,15 @@ private function openFileOrMemory(string $filename): void
281288
}
282289
}
283290

284-
private static function setAutoDetect(?string $value): ?string
291+
public function setTestAutoDetect(bool $value): void
292+
{
293+
$this->testAutodetect = $value;
294+
}
295+
296+
private function setAutoDetect(?string $value): ?string
285297
{
286298
$retVal = null;
287-
if ($value !== null) {
299+
if ($value !== null && $this->testAutodetect) {
288300
$retVal2 = @ini_set('auto_detect_line_endings', $value);
289301
if (is_string($retVal2)) {
290302
$retVal = $retVal2;
@@ -308,7 +320,7 @@ public function castFormattedNumberToNumeric(
308320
public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Spreadsheet
309321
{
310322
// Deprecated in Php8.1
311-
$iniset = self::setAutoDetect('1');
323+
$iniset = $this->setAutoDetect('1');
312324

313325
// Open file
314326
$this->openFileOrMemory($filename);
@@ -364,7 +376,7 @@ public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Sp
364376
// Close file
365377
fclose($fileHandle);
366378

367-
self::setAutoDetect($iniset);
379+
$this->setAutoDetect($iniset);
368380

369381
// Return
370382
return $spreadsheet;

tests/PhpSpreadsheetTests/Functional/DrawingImageHyperlinkTest.php

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,43 @@ class DrawingImageHyperlinkTest extends AbstractFunctional
1010
{
1111
public function testDrawingImageHyperlinkTest(): void
1212
{
13-
$baseUrl = 'https://github.com/PHPOffice/PhpSpreadsheet';
14-
$spreadsheet = new Spreadsheet();
15-
16-
$aSheet = $spreadsheet->getActiveSheet();
17-
1813
$gdImage = @imagecreatetruecolor(120, 20);
19-
$textColor = imagecolorallocate($gdImage, 255, 255, 255);
20-
imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor);
21-
22-
$drawing = new MemoryDrawing();
23-
$drawing->setName('In-Memory image 1');
24-
$drawing->setDescription('In-Memory image 1');
25-
$drawing->setCoordinates('A1');
26-
$drawing->setImageResource($gdImage);
27-
$drawing->setRenderingFunction(
28-
MemoryDrawing::RENDERING_JPEG
29-
);
30-
$drawing->setMimeType(MemoryDrawing::MIMETYPE_DEFAULT);
31-
$drawing->setHeight(36);
32-
$hyperLink = new Hyperlink($baseUrl, 'test image');
33-
$drawing->setHyperlink($hyperLink);
34-
$drawing->setWorksheet($aSheet);
35-
36-
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx');
37-
38-
foreach ($reloadedSpreadsheet->getActiveSheet()->getDrawingCollection() as $pDrawing) {
39-
self::assertEquals('https://github.com/PHPOffice/PhpSpreadsheet', $pDrawing->getHyperlink()->getUrl(), 'functional test drawing hyperlink');
14+
$textColor = ($gdImage === false) ? false : imagecolorallocate($gdImage, 255, 255, 255);
15+
if ($gdImage === false || $textColor === false) {
16+
self::fail('imagecreatetruecolor or imagecolorallocate failed');
17+
} else {
18+
$baseUrl = 'https://github.com/PHPOffice/PhpSpreadsheet';
19+
$spreadsheet = new Spreadsheet();
20+
21+
$aSheet = $spreadsheet->getActiveSheet();
22+
imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor);
23+
24+
$drawing = new MemoryDrawing();
25+
$drawing->setName('In-Memory image 1');
26+
$drawing->setDescription('In-Memory image 1');
27+
$drawing->setCoordinates('A1');
28+
$drawing->setImageResource($gdImage);
29+
$drawing->setRenderingFunction(
30+
MemoryDrawing::RENDERING_JPEG
31+
);
32+
$drawing->setMimeType(MemoryDrawing::MIMETYPE_DEFAULT);
33+
$drawing->setHeight(36);
34+
$hyperLink = new Hyperlink($baseUrl, 'test image');
35+
$drawing->setHyperlink($hyperLink);
36+
$drawing->setWorksheet($aSheet);
37+
38+
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx');
39+
$spreadsheet->disconnectWorksheets();
40+
41+
foreach ($reloadedSpreadsheet->getActiveSheet()->getDrawingCollection() as $pDrawing) {
42+
$getHyperlink = $pDrawing->getHyperlink();
43+
if ($getHyperlink === null) {
44+
self::fail('getHyperlink returned null');
45+
} else {
46+
self::assertEquals('https://github.com/PHPOffice/PhpSpreadsheet', $getHyperlink->getUrl(), 'functional test drawing hyperlink');
47+
}
48+
}
49+
$reloadedSpreadsheet->disconnectWorksheets();
4050
}
4151
}
4252
}

tests/PhpSpreadsheetTests/Functional/StreamTest.php

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,22 @@ public function testAllWritersCanWriteToStream(string $format): void
3939
$writer = IOFactory::createWriter($spreadsheet, $format);
4040

4141
$stream = fopen('php://memory', 'wb+');
42-
self::assertSame(0, fstat($stream)['size']);
43-
44-
$writer->save($stream);
45-
46-
self::assertIsResource($stream, 'should not close the stream for further usage out of PhpSpreadsheet');
47-
self::assertGreaterThan(0, fstat($stream)['size'], 'something should have been written to the stream');
48-
self::assertGreaterThan(0, ftell($stream), 'should not be rewinded, because not all streams support it');
42+
$stat = ($stream === false) ? false : fstat($stream);
43+
if ($stream === false || $stat === false) {
44+
self::fail('fopen or fstat failed');
45+
} else {
46+
self::assertSame(0, $stat['size']);
47+
48+
$writer->save($stream);
49+
50+
self::assertIsResource($stream, 'should not close the stream for further usage out of PhpSpreadsheet');
51+
$stat = fstat($stream);
52+
if ($stat === false) {
53+
self::fail('fstat failed');
54+
} else {
55+
self::assertGreaterThan(0, $stat['size'], 'something should have been written to the stream');
56+
}
57+
self::assertGreaterThan(0, ftell($stream), 'should not be rewinded, because not all streams support it');
58+
}
4959
}
5060
}

tests/PhpSpreadsheetTests/Reader/Csv/CsvLineEndingTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,31 @@ public function testEndings(string $ending): void
3636
$spreadsheet->disconnectWorksheets();
3737
}
3838

39+
/**
40+
* @dataProvider providerEndings
41+
*/
42+
public function testEndingsNoDetect(string $ending): void
43+
{
44+
$this->tempFile = $filename = File::temporaryFilename();
45+
$data = ['123', '456', '789'];
46+
file_put_contents($filename, implode($ending, $data));
47+
$reader = new Csv();
48+
$reader->setTestAutoDetect(false);
49+
$spreadsheet = $reader->load($filename);
50+
$sheet = $spreadsheet->getActiveSheet();
51+
if ($ending === "\r") {
52+
// Can't handle Mac line endings without autoDetect
53+
self::assertEquals(implode("\n", $data), $sheet->getCell('A1')->getValue());
54+
self::assertNull($sheet->getCell('A2')->getValue());
55+
self::assertNull($sheet->getCell('A3')->getValue());
56+
} else {
57+
self::assertEquals($data[0], $sheet->getCell('A1')->getValue());
58+
self::assertEquals($data[1], $sheet->getCell('A2')->getValue());
59+
self::assertEquals($data[2], $sheet->getCell('A3')->getValue());
60+
}
61+
$spreadsheet->disconnectWorksheets();
62+
}
63+
3964
public function providerEndings(): array
4065
{
4166
return [

tests/PhpSpreadsheetTests/Worksheet/DrawingTest.php

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,35 @@ class DrawingTest extends TestCase
1010
{
1111
public function testCloningWorksheetWithImages(): void
1212
{
13-
$spreadsheet = new Spreadsheet();
14-
$aSheet = $spreadsheet->getActiveSheet();
15-
1613
$gdImage = @imagecreatetruecolor(120, 20);
17-
$textColor = imagecolorallocate($gdImage, 255, 255, 255);
18-
imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor);
14+
$textColor = ($gdImage === false) ? false : imagecolorallocate($gdImage, 255, 255, 255);
15+
if ($gdImage === false || $textColor === false) {
16+
self::fail('imagecreatetruecolor or imagecolorallocate failed');
17+
} else {
18+
$spreadsheet = new Spreadsheet();
19+
$aSheet = $spreadsheet->getActiveSheet();
20+
imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor);
1921

20-
$drawing = new MemoryDrawing();
21-
$drawing->setName('In-Memory image 1');
22-
$drawing->setDescription('In-Memory image 1');
23-
$drawing->setCoordinates('A1');
24-
$drawing->setImageResource($gdImage);
25-
$drawing->setRenderingFunction(
26-
MemoryDrawing::RENDERING_JPEG
27-
);
28-
$drawing->setMimeType(MemoryDrawing::MIMETYPE_DEFAULT);
29-
$drawing->setHeight(36);
30-
$drawing->setWorksheet($aSheet);
22+
$drawing = new MemoryDrawing();
23+
$drawing->setName('In-Memory image 1');
24+
$drawing->setDescription('In-Memory image 1');
25+
$drawing->setCoordinates('A1');
26+
$drawing->setImageResource($gdImage);
27+
$drawing->setRenderingFunction(
28+
MemoryDrawing::RENDERING_JPEG
29+
);
30+
$drawing->setMimeType(MemoryDrawing::MIMETYPE_DEFAULT);
31+
$drawing->setHeight(36);
32+
$drawing->setWorksheet($aSheet);
3133

32-
$originDrawingCount = count($aSheet->getDrawingCollection());
33-
$clonedWorksheet = clone $aSheet;
34-
$clonedDrawingCount = count($clonedWorksheet->getDrawingCollection());
34+
$originDrawingCount = count($aSheet->getDrawingCollection());
35+
$clonedWorksheet = clone $aSheet;
36+
$clonedDrawingCount = count($clonedWorksheet->getDrawingCollection());
3537

36-
self::assertEquals($originDrawingCount, $clonedDrawingCount);
37-
self::assertNotSame($aSheet, $clonedWorksheet);
38-
self::assertNotSame($aSheet->getDrawingCollection(), $clonedWorksheet->getDrawingCollection());
38+
self::assertEquals($originDrawingCount, $clonedDrawingCount);
39+
self::assertNotSame($aSheet, $clonedWorksheet);
40+
self::assertNotSame($aSheet->getDrawingCollection(), $clonedWorksheet->getDrawingCollection());
41+
$spreadsheet->disconnectWorksheets();
42+
}
3943
}
4044
}

0 commit comments

Comments
 (0)