Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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