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

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Worksheet;
   4  
   5  use PhpOffice\PhpSpreadsheet\Cell\Cell;
   6  use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
   7  use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
   8  
   9  /**
  10   * @extends CellIterator<string>
  11   */
  12  class RowCellIterator extends CellIterator
  13  {
  14      /**
  15       * Current iterator position.
  16       *
  17       * @var int
  18       */
  19      private $currentColumnIndex;
  20  
  21      /**
  22       * Row index.
  23       *
  24       * @var int
  25       */
  26      private $rowIndex = 1;
  27  
  28      /**
  29       * Start position.
  30       *
  31       * @var int
  32       */
  33      private $startColumnIndex = 1;
  34  
  35      /**
  36       * End position.
  37       *
  38       * @var int
  39       */
  40      private $endColumnIndex = 1;
  41  
  42      /**
  43       * Create a new column iterator.
  44       *
  45       * @param Worksheet $worksheet The worksheet to iterate over
  46       * @param int $rowIndex The row that we want to iterate
  47       * @param string $startColumn The column address at which to start iterating
  48       * @param string $endColumn Optionally, the column address at which to stop iterating
  49       */
  50      public function __construct(Worksheet $worksheet, $rowIndex = 1, $startColumn = 'A', $endColumn = null)
  51      {
  52          // Set subject and row index
  53          $this->worksheet = $worksheet;
  54          $this->cellCollection = $worksheet->getCellCollection();
  55          $this->rowIndex = $rowIndex;
  56          $this->resetEnd($endColumn);
  57          $this->resetStart($startColumn);
  58      }
  59  
  60      /**
  61       * (Re)Set the start column and the current column pointer.
  62       *
  63       * @param string $startColumn The column address at which to start iterating
  64       *
  65       * @return $this
  66       */
  67      public function resetStart(string $startColumn = 'A')
  68      {
  69          $this->startColumnIndex = Coordinate::columnIndexFromString($startColumn);
  70          $this->adjustForExistingOnlyRange();
  71          $this->seek(Coordinate::stringFromColumnIndex($this->startColumnIndex));
  72  
  73          return $this;
  74      }
  75  
  76      /**
  77       * (Re)Set the end column.
  78       *
  79       * @param string $endColumn The column address at which to stop iterating
  80       *
  81       * @return $this
  82       */
  83      public function resetEnd($endColumn = null)
  84      {
  85          $endColumn = $endColumn ?: $this->worksheet->getHighestColumn();
  86          $this->endColumnIndex = Coordinate::columnIndexFromString($endColumn);
  87          $this->adjustForExistingOnlyRange();
  88  
  89          return $this;
  90      }
  91  
  92      /**
  93       * Set the column pointer to the selected column.
  94       *
  95       * @param string $column The column address to set the current pointer at
  96       *
  97       * @return $this
  98       */
  99      public function seek(string $column = 'A')
 100      {
 101          $columnId = Coordinate::columnIndexFromString($column);
 102          if ($this->onlyExistingCells && !($this->cellCollection->has($column . $this->rowIndex))) {
 103              throw new PhpSpreadsheetException('In "IterateOnlyExistingCells" mode and Cell does not exist');
 104          }
 105          if (($columnId < $this->startColumnIndex) || ($columnId > $this->endColumnIndex)) {
 106              throw new PhpSpreadsheetException("Column $column is out of range ({$this->startColumnIndex} - {$this->endColumnIndex})");
 107          }
 108          $this->currentColumnIndex = $columnId;
 109  
 110          return $this;
 111      }
 112  
 113      /**
 114       * Rewind the iterator to the starting column.
 115       */
 116      public function rewind(): void
 117      {
 118          $this->currentColumnIndex = $this->startColumnIndex;
 119      }
 120  
 121      /**
 122       * Return the current cell in this worksheet row.
 123       */
 124      public function current(): ?Cell
 125      {
 126          $cellAddress = Coordinate::stringFromColumnIndex($this->currentColumnIndex) . $this->rowIndex;
 127  
 128          return $this->cellCollection->has($cellAddress)
 129              ? $this->cellCollection->get($cellAddress)
 130              : $this->worksheet->createNewCell($cellAddress);
 131      }
 132  
 133      /**
 134       * Return the current iterator key.
 135       */
 136      public function key(): string
 137      {
 138          return Coordinate::stringFromColumnIndex($this->currentColumnIndex);
 139      }
 140  
 141      /**
 142       * Set the iterator to its next value.
 143       */
 144      public function next(): void
 145      {
 146          do {
 147              ++$this->currentColumnIndex;
 148          } while (($this->onlyExistingCells) && (!$this->cellCollection->has(Coordinate::stringFromColumnIndex($this->currentColumnIndex) . $this->rowIndex)) && ($this->currentColumnIndex <= $this->endColumnIndex));
 149      }
 150  
 151      /**
 152       * Set the iterator to its previous value.
 153       */
 154      public function prev(): void
 155      {
 156          do {
 157              --$this->currentColumnIndex;
 158          } while (($this->onlyExistingCells) && (!$this->cellCollection->has(Coordinate::stringFromColumnIndex($this->currentColumnIndex) . $this->rowIndex)) && ($this->currentColumnIndex >= $this->startColumnIndex));
 159      }
 160  
 161      /**
 162       * Indicate if more columns exist in the worksheet range of columns that we're iterating.
 163       */
 164      public function valid(): bool
 165      {
 166          return $this->currentColumnIndex <= $this->endColumnIndex && $this->currentColumnIndex >= $this->startColumnIndex;
 167      }
 168  
 169      /**
 170       * Return the current iterator position.
 171       */
 172      public function getCurrentColumnIndex(): int
 173      {
 174          return $this->currentColumnIndex;
 175      }
 176  
 177      /**
 178       * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary.
 179       */
 180      protected function adjustForExistingOnlyRange(): void
 181      {
 182          if ($this->onlyExistingCells) {
 183              while ((!$this->cellCollection->has(Coordinate::stringFromColumnIndex($this->startColumnIndex) . $this->rowIndex)) && ($this->startColumnIndex <= $this->endColumnIndex)) {
 184                  ++$this->startColumnIndex;
 185              }
 186              while ((!$this->cellCollection->has(Coordinate::stringFromColumnIndex($this->endColumnIndex) . $this->rowIndex)) && ($this->endColumnIndex >= $this->startColumnIndex)) {
 187                  --$this->endColumnIndex;
 188              }
 189          }
 190      }
 191  }