PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 3.6.65
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v3.6.65
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / app / Services / Spout / Writer / Common / Helper / ZipHelper.php

ZipHelper.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 3.6.65, at app/Services/Spout/Writer/Common/Helper/ZipHelper.php

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