PluginProbe
wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin / 6.5.1.7
wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin v6.5.1.7
6.5.1.7 6.5.1.6 6.5.1.5 6.5.1.4 6.5.1.3 6.5.1.2 6.5.1.1 6.5.0.9 6.5.0.8 6.5.0.7 6.5.0.6 trunk 3.4.2.40 3.4.2.41 3.4.2.42 3.4.2.43 3.4.2.44 3.4.2.45 3.4.2.46 3.4.2.47 3.4.2.48 3.4.2.49 3.4.2.50 6.3.2 6.3.3.1 All 47 releases
wpdatatables / lib / phpoffice / phpspreadsheet / src / PhpSpreadsheet / Calculation / Functions.php

Functions.php in wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin 6.5.1.7, at lib/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php

678 lines 18.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace PhpOffice\PhpSpreadsheet\Calculation;
4
5 use PhpOffice\PhpSpreadsheet\Cell\Cell;
6 use PhpOffice\PhpSpreadsheet\Shared\Date;
7
8 class Functions
9 {
10 const PRECISION = 8.88E-016;
11
12 /**
13 * 2 / PI.
14 */
15 const M_2DIVPI = 0.63661977236758134307553505349006;
16
17 const COMPATIBILITY_EXCEL = 'Excel';
18 const COMPATIBILITY_GNUMERIC = 'Gnumeric';
19 const COMPATIBILITY_OPENOFFICE = 'OpenOfficeCalc';
20
21 /** Use of RETURNDATE_PHP_NUMERIC is discouraged - not 32-bit Y2038-safe, no timezone. */
22 const RETURNDATE_PHP_NUMERIC = 'P';
23 /** Use of RETURNDATE_UNIX_TIMESTAMP is discouraged - not 32-bit Y2038-safe, no timezone. */
24 const RETURNDATE_UNIX_TIMESTAMP = 'P';
25 const RETURNDATE_PHP_OBJECT = 'O';
26 const RETURNDATE_PHP_DATETIME_OBJECT = 'O';
27 const RETURNDATE_EXCEL = 'E';
28
29 /**
30 * Compatibility mode to use for error checking and responses.
31 *
32 * @var string
33 */
34 protected static $compatibilityMode = self::COMPATIBILITY_EXCEL;
35
36 /**
37 * Data Type to use when returning date values.
38 *
39 * @var string
40 */
41 protected static $returnDateType = self::RETURNDATE_EXCEL;
42
43 /**
44 * Set the Compatibility Mode.
45 *
46 * @param string $compatibilityMode Compatibility Mode
47 * Permitted values are:
48 * Functions::COMPATIBILITY_EXCEL 'Excel'
49 * Functions::COMPATIBILITY_GNUMERIC 'Gnumeric'
50 * Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc'
51 *
52 * @return bool (Success or Failure)
53 */
54 public static function setCompatibilityMode($compatibilityMode)
55 {
56 if (
57 ($compatibilityMode == self::COMPATIBILITY_EXCEL) ||
58 ($compatibilityMode == self::COMPATIBILITY_GNUMERIC) ||
59 ($compatibilityMode == self::COMPATIBILITY_OPENOFFICE)
60 ) {
61 self::$compatibilityMode = $compatibilityMode;
62
63 return true;
64 }
65
66 return false;
67 }
68
69 /**
70 * Return the current Compatibility Mode.
71 *
72 * @return string Compatibility Mode
73 * Possible Return values are:
74 * Functions::COMPATIBILITY_EXCEL 'Excel'
75 * Functions::COMPATIBILITY_GNUMERIC 'Gnumeric'
76 * Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc'
77 */
78 public static function getCompatibilityMode()
79 {
80 return self::$compatibilityMode;
81 }
82
83 /**
84 * Set the Return Date Format used by functions that return a date/time (Excel, PHP Serialized Numeric or PHP DateTime Object).
85 *
86 * @param string $returnDateType Return Date Format
87 * Permitted values are:
88 * Functions::RETURNDATE_UNIX_TIMESTAMP 'P'
89 * Functions::RETURNDATE_PHP_DATETIME_OBJECT 'O'
90 * Functions::RETURNDATE_EXCEL 'E'
91 *
92 * @return bool Success or failure
93 */
94 public static function setReturnDateType($returnDateType)
95 {
96 if (
97 ($returnDateType == self::RETURNDATE_UNIX_TIMESTAMP) ||
98 ($returnDateType == self::RETURNDATE_PHP_DATETIME_OBJECT) ||
99 ($returnDateType == self::RETURNDATE_EXCEL)
100 ) {
101 self::$returnDateType = $returnDateType;
102
103 return true;
104 }
105
106 return false;
107 }
108
109 /**
110 * Return the current Return Date Format for functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object).
111 *
112 * @return string Return Date Format
113 * Possible Return values are:
114 * Functions::RETURNDATE_UNIX_TIMESTAMP 'P'
115 * Functions::RETURNDATE_PHP_DATETIME_OBJECT 'O'
116 * Functions::RETURNDATE_EXCEL ' 'E'
117 */
118 public static function getReturnDateType()
119 {
120 return self::$returnDateType;
121 }
122
123 /**
124 * DUMMY.
125 *
126 * @return string #Not Yet Implemented
127 */
128 public static function DUMMY()
129 {
130 return '#Not Yet Implemented';
131 }
132
133 /** @param mixed $idx */
134 public static function isMatrixValue($idx): bool
135 {
136 return (substr_count($idx, '.') <= 1) || (preg_match('/\.[A-Z]/', $idx) > 0);
137 }
138
139 /** @param mixed $idx */
140 public static function isValue($idx): bool
141 {
142 return substr_count($idx, '.') === 0;
143 }
144
145 /** @param mixed $idx */
146 public static function isCellValue($idx): bool
147 {
148 return substr_count($idx, '.') > 1;
149 }
150
151 /** @param mixed $condition */
152 public static function ifCondition($condition): string
153 {
154 $condition = self::flattenSingleValue($condition);
155
156 if ($condition === '') {
157 return '=""';
158 }
159 if (!is_string($condition) || !in_array($condition[0], ['>', '<', '='], true)) {
160 $condition = self::operandSpecialHandling($condition);
161 if (is_bool($condition)) {
162 return '=' . ($condition ? 'TRUE' : 'FALSE');
163 } elseif (!is_numeric($condition)) {
164 if ($condition !== '""') { // Not an empty string
165 // Escape any quotes in the string value
166 $condition = (string) preg_replace('/"/ui', '""', $condition);
167 }
168 $condition = Calculation::wrapResult(strtoupper($condition));
169 }
170
171 return str_replace('""""', '""', '=' . $condition);
172 }
173 preg_match('/(=|<[>=]?|>=?)(.*)/', $condition, $matches);
174 [, $operator, $operand] = $matches;
175
176 $operand = self::operandSpecialHandling($operand);
177 if (is_numeric(trim($operand, '"'))) {
178 $operand = trim($operand, '"');
179 } elseif (!is_numeric($operand) && $operand !== 'FALSE' && $operand !== 'TRUE') {
180 $operand = str_replace('"', '""', $operand);
181 $operand = Calculation::wrapResult(strtoupper($operand));
182 }
183
184 return str_replace('""""', '""', $operator . $operand);
185 }
186
187 /**
188 * @param mixed $operand
189 *
190 * @return mixed
191 */
192 private static function operandSpecialHandling($operand)
193 {
194 if (is_numeric($operand) || is_bool($operand)) {
195 return $operand;
196 } elseif (strtoupper($operand) === Calculation::getTRUE() || strtoupper($operand) === Calculation::getFALSE()) {
197 return strtoupper($operand);
198 }
199
200 // Check for percentage
201 if (preg_match('/^\-?\d*\.?\d*\s?\%$/', $operand)) {
202 return ((float) rtrim($operand, '%')) / 100;
203 }
204
205 // Check for dates
206 if (($dateValueOperand = Date::stringToExcel($operand)) !== false) {
207 return $dateValueOperand;
208 }
209
210 return $operand;
211 }
212
213 /**
214 * NULL.
215 *
216 * Returns the error value #NULL!
217 *
218 * @deprecated 1.23.0 Use the null() method in the Information\ExcelError class instead
219 * @see Information\ExcelError::null()
220 *
221 * @return string #NULL!
222 */
223 public static function null()
224 {
225 return Information\ExcelError::null();
226 }
227
228 /**
229 * NaN.
230 *
231 * Returns the error value #NUM!
232 *
233 * @deprecated 1.23.0 Use the NAN() method in the Information\Error class instead
234 * @see Information\ExcelError::NAN()
235 *
236 * @return string #NUM!
237 */
238 public static function NAN()
239 {
240 return Information\ExcelError::NAN();
241 }
242
243 /**
244 * REF.
245 *
246 * Returns the error value #REF!
247 *
248 * @deprecated 1.23.0 Use the REF() method in the Information\ExcelError class instead
249 * @see Information\ExcelError::REF()
250 *
251 * @return string #REF!
252 */
253 public static function REF()
254 {
255 return Information\ExcelError::REF();
256 }
257
258 /**
259 * NA.
260 *
261 * Excel Function:
262 * =NA()
263 *
264 * Returns the error value #N/A
265 * #N/A is the error value that means "no value is available."
266 *
267 * @deprecated 1.23.0 Use the NA() method in the Information\ExcelError class instead
268 * @see Information\ExcelError::NA()
269 *
270 * @return string #N/A!
271 */
272 public static function NA()
273 {
274 return Information\ExcelError::NA();
275 }
276
277 /**
278 * VALUE.
279 *
280 * Returns the error value #VALUE!
281 *
282 * @deprecated 1.23.0 Use the VALUE() method in the Information\ExcelError class instead
283 * @see Information\ExcelError::VALUE()
284 *
285 * @return string #VALUE!
286 */
287 public static function VALUE()
288 {
289 return Information\ExcelError::VALUE();
290 }
291
292 /**
293 * NAME.
294 *
295 * Returns the error value #NAME?
296 *
297 * @deprecated 1.23.0 Use the NAME() method in the Information\ExcelError class instead
298 * @see Information\ExcelError::NAME()
299 *
300 * @return string #NAME?
301 */
302 public static function NAME()
303 {
304 return Information\ExcelError::NAME();
305 }
306
307 /**
308 * DIV0.
309 *
310 * @deprecated 1.23.0 Use the DIV0() method in the Information\ExcelError class instead
311 * @see Information\ExcelError::DIV0()
312 *
313 * @return string #Not Yet Implemented
314 */
315 public static function DIV0()
316 {
317 return Information\ExcelError::DIV0();
318 }
319
320 /**
321 * ERROR_TYPE.
322 *
323 * @param mixed $value Value to check
324 *
325 * @deprecated 1.23.0 Use the type() method in the Information\ExcelError class instead
326 * @see Information\ExcelError::type()
327 *
328 * @return array|int|string
329 */
330 public static function errorType($value = '')
331 {
332 return Information\ExcelError::type($value);
333 }
334
335 /**
336 * IS_BLANK.
337 *
338 * @param mixed $value Value to check
339 *
340 * @deprecated 1.23.0 Use the isBlank() method in the Information\Value class instead
341 * @see Information\Value::isBlank()
342 *
343 * @return array|bool
344 */
345 public static function isBlank($value = null)
346 {
347 return Information\Value::isBlank($value);
348 }
349
350 /**
351 * IS_ERR.
352 *
353 * @param mixed $value Value to check
354 *
355 * @deprecated 1.23.0 Use the isErr() method in the Information\ErrorValue class instead
356 * @see Information\ErrorValue::isErr()
357 *
358 * @return array|bool
359 */
360 public static function isErr($value = '')
361 {
362 return Information\ErrorValue::isErr($value);
363 }
364
365 /**
366 * IS_ERROR.
367 *
368 * @param mixed $value Value to check
369 *
370 * @deprecated 1.23.0 Use the isError() method in the Information\ErrorValue class instead
371 * @see Information\ErrorValue::isError()
372 *
373 * @return array|bool
374 */
375 public static function isError($value = '')
376 {
377 return Information\ErrorValue::isError($value);
378 }
379
380 /**
381 * IS_NA.
382 *
383 * @param mixed $value Value to check
384 *
385 * @deprecated 1.23.0 Use the isNa() method in the Information\ErrorValue class instead
386 * @see Information\ErrorValue::isNa()
387 *
388 * @return array|bool
389 */
390 public static function isNa($value = '')
391 {
392 return Information\ErrorValue::isNa($value);
393 }
394
395 /**
396 * IS_EVEN.
397 *
398 * @param mixed $value Value to check
399 *
400 * @deprecated 1.23.0 Use the isEven() method in the Information\Value class instead
401 * @see Information\Value::isEven()
402 *
403 * @return array|bool|string
404 */
405 public static function isEven($value = null)
406 {
407 return Information\Value::isEven($value);
408 }
409
410 /**
411 * IS_ODD.
412 *
413 * @param mixed $value Value to check
414 *
415 * @deprecated 1.23.0 Use the isOdd() method in the Information\Value class instead
416 * @see Information\Value::isOdd()
417 *
418 * @return array|bool|string
419 */
420 public static function isOdd($value = null)
421 {
422 return Information\Value::isOdd($value);
423 }
424
425 /**
426 * IS_NUMBER.
427 *
428 * @param mixed $value Value to check
429 *
430 * @deprecated 1.23.0 Use the isNumber() method in the Information\Value class instead
431 * @see Information\Value::isNumber()
432 *
433 * @return array|bool
434 */
435 public static function isNumber($value = null)
436 {
437 return Information\Value::isNumber($value);
438 }
439
440 /**
441 * IS_LOGICAL.
442 *
443 * @param mixed $value Value to check
444 *
445 * @deprecated 1.23.0 Use the isLogical() method in the Information\Value class instead
446 * @see Information\Value::isLogical()
447 *
448 * @return array|bool
449 */
450 public static function isLogical($value = null)
451 {
452 return Information\Value::isLogical($value);
453 }
454
455 /**
456 * IS_TEXT.
457 *
458 * @param mixed $value Value to check
459 *
460 * @deprecated 1.23.0 Use the isText() method in the Information\Value class instead
461 * @see Information\Value::isText()
462 *
463 * @return array|bool
464 */
465 public static function isText($value = null)
466 {
467 return Information\Value::isText($value);
468 }
469
470 /**
471 * IS_NONTEXT.
472 *
473 * @param mixed $value Value to check
474 *
475 * @deprecated 1.23.0 Use the isNonText() method in the Information\Value class instead
476 * @see Information\Value::isNonText()
477 *
478 * @return array|bool
479 */
480 public static function isNonText($value = null)
481 {
482 return Information\Value::isNonText($value);
483 }
484
485 /**
486 * N.
487 *
488 * Returns a value converted to a number
489 *
490 * @deprecated 1.23.0 Use the asNumber() method in the Information\Value class instead
491 * @see Information\Value::asNumber()
492 *
493 * @param null|mixed $value The value you want converted
494 *
495 * @return number|string N converts values listed in the following table
496 * If value is or refers to N returns
497 * A number That number
498 * A date The serial number of that date
499 * TRUE 1
500 * FALSE 0
501 * An error value The error value
502 * Anything else 0
503 */
504 public static function n($value = null)
505 {
506 return Information\Value::asNumber($value);
507 }
508
509 /**
510 * TYPE.
511 *
512 * Returns a number that identifies the type of a value
513 *
514 * @deprecated 1.23.0 Use the type() method in the Information\Value class instead
515 * @see Information\Value::type()
516 *
517 * @param null|mixed $value The value you want tested
518 *
519 * @return number N converts values listed in the following table
520 * If value is or refers to N returns
521 * A number 1
522 * Text 2
523 * Logical Value 4
524 * An error value 16
525 * Array or Matrix 64
526 */
527 public static function TYPE($value = null)
528 {
529 return Information\Value::type($value);
530 }
531
532 /**
533 * Convert a multi-dimensional array to a simple 1-dimensional array.
534 *
535 * @param array|mixed $array Array to be flattened
536 *
537 * @return array Flattened array
538 */
539 public static function flattenArray($array)
540 {
541 if (!is_array($array)) {
542 return (array) $array;
543 }
544
545 $flattened = [];
546 $stack = array_values($array);
547
548 while (!empty($stack)) {
549 $value = array_shift($stack);
550
551 if (is_array($value)) {
552 array_unshift($stack, ...array_values($value));
553 } else {
554 $flattened[] = $value;
555 }
556 }
557
558 return $flattened;
559 }
560
561 /**
562 * @param mixed $value
563 *
564 * @return null|mixed
565 */
566 public static function scalar($value)
567 {
568 if (!is_array($value)) {
569 return $value;
570 }
571
572 do {
573 $value = array_pop($value);
574 } while (is_array($value));
575
576 return $value;
577 }
578
579 /**
580 * Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing.
581 *
582 * @param array|mixed $array Array to be flattened
583 *
584 * @return array Flattened array
585 */
586 public static function flattenArrayIndexed($array)
587 {
588 if (!is_array($array)) {
589 return (array) $array;
590 }
591
592 $arrayValues = [];
593 foreach ($array as $k1 => $value) {
594 if (is_array($value)) {
595 foreach ($value as $k2 => $val) {
596 if (is_array($val)) {
597 foreach ($val as $k3 => $v) {
598 $arrayValues[$k1 . '.' . $k2 . '.' . $k3] = $v;
599 }
600 } else {
601 $arrayValues[$k1 . '.' . $k2] = $val;
602 }
603 }
604 } else {
605 $arrayValues[$k1] = $value;
606 }
607 }
608
609 return $arrayValues;
610 }
611
612 /**
613 * Convert an array to a single scalar value by extracting the first element.
614 *
615 * @param mixed $value Array or scalar value
616 *
617 * @return mixed
618 */
619 public static function flattenSingleValue($value = '')
620 {
621 while (is_array($value)) {
622 $value = array_shift($value);
623 }
624
625 return $value;
626 }
627
628 /**
629 * ISFORMULA.
630 *
631 * @deprecated 1.23.0 Use the isFormula() method in the Information\Value class instead
632 * @see Information\Value::isFormula()
633 *
634 * @param mixed $cellReference The cell to check
635 * @param ?Cell $cell The current cell (containing this formula)
636 *
637 * @return array|bool|string
638 */
639 public static function isFormula($cellReference = '', ?Cell $cell = null)
640 {
641 return Information\Value::isFormula($cellReference, $cell);
642 }
643
644 public static function expandDefinedName(string $coordinate, Cell $cell): string
645 {
646 $worksheet = $cell->getWorksheet();
647 $spreadsheet = $worksheet->getParentOrThrow();
648 // Uppercase coordinate
649 $pCoordinatex = strtoupper($coordinate);
650 // Eliminate leading equal sign
651 $pCoordinatex = (string) preg_replace('/^=/', '', $pCoordinatex);
652 $defined = $spreadsheet->getDefinedName($pCoordinatex, $worksheet);
653 if ($defined !== null) {
654 $worksheet2 = $defined->getWorkSheet();
655 if (!$defined->isFormula() && $worksheet2 !== null) {
656 $coordinate = "'" . $worksheet2->getTitle() . "'!" .
657 (string) preg_replace('/^=/', '', str_replace('$', '', $defined->getValue()));
658 }
659 }
660
661 return $coordinate;
662 }
663
664 public static function trimTrailingRange(string $coordinate): string
665 {
666 return (string) preg_replace('/:[\w\$]+$/', '', $coordinate);
667 }
668
669 public static function trimSheetFromCellReference(string $coordinate): string
670 {
671 if (strpos($coordinate, '!') !== false) {
672 $coordinate = substr($coordinate, strrpos($coordinate, '!') + 1);
673 }
674
675 return $coordinate;
676 }
677 }
678