Passed
Push — develop ( 3028c6...9b44cf )
by Mark
29:23
created

Logical::logicalOr()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 3
nop 1
dl 0
loc 18
ccs 10
cts 10
cp 1
crap 5
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Calculation;
4
5
class Logical
6
{
7
    /**
8
     * TRUE.
9
     *
10
     * Returns the boolean TRUE.
11
     *
12
     * Excel Function:
13
     *        =TRUE()
14
     *
15
     * @category Logical Functions
16
     *
17
     * @return bool True
18
     */
19 5
    public static function true()
20
    {
21 5
        return true;
22
    }
23
24
    /**
25
     * FALSE.
26
     *
27
     * Returns the boolean FALSE.
28
     *
29
     * Excel Function:
30
     *        =FALSE()
31
     *
32
     * @category Logical Functions
33
     *
34
     * @return bool False
35
     */
36 4
    public static function false()
37
    {
38 4
        return false;
39
    }
40
41 59
    private static function countTrueValues(array $args)
42
    {
43 59
        $returnValue = 0;
44
45 59
        foreach ($args as $arg) {
46
            // Is it a boolean value?
47 57
            if (is_bool($arg)) {
48 37
                $returnValue += $arg;
49 22
            } elseif ((is_numeric($arg)) && (!is_string($arg))) {
50 16
                $returnValue += ((int) $arg != 0);
51 10
            } elseif (is_string($arg)) {
52 10
                $arg = strtoupper($arg);
53 10
                if (($arg == 'TRUE') || ($arg == Calculation::getTRUE())) {
54 3
                    $arg = true;
55 7
                } elseif (($arg == 'FALSE') || ($arg == Calculation::getFALSE())) {
56 3
                    $arg = false;
57
                } else {
58 4
                    return Functions::VALUE();
59
                }
60 53
                $returnValue += ($arg != 0);
61
            }
62
        }
63
64 55
        return $returnValue;
65
    }
66
67
    /**
68
     * LOGICAL_AND.
69
     *
70
     * Returns boolean TRUE if all its arguments are TRUE; returns FALSE if one or more argument is FALSE.
71
     *
72
     * Excel Function:
73
     *        =AND(logical1[,logical2[, ...]])
74
     *
75
     *        The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays
76
     *            or references that contain logical values.
77
     *
78
     *        Boolean arguments are treated as True or False as appropriate
79
     *        Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
80
     *        If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds
81
     *            the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
82
     *
83
     * @category Logical Functions
84
     *
85
     * @param mixed ...$args Data values
86
     *
87
     * @return bool|string the logical AND of the arguments
88
     */
89 27
    public static function logicalAnd(...$args)
90
    {
91 27
        $args = Functions::flattenArray($args);
92
93 27
        if (count($args) == 0) {
94 1
            return Functions::VALUE();
95
        }
96
97
        $args = array_filter($args, function ($value) {
98 26
            return $value !== null || (is_string($value) && trim($value) == '');
99 26
        });
100 26
        $argCount = count($args);
101
102 26
        $returnValue = self::countTrueValues($args);
103 26
        if (is_string($returnValue)) {
104 2
            return $returnValue;
105
        }
106
107 24
        return ($returnValue > 0) && ($returnValue == $argCount);
108
    }
109
110
    /**
111
     * LOGICAL_OR.
112
     *
113
     * Returns boolean TRUE if any argument is TRUE; returns FALSE if all arguments are FALSE.
114
     *
115
     * Excel Function:
116
     *        =OR(logical1[,logical2[, ...]])
117
     *
118
     *        The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays
119
     *            or references that contain logical values.
120
     *
121
     *        Boolean arguments are treated as True or False as appropriate
122
     *        Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
123
     *        If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds
124
     *            the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
125
     *
126
     * @category Logical Functions
127
     *
128
     * @param mixed $args Data values
129
     *
130
     * @return bool|string the logical OR of the arguments
131
     */
132 28
    public static function logicalOr(...$args)
133
    {
134 28
        $args = Functions::flattenArray($args);
135
136 28
        if (count($args) == 0) {
137 1
            return Functions::VALUE();
138
        }
139
140
        $args = array_filter($args, function ($value) {
141 27
            return $value !== null || (is_string($value) && trim($value) == '');
142 27
        });
143
144 27
        $returnValue = self::countTrueValues($args);
145 27
        if (is_string($returnValue)) {
146 1
            return $returnValue;
147
        }
148
149 26
        return $returnValue > 0;
150
    }
151
152
    /**
153
     * LOGICAL_XOR.
154
     *
155
     * Returns the Exclusive Or logical operation for one or more supplied conditions.
156
     * i.e. the Xor function returns TRUE if an odd number of the supplied conditions evaluate to TRUE, and FALSE otherwise.
157
     *
158
     * Excel Function:
159
     *        =XOR(logical1[,logical2[, ...]])
160
     *
161
     *        The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays
162
     *            or references that contain logical values.
163
     *
164
     *        Boolean arguments are treated as True or False as appropriate
165
     *        Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
166
     *        If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds
167
     *            the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
168
     *
169
     * @category Logical Functions
170
     *
171
     * @param mixed $args Data values
172
     *
173
     * @return bool|string the logical XOR of the arguments
174
     */
175 11
    public static function logicalXor(...$args)
176
    {
177 11
        $args = Functions::flattenArray($args);
178
179 11
        if (count($args) == 0) {
180 1
            return Functions::VALUE();
181
        }
182
183 10
        $args = array_filter($args, function ($value) {
184 10
            return $value !== null || (is_string($value) && trim($value) == '');
185 10
        });
186
187 10
        $returnValue = self::countTrueValues($args);
188 10
        if (is_string($returnValue)) {
189 1
            return $returnValue;
190
        }
191
192 9
        return $returnValue % 2 == 1;
193
    }
194
195
    /**
196
     * NOT.
197
     *
198
     * Returns the boolean inverse of the argument.
199
     *
200
     * Excel Function:
201
     *        =NOT(logical)
202
     *
203
     *        The argument must evaluate to a logical value such as TRUE or FALSE
204
     *
205
     *        Boolean arguments are treated as True or False as appropriate
206
     *        Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
207
     *        If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds
208
     *            the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
209
     *
210
     * @category Logical Functions
211
     *
212
     * @param mixed $logical A value or expression that can be evaluated to TRUE or FALSE
213
     *
214
     * @return bool|string the boolean inverse of the argument
215
     */
216 20
    public static function NOT($logical = false)
217
    {
218 20
        $logical = Functions::flattenSingleValue($logical);
219
220 20
        if (is_string($logical)) {
221 10
            $logical = strtoupper($logical);
222 10
            if (($logical == 'TRUE') || ($logical == Calculation::getTRUE())) {
223 1
                return false;
224 9
            } elseif (($logical == 'FALSE') || ($logical == Calculation::getFALSE())) {
225 1
                return true;
226
            }
227
228 8
            return Functions::VALUE();
229
        }
230
231 10
        return !$logical;
232
    }
233
234
    /**
235
     * STATEMENT_IF.
236
     *
237
     * Returns one value if a condition you specify evaluates to TRUE and another value if it evaluates to FALSE.
238
     *
239
     * Excel Function:
240
     *        =IF(condition[,returnIfTrue[,returnIfFalse]])
241
     *
242
     *        Condition is any value or expression that can be evaluated to TRUE or FALSE.
243
     *            For example, A10=100 is a logical expression; if the value in cell A10 is equal to 100,
244
     *            the expression evaluates to TRUE. Otherwise, the expression evaluates to FALSE.
245
     *            This argument can use any comparison calculation operator.
246
     *        ReturnIfTrue is the value that is returned if condition evaluates to TRUE.
247
     *            For example, if this argument is the text string "Within budget" and the condition argument evaluates to TRUE,
248
     *            then the IF function returns the text "Within budget"
249
     *            If condition is TRUE and ReturnIfTrue is blank, this argument returns 0 (zero). To display the word TRUE, use
250
     *            the logical value TRUE for this argument.
251
     *            ReturnIfTrue can be another formula.
252
     *        ReturnIfFalse is the value that is returned if condition evaluates to FALSE.
253
     *            For example, if this argument is the text string "Over budget" and the condition argument evaluates to FALSE,
254
     *            then the IF function returns the text "Over budget".
255
     *            If condition is FALSE and ReturnIfFalse is omitted, then the logical value FALSE is returned.
256
     *            If condition is FALSE and ReturnIfFalse is blank, then the value 0 (zero) is returned.
257
     *            ReturnIfFalse can be another formula.
258
     *
259
     * @category Logical Functions
260
     *
261
     * @param mixed $condition Condition to evaluate
262
     * @param mixed $returnIfTrue Value to return when condition is true
263
     * @param mixed $returnIfFalse Optional value to return when condition is false
264
     *
265
     * @return mixed The value of returnIfTrue or returnIfFalse determined by condition
266
     */
267 28
    public static function statementIf($condition = true, $returnIfTrue = 0, $returnIfFalse = false)
268
    {
269 28
        $condition = ($condition === null) ? true : (bool) Functions::flattenSingleValue($condition);
270 28
        $returnIfTrue = ($returnIfTrue === null) ? 0 : Functions::flattenSingleValue($returnIfTrue);
271 28
        $returnIfFalse = ($returnIfFalse === null) ? false : Functions::flattenSingleValue($returnIfFalse);
272
273 28
        return ($condition) ? $returnIfTrue : $returnIfFalse;
274
    }
275
276
    /**
277
     * IFERROR.
278
     *
279
     * Excel Function:
280
     *        =IFERROR(testValue,errorpart)
281
     *
282
     * @category Logical Functions
283
     *
284
     * @param mixed $testValue Value to check, is also the value returned when no error
285
     * @param mixed $errorpart Value to return when testValue is an error condition
286
     *
287
     * @return mixed The value of errorpart or testValue determined by error condition
288
     */
289 8
    public static function IFERROR($testValue = '', $errorpart = '')
290
    {
291 8
        $testValue = ($testValue === null) ? '' : Functions::flattenSingleValue($testValue);
292 8
        $errorpart = ($errorpart === null) ? '' : Functions::flattenSingleValue($errorpart);
293
294 8
        return self::statementIf(Functions::isError($testValue), $errorpart, $testValue);
295
    }
296
}
297