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

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Calculation\Logical;
   4  
   5  use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
   6  use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
   7  use PhpOffice\PhpSpreadsheet\Calculation\Functions;
   8  use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
   9  
  10  class Operations
  11  {
  12      use ArrayEnabled;
  13  
  14      /**
  15       * LOGICAL_AND.
  16       *
  17       * Returns boolean TRUE if all its arguments are TRUE; returns FALSE if one or more argument is FALSE.
  18       *
  19       * Excel Function:
  20       *        =AND(logical1[,logical2[, ...]])
  21       *
  22       *        The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays
  23       *            or references that contain logical values.
  24       *
  25       *        Boolean arguments are treated as True or False as appropriate
  26       *        Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
  27       *        If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string
  28       *            holds the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
  29       *
  30       * @param mixed ...$args Data values
  31       *
  32       * @return bool|string the logical AND of the arguments
  33       */
  34      public static function logicalAnd(...$args)
  35      {
  36          return self::countTrueValues($args, function (int $trueValueCount, int $count): bool {
  37              return $trueValueCount === $count;
  38          });
  39      }
  40  
  41      /**
  42       * LOGICAL_OR.
  43       *
  44       * Returns boolean TRUE if any argument is TRUE; returns FALSE if all arguments are FALSE.
  45       *
  46       * Excel Function:
  47       *        =OR(logical1[,logical2[, ...]])
  48       *
  49       *        The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays
  50       *            or references that contain logical values.
  51       *
  52       *        Boolean arguments are treated as True or False as appropriate
  53       *        Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
  54       *        If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string
  55       *            holds the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
  56       *
  57       * @param mixed $args Data values
  58       *
  59       * @return bool|string the logical OR of the arguments
  60       */
  61      public static function logicalOr(...$args)
  62      {
  63          return self::countTrueValues($args, function (int $trueValueCount): bool {
  64              return $trueValueCount > 0;
  65          });
  66      }
  67  
  68      /**
  69       * LOGICAL_XOR.
  70       *
  71       * Returns the Exclusive Or logical operation for one or more supplied conditions.
  72       * i.e. the Xor function returns TRUE if an odd number of the supplied conditions evaluate to TRUE,
  73       *      and FALSE otherwise.
  74       *
  75       * Excel Function:
  76       *        =XOR(logical1[,logical2[, ...]])
  77       *
  78       *        The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays
  79       *            or references that contain logical values.
  80       *
  81       *        Boolean arguments are treated as True or False as appropriate
  82       *        Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
  83       *        If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string
  84       *            holds the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
  85       *
  86       * @param mixed $args Data values
  87       *
  88       * @return bool|string the logical XOR of the arguments
  89       */
  90      public static function logicalXor(...$args)
  91      {
  92          return self::countTrueValues($args, function (int $trueValueCount): bool {
  93              return $trueValueCount % 2 === 1;
  94          });
  95      }
  96  
  97      /**
  98       * NOT.
  99       *
 100       * Returns the boolean inverse of the argument.
 101       *
 102       * Excel Function:
 103       *        =NOT(logical)
 104       *
 105       *        The argument must evaluate to a logical value such as TRUE or FALSE
 106       *
 107       *        Boolean arguments are treated as True or False as appropriate
 108       *        Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
 109       *        If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string
 110       *            holds the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
 111       *
 112       * @param mixed $logical A value or expression that can be evaluated to TRUE or FALSE
 113       *                      Or can be an array of values
 114       *
 115       * @return array|bool|string the boolean inverse of the argument
 116       *         If an array of values is passed as an argument, then the returned result will also be an array
 117       *            with the same dimensions
 118       */
 119      public static function NOT($logical = false)
 120      {
 121          if (is_array($logical)) {
 122              return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $logical);
 123          }
 124  
 125          if (is_string($logical)) {
 126              $logical = mb_strtoupper($logical, 'UTF-8');
 127              if (($logical == 'TRUE') || ($logical == Calculation::getTRUE())) {
 128                  return false;
 129              } elseif (($logical == 'FALSE') || ($logical == Calculation::getFALSE())) {
 130                  return true;
 131              }
 132  
 133              return ExcelError::VALUE();
 134          }
 135  
 136          return !$logical;
 137      }
 138  
 139      /**
 140       * @return bool|string
 141       */
 142      private static function countTrueValues(array $args, callable $func)
 143      {
 144          $trueValueCount = 0;
 145          $count = 0;
 146  
 147          $aArgs = Functions::flattenArrayIndexed($args);
 148          foreach ($aArgs as $k => $arg) {
 149              ++$count;
 150              // Is it a boolean value?
 151              if (is_bool($arg)) {
 152                  $trueValueCount += $arg;
 153              } elseif (is_string($arg)) {
 154                  $isLiteral = !Functions::isCellValue($k);
 155                  $arg = mb_strtoupper($arg, 'UTF-8');
 156                  if ($isLiteral && ($arg == 'TRUE' || $arg == Calculation::getTRUE())) {
 157                      ++$trueValueCount;
 158                  } elseif ($isLiteral && ($arg == 'FALSE' || $arg == Calculation::getFALSE())) {
 159                      //$trueValueCount += 0;
 160                  } else {
 161                      --$count;
 162                  }
 163              } elseif (is_int($arg) || is_float($arg)) {
 164                  $trueValueCount += (int) ($arg != 0);
 165              } else {
 166                  --$count;
 167              }
 168          }
 169  
 170          return ($count === 0) ? ExcelError::VALUE() : $func($trueValueCount, $count);
 171      }
 172  }