Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [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              : (
 131                  $this->ifNotExists === self::IF_NOT_EXISTS_CREATE_NEW
 132                  ? $this->worksheet->createNewCell($cellAddress)
 133                  : null
 134              );
 135      }
 136  
 137      /**
 138       * Return the current iterator key.
 139       */
 140      public function key(): string
 141      {
 142          return Coordinate::stringFromColumnIndex($this->currentColumnIndex);
 143      }
 144  
 145      /**
 146       * Set the iterator to its next value.
 147       */
 148      public function next(): void
 149      {
 150          do {
 151              ++$this->currentColumnIndex;
 152          } while (($this->onlyExistingCells) && (!$this->cellCollection->has(Coordinate::stringFromColumnIndex($this->currentColumnIndex) . $this->rowIndex)) && ($this->currentColumnIndex <= $this->endColumnIndex));
 153      }
 154  
 155      /**
 156       * Set the iterator to its previous value.
 157       */
 158      public function prev(): void
 159      {
 160          do {
 161              --$this->currentColumnIndex;
 162          } while (($this->onlyExistingCells) && (!$this->cellCollection->has(Coordinate::stringFromColumnIndex($this->currentColumnIndex) . $this->rowIndex)) && ($this->currentColumnIndex >= $this->startColumnIndex));
 163      }
 164  
 165      /**
 166       * Indicate if more columns exist in the worksheet range of columns that we're iterating.
 167       */
 168      public function valid(): bool
 169      {
 170          return $this->currentColumnIndex <= $this->endColumnIndex && $this->currentColumnIndex >= $this->startColumnIndex;
 171      }
 172  
 173      /**
 174       * Return the current iterator position.
 175       */
 176      public function getCurrentColumnIndex(): int
 177      {
 178          return $this->currentColumnIndex;
 179      }
 180  
 181      /**
 182       * Validate start/end values for "IterateOnlyExistingCells" mode, and adjust if necessary.
 183       */
 184      protected function adjustForExistingOnlyRange(): void
 185      {
 186          if ($this->onlyExistingCells) {
 187              while ((!$this->cellCollection->has(Coordinate::stringFromColumnIndex($this->startColumnIndex) . $this->rowIndex)) && ($this->startColumnIndex <= $this->endColumnIndex)) {
 188                  ++$this->startColumnIndex;
 189              }
 190              while ((!$this->cellCollection->has(Coordinate::stringFromColumnIndex($this->endColumnIndex) . $this->rowIndex)) && ($this->endColumnIndex >= $this->startColumnIndex)) {
 191                  --$this->endColumnIndex;
 192              }
 193          }
 194      }
 195  }