![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/demo.cartinsight.co/vendor/openspout/openspout/src/Writer/Common/Helper/ |
<?php declare(strict_types=1); namespace OpenSpout\Writer\Common\Helper; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use SplFileInfo; use ZipArchive; /** * @internal */ final class ZipHelper { public const ZIP_EXTENSION = '.zip'; /** * Controls what to do when trying to add an existing file. */ public const EXISTING_FILES_SKIP = 'skip'; public const EXISTING_FILES_OVERWRITE = 'overwrite'; /** * 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 */ public function createZip(string $tmpFolderPath): ZipArchive { $zip = new ZipArchive(); $zipFilePath = $tmpFolderPath.self::ZIP_EXTENSION; $zip->open($zipFilePath, ZipArchive::CREATE | ZipArchive::OVERWRITE); 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(ZipArchive $zip): string { return $zip->filename; } /** * Adds the given file, located under the given root folder to the archive. * The file will be compressed. * * Example of use: * 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 $existingFileMode Controls what to do when trying to add an existing file */ public function addFileToArchive(ZipArchive $zip, string $rootFolderPath, string $localFilePath, string $existingFileMode = self::EXISTING_FILES_OVERWRITE): void { $this->addFileToArchiveWithCompressionMethod( $zip, $rootFolderPath, $localFilePath, $existingFileMode, ZipArchive::CM_DEFAULT ); } /** * Adds the given file, located under the given root folder to the archive. * The file will NOT be compressed. * * Example of use: * 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 */ public function addUncompressedFileToArchive(ZipArchive $zip, string $rootFolderPath, string $localFilePath, string $existingFileMode = self::EXISTING_FILES_OVERWRITE): void { $this->addFileToArchiveWithCompressionMethod( $zip, $rootFolderPath, $localFilePath, $existingFileMode, ZipArchive::CM_STORE ); } /** * @param ZipArchive $zip An opened zip archive object * @param string $folderPath Path to the folder to be zipped * @param string $existingFileMode Controls what to do when trying to add an existing file */ public function addFolderToArchive(ZipArchive $zip, string $folderPath, string $existingFileMode = self::EXISTING_FILES_OVERWRITE): void { $folderRealPath = $this->getNormalizedRealPath($folderPath).'/'; $itemIterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($folderPath, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST ); foreach ($itemIterator as $itemInfo) { \assert($itemInfo instanceof SplFileInfo); $itemRealPath = $this->getNormalizedRealPath($itemInfo->getPathname()); $itemLocalPath = str_replace($folderRealPath, '', $itemRealPath); if ($itemInfo->isFile() && !$this->shouldSkipFile($zip, $itemLocalPath, $existingFileMode)) { $zip->addFile($itemRealPath, $itemLocalPath); } } } /** * 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 */ public function closeArchiveAndCopyToStream(ZipArchive $zip, $streamPointer): void { $zipFilePath = $zip->filename; $zip->close(); $this->copyZipToStream($zipFilePath, $streamPointer); } /** * Adds the given file, located under the given root folder to the archive. * The file will NOT be compressed. * * Example of use: * 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 */ private function addFileToArchiveWithCompressionMethod(ZipArchive $zip, string $rootFolderPath, string $localFilePath, string $existingFileMode, int $compressionMethod): void { $normalizedLocalFilePath = str_replace('\\', '/', $localFilePath); if (!$this->shouldSkipFile($zip, $normalizedLocalFilePath, $existingFileMode)) { $normalizedFullFilePath = $this->getNormalizedRealPath($rootFolderPath.'/'.$normalizedLocalFilePath); $zip->addFile($normalizedFullFilePath, $normalizedLocalFilePath); $zip->setCompressionName($normalizedLocalFilePath, $compressionMethod); } } /** * @return bool Whether the file should be added to the archive or skipped */ private function shouldSkipFile(ZipArchive $zip, string $itemLocalPath, string $existingFileMode): bool { // Skip files if: // - EXISTING_FILES_SKIP mode chosen // - File already exists in the archive return self::EXISTING_FILES_SKIP === $existingFileMode && false !== $zip->locateName($itemLocalPath); } /** * Returns canonicalized absolute pathname, containing only forward slashes. * * @param string $path Path to normalize * * @return string Normalized and canonicalized path */ private function getNormalizedRealPath(string $path): string { $realPath = realpath($path); \assert(false !== $realPath); return str_replace(\DIRECTORY_SEPARATOR, '/', $realPath); } /** * 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 */ private function copyZipToStream(string $zipFilePath, $pointer): void { $zipFilePointer = fopen($zipFilePath, 'r'); \assert(false !== $zipFilePointer); stream_copy_to_stream($zipFilePointer, $pointer); fclose($zipFilePointer); } }