From 26c26ae8df48d83771b9e59410870a78fb4ba3f1 Mon Sep 17 00:00:00 2001 From: oleibman Date: Sun, 31 Oct 2021 21:28:51 -0700 Subject: [PATCH] Xlsx Writer Support for WMF Files (#2339) PR #1844 fixes it, but changes were requested. It has been almost 3 months and those changes have not been made. This PR replaces that one; it should be suitable for all supported releases of PHP through 8.1, and includes a formal unit test. Fixes #1685 Closes #1844 --- phpstan-baseline.neon | 10 ------ .../Writer/Xlsx/ContentTypes.php | 4 +-- .../Writer/Xlsx/WmfTest.php | 34 ++++++++++++++++++ tests/data/Writer/XLSX/wmffile.xlsx | Bin 0 -> 10141 bytes 4 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Writer/Xlsx/WmfTest.php create mode 100644 tests/data/Writer/XLSX/wmffile.xlsx diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 4423b594..d56cf27d 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5660,16 +5660,6 @@ parameters: count: 2 path: src/PhpSpreadsheet/Writer/Xlsx/Comments.php - - - message: "#^Parameter \\#1 \\$arr1 of function array_diff expects array, array\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php - - - - message: "#^Cannot access offset 2 on array\\|false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php - - message: "#^Parameter \\#2 \\$content of method XMLWriter\\:\\:writeElement\\(\\) expects string\\|null, int given\\.$#" count: 1 diff --git a/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php b/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php index 2cff1a8f..e5cf65c9 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php @@ -141,7 +141,7 @@ class ContentTypes extends WriterPart if ($spreadsheet->hasRibbonBinObjects()) { // Some additional objects in the ribbon ? // we need to write "Extension" but not already write for media content - $tabRibbonTypes = array_diff($spreadsheet->getRibbonBinObjects('types'), array_keys($aMediaContentTypes)); + $tabRibbonTypes = array_diff($spreadsheet->getRibbonBinObjects('types') ?? [], array_keys($aMediaContentTypes)); foreach ($tabRibbonTypes as $aRibbonType) { $mimeType = 'image/.' . $aRibbonType; //we wrote $mimeType like customUI Editor $this->writeDefaultContentType($objWriter, $aRibbonType, $mimeType); @@ -192,7 +192,7 @@ class ContentTypes extends WriterPart if (File::fileExists($pFile)) { $image = getimagesize($pFile); - return image_type_to_mime_type($image[2]); + return image_type_to_mime_type((is_array($image) && count($image) >= 3) ? $image[2] : 0); } throw new WriterException("File $pFile does not exist"); diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/WmfTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/WmfTest.php new file mode 100644 index 00000000..35ae742c --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/WmfTest.php @@ -0,0 +1,34 @@ +load($inputFilename); + $drawings = $spreadsheet->getActiveSheet()->getDrawingCollection(); + self::assertCount(1, $drawings); + $drawing = $drawings[0]; + self::assertSame('wmf', $drawing->getExtension()); + + // Save spreadsheet to file and read it back + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx'); + $drawings = $reloadedSpreadsheet->getActiveSheet()->getDrawingCollection(); + self::assertCount(1, $drawings); + $drawing = $drawings[0]; + self::assertSame('wmf', $drawing->getExtension()); + + $spreadsheet->disconnectWorksheets(); + $reloadedSpreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/data/Writer/XLSX/wmffile.xlsx b/tests/data/Writer/XLSX/wmffile.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..64df51aad3adff29d6d65bba5939dc1c9097e2e8 GIT binary patch literal 10141 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 literal 0 HcmV?d00001