PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.3.27
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.3.27
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
fluent-cart / vendor / openspout / openspout / src / Writer / XLSX / Helper / FileSystemHelper.php

FileSystemHelper.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.3.27, at vendor/openspout/openspout/src/Writer/XLSX/Helper/FileSystemHelper.php

338 lines 14.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\OpenSpout\Writer\XLSX\Helper;
4
5 use FluentCart\OpenSpout\Writer\Common\Entity\Worksheet;
6 use FluentCart\OpenSpout\Writer\Common\Helper\FileSystemWithRootFolderHelperInterface;
7 use FluentCart\OpenSpout\Writer\Common\Helper\ZipHelper;
8 use FluentCart\OpenSpout\Writer\XLSX\Manager\Style\StyleManager;
9 /**
10 * This class provides helper functions to help with the file system operations
11 * like files/folders creation & deletion for XLSX files.
12 */
13 class FileSystemHelper extends \FluentCart\OpenSpout\Common\Helper\FileSystemHelper implements FileSystemWithRootFolderHelperInterface
14 {
15 public const APP_NAME = 'Spout';
16 public const RELS_FOLDER_NAME = '_rels';
17 public const DOC_PROPS_FOLDER_NAME = 'docProps';
18 public const XL_FOLDER_NAME = 'xl';
19 public const WORKSHEETS_FOLDER_NAME = 'worksheets';
20 public const RELS_FILE_NAME = '.rels';
21 public const APP_XML_FILE_NAME = 'app.xml';
22 public const CORE_XML_FILE_NAME = 'core.xml';
23 public const CONTENT_TYPES_XML_FILE_NAME = '[Content_Types].xml';
24 public const WORKBOOK_XML_FILE_NAME = 'workbook.xml';
25 public const WORKBOOK_RELS_XML_FILE_NAME = 'workbook.xml.rels';
26 public const STYLES_XML_FILE_NAME = 'styles.xml';
27 /** @var ZipHelper Helper to perform tasks with Zip archive */
28 private $zipHelper;
29 /** @var \OpenSpout\Common\Helper\Escaper\XLSX Used to escape XML data */
30 private $escaper;
31 /** @var string Path to the root folder inside the temp folder where the files to create the XLSX will be stored */
32 private $rootFolder;
33 /** @var string Path to the "_rels" folder inside the root folder */
34 private $relsFolder;
35 /** @var string Path to the "docProps" folder inside the root folder */
36 private $docPropsFolder;
37 /** @var string Path to the "xl" folder inside the root folder */
38 private $xlFolder;
39 /** @var string Path to the "_rels" folder inside the "xl" folder */
40 private $xlRelsFolder;
41 /** @var string Path to the "worksheets" folder inside the "xl" folder */
42 private $xlWorksheetsFolder;
43 /**
44 * @param string $baseFolderPath The path of the base folder where all the I/O can occur
45 * @param ZipHelper $zipHelper Helper to perform tasks with Zip archive
46 * @param \OpenSpout\Common\Helper\Escaper\XLSX $escaper Used to escape XML data
47 */
48 public function __construct($baseFolderPath, $zipHelper, $escaper)
49 {
50 parent::__construct($baseFolderPath);
51 $this->zipHelper = $zipHelper;
52 $this->escaper = $escaper;
53 }
54 /**
55 * @return string
56 */
57 public function getRootFolder()
58 {
59 return $this->rootFolder;
60 }
61 /**
62 * @return string
63 */
64 public function getXlFolder()
65 {
66 return $this->xlFolder;
67 }
68 /**
69 * @return string
70 */
71 public function getXlWorksheetsFolder()
72 {
73 return $this->xlWorksheetsFolder;
74 }
75 /**
76 * Creates all the folders needed to create a XLSX file, as well as the files that won't change.
77 *
78 * @throws \OpenSpout\Common\Exception\IOException If unable to create at least one of the base folders
79 */
80 public function createBaseFilesAndFolders()
81 {
82 $this->createRootFolder()->createRelsFolderAndFile()->createDocPropsFolderAndFiles()->createXlFolderAndSubFolders();
83 }
84 /**
85 * Creates the "[Content_Types].xml" file under the root folder.
86 *
87 * @param Worksheet[] $worksheets
88 *
89 * @return FileSystemHelper
90 */
91 public function createContentTypesFile($worksheets)
92 {
93 $contentTypesXmlFileContents = <<<'EOD'
94 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
95 <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
96 <Default ContentType="application/xml" Extension="xml"/>
97 <Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/>
98 <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" PartName="/xl/workbook.xml"/>
99 EOD;
100 /** @var Worksheet $worksheet */
101 foreach ($worksheets as $worksheet) {
102 $contentTypesXmlFileContents .= '<Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" PartName="/xl/worksheets/sheet' . $worksheet->getId() . '.xml"/>';
103 }
104 $contentTypesXmlFileContents .= <<<'EOD'
105 <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" PartName="/xl/styles.xml"/>
106 <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml" PartName="/xl/sharedStrings.xml"/>
107 <Override ContentType="application/vnd.openxmlformats-package.core-properties+xml" PartName="/docProps/core.xml"/>
108 <Override ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" PartName="/docProps/app.xml"/>
109 </Types>
110 EOD;
111 $this->createFileWithContents($this->rootFolder, self::CONTENT_TYPES_XML_FILE_NAME, $contentTypesXmlFileContents);
112 return $this;
113 }
114 /**
115 * Creates the "workbook.xml" file under the "xl" folder.
116 *
117 * @param Worksheet[] $worksheets
118 *
119 * @return FileSystemHelper
120 */
121 public function createWorkbookFile($worksheets)
122 {
123 $workbookXmlFileContents = <<<'EOD'
124 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
125 <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
126 <sheets>
127 EOD;
128 /** @var Worksheet $worksheet */
129 foreach ($worksheets as $worksheet) {
130 $worksheetName = $worksheet->getExternalSheet()->getName();
131 $worksheetVisibility = $worksheet->getExternalSheet()->isVisible() ? 'visible' : 'hidden';
132 $worksheetId = $worksheet->getId();
133 $workbookXmlFileContents .= '<sheet name="' . $this->escaper->escape($worksheetName) . '" sheetId="' . $worksheetId . '" r:id="rIdSheet' . $worksheetId . '" state="' . $worksheetVisibility . '"/>';
134 }
135 $workbookXmlFileContents .= <<<'EOD'
136 </sheets>
137 </workbook>
138 EOD;
139 $this->createFileWithContents($this->xlFolder, self::WORKBOOK_XML_FILE_NAME, $workbookXmlFileContents);
140 return $this;
141 }
142 /**
143 * Creates the "workbook.xml.res" file under the "xl/_res" folder.
144 *
145 * @param Worksheet[] $worksheets
146 *
147 * @return FileSystemHelper
148 */
149 public function createWorkbookRelsFile($worksheets)
150 {
151 $workbookRelsXmlFileContents = <<<'EOD'
152 <?xml version="1.0" encoding="UTF-8"?>
153 <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
154 <Relationship Id="rIdStyles" Target="styles.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"/>
155 <Relationship Id="rIdSharedStrings" Target="sharedStrings.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"/>
156 EOD;
157 /** @var Worksheet $worksheet */
158 foreach ($worksheets as $worksheet) {
159 $worksheetId = $worksheet->getId();
160 $workbookRelsXmlFileContents .= '<Relationship Id="rIdSheet' . $worksheetId . '" Target="worksheets/sheet' . $worksheetId . '.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"/>';
161 }
162 $workbookRelsXmlFileContents .= '</Relationships>';
163 $this->createFileWithContents($this->xlRelsFolder, self::WORKBOOK_RELS_XML_FILE_NAME, $workbookRelsXmlFileContents);
164 return $this;
165 }
166 /**
167 * Creates the "styles.xml" file under the "xl" folder.
168 *
169 * @param StyleManager $styleManager
170 *
171 * @return FileSystemHelper
172 */
173 public function createStylesFile($styleManager)
174 {
175 $stylesXmlFileContents = $styleManager->getStylesXMLFileContent();
176 $this->createFileWithContents($this->xlFolder, self::STYLES_XML_FILE_NAME, $stylesXmlFileContents);
177 return $this;
178 }
179 /**
180 * Zips the root folder and streams the contents of the zip into the given stream.
181 *
182 * @param resource $streamPointer Pointer to the stream to copy the zip
183 */
184 public function zipRootFolderAndCopyToStream($streamPointer)
185 {
186 $zip = $this->zipHelper->createZip($this->rootFolder);
187 $zipFilePath = $this->zipHelper->getZipFilePath($zip);
188 // In order to have the file's mime type detected properly, files need to be added
189 // to the zip file in a particular order.
190 // "[Content_Types].xml" then at least 2 files located in "xl" folder should be zipped first.
191 $this->zipHelper->addFileToArchive($zip, $this->rootFolder, self::CONTENT_TYPES_XML_FILE_NAME);
192 $this->zipHelper->addFileToArchive($zip, $this->rootFolder, self::XL_FOLDER_NAME . '/' . self::WORKBOOK_XML_FILE_NAME);
193 $this->zipHelper->addFileToArchive($zip, $this->rootFolder, self::XL_FOLDER_NAME . '/' . self::STYLES_XML_FILE_NAME);
194 $this->zipHelper->addFolderToArchive($zip, $this->rootFolder, ZipHelper::EXISTING_FILES_SKIP);
195 $this->zipHelper->closeArchiveAndCopyToStream($zip, $streamPointer);
196 // once the zip is copied, remove it
197 $this->deleteFile($zipFilePath);
198 }
199 /**
200 * Creates the folder that will be used as root.
201 *
202 * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder
203 *
204 * @return FileSystemHelper
205 */
206 private function createRootFolder()
207 {
208 $this->rootFolder = $this->createFolder($this->baseFolderRealPath, \uniqid('xlsx', \true));
209 return $this;
210 }
211 /**
212 * Creates the "_rels" folder under the root folder as well as the ".rels" file in it.
213 *
214 * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder or the ".rels" file
215 *
216 * @return FileSystemHelper
217 */
218 private function createRelsFolderAndFile()
219 {
220 $this->relsFolder = $this->createFolder($this->rootFolder, self::RELS_FOLDER_NAME);
221 $this->createRelsFile();
222 return $this;
223 }
224 /**
225 * Creates the ".rels" file under the "_rels" folder (under root).
226 *
227 * @throws \OpenSpout\Common\Exception\IOException If unable to create the file
228 *
229 * @return FileSystemHelper
230 */
231 private function createRelsFile()
232 {
233 $relsFileContents = <<<'EOD'
234 <?xml version="1.0" encoding="UTF-8"?>
235 <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
236 <Relationship Id="rIdWorkbook" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
237 <Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/officedocument/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
238 <Relationship Id="rIdApp" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
239 </Relationships>
240 EOD;
241 $this->createFileWithContents($this->relsFolder, self::RELS_FILE_NAME, $relsFileContents);
242 return $this;
243 }
244 /**
245 * Creates the "docProps" folder under the root folder as well as the "app.xml" and "core.xml" files in it.
246 *
247 * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder or one of the files
248 *
249 * @return FileSystemHelper
250 */
251 private function createDocPropsFolderAndFiles()
252 {
253 $this->docPropsFolder = $this->createFolder($this->rootFolder, self::DOC_PROPS_FOLDER_NAME);
254 $this->createAppXmlFile();
255 $this->createCoreXmlFile();
256 return $this;
257 }
258 /**
259 * Creates the "app.xml" file under the "docProps" folder.
260 *
261 * @throws \OpenSpout\Common\Exception\IOException If unable to create the file
262 *
263 * @return FileSystemHelper
264 */
265 private function createAppXmlFile()
266 {
267 $appName = self::APP_NAME;
268 $appXmlFileContents = <<<EOD
269 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
270 <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties">
271 <Application>{$appName}</Application>
272 <TotalTime>0</TotalTime>
273 </Properties>
274 EOD;
275 $this->createFileWithContents($this->docPropsFolder, self::APP_XML_FILE_NAME, $appXmlFileContents);
276 return $this;
277 }
278 /**
279 * Creates the "core.xml" file under the "docProps" folder.
280 *
281 * @throws \OpenSpout\Common\Exception\IOException If unable to create the file
282 *
283 * @return FileSystemHelper
284 */
285 private function createCoreXmlFile()
286 {
287 $createdDate = (new \DateTime())->format(\DateTime::W3C);
288 $coreXmlFileContents = <<<EOD
289 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
290 <cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
291 <dcterms:created xsi:type="dcterms:W3CDTF">{$createdDate}</dcterms:created>
292 <dcterms:modified xsi:type="dcterms:W3CDTF">{$createdDate}</dcterms:modified>
293 <cp:revision>0</cp:revision>
294 </cp:coreProperties>
295 EOD;
296 $this->createFileWithContents($this->docPropsFolder, self::CORE_XML_FILE_NAME, $coreXmlFileContents);
297 return $this;
298 }
299 /**
300 * Creates the "xl" folder under the root folder as well as its subfolders.
301 *
302 * @throws \OpenSpout\Common\Exception\IOException If unable to create at least one of the folders
303 *
304 * @return FileSystemHelper
305 */
306 private function createXlFolderAndSubFolders()
307 {
308 $this->xlFolder = $this->createFolder($this->rootFolder, self::XL_FOLDER_NAME);
309 $this->createXlRelsFolder();
310 $this->createXlWorksheetsFolder();
311 return $this;
312 }
313 /**
314 * Creates the "_rels" folder under the "xl" folder.
315 *
316 * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder
317 *
318 * @return FileSystemHelper
319 */
320 private function createXlRelsFolder()
321 {
322 $this->xlRelsFolder = $this->createFolder($this->xlFolder, self::RELS_FOLDER_NAME);
323 return $this;
324 }
325 /**
326 * Creates the "worksheets" folder under the "xl" folder.
327 *
328 * @throws \OpenSpout\Common\Exception\IOException If unable to create the folder
329 *
330 * @return FileSystemHelper
331 */
332 private function createXlWorksheetsFolder()
333 {
334 $this->xlWorksheetsFolder = $this->createFolder($this->xlFolder, self::WORKSHEETS_FOLDER_NAME);
335 return $this;
336 }
337 }
338