[
MAINHACK
]
Mail Test
BC
Config Scan
HOME
Create...
New File
New Folder
Viewing / Editing File: FileSystemHelper.php
<?php declare(strict_types=1); namespace OpenSpout\Writer\XLSX\Helper; use DateTimeImmutable; use OpenSpout\Common\Exception\IOException; use OpenSpout\Common\Helper\Escaper\XLSX; use OpenSpout\Common\Helper\FileSystemHelper as CommonFileSystemHelper; use OpenSpout\Writer\Common\Entity\Sheet; use OpenSpout\Writer\Common\Entity\Worksheet; use OpenSpout\Writer\Common\Helper\CellHelper; use OpenSpout\Writer\Common\Helper\FileSystemWithRootFolderHelperInterface; use OpenSpout\Writer\Common\Helper\ZipHelper; use OpenSpout\Writer\XLSX\Manager\Style\StyleManager; use OpenSpout\Writer\XLSX\MergeCell; use OpenSpout\Writer\XLSX\Options; /** * @internal */ final class FileSystemHelper implements FileSystemWithRootFolderHelperInterface { public const RELS_FOLDER_NAME = '_rels'; public const DRAWINGS_FOLDER_NAME = 'drawings'; public const DOC_PROPS_FOLDER_NAME = 'docProps'; public const XL_FOLDER_NAME = 'xl'; public const WORKSHEETS_FOLDER_NAME = 'worksheets'; public const RELS_FILE_NAME = '.rels'; public const APP_XML_FILE_NAME = 'app.xml'; public const CORE_XML_FILE_NAME = 'core.xml'; public const CONTENT_TYPES_XML_FILE_NAME = '[Content_Types].xml'; public const WORKBOOK_XML_FILE_NAME = 'workbook.xml'; public const WORKBOOK_RELS_XML_FILE_NAME = 'workbook.xml.rels'; public const STYLES_XML_FILE_NAME = 'styles.xml'; private const SHEET_XML_FILE_HEADER = <<<'EOD' <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> EOD; private readonly string $baseFolderRealPath; private readonly CommonFileSystemHelper $baseFileSystemHelper; /** @var ZipHelper Helper to perform tasks with Zip archive */ private readonly ZipHelper $zipHelper; /** @var string document creator */ private readonly string $creator; /** @var XLSX Used to escape XML data */ private readonly XLSX $escaper; /** @var string Path to the root folder inside the temp folder where the files to create the XLSX will be stored */ private string $rootFolder; /** @var string Path to the "_rels" folder inside the root folder */ private string $relsFolder; /** @var string Path to the "docProps" folder inside the root folder */ private string $docPropsFolder; /** @var string Path to the "xl" folder inside the root folder */ private string $xlFolder; /** @var string Path to the "_rels" folder inside the "xl" folder */ private string $xlRelsFolder; /** @var string Path to the "worksheets" folder inside the "xl" folder */ private string $xlWorksheetsFolder; /** @var string Path to the temp folder, inside the root folder, where specific sheets content will be written to */ private string $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 * @param XLSX $escaper Used to escape XML data * @param string $creator document creator */ public function __construct(string $baseFolderPath, ZipHelper $zipHelper, XLSX $escaper, string $creator) { $this->baseFileSystemHelper = new CommonFileSystemHelper($baseFolderPath); $this->baseFolderRealPath = $this->baseFileSystemHelper->getBaseFolderRealPath(); $this->zipHelper = $zipHelper; $this->escaper = $escaper; $this->creator = $creator; } public function createFolder(string $parentFolderPath, string $folderName): string { return $this->baseFileSystemHelper->createFolder($parentFolderPath, $folderName); } public function createFileWithContents(string $parentFolderPath, string $fileName, string $fileContents): string { return $this->baseFileSystemHelper->createFileWithContents($parentFolderPath, $fileName, $fileContents); } public function deleteFile(string $filePath): void { $this->baseFileSystemHelper->deleteFile($filePath); } public function deleteFolderRecursively(string $folderPath): void { $this->baseFileSystemHelper->deleteFolderRecursively($folderPath); } public function getRootFolder(): string { return $this->rootFolder; } public function getXlFolder(): string { return $this->xlFolder; } public function getXlWorksheetsFolder(): string { return $this->xlWorksheetsFolder; } public function getSheetsContentTempFolder(): string { return $this->sheetsContentTempFolder; } /** * Creates all the folders needed to create a XLSX file, as well as the files that won't change. * * @throws IOException If unable to create at least one of the base folders */ public function createBaseFilesAndFolders(): void { $this ->createRootFolder() ->createRelsFolderAndFile() ->createDocPropsFolderAndFiles() ->createXlFolderAndSubFolders() ->createSheetsContentTempFolder() ; } /** * Creates the "[Content_Types].xml" file under the root folder. * * @param Worksheet[] $worksheets */ public function createContentTypesFile(array $worksheets): self { $contentTypesXmlFileContents = <<<'EOD' <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> <Default ContentType="application/xml" Extension="xml"/> <Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/> <Default ContentType="application/vnd.openxmlformats-officedocument.vmlDrawing" Extension="vml"/> <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" PartName="/xl/workbook.xml"/> EOD; /** @var Worksheet $worksheet */ foreach ($worksheets as $worksheet) { $contentTypesXmlFileContents .= '<Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" PartName="/xl/worksheets/sheet'.$worksheet->getId().'.xml"/>'; $contentTypesXmlFileContents .= '<Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml" PartName="/xl/comments'.$worksheet->getId().'.xml" />'; } $contentTypesXmlFileContents .= <<<'EOD' <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" PartName="/xl/styles.xml"/> <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml" PartName="/xl/sharedStrings.xml"/> <Override ContentType="application/vnd.openxmlformats-package.core-properties+xml" PartName="/docProps/core.xml"/> <Override ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" PartName="/docProps/app.xml"/> </Types> EOD; $this->createFileWithContents($this->rootFolder, self::CONTENT_TYPES_XML_FILE_NAME, $contentTypesXmlFileContents); return $this; } /** * Creates the "workbook.xml" file under the "xl" folder. * * @param Worksheet[] $worksheets */ public function createWorkbookFile(array $worksheets): self { $workbookXmlFileContents = <<<'EOD' <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> <sheets> EOD; /** @var Worksheet $worksheet */ foreach ($worksheets as $worksheet) { $worksheetName = $worksheet->getExternalSheet()->getName(); $worksheetVisibility = $worksheet->getExternalSheet()->isVisible() ? 'visible' : 'hidden'; $worksheetId = $worksheet->getId(); $workbookXmlFileContents .= '<sheet name="'.$this->escaper->escape($worksheetName).'" sheetId="'.$worksheetId.'" r:id="rIdSheet'.$worksheetId.'" state="'.$worksheetVisibility.'"/>'; } $workbookXmlFileContents .= <<<'EOD' </sheets> EOD; $definedNames = ''; /** @var Worksheet $worksheet */ foreach ($worksheets as $worksheet) { $sheet = $worksheet->getExternalSheet(); if (null !== $autofilter = $sheet->getAutoFilter()) { $worksheetName = $sheet->getName(); $name = sprintf( '\'%s\'!$%s$%s:$%s$%s', $this->escaper->escape($worksheetName), CellHelper::getColumnLettersFromColumnIndex($autofilter->fromColumnIndex), $autofilter->fromRow, CellHelper::getColumnLettersFromColumnIndex($autofilter->toColumnIndex), $autofilter->toRow ); $definedNames .= '<definedName function="false" hidden="true" localSheetId="'.$sheet->getIndex().'" name="_xlnm._FilterDatabase" vbProcedure="false">'.$name.'</definedName>'; } if (null !== $printTitleRows = $sheet->getPrintTitleRows()) { $definedNames .= '<definedName name="_xlnm.Print_Titles" localSheetId="'.$sheet->getIndex().'">'.$this->escaper->escape($sheet->getName()).'!'.$printTitleRows.'</definedName>'; } } if ('' !== $definedNames) { $workbookXmlFileContents .= '<definedNames>'.$definedNames.'</definedNames>'; } $workbookXmlFileContents .= <<<'EOD' </workbook> EOD; $this->createFileWithContents($this->xlFolder, self::WORKBOOK_XML_FILE_NAME, $workbookXmlFileContents); return $this; } /** * Creates the "workbook.xml.res" file under the "xl/_res" folder. * * @param Worksheet[] $worksheets */ public function createWorkbookRelsFile(array $worksheets): self { $workbookRelsXmlFileContents = <<<'EOD' <?xml version="1.0" encoding="UTF-8"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Id="rIdStyles" Target="styles.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"/> <Relationship Id="rIdSharedStrings" Target="sharedStrings.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"/> EOD; /** @var Worksheet $worksheet */ foreach ($worksheets as $worksheet) { $worksheetId = $worksheet->getId(); $workbookRelsXmlFileContents .= '<Relationship Id="rIdSheet'.$worksheetId.'" Target="worksheets/sheet'.$worksheetId.'.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"/>'; } $workbookRelsXmlFileContents .= '</Relationships>'; $this->createFileWithContents($this->xlRelsFolder, self::WORKBOOK_RELS_XML_FILE_NAME, $workbookRelsXmlFileContents); return $this; } /** * Create the "rels" file for a given worksheet. This contains relations to the comments.xml and drawing.vml files for this worksheet. * * @param Worksheet[] $worksheets */ public function createWorksheetRelsFiles(array $worksheets): self { $this->createFolder($this->getXlWorksheetsFolder(), self::RELS_FOLDER_NAME); foreach ($worksheets as $worksheet) { $worksheetId = $worksheet->getId(); $worksheetRelsContent = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Id="rId_comments_vml1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing" Target="../drawings/vmlDrawing'.$worksheetId.'.vml"/> <Relationship Id="rId_comments1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" Target="../comments'.$worksheetId.'.xml"/> </Relationships>'; $folder = $this->getXlWorksheetsFolder().\DIRECTORY_SEPARATOR.'_rels'; $filename = 'sheet'.$worksheetId.'.xml.rels'; $this->createFileWithContents($folder, $filename, $worksheetRelsContent); } return $this; } /** * Creates the "styles.xml" file under the "xl" folder. */ public function createStylesFile(StyleManager $styleManager): self { $stylesXmlFileContents = $styleManager->getStylesXMLFileContent(); $this->createFileWithContents($this->xlFolder, self::STYLES_XML_FILE_NAME, $stylesXmlFileContents); return $this; } /** * Creates the "content.xml" file under the root folder. * * @param Worksheet[] $worksheets */ public function createContentFiles(Options $options, array $worksheets): self { $allMergeCells = $options->getMergeCells(); $pageSetup = $options->getPageSetup(); foreach ($worksheets as $worksheet) { $contentXmlFilePath = $this->getXlWorksheetsFolder().\DIRECTORY_SEPARATOR.basename($worksheet->getFilePath()); $worksheetFilePointer = fopen($contentXmlFilePath, 'w'); \assert(false !== $worksheetFilePointer); $sheet = $worksheet->getExternalSheet(); fwrite($worksheetFilePointer, self::SHEET_XML_FILE_HEADER); // AutoFilter tags $range = ''; if (null !== $autofilter = $sheet->getAutoFilter()) { $range = sprintf( '%s%s:%s%s', CellHelper::getColumnLettersFromColumnIndex($autofilter->fromColumnIndex), $autofilter->fromRow, CellHelper::getColumnLettersFromColumnIndex($autofilter->toColumnIndex), $autofilter->toRow ); if (isset($pageSetup) && $pageSetup->fitToPage) { fwrite($worksheetFilePointer, '<sheetPr filterMode="false"><pageSetUpPr fitToPage="true"/></sheetPr>'); } else { fwrite($worksheetFilePointer, '<sheetPr filterMode="false"><pageSetUpPr fitToPage="false"/></sheetPr>'); } fwrite($worksheetFilePointer, sprintf('<dimension ref="%s"/>', $range)); } elseif (isset($pageSetup) && $pageSetup->fitToPage) { fwrite($worksheetFilePointer, '<sheetPr><pageSetUpPr fitToPage="true"/></sheetPr>'); } if (null !== ($sheetView = $sheet->getSheetView())) { fwrite($worksheetFilePointer, '<sheetViews>'.$sheetView->getXml().'</sheetViews>'); } fwrite($worksheetFilePointer, $this->getXMLFragmentForDefaultCellSizing($options)); fwrite($worksheetFilePointer, $this->getXMLFragmentForColumnWidths($options, $sheet)); fwrite($worksheetFilePointer, '<sheetData>'); $worksheetFilePath = $worksheet->getFilePath(); $this->copyFileContentsToTarget($worksheetFilePath, $worksheetFilePointer); fwrite($worksheetFilePointer, '</sheetData>'); // AutoFilter tag if ('' !== $range) { fwrite($worksheetFilePointer, sprintf('<autoFilter ref="%s"/>', $range)); } // create nodes for merge cells $mergeCells = array_filter( $allMergeCells, static fn (MergeCell $c) => $c->sheetIndex === $worksheet->getExternalSheet()->getIndex(), ); if ([] !== $mergeCells) { $mergeCellString = '<mergeCells count="'.\count($mergeCells).'">'; foreach ($mergeCells as $mergeCell) { $topLeft = CellHelper::getColumnLettersFromColumnIndex($mergeCell->topLeftColumn).$mergeCell->topLeftRow; $bottomRight = CellHelper::getColumnLettersFromColumnIndex($mergeCell->bottomRightColumn).$mergeCell->bottomRightRow; $mergeCellString .= sprintf( '<mergeCell ref="%s:%s"/>', $topLeft, $bottomRight ); } $mergeCellString .= '</mergeCells>'; fwrite($worksheetFilePointer, $mergeCellString); } $this->getXMLFragmentForPageMargin($worksheetFilePointer, $options); $this->getXMLFragmentForPageSetup($worksheetFilePointer, $options); $this->getXMLFragmentForHeaderFooter($worksheetFilePointer, $options); // Add the legacy drawing for comments fwrite($worksheetFilePointer, '<legacyDrawing r:id="rId_comments_vml1"/>'); fwrite($worksheetFilePointer, '</worksheet>'); fclose($worksheetFilePointer); } return $this; } /** * Deletes the temporary folder where sheets content was stored. */ public function deleteWorksheetTempFolder(): self { $this->deleteFolderRecursively($this->sheetsContentTempFolder); return $this; } /** * Zips the root folder and streams the contents of the zip into the given stream. * * @param resource $streamPointer Pointer to the stream to copy the zip */ public function zipRootFolderAndCopyToStream($streamPointer): void { $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. $this->zipHelper->addFileToArchive($zip, $this->rootFolder, self::CONTENT_TYPES_XML_FILE_NAME); $this->zipHelper->addFileToArchive($zip, $this->rootFolder, self::XL_FOLDER_NAME.\DIRECTORY_SEPARATOR.self::WORKBOOK_XML_FILE_NAME); $this->zipHelper->addFileToArchive($zip, $this->rootFolder, self::XL_FOLDER_NAME.\DIRECTORY_SEPARATOR.self::STYLES_XML_FILE_NAME); $this->zipHelper->addFolderToArchive($zip, $this->rootFolder, ZipHelper::EXISTING_FILES_SKIP); $this->zipHelper->closeArchiveAndCopyToStream($zip, $streamPointer); // once the zip is copied, remove it $this->deleteFile($zipFilePath); } /** * @param resource $targetResource */ private function getXMLFragmentForPageMargin($targetResource, Options $options): void { $pageMargin = $options->getPageMargin(); if (null === $pageMargin) { return; } fwrite($targetResource, "<pageMargins top=\"{$pageMargin->top}\" right=\"{$pageMargin->right}\" bottom=\"{$pageMargin->bottom}\" left=\"{$pageMargin->left}\" header=\"{$pageMargin->header}\" footer=\"{$pageMargin->footer}\"/>"); } /** * @param resource $targetResource */ private function getXMLFragmentForHeaderFooter($targetResource, Options $options): void { $headerFooter = $options->getHeaderFooter(); if (null === $headerFooter) { return; } $xml = '<headerFooter'; if ($headerFooter->differentOddEven) { $xml .= " differentOddEven=\"{$headerFooter->differentOddEven}\""; } $xml .= '>'; if (null !== $headerFooter->oddHeader) { $xml .= "<oddHeader>{$headerFooter->oddHeader}</oddHeader>"; } if (null !== $headerFooter->oddFooter) { $xml .= "<oddFooter>{$headerFooter->oddFooter}</oddFooter>"; } if ($headerFooter->differentOddEven) { if (null !== $headerFooter->evenHeader) { $xml .= "<evenHeader>{$headerFooter->evenHeader}</evenHeader>"; } if (null !== $headerFooter->evenFooter) { $xml .= "<evenFooter>{$headerFooter->evenFooter}</evenFooter>"; } } $xml .= '</headerFooter>'; fwrite($targetResource, $xml); } /** * @param resource $targetResource */ private function getXMLFragmentForPageSetup($targetResource, Options $options): void { $pageSetup = $options->getPageSetup(); if (null === $pageSetup) { return; } $xml = '<pageSetup'; if (null !== $pageSetup->pageOrientation) { $xml .= " orientation=\"{$pageSetup->pageOrientation->value}\""; } if (null !== $pageSetup->paperSize) { $xml .= " paperSize=\"{$pageSetup->paperSize->value}\""; } if (null !== $pageSetup->fitToHeight) { $xml .= " fitToHeight=\"{$pageSetup->fitToHeight}\""; } if (null !== $pageSetup->fitToWidth) { $xml .= " fitToWidth=\"{$pageSetup->fitToWidth}\""; } $xml .= '/>'; fwrite($targetResource, $xml); } /** * Construct column width references xml to inject into worksheet xml file. */ private function getXMLFragmentForColumnWidths(Options $options, Sheet $sheet): string { if ([] !== $sheet->getColumnWidths()) { $widths = $sheet->getColumnWidths(); } elseif ([] !== $options->getColumnWidths()) { $widths = $options->getColumnWidths(); } else { return ''; } $xml = '<cols>'; foreach ($widths as $columnWidth) { $xml .= '<col min="'.$columnWidth->start.'" max="'.$columnWidth->end.'" width="'.$columnWidth->width.'" customWidth="true"/>'; } $xml .= '</cols>'; return $xml; } /** * Constructs default row height and width xml to inject into worksheet xml file. */ private function getXMLFragmentForDefaultCellSizing(Options $options): string { $rowHeightXml = null === $options->DEFAULT_ROW_HEIGHT ? '' : " defaultRowHeight=\"{$options->DEFAULT_ROW_HEIGHT}\""; $colWidthXml = null === $options->DEFAULT_COLUMN_WIDTH ? '' : " defaultColWidth=\"{$options->DEFAULT_COLUMN_WIDTH}\""; if ('' === $colWidthXml && '' === $rowHeightXml) { return ''; } // Ensure that the required defaultRowHeight is set $rowHeightXml = '' === $rowHeightXml ? ' defaultRowHeight="0"' : $rowHeightXml; return "<sheetFormatPr{$colWidthXml}{$rowHeightXml}/>"; } /** * Creates the folder that will be used as root. * * @throws IOException If unable to create the folder */ private function createRootFolder(): self { $this->rootFolder = $this->createFolder($this->baseFolderRealPath, uniqid('xlsx', true)); return $this; } /** * Creates the "_rels" folder under the root folder as well as the ".rels" file in it. * * @throws IOException If unable to create the folder or the ".rels" file */ private function createRelsFolderAndFile(): self { $this->relsFolder = $this->createFolder($this->rootFolder, self::RELS_FOLDER_NAME); $this->createRelsFile(); return $this; } /** * Creates the ".rels" file under the "_rels" folder (under root). * * @throws IOException If unable to create the file */ private function createRelsFile(): self { $relsFileContents = <<<'EOD' <?xml version="1.0" encoding="UTF-8"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Id="rIdWorkbook" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/> <Relationship Id="rIdCore" Type="http://schemas.openxmlformats.org/officedocument/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/> <Relationship Id="rIdApp" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/> </Relationships> EOD; $this->createFileWithContents($this->relsFolder, self::RELS_FILE_NAME, $relsFileContents); return $this; } /** * Creates the "docProps" folder under the root folder as well as the "app.xml" and "core.xml" files in it. * * @throws IOException If unable to create the folder or one of the files */ private function createDocPropsFolderAndFiles(): self { $this->docPropsFolder = $this->createFolder($this->rootFolder, self::DOC_PROPS_FOLDER_NAME); $this->createAppXmlFile(); $this->createCoreXmlFile(); return $this; } /** * Creates the "app.xml" file under the "docProps" folder. * * @throws IOException If unable to create the file */ private function createAppXmlFile(): self { $appXmlFileContents = <<<EOD <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"> <Application>{$this->creator}</Application> <TotalTime>0</TotalTime> </Properties> EOD; $this->createFileWithContents($this->docPropsFolder, self::APP_XML_FILE_NAME, $appXmlFileContents); return $this; } /** * Creates the "core.xml" file under the "docProps" folder. * * @throws IOException If unable to create the file */ private function createCoreXmlFile(): self { $createdDate = (new DateTimeImmutable())->format(DateTimeImmutable::W3C); $coreXmlFileContents = <<<EOD <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <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"> <dcterms:created xsi:type="dcterms:W3CDTF">{$createdDate}</dcterms:created> <dcterms:modified xsi:type="dcterms:W3CDTF">{$createdDate}</dcterms:modified> <cp:revision>0</cp:revision> </cp:coreProperties> EOD; $this->createFileWithContents($this->docPropsFolder, self::CORE_XML_FILE_NAME, $coreXmlFileContents); return $this; } /** * Creates the "xl" folder under the root folder as well as its subfolders. * * @throws IOException If unable to create at least one of the folders */ private function createXlFolderAndSubFolders(): self { $this->xlFolder = $this->createFolder($this->rootFolder, self::XL_FOLDER_NAME); $this->createXlRelsFolder(); $this->createXlWorksheetsFolder(); $this->createDrawingsFolder(); return $this; } /** * Creates the temp folder where specific sheets content will be written to. * This folder is not part of the final ODS file and is only used to be able to jump between sheets. * * @throws IOException If unable to create the folder */ private function createSheetsContentTempFolder(): self { $this->sheetsContentTempFolder = $this->createFolder($this->rootFolder, 'worksheets-temp'); return $this; } /** * Creates the "_rels" folder under the "xl" folder. * * @throws IOException If unable to create the folder */ private function createXlRelsFolder(): self { $this->xlRelsFolder = $this->createFolder($this->xlFolder, self::RELS_FOLDER_NAME); return $this; } /** * Creates the "drawings" folder under the "xl" folder. * * @throws IOException If unable to create the folder */ private function createDrawingsFolder(): self { $this->createFolder($this->getXlFolder(), self::DRAWINGS_FOLDER_NAME); return $this; } /** * Creates the "worksheets" folder under the "xl" folder. * * @throws IOException If unable to create the folder */ private function createXlWorksheetsFolder(): self { $this->xlWorksheetsFolder = $this->createFolder($this->xlFolder, self::WORKSHEETS_FOLDER_NAME); return $this; } /** * Streams the content of the file at the given path into the target resource. * Depending on which mode the target resource was created with, it will truncate then copy * or append the content to the target file. * * @param string $sourceFilePath Path of the file whose content will be copied * @param resource $targetResource Target resource that will receive the content */ private function copyFileContentsToTarget(string $sourceFilePath, $targetResource): void { $sourceHandle = fopen($sourceFilePath, 'r'); \assert(false !== $sourceHandle); stream_copy_to_stream($sourceHandle, $targetResource); fclose($sourceHandle); } }
Save Changes
Cancel / Back
Close ×
Server Info
Hostname: server1.winmanyltd.com
Server IP: 203.161.60.52
PHP Version: 8.3.27
Server Software: Apache
System: Linux server1.winmanyltd.com 4.18.0-553.22.1.el8_10.x86_64 #1 SMP Tue Sep 24 05:16:59 EDT 2024 x86_64
HDD Total: 117.98 GB
HDD Free: 59.74 GB
Domains on IP: N/A (Requires external lookup)
System Features
Safe Mode:
Off
disable_functions:
None
allow_url_fopen:
On
allow_url_include:
Off
magic_quotes_gpc:
Off
register_globals:
Off
open_basedir:
None
cURL:
Enabled
ZipArchive:
Enabled
MySQLi:
Enabled
PDO:
Enabled
wget:
Yes
curl (cmd):
Yes
perl:
Yes
python:
Yes (py3)
gcc:
Yes
pkexec:
Yes
git:
Yes
User Info
Username: eliosofonline
User ID (UID): 1002
Group ID (GID): 1003
Script Owner UID: 1002
Current Dir Owner: 1002