[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/spout/src/Spout/Writer/XLSX/Helper/ -> FileSystemHelper.php (source)

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


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1