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\Worksheet\AutoFilter;
   4  
   5  use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
   6  use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter;
   7  
   8  class Column
   9  {
  10      const AUTOFILTER_FILTERTYPE_FILTER = 'filters';
  11      const AUTOFILTER_FILTERTYPE_CUSTOMFILTER = 'customFilters';
  12      //    Supports no more than 2 rules, with an And/Or join criteria
  13      //        if more than 1 rule is defined
  14      const AUTOFILTER_FILTERTYPE_DYNAMICFILTER = 'dynamicFilter';
  15      //    Even though the filter rule is constant, the filtered data can vary
  16      //        e.g. filtered by date = TODAY
  17      const AUTOFILTER_FILTERTYPE_TOPTENFILTER = 'top10';
  18  
  19      /**
  20       * Types of autofilter rules.
  21       *
  22       * @var string[]
  23       */
  24      private static $filterTypes = [
  25          //    Currently we're not handling
  26          //        colorFilter
  27          //        extLst
  28          //        iconFilter
  29          self::AUTOFILTER_FILTERTYPE_FILTER,
  30          self::AUTOFILTER_FILTERTYPE_CUSTOMFILTER,
  31          self::AUTOFILTER_FILTERTYPE_DYNAMICFILTER,
  32          self::AUTOFILTER_FILTERTYPE_TOPTENFILTER,
  33      ];
  34  
  35      // Multiple Rule Connections
  36      const AUTOFILTER_COLUMN_JOIN_AND = 'and';
  37      const AUTOFILTER_COLUMN_JOIN_OR = 'or';
  38  
  39      /**
  40       * Join options for autofilter rules.
  41       *
  42       * @var string[]
  43       */
  44      private static $ruleJoins = [
  45          self::AUTOFILTER_COLUMN_JOIN_AND,
  46          self::AUTOFILTER_COLUMN_JOIN_OR,
  47      ];
  48  
  49      /**
  50       * Autofilter.
  51       *
  52       * @var AutoFilter
  53       */
  54      private $parent;
  55  
  56      /**
  57       * Autofilter Column Index.
  58       *
  59       * @var string
  60       */
  61      private $columnIndex = '';
  62  
  63      /**
  64       * Autofilter Column Filter Type.
  65       *
  66       * @var string
  67       */
  68      private $filterType = self::AUTOFILTER_FILTERTYPE_FILTER;
  69  
  70      /**
  71       * Autofilter Multiple Rules And/Or.
  72       *
  73       * @var string
  74       */
  75      private $join = self::AUTOFILTER_COLUMN_JOIN_OR;
  76  
  77      /**
  78       * Autofilter Column Rules.
  79       *
  80       * @var array of Column\Rule
  81       */
  82      private $ruleset = [];
  83  
  84      /**
  85       * Autofilter Column Dynamic Attributes.
  86       *
  87       * @var array of mixed
  88       */
  89      private $attributes = [];
  90  
  91      /**
  92       * Create a new Column.
  93       *
  94       * @param string $pColumn Column (e.g. A)
  95       * @param AutoFilter $pParent Autofilter for this column
  96       */
  97      public function __construct($pColumn, ?AutoFilter $pParent = null)
  98      {
  99          $this->columnIndex = $pColumn;
 100          $this->parent = $pParent;
 101      }
 102  
 103      /**
 104       * Get AutoFilter column index as string eg: 'A'.
 105       *
 106       * @return string
 107       */
 108      public function getColumnIndex()
 109      {
 110          return $this->columnIndex;
 111      }
 112  
 113      /**
 114       * Set AutoFilter column index as string eg: 'A'.
 115       *
 116       * @param string $pColumn Column (e.g. A)
 117       *
 118       * @return $this
 119       */
 120      public function setColumnIndex($pColumn)
 121      {
 122          // Uppercase coordinate
 123          $pColumn = strtoupper($pColumn);
 124          if ($this->parent !== null) {
 125              $this->parent->testColumnInRange($pColumn);
 126          }
 127  
 128          $this->columnIndex = $pColumn;
 129  
 130          return $this;
 131      }
 132  
 133      /**
 134       * Get this Column's AutoFilter Parent.
 135       *
 136       * @return AutoFilter
 137       */
 138      public function getParent()
 139      {
 140          return $this->parent;
 141      }
 142  
 143      /**
 144       * Set this Column's AutoFilter Parent.
 145       *
 146       * @param AutoFilter $pParent
 147       *
 148       * @return $this
 149       */
 150      public function setParent(?AutoFilter $pParent = null)
 151      {
 152          $this->parent = $pParent;
 153  
 154          return $this;
 155      }
 156  
 157      /**
 158       * Get AutoFilter Type.
 159       *
 160       * @return string
 161       */
 162      public function getFilterType()
 163      {
 164          return $this->filterType;
 165      }
 166  
 167      /**
 168       * Set AutoFilter Type.
 169       *
 170       * @param string $pFilterType
 171       *
 172       * @return $this
 173       */
 174      public function setFilterType($pFilterType)
 175      {
 176          if (!in_array($pFilterType, self::$filterTypes)) {
 177              throw new PhpSpreadsheetException('Invalid filter type for column AutoFilter.');
 178          }
 179  
 180          $this->filterType = $pFilterType;
 181  
 182          return $this;
 183      }
 184  
 185      /**
 186       * Get AutoFilter Multiple Rules And/Or Join.
 187       *
 188       * @return string
 189       */
 190      public function getJoin()
 191      {
 192          return $this->join;
 193      }
 194  
 195      /**
 196       * Set AutoFilter Multiple Rules And/Or.
 197       *
 198       * @param string $pJoin And/Or
 199       *
 200       * @return $this
 201       */
 202      public function setJoin($pJoin)
 203      {
 204          // Lowercase And/Or
 205          $pJoin = strtolower($pJoin);
 206          if (!in_array($pJoin, self::$ruleJoins)) {
 207              throw new PhpSpreadsheetException('Invalid rule connection for column AutoFilter.');
 208          }
 209  
 210          $this->join = $pJoin;
 211  
 212          return $this;
 213      }
 214  
 215      /**
 216       * Set AutoFilter Attributes.
 217       *
 218       * @param string[] $attributes
 219       *
 220       * @return $this
 221       */
 222      public function setAttributes(array $attributes)
 223      {
 224          $this->attributes = $attributes;
 225  
 226          return $this;
 227      }
 228  
 229      /**
 230       * Set An AutoFilter Attribute.
 231       *
 232       * @param string $pName Attribute Name
 233       * @param string $pValue Attribute Value
 234       *
 235       * @return $this
 236       */
 237      public function setAttribute($pName, $pValue)
 238      {
 239          $this->attributes[$pName] = $pValue;
 240  
 241          return $this;
 242      }
 243  
 244      /**
 245       * Get AutoFilter Column Attributes.
 246       *
 247       * @return string[]
 248       */
 249      public function getAttributes()
 250      {
 251          return $this->attributes;
 252      }
 253  
 254      /**
 255       * Get specific AutoFilter Column Attribute.
 256       *
 257       * @param string $pName Attribute Name
 258       *
 259       * @return string
 260       */
 261      public function getAttribute($pName)
 262      {
 263          if (isset($this->attributes[$pName])) {
 264              return $this->attributes[$pName];
 265          }
 266  
 267          return null;
 268      }
 269  
 270      /**
 271       * Get all AutoFilter Column Rules.
 272       *
 273       * @return Column\Rule[]
 274       */
 275      public function getRules()
 276      {
 277          return $this->ruleset;
 278      }
 279  
 280      /**
 281       * Get a specified AutoFilter Column Rule.
 282       *
 283       * @param int $pIndex Rule index in the ruleset array
 284       *
 285       * @return Column\Rule
 286       */
 287      public function getRule($pIndex)
 288      {
 289          if (!isset($this->ruleset[$pIndex])) {
 290              $this->ruleset[$pIndex] = new Column\Rule($this);
 291          }
 292  
 293          return $this->ruleset[$pIndex];
 294      }
 295  
 296      /**
 297       * Create a new AutoFilter Column Rule in the ruleset.
 298       *
 299       * @return Column\Rule
 300       */
 301      public function createRule()
 302      {
 303          $this->ruleset[] = new Column\Rule($this);
 304  
 305          return end($this->ruleset);
 306      }
 307  
 308      /**
 309       * Add a new AutoFilter Column Rule to the ruleset.
 310       *
 311       * @return $this
 312       */
 313      public function addRule(Column\Rule $pRule)
 314      {
 315          $pRule->setParent($this);
 316          $this->ruleset[] = $pRule;
 317  
 318          return $this;
 319      }
 320  
 321      /**
 322       * Delete a specified AutoFilter Column Rule
 323       * If the number of rules is reduced to 1, then we reset And/Or logic to Or.
 324       *
 325       * @param int $pIndex Rule index in the ruleset array
 326       *
 327       * @return $this
 328       */
 329      public function deleteRule($pIndex)
 330      {
 331          if (isset($this->ruleset[$pIndex])) {
 332              unset($this->ruleset[$pIndex]);
 333              //    If we've just deleted down to a single rule, then reset And/Or joining to Or
 334              if (count($this->ruleset) <= 1) {
 335                  $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR);
 336              }
 337          }
 338  
 339          return $this;
 340      }
 341  
 342      /**
 343       * Delete all AutoFilter Column Rules.
 344       *
 345       * @return $this
 346       */
 347      public function clearRules()
 348      {
 349          $this->ruleset = [];
 350          $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR);
 351  
 352          return $this;
 353      }
 354  
 355      /**
 356       * Implement PHP __clone to create a deep clone, not just a shallow copy.
 357       */
 358      public function __clone()
 359      {
 360          $vars = get_object_vars($this);
 361          foreach ($vars as $key => $value) {
 362              if ($key === 'parent') {
 363                  // Detach from autofilter parent
 364                  $this->parent = null;
 365              } elseif ($key === 'ruleset') {
 366                  // The columns array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter objects
 367                  $this->ruleset = [];
 368                  foreach ($value as $k => $v) {
 369                      $cloned = clone $v;
 370                      $cloned->setParent($this); // attach the new cloned Rule to this new cloned Autofilter Cloned object
 371                      $this->ruleset[$k] = $cloned;
 372                  }
 373              } elseif (is_object($value)) {
 374                  $this->$key = clone $value;
 375              } else {
 376                  $this->$key = $value;
 377              }
 378          }
 379      }
 380  }