Search moodle.org's
Developer Documentation

See Release Notes

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

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

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet;
   4  
   5  use PhpOffice\PhpSpreadsheet\Cell\AddressRange;
   6  use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
   7  
   8  class CellReferenceHelper
   9  {
  10      /**
  11       * @var string
  12       */
  13      protected $beforeCellAddress;
  14  
  15      /**
  16       * @var int
  17       */
  18      protected $beforeColumn;
  19  
  20      /**
  21       * @var int
  22       */
  23      protected $beforeRow;
  24  
  25      /**
  26       * @var int
  27       */
  28      protected $numberOfColumns;
  29  
  30      /**
  31       * @var int
  32       */
  33      protected $numberOfRows;
  34  
  35      public function __construct(string $beforeCellAddress = 'A1', int $numberOfColumns = 0, int $numberOfRows = 0)
  36      {
  37          $this->beforeCellAddress = str_replace('$', '', $beforeCellAddress);
  38          $this->numberOfColumns = $numberOfColumns;
  39          $this->numberOfRows = $numberOfRows;
  40  
  41          // Get coordinate of $beforeCellAddress
  42          [$beforeColumn, $beforeRow] = Coordinate::coordinateFromString($beforeCellAddress);
  43          $this->beforeColumn = (int) Coordinate::columnIndexFromString($beforeColumn);
  44          $this->beforeRow = (int) $beforeRow;
  45      }
  46  
  47      public function beforeCellAddress(): string
  48      {
  49          return $this->beforeCellAddress;
  50      }
  51  
  52      public function refreshRequired(string $beforeCellAddress, int $numberOfColumns, int $numberOfRows): bool
  53      {
  54          return $this->beforeCellAddress !== $beforeCellAddress ||
  55              $this->numberOfColumns !== $numberOfColumns ||
  56              $this->numberOfRows !== $numberOfRows;
  57      }
  58  
  59      public function updateCellReference(string $cellReference = 'A1', bool $includeAbsoluteReferences = false): string
  60      {
  61          if (Coordinate::coordinateIsRange($cellReference)) {
  62              throw new Exception('Only single cell references may be passed to this method.');
  63          }
  64  
  65          // Get coordinate of $cellReference
  66          [$newColumn, $newRow] = Coordinate::coordinateFromString($cellReference);
  67          $newColumnIndex = (int) Coordinate::columnIndexFromString(str_replace('$', '', $newColumn));
  68          $newRowIndex = (int) str_replace('$', '', $newRow);
  69  
  70          $absoluteColumn = $newColumn[0] === '$' ? '$' : '';
  71          $absoluteRow = $newRow[0] === '$' ? '$' : '';
  72          // Verify which parts should be updated
  73          if ($includeAbsoluteReferences === false) {
  74              $updateColumn = (($absoluteColumn !== '$') && $newColumnIndex >= $this->beforeColumn);
  75              $updateRow = (($absoluteRow !== '$') && $newRowIndex >= $this->beforeRow);
  76          } else {
  77              $updateColumn = ($newColumnIndex >= $this->beforeColumn);
  78              $updateRow = ($newRowIndex >= $this->beforeRow);
  79          }
  80  
  81          // Create new column reference
  82          if ($updateColumn) {
  83              $newColumn = $this->updateColumnReference($newColumnIndex, $absoluteColumn);
  84          }
  85  
  86          // Create new row reference
  87          if ($updateRow) {
  88              $newRow = $this->updateRowReference($newRowIndex, $absoluteRow);
  89          }
  90  
  91          // Return new reference
  92          return "{$newColumn}{$newRow}";
  93      }
  94  
  95      public function cellAddressInDeleteRange(string $cellAddress): bool
  96      {
  97          [$cellColumn, $cellRow] = Coordinate::coordinateFromString($cellAddress);
  98          $cellColumnIndex = Coordinate::columnIndexFromString($cellColumn);
  99          //    Is cell within the range of rows/columns if we're deleting
 100          if (
 101              $this->numberOfRows < 0 &&
 102              ($cellRow >= ($this->beforeRow + $this->numberOfRows)) &&
 103              ($cellRow < $this->beforeRow)
 104          ) {
 105              return true;
 106          } elseif (
 107              $this->numberOfColumns < 0 &&
 108              ($cellColumnIndex >= ($this->beforeColumn + $this->numberOfColumns)) &&
 109              ($cellColumnIndex < $this->beforeColumn)
 110          ) {
 111              return true;
 112          }
 113  
 114          return false;
 115      }
 116  
 117      protected function updateColumnReference(int $newColumnIndex, string $absoluteColumn): string
 118      {
 119          $newColumn = Coordinate::stringFromColumnIndex(min($newColumnIndex + $this->numberOfColumns, AddressRange::MAX_COLUMN_INT));
 120  
 121          return $absoluteColumn . $newColumn;
 122      }
 123  
 124      protected function updateRowReference(int $newRowIndex, string $absoluteRow): string
 125      {
 126          $newRow = $newRowIndex + $this->numberOfRows;
 127          $newRow = ($newRow > AddressRange::MAX_ROW) ? AddressRange::MAX_ROW : $newRow;
 128  
 129          return $absoluteRow . (string) $newRow;
 130      }
 131  }