PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.10
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.10
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
visualizer / vendor / openspout / openspout / src / Writer / Common / Helper / ZipHelper.php

ZipHelper.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.11.10, at vendor/openspout/openspout/src/Writer/Common/Helper/ZipHelper.php

215 lines 8.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace OpenSpout\Writer\Common\Helper;
4
5 use OpenSpout\Writer\Common\Creator\InternalEntityFactory;
6
7 /**
8 * This class provides helper functions to create zip files.
9 */
10 class ZipHelper
11 {
12 public const ZIP_EXTENSION = '.zip';
13
14 /** Controls what to do when trying to add an existing file */
15 public const EXISTING_FILES_SKIP = 'skip';
16 public const EXISTING_FILES_OVERWRITE = 'overwrite';
17
18 /** @var InternalEntityFactory Factory to create entities */
19 private $entityFactory;
20
21 /**
22 * @param InternalEntityFactory $entityFactory Factory to create entities
23 */
24 public function __construct($entityFactory)
25 {
26 $this->entityFactory = $entityFactory;
27 }
28
29 /**
30 * Returns a new ZipArchive instance pointing at the given path.
31 *
32 * @param string $tmpFolderPath Path of the temp folder where the zip file will be created
33 *
34 * @return \ZipArchive
35 */
36 public function createZip($tmpFolderPath)
37 {
38 $zip = $this->entityFactory->createZipArchive();
39 $zipFilePath = $tmpFolderPath.self::ZIP_EXTENSION;
40
41 $zip->open($zipFilePath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
42
43 return $zip;
44 }
45
46 /**
47 * @param \ZipArchive $zip An opened zip archive object
48 *
49 * @return string Path where the zip file of the given folder will be created
50 */
51 public function getZipFilePath(\ZipArchive $zip)
52 {
53 return $zip->filename;
54 }
55
56 /**
57 * Adds the given file, located under the given root folder to the archive.
58 * The file will be compressed.
59 *
60 * Example of use:
61 * addFileToArchive($zip, '/tmp/xlsx/foo', 'bar/baz.xml');
62 * => will add the file located at '/tmp/xlsx/foo/bar/baz.xml' in the archive, but only as 'bar/baz.xml'
63 *
64 * @param \ZipArchive $zip An opened zip archive object
65 * @param string $rootFolderPath path of the root folder that will be ignored in the archive tree
66 * @param string $localFilePath Path of the file to be added, under the root folder
67 * @param string $existingFileMode Controls what to do when trying to add an existing file
68 */
69 public function addFileToArchive($zip, $rootFolderPath, $localFilePath, $existingFileMode = self::EXISTING_FILES_OVERWRITE)
70 {
71 $this->addFileToArchiveWithCompressionMethod(
72 $zip,
73 $rootFolderPath,
74 $localFilePath,
75 $existingFileMode,
76 \ZipArchive::CM_DEFAULT
77 );
78 }
79
80 /**
81 * Adds the given file, located under the given root folder to the archive.
82 * The file will NOT be compressed.
83 *
84 * Example of use:
85 * addUncompressedFileToArchive($zip, '/tmp/xlsx/foo', 'bar/baz.xml');
86 * => will add the file located at '/tmp/xlsx/foo/bar/baz.xml' in the archive, but only as 'bar/baz.xml'
87 *
88 * @param \ZipArchive $zip An opened zip archive object
89 * @param string $rootFolderPath path of the root folder that will be ignored in the archive tree
90 * @param string $localFilePath Path of the file to be added, under the root folder
91 * @param string $existingFileMode Controls what to do when trying to add an existing file
92 */
93 public function addUncompressedFileToArchive($zip, $rootFolderPath, $localFilePath, $existingFileMode = self::EXISTING_FILES_OVERWRITE)
94 {
95 $this->addFileToArchiveWithCompressionMethod(
96 $zip,
97 $rootFolderPath,
98 $localFilePath,
99 $existingFileMode,
100 \ZipArchive::CM_STORE
101 );
102 }
103
104 /**
105 * @return bool Whether it is possible to choose the desired compression method to be used
106 */
107 public static function canChooseCompressionMethod()
108 {
109 // setCompressionName() is a PHP7+ method...
110 return method_exists(new \ZipArchive(), 'setCompressionName');
111 }
112
113 /**
114 * @param \ZipArchive $zip An opened zip archive object
115 * @param string $folderPath Path to the folder to be zipped
116 * @param string $existingFileMode Controls what to do when trying to add an existing file
117 */
118 public function addFolderToArchive($zip, $folderPath, $existingFileMode = self::EXISTING_FILES_OVERWRITE)
119 {
120 $folderRealPath = $this->getNormalizedRealPath($folderPath).'/';
121 $itemIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($folderPath, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
122
123 foreach ($itemIterator as $itemInfo) {
124 $itemRealPath = $this->getNormalizedRealPath($itemInfo->getPathname());
125 $itemLocalPath = str_replace($folderRealPath, '', $itemRealPath);
126
127 if ($itemInfo->isFile() && !$this->shouldSkipFile($zip, $itemLocalPath, $existingFileMode)) {
128 $zip->addFile($itemRealPath, $itemLocalPath);
129 }
130 }
131 }
132
133 /**
134 * Closes the archive and copies it into the given stream.
135 *
136 * @param \ZipArchive $zip An opened zip archive object
137 * @param resource $streamPointer Pointer to the stream to copy the zip
138 */
139 public function closeArchiveAndCopyToStream($zip, $streamPointer)
140 {
141 $zipFilePath = $zip->filename;
142 $zip->close();
143
144 $this->copyZipToStream($zipFilePath, $streamPointer);
145 }
146
147 /**
148 * Adds the given file, located under the given root folder to the archive.
149 * The file will NOT be compressed.
150 *
151 * Example of use:
152 * addUncompressedFileToArchive($zip, '/tmp/xlsx/foo', 'bar/baz.xml');
153 * => will add the file located at '/tmp/xlsx/foo/bar/baz.xml' in the archive, but only as 'bar/baz.xml'
154 *
155 * @param \ZipArchive $zip An opened zip archive object
156 * @param string $rootFolderPath path of the root folder that will be ignored in the archive tree
157 * @param string $localFilePath Path of the file to be added, under the root folder
158 * @param string $existingFileMode Controls what to do when trying to add an existing file
159 * @param int $compressionMethod The compression method
160 */
161 protected function addFileToArchiveWithCompressionMethod($zip, $rootFolderPath, $localFilePath, $existingFileMode, $compressionMethod)
162 {
163 if (!$this->shouldSkipFile($zip, $localFilePath, $existingFileMode)) {
164 $normalizedFullFilePath = $this->getNormalizedRealPath($rootFolderPath.'/'.$localFilePath);
165 $zip->addFile($normalizedFullFilePath, $localFilePath);
166
167 if (self::canChooseCompressionMethod()) {
168 $zip->setCompressionName($localFilePath, $compressionMethod);
169 }
170 }
171 }
172
173 /**
174 * @param \ZipArchive $zip
175 * @param string $itemLocalPath
176 * @param string $existingFileMode
177 *
178 * @return bool Whether the file should be added to the archive or skipped
179 */
180 protected function shouldSkipFile($zip, $itemLocalPath, $existingFileMode)
181 {
182 // Skip files if:
183 // - EXISTING_FILES_SKIP mode chosen
184 // - File already exists in the archive
185 return self::EXISTING_FILES_SKIP === $existingFileMode && false !== $zip->locateName($itemLocalPath);
186 }
187
188 /**
189 * Returns canonicalized absolute pathname, containing only forward slashes.
190 *
191 * @param string $path Path to normalize
192 *
193 * @return string Normalized and canonicalized path
194 */
195 protected function getNormalizedRealPath($path)
196 {
197 $realPath = realpath($path);
198
199 return str_replace(\DIRECTORY_SEPARATOR, '/', $realPath);
200 }
201
202 /**
203 * Streams the contents of the zip file into the given stream.
204 *
205 * @param string $zipFilePath Path of the zip file
206 * @param resource $pointer Pointer to the stream to copy the zip
207 */
208 protected function copyZipToStream($zipFilePath, $pointer)
209 {
210 $zipFilePointer = fopen($zipFilePath, 'r');
211 stream_copy_to_stream($zipFilePointer, $pointer);
212 fclose($zipFilePointer);
213 }
214 }
215