From 582978de67d0fc007c0a95a0bacf9afb5f15edc9 Mon Sep 17 00:00:00 2001 From: Adrien Loison Date: Tue, 30 May 2017 15:11:06 +0200 Subject: [PATCH] Inject ZipHelper through constructor --- src/Spout/Writer/Common/Helper/ZipHelper.php | 72 ++++++++----------- .../Writer/ODS/Creator/InternalFactory.php | 13 +++- .../Writer/ODS/Helper/FileSystemHelper.php | 25 +++++-- .../Writer/XLSX/Creator/InternalFactory.php | 13 +++- .../Writer/XLSX/Helper/FileSystemHelper.php | 29 ++++++-- 5 files changed, 96 insertions(+), 56 deletions(-) diff --git a/src/Spout/Writer/Common/Helper/ZipHelper.php b/src/Spout/Writer/Common/Helper/ZipHelper.php index 1670d17..f6fec55 100644 --- a/src/Spout/Writer/Common/Helper/ZipHelper.php +++ b/src/Spout/Writer/Common/Helper/ZipHelper.php @@ -16,44 +16,29 @@ class ZipHelper const EXISTING_FILES_SKIP = 'skip'; const EXISTING_FILES_OVERWRITE = 'overwrite'; - /** @var string Path of the folder where the zip file will be created */ - protected $tmpFolderPath; - - /** @var \ZipArchive The ZipArchive instance */ - protected $zip; - /** - * @param string $tmpFolderPath Path of the temp folder where the zip file will be created - */ - public function __construct($tmpFolderPath) - { - $this->tmpFolderPath = $tmpFolderPath; - } - - /** - * Returns the already created ZipArchive instance or - * creates one if none exists. + * Returns a new ZipArchive instance pointing at the given path. * + * @param string $tmpFolderPath Path of the temp folder where the zip file will be created * @return \ZipArchive */ - protected function createOrGetZip() + public function createZip($tmpFolderPath) { - if (!isset($this->zip)) { - $this->zip = new \ZipArchive(); - $zipFilePath = $this->getZipFilePath(); + $zip = new \ZipArchive(); + $zipFilePath = $tmpFolderPath . self::ZIP_EXTENSION; - $this->zip->open($zipFilePath, \ZipArchive::CREATE|\ZipArchive::OVERWRITE); - } + $zip->open($zipFilePath, \ZipArchive::CREATE|\ZipArchive::OVERWRITE); - return $this->zip; + return $zip; } /** + * @param \ZipArchive $zip An opened zip archive object * @return string Path where the zip file of the given folder will be created */ - public function getZipFilePath() + public function getZipFilePath(\ZipArchive $zip) { - return $this->tmpFolderPath . self::ZIP_EXTENSION; + return $zip->filename; } /** @@ -61,17 +46,19 @@ class ZipHelper * The file will be compressed. * * Example of use: - * addFileToArchive('/tmp/xlsx/foo', 'bar/baz.xml'); + * addFileToArchive($zip, '/tmp/xlsx/foo', 'bar/baz.xml'); * => will add the file located at '/tmp/xlsx/foo/bar/baz.xml' in the archive, but only as 'bar/baz.xml' * + * @param \ZipArchive $zip An opened zip archive object * @param string $rootFolderPath Path of the root folder that will be ignored in the archive tree. * @param string $localFilePath Path of the file to be added, under the root folder * @param string|void $existingFileMode Controls what to do when trying to add an existing file * @return void */ - public function addFileToArchive($rootFolderPath, $localFilePath, $existingFileMode = self::EXISTING_FILES_OVERWRITE) + public function addFileToArchive($zip, $rootFolderPath, $localFilePath, $existingFileMode = self::EXISTING_FILES_OVERWRITE) { $this->addFileToArchiveWithCompressionMethod( + $zip, $rootFolderPath, $localFilePath, $existingFileMode, @@ -84,17 +71,19 @@ class ZipHelper * The file will NOT be compressed. * * Example of use: - * addUncompressedFileToArchive('/tmp/xlsx/foo', 'bar/baz.xml'); + * addUncompressedFileToArchive($zip, '/tmp/xlsx/foo', 'bar/baz.xml'); * => will add the file located at '/tmp/xlsx/foo/bar/baz.xml' in the archive, but only as 'bar/baz.xml' * + * @param \ZipArchive $zip An opened zip archive object * @param string $rootFolderPath Path of the root folder that will be ignored in the archive tree. * @param string $localFilePath Path of the file to be added, under the root folder * @param string|void $existingFileMode Controls what to do when trying to add an existing file * @return void */ - public function addUncompressedFileToArchive($rootFolderPath, $localFilePath, $existingFileMode = self::EXISTING_FILES_OVERWRITE) + public function addUncompressedFileToArchive($zip, $rootFolderPath, $localFilePath, $existingFileMode = self::EXISTING_FILES_OVERWRITE) { $this->addFileToArchiveWithCompressionMethod( + $zip, $rootFolderPath, $localFilePath, $existingFileMode, @@ -107,19 +96,18 @@ class ZipHelper * The file will NOT be compressed. * * Example of use: - * addUncompressedFileToArchive('/tmp/xlsx/foo', 'bar/baz.xml'); + * addUncompressedFileToArchive($zip, '/tmp/xlsx/foo', 'bar/baz.xml'); * => will add the file located at '/tmp/xlsx/foo/bar/baz.xml' in the archive, but only as 'bar/baz.xml' * + * @param \ZipArchive $zip An opened zip archive object * @param string $rootFolderPath Path of the root folder that will be ignored in the archive tree. * @param string $localFilePath Path of the file to be added, under the root folder * @param string $existingFileMode Controls what to do when trying to add an existing file * @param int $compressionMethod The compression method * @return void */ - protected function addFileToArchiveWithCompressionMethod($rootFolderPath, $localFilePath, $existingFileMode, $compressionMethod) + protected function addFileToArchiveWithCompressionMethod($zip, $rootFolderPath, $localFilePath, $existingFileMode, $compressionMethod) { - $zip = $this->createOrGetZip(); - if (!$this->shouldSkipFile($zip, $localFilePath, $existingFileMode)) { $normalizedFullFilePath = $this->getNormalizedRealPath($rootFolderPath . '/' . $localFilePath); $zip->addFile($normalizedFullFilePath, $localFilePath); @@ -140,14 +128,13 @@ class ZipHelper } /** + * @param \ZipArchive $zip An opened zip archive object * @param string $folderPath Path to the folder to be zipped * @param string|void $existingFileMode Controls what to do when trying to add an existing file * @return void */ - public function addFolderToArchive($folderPath, $existingFileMode = self::EXISTING_FILES_OVERWRITE) + public function addFolderToArchive($zip, $folderPath, $existingFileMode = self::EXISTING_FILES_OVERWRITE) { - $zip = $this->createOrGetZip(); - $folderRealPath = $this->getNormalizedRealPath($folderPath) . '/'; $itemIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($folderPath, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST); @@ -190,27 +177,28 @@ class ZipHelper /** * Closes the archive and copies it into the given stream * + * @param \ZipArchive $zip An opened zip archive object * @param resource $streamPointer Pointer to the stream to copy the zip * @return void */ - public function closeArchiveAndCopyToStream($streamPointer) + public function closeArchiveAndCopyToStream($zip, $streamPointer) { - $zip = $this->createOrGetZip(); + $zipFilePath = $zip->filename; $zip->close(); - unset($this->zip); - $this->copyZipToStream($streamPointer); + $this->copyZipToStream($zipFilePath, $streamPointer); } /** * Streams the contents of the zip file into the given stream * + * @param string $zipFilePath Path of the zip file * @param resource $pointer Pointer to the stream to copy the zip * @return void */ - protected function copyZipToStream($pointer) + protected function copyZipToStream($zipFilePath, $pointer) { - $zipFilePointer = fopen($this->getZipFilePath(), 'r'); + $zipFilePointer = fopen($zipFilePath, 'r'); stream_copy_to_stream($zipFilePointer, $pointer); fclose($zipFilePointer); } diff --git a/src/Spout/Writer/ODS/Creator/InternalFactory.php b/src/Spout/Writer/ODS/Creator/InternalFactory.php index 2d9facd..885bff3 100644 --- a/src/Spout/Writer/ODS/Creator/InternalFactory.php +++ b/src/Spout/Writer/ODS/Creator/InternalFactory.php @@ -3,6 +3,7 @@ namespace Box\Spout\Writer\ODS\Creator; use Box\Spout\Common\Helper\StringHelper; +use Box\Spout\Writer\Common\Helper\ZipHelper; use Box\Spout\Writer\Common\Manager\OptionsManagerInterface; use Box\Spout\Writer\Common\Entity\Options; use Box\Spout\Writer\Common\Creator\EntityFactory; @@ -90,7 +91,17 @@ class InternalFactory implements InternalFactoryInterface public function createFileSystemHelper(OptionsManagerInterface $optionsManager) { $tempFolder = $optionsManager->getOption(Options::TEMP_FOLDER); - return new FileSystemHelper($tempFolder); + $zipHelper = $this->createZipHelper(); + + return new FileSystemHelper($tempFolder, $zipHelper); + } + + /** + * @return ZipHelper + */ + private function createZipHelper() + { + return new ZipHelper(); } /** diff --git a/src/Spout/Writer/ODS/Helper/FileSystemHelper.php b/src/Spout/Writer/ODS/Helper/FileSystemHelper.php index 8ccd863..661a8ca 100644 --- a/src/Spout/Writer/ODS/Helper/FileSystemHelper.php +++ b/src/Spout/Writer/ODS/Helper/FileSystemHelper.php @@ -29,6 +29,9 @@ class FileSystemHelper extends \Box\Spout\Common\Helper\FileSystemHelper impleme const MIMETYPE_FILE_NAME = 'mimetype'; const STYLES_XML_FILE_NAME = 'styles.xml'; + /** @var ZipHelper Helper to perform tasks with Zip archive */ + private $zipHelper; + /** @var string Path to the root folder inside the temp folder where the files to create the ODS will be stored */ protected $rootFolder; @@ -38,6 +41,16 @@ class FileSystemHelper extends \Box\Spout\Common\Helper\FileSystemHelper impleme /** @var string Path to the temp folder, inside the root folder, where specific sheets content will be written to */ protected $sheetsContentTempFolder; + /** + * @param string $baseFolderPath The path of the base folder where all the I/O can occur + * @param ZipHelper $zipHelper Helper to perform tasks with Zip archive + */ + public function __construct($baseFolderPath, $zipHelper) + { + parent::__construct($baseFolderPath); + $this->zipHelper = $zipHelper; + } + /** * @return string */ @@ -267,17 +280,19 @@ EOD; */ public function zipRootFolderAndCopyToStream($streamPointer) { - $zipHelper = new ZipHelper($this->rootFolder); + $zip = $this->zipHelper->createZip($this->rootFolder); + + $zipFilePath = $this->zipHelper->getZipFilePath($zip); // In order to have the file's mime type detected properly, files need to be added // to the zip file in a particular order. // @see http://www.jejik.com/articles/2010/03/how_to_correctly_create_odf_documents_using_zip/ - $zipHelper->addUncompressedFileToArchive($this->rootFolder, self::MIMETYPE_FILE_NAME); + $this->zipHelper->addUncompressedFileToArchive($zip, $this->rootFolder, self::MIMETYPE_FILE_NAME); - $zipHelper->addFolderToArchive($this->rootFolder, ZipHelper::EXISTING_FILES_SKIP); - $zipHelper->closeArchiveAndCopyToStream($streamPointer); + $this->zipHelper->addFolderToArchive($zip, $this->rootFolder, ZipHelper::EXISTING_FILES_SKIP); + $this->zipHelper->closeArchiveAndCopyToStream($zip, $streamPointer); // once the zip is copied, remove it - $this->deleteFile($zipHelper->getZipFilePath()); + $this->deleteFile($zipFilePath); } } diff --git a/src/Spout/Writer/XLSX/Creator/InternalFactory.php b/src/Spout/Writer/XLSX/Creator/InternalFactory.php index d854a96..9fd312a 100644 --- a/src/Spout/Writer/XLSX/Creator/InternalFactory.php +++ b/src/Spout/Writer/XLSX/Creator/InternalFactory.php @@ -7,6 +7,7 @@ use Box\Spout\Common\Helper\StringHelper; use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\Common\Creator\InternalFactoryInterface; use Box\Spout\Writer\Common\Entity\Options; +use Box\Spout\Writer\Common\Helper\ZipHelper; use Box\Spout\Writer\Common\Manager\OptionsManagerInterface; use Box\Spout\Writer\XLSX\Helper\FileSystemHelper; use Box\Spout\Writer\XLSX\Manager\SharedStringsManager; @@ -111,7 +112,17 @@ class InternalFactory implements InternalFactoryInterface private function createFileSystemHelper(OptionsManagerInterface $optionsManager) { $tempFolder = $optionsManager->getOption(Options::TEMP_FOLDER); - return new FileSystemHelper($tempFolder); + $zipHelper = $this->createZipHelper(); + + return new FileSystemHelper($tempFolder, $zipHelper); + } + + /** + * @return ZipHelper + */ + private function createZipHelper() + { + return new ZipHelper(); } /** diff --git a/src/Spout/Writer/XLSX/Helper/FileSystemHelper.php b/src/Spout/Writer/XLSX/Helper/FileSystemHelper.php index c3efd55..e640d09 100644 --- a/src/Spout/Writer/XLSX/Helper/FileSystemHelper.php +++ b/src/Spout/Writer/XLSX/Helper/FileSystemHelper.php @@ -31,6 +31,9 @@ class FileSystemHelper extends \Box\Spout\Common\Helper\FileSystemHelper impleme const WORKBOOK_RELS_XML_FILE_NAME = 'workbook.xml.rels'; const STYLES_XML_FILE_NAME = 'styles.xml'; + /** @var ZipHelper Helper to perform tasks with Zip archive */ + private $zipHelper; + /** @var string Path to the root folder inside the temp folder where the files to create the XLSX will be stored */ private $rootFolder; @@ -49,6 +52,16 @@ class FileSystemHelper extends \Box\Spout\Common\Helper\FileSystemHelper impleme /** @var string Path to the "worksheets" folder inside the "xl" folder */ private $xlWorksheetsFolder; + /** + * @param string $baseFolderPath The path of the base folder where all the I/O can occur + * @param ZipHelper $zipHelper Helper to perform tasks with Zip archive + */ + public function __construct($baseFolderPath, $zipHelper) + { + parent::__construct($baseFolderPath); + $this->zipHelper = $zipHelper; + } + /** * @return string */ @@ -355,19 +368,21 @@ EOD; */ public function zipRootFolderAndCopyToStream($streamPointer) { - $zipHelper = new ZipHelper($this->rootFolder); + $zip = $this->zipHelper->createZip($this->rootFolder); + + $zipFilePath = $this->zipHelper->getZipFilePath($zip); // In order to have the file's mime type detected properly, files need to be added // to the zip file in a particular order. // "[Content_Types].xml" then at least 2 files located in "xl" folder should be zipped first. - $zipHelper->addFileToArchive($this->rootFolder, self::CONTENT_TYPES_XML_FILE_NAME); - $zipHelper->addFileToArchive($this->rootFolder, self::XL_FOLDER_NAME . '/' . self::WORKBOOK_XML_FILE_NAME); - $zipHelper->addFileToArchive($this->rootFolder, self::XL_FOLDER_NAME . '/' . self::STYLES_XML_FILE_NAME); + $this->zipHelper->addFileToArchive($zip, $this->rootFolder, self::CONTENT_TYPES_XML_FILE_NAME); + $this->zipHelper->addFileToArchive($zip, $this->rootFolder, self::XL_FOLDER_NAME . '/' . self::WORKBOOK_XML_FILE_NAME); + $this->zipHelper->addFileToArchive($zip, $this->rootFolder, self::XL_FOLDER_NAME . '/' . self::STYLES_XML_FILE_NAME); - $zipHelper->addFolderToArchive($this->rootFolder, ZipHelper::EXISTING_FILES_SKIP); - $zipHelper->closeArchiveAndCopyToStream($streamPointer); + $this->zipHelper->addFolderToArchive($zip, $this->rootFolder, ZipHelper::EXISTING_FILES_SKIP); + $this->zipHelper->closeArchiveAndCopyToStream($zip, $streamPointer); // once the zip is copied, remove it - $this->deleteFile($zipHelper->getZipFilePath()); + $this->deleteFile($zipFilePath); } }