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\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          $args = Functions::flattenArray($args);
  37  
  38          if (count($args) == 0) {
  39              return ExcelError::VALUE();
  40          }
  41  
  42          $args = array_filter($args, function ($value) {
  43              return $value !== null || (is_string($value) && trim($value) == '');
  44          });
  45  
  46          $returnValue = self::countTrueValues($args);
  47          if (is_string($returnValue)) {
  48              return $returnValue;
  49          }
  50          $argCount = count($args);
  51  
  52          return ($returnValue > 0) && ($returnValue == $argCount);
  53      }
  54  
  55      /**
  56       * LOGICAL_OR.
  57       *
  58       * Returns boolean TRUE if any argument is TRUE; returns FALSE if all arguments are FALSE.
  59       *
  60       * Excel Function:
  61       *        =OR(logical1[,logical2[, ...]])
  62       *
  63       *        The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays
  64       *            or references that contain logical values.
  65       *
  66       *        Boolean arguments are treated as True or False as appropriate
  67       *        Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
  68       *        If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string
  69       *            holds the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
  70       *
  71       * @param mixed $args Data values
  72       *
  73       * @return bool|string the logical OR of the arguments
  74       */
  75      public static function logicalOr(...$args)
  76      {
  77          $args = Functions::flattenArray($args);
  78  
  79          if (count($args) == 0) {
  80              return ExcelError::VALUE();
  81          }
  82  
  83          $args = array_filter($args, function ($value) {
  84              return $value !== null || (is_string($value) && trim($value) == '');
  85          });
  86  
  87          $returnValue = self::countTrueValues($args);
  88          if (is_string($returnValue)) {
  89              return $returnValue;
  90          }
  91  
  92          return $returnValue > 0;
  93      }
  94  
  95      /**
  96       * LOGICAL_XOR.
  97       *
  98       * Returns the Exclusive Or logical operation for one or more supplied conditions.
  99       * i.e. the Xor function returns TRUE if an odd number of the supplied conditions evaluate to TRUE,
 100       *      and FALSE otherwise.
 101       *
 102       * Excel Function:
 103       *        =XOR(logical1[,logical2[, ...]])
 104       *
 105       *        The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays
 106       *            or references that contain logical values.
 107       *
 108       *        Boolean arguments are treated as True or False as appropriate
 109       *        Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
 110       *        If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string
 111       *            holds the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
 112       *
 113       * @param mixed $args Data values
 114       *
 115       * @return bool|string the logical XOR of the arguments
 116       */
 117      public static function logicalXor(...$args)
 118      {
 119          $args = Functions::flattenArray($args);
 120  
 121          if (count($args) == 0) {
 122              return ExcelError::VALUE();
 123          }
 124  
 125          $args = array_filter($args, function ($value) {
 126              return $value !== null || (is_string($value) && trim($value) == '');
 127          });
 128  
 129          $returnValue = self::countTrueValues($args);
 130          if (is_string($returnValue)) {
 131              return $returnValue;
 132          }
 133  
 134          return $returnValue % 2 == 1;
 135      }
 136  
 137      /**
 138       * NOT.
 139       *
 140       * Returns the boolean inverse of the argument.
 141       *
 142       * Excel Function:
 143       *        =NOT(logical)
 144       *
 145       *        The argument must evaluate to a logical value such as TRUE or FALSE
 146       *
 147       *        Boolean arguments are treated as True or False as appropriate
 148       *        Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
 149       *        If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string
 150       *            holds the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
 151       *
 152       * @param mixed $logical A value or expression that can be evaluated to TRUE or FALSE
 153       *                      Or can be an array of values
 154       *
 155       * @return array|bool|string the boolean inverse of the argument
 156       *         If an array of values is passed as an argument, then the returned result will also be an array
 157       *            with the same dimensions
 158       */
 159      public static function NOT($logical = false)
 160      {
 161          if (is_array($logical)) {
 162              return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $logical);
 163          }
 164  
 165          if (is_string($logical)) {
 166              $logical = mb_strtoupper($logical, 'UTF-8');
 167              if (($logical == 'TRUE') || ($logical == Calculation::getTRUE())) {
 168                  return false;
 169              } elseif (($logical == 'FALSE') || ($logical == Calculation::getFALSE())) {
 170                  return true;
 171              }
 172  
 173              return ExcelError::VALUE();
 174          }
 175  
 176          return !$logical;
 177      }
 178  
 179      /**
 180       * @return int|string
 181       */
 182      private static function countTrueValues(array $args)
 183      {
 184          $trueValueCount = 0;
 185  
 186          foreach ($args as $arg) {
 187              // Is it a boolean value?
 188              if (is_bool($arg)) {
 189                  $trueValueCount += $arg;
 190              } elseif ((is_numeric($arg)) && (!is_string($arg))) {
 191                  $trueValueCount += ((int) $arg != 0);
 192              } elseif (is_string($arg)) {
 193                  $arg = mb_strtoupper($arg, 'UTF-8');
 194                  if (($arg == 'TRUE') || ($arg == Calculation::getTRUE())) {
 195                      $arg = true;
 196                  } elseif (($arg == 'FALSE') || ($arg == Calculation::getFALSE())) {
 197                      $arg = false;
 198                  } else {
 199                      return ExcelError::VALUE();
 200                  }
 201                  $trueValueCount += ($arg != 0);
 202              }
 203          }
 204  
 205          return $trueValueCount;
 206      }
 207  }