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.
   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Calculation;
   4  
   5  use PhpOffice\PhpSpreadsheet\Calculation\Engine\ArrayArgumentHelper;
   6  use PhpOffice\PhpSpreadsheet\Calculation\Engine\ArrayArgumentProcessor;
   7  
   8  trait ArrayEnabled
   9  {
  10      /**
  11       * @var ArrayArgumentHelper
  12       */
  13      private static $arrayArgumentHelper;
  14  
  15      /**
  16       * @param array|false $arguments Can be changed to array for Php8.1+
  17       */
  18      private static function initialiseHelper($arguments): void
  19      {
  20          if (self::$arrayArgumentHelper === null) {
  21              self::$arrayArgumentHelper = new ArrayArgumentHelper();
  22          }
  23          self::$arrayArgumentHelper->initialise(($arguments === false) ? [] : $arguments);
  24      }
  25  
  26      /**
  27       * Handles array argument processing when the function accepts a single argument that can be an array argument.
  28       * Example use for:
  29       *         DAYOFMONTH() or FACT().
  30       */
  31      protected static function evaluateSingleArgumentArray(callable $method, array $values): array
  32      {
  33          $result = [];
  34          foreach ($values as $value) {
  35              $result[] = $method($value);
  36          }
  37  
  38          return $result;
  39      }
  40  
  41      /**
  42       * Handles array argument processing when the function accepts multiple arguments,
  43       *     and any of them can be an array argument.
  44       * Example use for:
  45       *         ROUND() or DATE().
  46       *
  47       * @param mixed ...$arguments
  48       */
  49      protected static function evaluateArrayArguments(callable $method, ...$arguments): array
  50      {
  51          self::initialiseHelper($arguments);
  52          $arguments = self::$arrayArgumentHelper->arguments();
  53  
  54          return ArrayArgumentProcessor::processArguments(self::$arrayArgumentHelper, $method, ...$arguments);
  55      }
  56  
  57      /**
  58       * Handles array argument processing when the function accepts multiple arguments,
  59       *     but only the first few (up to limit) can be an array arguments.
  60       * Example use for:
  61       *         NETWORKDAYS() or CONCATENATE(), where the last argument is a matrix (or a series of values) that need
  62       *                                         to be treated as a such rather than as an array arguments.
  63       *
  64       * @param mixed ...$arguments
  65       */
  66      protected static function evaluateArrayArgumentsSubset(callable $method, int $limit, ...$arguments): array
  67      {
  68          self::initialiseHelper(array_slice($arguments, 0, $limit));
  69          $trailingArguments = array_slice($arguments, $limit);
  70          $arguments = self::$arrayArgumentHelper->arguments();
  71          $arguments = array_merge($arguments, $trailingArguments);
  72  
  73          return ArrayArgumentProcessor::processArguments(self::$arrayArgumentHelper, $method, ...$arguments);
  74      }
  75  
  76      /**
  77       * @param mixed $value
  78       */
  79      private static function testFalse($value): bool
  80      {
  81          return $value === false;
  82      }
  83  
  84      /**
  85       * Handles array argument processing when the function accepts multiple arguments,
  86       *     but only the last few (from start) can be an array arguments.
  87       * Example use for:
  88       *         Z.TEST() or INDEX(), where the first argument 1 is a matrix that needs to be treated as a dataset
  89       *                   rather than as an array argument.
  90       *
  91       * @param mixed ...$arguments
  92       */
  93      protected static function evaluateArrayArgumentsSubsetFrom(callable $method, int $start, ...$arguments): array
  94      {
  95          $arrayArgumentsSubset = array_combine(
  96              range($start, count($arguments) - $start),
  97              array_slice($arguments, $start)
  98          );
  99          if (self::testFalse($arrayArgumentsSubset)) {
 100              return ['#VALUE!'];
 101          }
 102  
 103          self::initialiseHelper($arrayArgumentsSubset);
 104          $leadingArguments = array_slice($arguments, 0, $start);
 105          $arguments = self::$arrayArgumentHelper->arguments();
 106          $arguments = array_merge($leadingArguments, $arguments);
 107  
 108          return ArrayArgumentProcessor::processArguments(self::$arrayArgumentHelper, $method, ...$arguments);
 109      }
 110  
 111      /**
 112       * Handles array argument processing when the function accepts multiple arguments,
 113       *     and any of them can be an array argument except for the one specified by ignore.
 114       * Example use for:
 115       *         HLOOKUP() and VLOOKUP(), where argument 1 is a matrix that needs to be treated as a database
 116       *                                  rather than as an array argument.
 117       *
 118       * @param mixed ...$arguments
 119       */
 120      protected static function evaluateArrayArgumentsIgnore(callable $method, int $ignore, ...$arguments): array
 121      {
 122          $leadingArguments = array_slice($arguments, 0, $ignore);
 123          $ignoreArgument = array_slice($arguments, $ignore, 1);
 124          $trailingArguments = array_slice($arguments, $ignore + 1);
 125  
 126          self::initialiseHelper(array_merge($leadingArguments, [[null]], $trailingArguments));
 127          $arguments = self::$arrayArgumentHelper->arguments();
 128  
 129          array_splice($arguments, $ignore, 1, $ignoreArgument);
 130  
 131          return ArrayArgumentProcessor::processArguments(self::$arrayArgumentHelper, $method, ...$arguments);
 132      }
 133  }