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 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
   4  
   5  use PhpOffice\PhpSpreadsheet\Document\Properties as DocumentProperties;
   6  use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
   7  use PhpOffice\PhpSpreadsheet\Settings;
   8  use SimpleXMLElement;
   9  
  10  class Properties
  11  {
  12      private $securityScanner;
  13  
  14      private $docProps;
  15  
  16      public function __construct(XmlScanner $securityScanner, DocumentProperties $docProps)
  17      {
  18          $this->securityScanner = $securityScanner;
  19          $this->docProps = $docProps;
  20      }
  21  
  22      private function extractPropertyData($propertyData)
  23      {
  24          return simplexml_load_string(
  25              $this->securityScanner->scan($propertyData),
  26              'SimpleXMLElement',
  27              Settings::getLibXmlLoaderOptions()
  28          );
  29      }
  30  
  31      public function readCoreProperties($propertyData): void
  32      {
  33          $xmlCore = $this->extractPropertyData($propertyData);
  34  
  35          if (is_object($xmlCore)) {
  36              $xmlCore->registerXPathNamespace('dc', 'http://purl.org/dc/elements/1.1/');
  37              $xmlCore->registerXPathNamespace('dcterms', 'http://purl.org/dc/terms/');
  38              $xmlCore->registerXPathNamespace('cp', 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties');
  39  
  40              $this->docProps->setCreator((string) self::getArrayItem($xmlCore->xpath('dc:creator')));
  41              $this->docProps->setLastModifiedBy((string) self::getArrayItem($xmlCore->xpath('cp:lastModifiedBy')));
  42              $this->docProps->setCreated(strtotime(self::getArrayItem($xmlCore->xpath('dcterms:created')))); //! respect xsi:type
  43              $this->docProps->setModified(strtotime(self::getArrayItem($xmlCore->xpath('dcterms:modified')))); //! respect xsi:type
  44              $this->docProps->setTitle((string) self::getArrayItem($xmlCore->xpath('dc:title')));
  45              $this->docProps->setDescription((string) self::getArrayItem($xmlCore->xpath('dc:description')));
  46              $this->docProps->setSubject((string) self::getArrayItem($xmlCore->xpath('dc:subject')));
  47              $this->docProps->setKeywords((string) self::getArrayItem($xmlCore->xpath('cp:keywords')));
  48              $this->docProps->setCategory((string) self::getArrayItem($xmlCore->xpath('cp:category')));
  49          }
  50      }
  51  
  52      public function readExtendedProperties($propertyData): void
  53      {
  54          $xmlCore = $this->extractPropertyData($propertyData);
  55  
  56          if (is_object($xmlCore)) {
  57              if (isset($xmlCore->Company)) {
  58                  $this->docProps->setCompany((string) $xmlCore->Company);
  59              }
  60              if (isset($xmlCore->Manager)) {
  61                  $this->docProps->setManager((string) $xmlCore->Manager);
  62              }
  63          }
  64      }
  65  
  66      public function readCustomProperties($propertyData): void
  67      {
  68          $xmlCore = $this->extractPropertyData($propertyData);
  69  
  70          if (is_object($xmlCore)) {
  71              foreach ($xmlCore as $xmlProperty) {
  72                  /** @var SimpleXMLElement $xmlProperty */
  73                  $cellDataOfficeAttributes = $xmlProperty->attributes();
  74                  if (isset($cellDataOfficeAttributes['name'])) {
  75                      $propertyName = (string) $cellDataOfficeAttributes['name'];
  76                      $cellDataOfficeChildren = $xmlProperty->children('http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes');
  77  
  78                      $attributeType = $cellDataOfficeChildren->getName();
  79                      $attributeValue = (string) $cellDataOfficeChildren->{$attributeType};
  80                      $attributeValue = DocumentProperties::convertProperty($attributeValue, $attributeType);
  81                      $attributeType = DocumentProperties::convertPropertyType($attributeType);
  82                      $this->docProps->setCustomProperty($propertyName, $attributeValue, $attributeType);
  83                  }
  84              }
  85          }
  86      }
  87  
  88      private static function getArrayItem(array $array, $key = 0)
  89      {
  90          return $array[$key] ?? null;
  91      }
  92  }