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

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
   4  
   5  use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
   6  use PhpOffice\PhpSpreadsheet\Calculation\Exception;
   7  use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
   8  
   9  class Matrix
  10  {
  11      use ArrayEnabled;
  12  
  13      /**
  14       * Helper function; NOT an implementation of any Excel Function.
  15       */
  16      public static function isColumnVector(array $values): bool
  17      {
  18          return count($values, COUNT_RECURSIVE) === (count($values, COUNT_NORMAL) * 2);
  19      }
  20  
  21      /**
  22       * Helper function; NOT an implementation of any Excel Function.
  23       */
  24      public static function isRowVector(array $values): bool
  25      {
  26          return count($values, COUNT_RECURSIVE) > 1 &&
  27              (count($values, COUNT_NORMAL) === 1 || count($values, COUNT_RECURSIVE) === count($values, COUNT_NORMAL));
  28      }
  29  
  30      /**
  31       * TRANSPOSE.
  32       *
  33       * @param array|mixed $matrixData A matrix of values
  34       *
  35       * @return array
  36       */
  37      public static function transpose($matrixData)
  38      {
  39          $returnMatrix = [];
  40          if (!is_array($matrixData)) {
  41              $matrixData = [[$matrixData]];
  42          }
  43  
  44          $column = 0;
  45          foreach ($matrixData as $matrixRow) {
  46              $row = 0;
  47              foreach ($matrixRow as $matrixCell) {
  48                  $returnMatrix[$row][$column] = $matrixCell;
  49                  ++$row;
  50              }
  51              ++$column;
  52          }
  53  
  54          return $returnMatrix;
  55      }
  56  
  57      /**
  58       * INDEX.
  59       *
  60       * Uses an index to choose a value from a reference or array
  61       *
  62       * Excel Function:
  63       *        =INDEX(range_array, row_num, [column_num], [area_num])
  64       *
  65       * @param mixed $matrix A range of cells or an array constant
  66       * @param mixed $rowNum The row in the array or range from which to return a value.
  67       *                          If row_num is omitted, column_num is required.
  68       *                      Or can be an array of values
  69       * @param mixed $columnNum The column in the array or range from which to return a value.
  70       *                          If column_num is omitted, row_num is required.
  71       *                      Or can be an array of values
  72       *
  73       * TODO Provide support for area_num, currently not supported
  74       *
  75       * @return mixed the value of a specified cell or array of cells
  76       *         If an array of values is passed as the $rowNum and/or $columnNum arguments, then the returned result
  77       *            will also be an array with the same dimensions
  78       */
  79      public static function index($matrix, $rowNum = 0, $columnNum = 0)
  80      {
  81          if (is_array($rowNum) || is_array($columnNum)) {
  82              return self::evaluateArrayArgumentsSubsetFrom([self::class, __FUNCTION__], 1, $matrix, $rowNum, $columnNum);
  83          }
  84  
  85          $rowNum = $rowNum ?? 0;
  86          $columnNum = $columnNum ?? 0;
  87  
  88          try {
  89              $rowNum = LookupRefValidations::validatePositiveInt($rowNum);
  90              $columnNum = LookupRefValidations::validatePositiveInt($columnNum);
  91          } catch (Exception $e) {
  92              return $e->getMessage();
  93          }
  94  
  95          if (!is_array($matrix) || ($rowNum > count($matrix))) {
  96              return ExcelError::REF();
  97          }
  98  
  99          $rowKeys = array_keys($matrix);
 100          $columnKeys = @array_keys($matrix[$rowKeys[0]]);
 101  
 102          if ($columnNum > count($columnKeys)) {
 103              return ExcelError::REF();
 104          }
 105  
 106          if ($columnNum === 0) {
 107              return self::extractRowValue($matrix, $rowKeys, $rowNum);
 108          }
 109  
 110          $columnNum = $columnKeys[--$columnNum];
 111          if ($rowNum === 0) {
 112              return array_map(
 113                  function ($value) {
 114                      return [$value];
 115                  },
 116                  array_column($matrix, $columnNum)
 117              );
 118          }
 119          $rowNum = $rowKeys[--$rowNum];
 120  
 121          return $matrix[$rowNum][$columnNum];
 122      }
 123  
 124      private static function extractRowValue(array $matrix, array $rowKeys, int $rowNum)
 125      {
 126          if ($rowNum === 0) {
 127              return $matrix;
 128          }
 129  
 130          $rowNum = $rowKeys[--$rowNum];
 131          $row = $matrix[$rowNum];
 132          if (is_array($row)) {
 133              return [$rowNum => $row];
 134          }
 135  
 136          return $row;
 137      }
 138  }