Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403]

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Reader\Ods;
   4  
   5  use DOMDocument;
   6  use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
   7  use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
   8  
   9  class PageSettings
  10  {
  11      private $officeNs;
  12  
  13      private $stylesNs;
  14  
  15      private $stylesFo;
  16  
  17      private $pageLayoutStyles = [];
  18  
  19      private $masterStylesCrossReference = [];
  20  
  21      private $masterPrintStylesCrossReference = [];
  22  
  23      public function __construct(DOMDocument $styleDom)
  24      {
  25          $this->setDomNameSpaces($styleDom);
  26          $this->readPageSettingStyles($styleDom);
  27          $this->readStyleMasterLookup($styleDom);
  28      }
  29  
  30      private function setDomNameSpaces(DOMDocument $styleDom): void
  31      {
  32          $this->officeNs = $styleDom->lookupNamespaceUri('office');
  33          $this->stylesNs = $styleDom->lookupNamespaceUri('style');
  34          $this->stylesFo = $styleDom->lookupNamespaceUri('fo');
  35      }
  36  
  37      private function readPageSettingStyles(DOMDocument $styleDom): void
  38      {
  39          $styles = $styleDom->getElementsByTagNameNS($this->officeNs, 'automatic-styles')
  40              ->item(0)
  41              ->getElementsByTagNameNS($this->stylesNs, 'page-layout');
  42  
  43          foreach ($styles as $styleSet) {
  44              $styleName = $styleSet->getAttributeNS($this->stylesNs, 'name');
  45              $pageLayoutProperties = $styleSet->getElementsByTagNameNS($this->stylesNs, 'page-layout-properties')[0];
  46              $styleOrientation = $pageLayoutProperties->getAttributeNS($this->stylesNs, 'print-orientation');
  47              $styleScale = $pageLayoutProperties->getAttributeNS($this->stylesNs, 'scale-to');
  48              $stylePrintOrder = $pageLayoutProperties->getAttributeNS($this->stylesNs, 'print-page-order');
  49              $centered = $pageLayoutProperties->getAttributeNS($this->stylesNs, 'table-centering');
  50  
  51              $marginLeft = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-left');
  52              $marginRight = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-right');
  53              $marginTop = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-top');
  54              $marginBottom = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-bottom');
  55              $header = $styleSet->getElementsByTagNameNS($this->stylesNs, 'header-style')[0];
  56              $headerProperties = $header->getElementsByTagNameNS($this->stylesNs, 'header-footer-properties')[0];
  57              $marginHeader = $headerProperties->getAttributeNS($this->stylesFo, 'min-height');
  58              $footer = $styleSet->getElementsByTagNameNS($this->stylesNs, 'footer-style')[0];
  59              $footerProperties = $footer->getElementsByTagNameNS($this->stylesNs, 'header-footer-properties')[0];
  60              $marginFooter = $footerProperties->getAttributeNS($this->stylesFo, 'min-height');
  61  
  62              $this->pageLayoutStyles[$styleName] = (object) [
  63                  'orientation' => $styleOrientation ?: PageSetup::ORIENTATION_DEFAULT,
  64                  'scale' => $styleScale ?: 100,
  65                  'printOrder' => $stylePrintOrder,
  66                  'horizontalCentered' => $centered === 'horizontal' || $centered === 'both',
  67                  'verticalCentered' => $centered === 'vertical' || $centered === 'both',
  68                  // margin size is already stored in inches, so no UOM conversion is required
  69                  'marginLeft' => (float) $marginLeft ?? 0.7,
  70                  'marginRight' => (float) $marginRight ?? 0.7,
  71                  'marginTop' => (float) $marginTop ?? 0.3,
  72                  'marginBottom' => (float) $marginBottom ?? 0.3,
  73                  'marginHeader' => (float) $marginHeader ?? 0.45,
  74                  'marginFooter' => (float) $marginFooter ?? 0.45,
  75              ];
  76          }
  77      }
  78  
  79      private function readStyleMasterLookup(DOMDocument $styleDom): void
  80      {
  81          $styleMasterLookup = $styleDom->getElementsByTagNameNS($this->officeNs, 'master-styles')
  82              ->item(0)
  83              ->getElementsByTagNameNS($this->stylesNs, 'master-page');
  84  
  85          foreach ($styleMasterLookup as $styleMasterSet) {
  86              $styleMasterName = $styleMasterSet->getAttributeNS($this->stylesNs, 'name');
  87              $pageLayoutName = $styleMasterSet->getAttributeNS($this->stylesNs, 'page-layout-name');
  88              $this->masterPrintStylesCrossReference[$styleMasterName] = $pageLayoutName;
  89          }
  90      }
  91  
  92      public function readStyleCrossReferences(DOMDocument $contentDom): void
  93      {
  94          $styleXReferences = $contentDom->getElementsByTagNameNS($this->officeNs, 'automatic-styles')
  95              ->item(0)
  96              ->getElementsByTagNameNS($this->stylesNs, 'style');
  97  
  98          foreach ($styleXReferences as $styleXreferenceSet) {
  99              $styleXRefName = $styleXreferenceSet->getAttributeNS($this->stylesNs, 'name');
 100              $stylePageLayoutName = $styleXreferenceSet->getAttributeNS($this->stylesNs, 'master-page-name');
 101              if (!empty($stylePageLayoutName)) {
 102                  $this->masterStylesCrossReference[$styleXRefName] = $stylePageLayoutName;
 103              }
 104          }
 105      }
 106  
 107      public function setPrintSettingsForWorksheet(Worksheet $worksheet, string $styleName): void
 108      {
 109          if (!array_key_exists($styleName, $this->masterStylesCrossReference)) {
 110              return;
 111          }
 112          $masterStyleName = $this->masterStylesCrossReference[$styleName];
 113  
 114          if (!array_key_exists($masterStyleName, $this->masterPrintStylesCrossReference)) {
 115              return;
 116          }
 117          $printSettingsIndex = $this->masterPrintStylesCrossReference[$masterStyleName];
 118  
 119          if (!array_key_exists($printSettingsIndex, $this->pageLayoutStyles)) {
 120              return;
 121          }
 122          $printSettings = $this->pageLayoutStyles[$printSettingsIndex];
 123  
 124          $worksheet->getPageSetup()
 125              ->setOrientation($printSettings->orientation ?? PageSetup::ORIENTATION_DEFAULT)
 126              ->setPageOrder($printSettings->printOrder === 'ltr' ? PageSetup::PAGEORDER_OVER_THEN_DOWN : PageSetup::PAGEORDER_DOWN_THEN_OVER)
 127              ->setScale((int) trim($printSettings->scale, '%'))
 128              ->setHorizontalCentered($printSettings->horizontalCentered)
 129              ->setVerticalCentered($printSettings->verticalCentered);
 130  
 131          $worksheet->getPageMargins()
 132              ->setLeft($printSettings->marginLeft)
 133              ->setRight($printSettings->marginRight)
 134              ->setTop($printSettings->marginTop)
 135              ->setBottom($printSettings->marginBottom)
 136              ->setHeader($printSettings->marginHeader)
 137              ->setFooter($printSettings->marginFooter);
 138      }
 139  }