From fb0175d6338111562938d0ebc15675212664f93a Mon Sep 17 00:00:00 2001 From: Adrien Loison Date: Tue, 12 May 2015 20:51:50 -0700 Subject: [PATCH] Fix issue with directory separators for zip:// on Windows Replaced "/" by DIRECTORY_SEPARATOR every time it was used with zip:// --- .../Reader/Helper/XLSX/SharedStringsHelper.php | 11 ++++++++++- src/Spout/Reader/Helper/XLSX/WorksheetHelper.php | 3 ++- src/Spout/Reader/Internal/XLSX/Worksheet.php | 6 ++++-- tests/Spout/Writer/SheetTest.php | 11 ++++++++++- tests/Spout/Writer/XLSXTest.php | 15 ++++++++++++--- 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/Spout/Reader/Helper/XLSX/SharedStringsHelper.php b/src/Spout/Reader/Helper/XLSX/SharedStringsHelper.php index 6a88d2d..678baa6 100644 --- a/src/Spout/Reader/Helper/XLSX/SharedStringsHelper.php +++ b/src/Spout/Reader/Helper/XLSX/SharedStringsHelper.php @@ -93,7 +93,7 @@ class SharedStringsHelper $this->tempFilePointer = null; $escaper = new \Box\Spout\Common\Escaper\XLSX(); - $sharedStringsFilePath = 'zip://' . $this->filePath . '#' . self::SHARED_STRINGS_XML_FILE_PATH; + $sharedStringsFilePath = $this->getSharedStringsFilePath(); if ($xmlReader->open($sharedStringsFilePath, null, LIBXML_NONET) === false) { throw new IOException('Could not open "' . self::SHARED_STRINGS_XML_FILE_PATH . '".'); } @@ -143,6 +143,15 @@ class SharedStringsHelper $xmlReader->close(); } + /** + * @return string The path to the shared strings XML file, working cross-platforms + */ + protected function getSharedStringsFilePath() + { + $sharedStringsXmlFilePath = str_replace('/', DIRECTORY_SEPARATOR, self::SHARED_STRINGS_XML_FILE_PATH); + return 'zip://' . $this->filePath . '#' . $sharedStringsXmlFilePath; + } + /** * Removes nodes that should not be read, like the pronunciation of the Kanji characters. * By keeping them, their text content would be added to the read string. diff --git a/src/Spout/Reader/Helper/XLSX/WorksheetHelper.php b/src/Spout/Reader/Helper/XLSX/WorksheetHelper.php index d869dd4..62dab69 100644 --- a/src/Spout/Reader/Helper/XLSX/WorksheetHelper.php +++ b/src/Spout/Reader/Helper/XLSX/WorksheetHelper.php @@ -186,7 +186,8 @@ class WorksheetHelper */ protected function getFileAsXMLElementWithNamespace($xmlFilePath, $mainNamespace) { - $xmlContents = $this->globalFunctionsHelper->file_get_contents('zip://' . $this->filePath . '#' . $xmlFilePath); + $normalizedXmlFilePath = str_replace('/', DIRECTORY_SEPARATOR, $xmlFilePath); + $xmlContents = $this->globalFunctionsHelper->file_get_contents('zip://' . $this->filePath . '#' . $normalizedXmlFilePath); $xmlElement = new \SimpleXMLElement($xmlContents); $xmlElement->registerXPathNamespace('ns', $mainNamespace); diff --git a/src/Spout/Reader/Internal/XLSX/Worksheet.php b/src/Spout/Reader/Internal/XLSX/Worksheet.php index bcf6d2f..f6bfa9a 100644 --- a/src/Spout/Reader/Internal/XLSX/Worksheet.php +++ b/src/Spout/Reader/Internal/XLSX/Worksheet.php @@ -32,11 +32,13 @@ class Worksheet } /** - * @return string Path of the XML file containing the worksheet data, without the leading slash + * @return string Path of the XML file containing the worksheet data, + * without the leading slash and working cross-platforms. */ public function getDataXmlFilePath() { - return ltrim($this->dataXmlFilePath, '/'); + $dataXmlFilePath = ltrim($this->dataXmlFilePath, '/'); + return str_replace('/', DIRECTORY_SEPARATOR, $dataXmlFilePath); } /** diff --git a/tests/Spout/Writer/SheetTest.php b/tests/Spout/Writer/SheetTest.php index c9a3e55..d33e860 100644 --- a/tests/Spout/Writer/SheetTest.php +++ b/tests/Spout/Writer/SheetTest.php @@ -90,9 +90,18 @@ class SheetTest extends \PHPUnit_Framework_TestCase */ private function assertSheetNameEquals($expectedName, $resourcePath, $message = '') { - $pathToWorkbookFile = $resourcePath . '#xl/workbook.xml'; + $pathToWorkbookFile = $resourcePath . $this->normalizePath('#xl/workbook.xml'); $xmlContents = file_get_contents('zip://' . $pathToWorkbookFile); $this->assertContains('getGeneratedResourcePath($fileName); - $pathToSheetFile = $resourcePath . '#xl/worksheets/sheet' . $sheetIndex . '.xml'; + $pathToSheetFile = $resourcePath . $this->normalizePath('#xl/worksheets/sheet' . $sheetIndex . '.xml'); $xmlContents = file_get_contents('zip://' . $pathToSheetFile); $this->assertContains((string)$inlineData, $xmlContents, $message); @@ -424,7 +424,7 @@ class XLSXTest extends \PHPUnit_Framework_TestCase private function assertInlineDataWasNotWrittenToSheet($fileName, $sheetIndex, $inlineData, $message = '') { $resourcePath = $this->getGeneratedResourcePath($fileName); - $pathToSheetFile = $resourcePath . '#xl/worksheets/sheet' . $sheetIndex . '.xml'; + $pathToSheetFile = $resourcePath . $this->normalizePath('#xl/worksheets/sheet' . $sheetIndex . '.xml'); $xmlContents = file_get_contents('zip://' . $pathToSheetFile); $this->assertNotContains((string)$inlineData, $xmlContents, $message); @@ -439,9 +439,18 @@ class XLSXTest extends \PHPUnit_Framework_TestCase private function assertSharedStringWasWritten($fileName, $sharedString, $message = '') { $resourcePath = $this->getGeneratedResourcePath($fileName); - $pathToSharedStringsFile = $resourcePath . '#xl/sharedStrings.xml'; + $pathToSharedStringsFile = $resourcePath . $this->normalizePath('#xl/sharedStrings.xml'); $xmlContents = file_get_contents('zip://' . $pathToSharedStringsFile); $this->assertContains($sharedString, $xmlContents, $message); } + + /** + * @param string $path + * @return string The path with the correct directory separators, as defined for the current platform + */ + private function normalizePath($path) + { + return str_replace('/', DIRECTORY_SEPARATOR, $path); + } }