Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

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

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting;
   4  
   5  use PhpOffice\PhpSpreadsheet\Style\Conditional;
   6  use SimpleXMLElement;
   7  
   8  class ConditionalFormattingRuleExtension
   9  {
  10      const CONDITION_EXTENSION_DATABAR = 'dataBar';
  11  
  12      /** <conditionalFormatting> attributes */
  13      private $id;
  14  
  15      /** @var string Conditional Formatting Rule */
  16      private $cfRule;
  17  
  18      /** <conditionalFormatting> children */
  19  
  20      /** @var ConditionalDataBarExtension */
  21      private $dataBar;
  22  
  23      /** @var string Sequence of References */
  24      private $sqref;
  25  
  26      /**
  27       * ConditionalFormattingRuleExtension constructor.
  28       */
  29      public function __construct($id = null, string $cfRule = self::CONDITION_EXTENSION_DATABAR)
  30      {
  31          if (null === $id) {
  32              $this->id = '{' . $this->generateUuid() . '}';
  33          } else {
  34              $this->id = $id;
  35          }
  36          $this->cfRule = $cfRule;
  37      }
  38  
  39      private function generateUuid()
  40      {
  41          $chars = str_split('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx');
  42  
  43          foreach ($chars as $i => $char) {
  44              if ($char === 'x') {
  45                  $chars[$i] = dechex(random_int(0, 15));
  46              } elseif ($char === 'y') {
  47                  $chars[$i] = dechex(random_int(8, 11));
  48              }
  49          }
  50  
  51          return implode('', $chars);
  52      }
  53  
  54      public static function parseExtLstXml($extLstXml)
  55      {
  56          $conditionalFormattingRuleExtensions = [];
  57          $conditionalFormattingRuleExtensionXml = null;
  58          if ($extLstXml instanceof SimpleXMLElement) {
  59              foreach ((count($extLstXml) > 0 ? $extLstXml : [$extLstXml]) as $extLst) {
  60                  //this uri is conditionalFormattings
  61                  //https://docs.microsoft.com/en-us/openspecs/office_standards/ms-xlsx/07d607af-5618-4ca2-b683-6a78dc0d9627
  62                  if (isset($extLst->ext['uri']) && (string) $extLst->ext['uri'] === '{78C0D931-6437-407d-A8EE-F0AAD7539E65}') {
  63                      $conditionalFormattingRuleExtensionXml = $extLst->ext;
  64                  }
  65              }
  66  
  67              if ($conditionalFormattingRuleExtensionXml) {
  68                  $ns = $conditionalFormattingRuleExtensionXml->getNamespaces(true);
  69                  $extFormattingsXml = $conditionalFormattingRuleExtensionXml->children($ns['x14']);
  70  
  71                  foreach ($extFormattingsXml->children($ns['x14']) as $extFormattingXml) {
  72                      $extCfRuleXml = $extFormattingXml->cfRule;
  73                      $attributes = $extCfRuleXml->attributes();
  74                      if (!$attributes || ((string) $attributes->type) !== Conditional::CONDITION_DATABAR) {
  75                          continue;
  76                      }
  77  
  78                      $extFormattingRuleObj = new self((string) $attributes->id);
  79                      $extFormattingRuleObj->setSqref((string) $extFormattingXml->children($ns['xm'])->sqref);
  80                      $conditionalFormattingRuleExtensions[$extFormattingRuleObj->getId()] = $extFormattingRuleObj;
  81  
  82                      $extDataBarObj = new ConditionalDataBarExtension();
  83                      $extFormattingRuleObj->setDataBarExt($extDataBarObj);
  84                      $dataBarXml = $extCfRuleXml->dataBar;
  85                      self::parseExtDataBarAttributesFromXml($extDataBarObj, $dataBarXml);
  86                      self::parseExtDataBarElementChildrenFromXml($extDataBarObj, $dataBarXml, $ns);
  87                  }
  88              }
  89          }
  90  
  91          return $conditionalFormattingRuleExtensions;
  92      }
  93  
  94      private static function parseExtDataBarAttributesFromXml(
  95          ConditionalDataBarExtension $extDataBarObj,
  96          SimpleXMLElement $dataBarXml
  97      ): void {
  98          $dataBarAttribute = $dataBarXml->attributes();
  99          if ($dataBarAttribute->minLength) {
 100              $extDataBarObj->setMinLength((int) $dataBarAttribute->minLength);
 101          }
 102          if ($dataBarAttribute->maxLength) {
 103              $extDataBarObj->setMaxLength((int) $dataBarAttribute->maxLength);
 104          }
 105          if ($dataBarAttribute->border) {
 106              $extDataBarObj->setBorder((bool) (string) $dataBarAttribute->border);
 107          }
 108          if ($dataBarAttribute->gradient) {
 109              $extDataBarObj->setGradient((bool) (string) $dataBarAttribute->gradient);
 110          }
 111          if ($dataBarAttribute->direction) {
 112              $extDataBarObj->setDirection((string) $dataBarAttribute->direction);
 113          }
 114          if ($dataBarAttribute->negativeBarBorderColorSameAsPositive) {
 115              $extDataBarObj->setNegativeBarBorderColorSameAsPositive((bool) (string) $dataBarAttribute->negativeBarBorderColorSameAsPositive);
 116          }
 117          if ($dataBarAttribute->axisPosition) {
 118              $extDataBarObj->setAxisPosition((string) $dataBarAttribute->axisPosition);
 119          }
 120      }
 121  
 122      private static function parseExtDataBarElementChildrenFromXml(ConditionalDataBarExtension $extDataBarObj, SimpleXMLElement $dataBarXml, $ns): void
 123      {
 124          if ($dataBarXml->borderColor) {
 125              $extDataBarObj->setBorderColor((string) $dataBarXml->borderColor->attributes()['rgb']);
 126          }
 127          if ($dataBarXml->negativeFillColor) {
 128              $extDataBarObj->setNegativeFillColor((string) $dataBarXml->negativeFillColor->attributes()['rgb']);
 129          }
 130          if ($dataBarXml->negativeBorderColor) {
 131              $extDataBarObj->setNegativeBorderColor((string) $dataBarXml->negativeBorderColor->attributes()['rgb']);
 132          }
 133          if ($dataBarXml->axisColor) {
 134              $axisColorAttr = $dataBarXml->axisColor->attributes();
 135              $extDataBarObj->setAxisColor((string) $axisColorAttr['rgb'], (string) $axisColorAttr['theme'], (string) $axisColorAttr['tint']);
 136          }
 137          $cfvoIndex = 0;
 138          foreach ($dataBarXml->cfvo as $cfvo) {
 139              $f = (string) $cfvo->children($ns['xm'])->f;
 140              $attributes = $cfvo->attributes();
 141              if (!($attributes)) {
 142                  continue;
 143              }
 144  
 145              if ($cfvoIndex === 0) {
 146                  $extDataBarObj->setMinimumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $attributes['type'], null, (empty($f) ? null : $f)));
 147              }
 148              if ($cfvoIndex === 1) {
 149                  $extDataBarObj->setMaximumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $attributes['type'], null, (empty($f) ? null : $f)));
 150              }
 151              ++$cfvoIndex;
 152          }
 153      }
 154  
 155      /**
 156       * @return mixed
 157       */
 158      public function getId()
 159      {
 160          return $this->id;
 161      }
 162  
 163      /**
 164       * @param mixed $id
 165       */
 166      public function setId($id): self
 167      {
 168          $this->id = $id;
 169  
 170          return $this;
 171      }
 172  
 173      public function getCfRule(): string
 174      {
 175          return $this->cfRule;
 176      }
 177  
 178      public function setCfRule(string $cfRule): self
 179      {
 180          $this->cfRule = $cfRule;
 181  
 182          return $this;
 183      }
 184  
 185      public function getDataBarExt(): ConditionalDataBarExtension
 186      {
 187          return $this->dataBar;
 188      }
 189  
 190      public function setDataBarExt(ConditionalDataBarExtension $dataBar): self
 191      {
 192          $this->dataBar = $dataBar;
 193  
 194          return $this;
 195      }
 196  
 197      public function getSqref(): string
 198      {
 199          return $this->sqref;
 200      }
 201  
 202      public function setSqref(string $sqref): self
 203      {
 204          $this->sqref = $sqref;
 205  
 206          return $this;
 207      }
 208  }