PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
tablepress / libraries / vendor / PhpSpreadsheet / Calculation / TextData / Concatenate.php

Concatenate.php in TablePress – Tables in WordPress made easy 3.4, at libraries/vendor/PhpSpreadsheet/Calculation/TextData/Concatenate.php

227 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TablePress\PhpOffice\PhpSpreadsheet\Calculation\TextData;
4
5 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
6 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Calculation;
7 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Functions;
8 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue;
9 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
10 use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Internal\ExcelArrayPseudoFunctions;
11 use TablePress\PhpOffice\PhpSpreadsheet\Cell\Cell;
12 use TablePress\PhpOffice\PhpSpreadsheet\Cell\DataType;
13 use TablePress\PhpOffice\PhpSpreadsheet\Shared\StringHelper;
14
15 class Concatenate
16 {
17 use ArrayEnabled;
18
19 /**
20 * This implements the CONCAT function, *not* CONCATENATE.
21 *
22 * @param mixed $args data to be concatenated
23 */
24 public static function CONCATENATE(...$args): string
25 {
26 $returnValue = '';
27
28 // Loop through arguments
29 $aArgs = Functions::flattenArray($args);
30
31 foreach ($aArgs as $arg) {
32 $value = Helpers::extractString($arg);
33 if (ErrorValue::isError($value, true)) {
34 $returnValue = $value;
35
36 break;
37 }
38 $returnValue .= Helpers::extractString($arg);
39 if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) {
40 $returnValue = ExcelError::CALC();
41
42 break;
43 }
44 }
45
46 return $returnValue;
47 }
48
49 /**
50 * This implements the CONCATENATE function.
51 *
52 * @param mixed $args data to be concatenated
53 *
54 * @return array<string>|string
55 */
56 public static function actualCONCATENATE(...$args)
57 {
58 $useSingle = false;
59 $cell = null;
60 $count = count($args);
61 if ($args[$count - 1] instanceof Cell) {
62 /** @var Cell */
63 $cell = array_pop($args);
64 $type = (($nullsafeVariable1 = $cell->getWorksheet()->getParent()) ? $nullsafeVariable1->getCalculationEngine()->getInstanceArrayReturnType() : null) ?? Calculation::getArrayReturnType();
65 $useSingle = $type === Calculation::RETURN_ARRAY_AS_VALUE;
66 }
67 if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_GNUMERIC) {
68 return self::CONCATENATE(...$args);
69 }
70 $result = '';
71 foreach ($args as $operand2) {
72 if ($useSingle && $cell instanceof Cell && is_array($operand2)) {
73 $temp = Functions::convertArrayToCellRange($operand2);
74 if ($temp !== '') {
75 $operand2 = ExcelArrayPseudoFunctions::single($temp, $cell);
76 }
77 }
78 /** @var null|array<mixed>|bool|float|int|string $operand2 */
79 $result = self::concatenate2Args($result, $operand2);
80 if (ErrorValue::isError($result, true) === true) {
81 break;
82 }
83 }
84
85 return $result;
86 }
87
88 /**
89 * @param array<string>|string $operand1
90 * @param null|array<mixed>|bool|float|int|string $operand2
91 *
92 * @return array<string>|string
93 */
94 private static function concatenate2Args($operand1, $operand2)
95 {
96 if (is_array($operand1) || is_array($operand2)) {
97 $operand1 = Calculation::boolToString($operand1);
98 $operand2 = Calculation::boolToString($operand2);
99 [$rows, $columns] = Calculation::checkMatrixOperands($operand1, $operand2, 2);
100 $errorFound = false;
101 for ($row = 0; $row < $rows && !$errorFound; ++$row) {
102 for ($column = 0; $column < $columns; ++$column) {
103 /** @var string[][] $operand2 */
104 if (ErrorValue::isError($operand2[$row][$column])) {
105 return $operand2[$row][$column];
106 }
107 /** @var string[][] $operand1 */
108 $operand1[$row][$column]
109 = StringHelper::convertToString($operand1[$row][$column], true, '', true)
110 . StringHelper::convertToString($operand2[$row][$column], true, '', true);
111 if (mb_strlen($operand1[$row][$column]) > DataType::MAX_STRING_LENGTH) {
112 $operand1 = ExcelError::CALC();
113 $errorFound = true;
114
115 break;
116 }
117 }
118 }
119 } elseif (ErrorValue::isError($operand2, true) === true) {
120 $operand1 = (string) $operand2;
121 } else {
122 $operand1 .= StringHelper::convertToString($operand2, true, '', true);
123 if (mb_strlen($operand1) > DataType::MAX_STRING_LENGTH) {
124 $operand1 = ExcelError::CALC();
125 }
126 }
127 /** @var array<string>|string $operand1 */
128
129 return $operand1;
130 }
131
132 /**
133 * TEXTJOIN.
134 *
135 * @param null|string|string[] $delimiter The delimiter to use between the joined arguments
136 * Or can be an array of values
137 * @param null|bool|bool[] $ignoreEmpty true/false Flag indicating whether empty arguments should be skipped
138 * Or can be an array of values
139 * @param mixed $args The values to join
140 *
141 * @return array<mixed>|string The joined string
142 * If an array of values is passed for the $delimiter or $ignoreEmpty arguments, then the returned result
143 * will also be an array with matching dimensions
144 */
145 public static function TEXTJOIN($delimiter = '', $ignoreEmpty = true, ...$args)
146 {
147 if (is_array($delimiter) || is_array($ignoreEmpty)) {
148 return self::evaluateArrayArgumentsSubset(
149 [self::class, __FUNCTION__],
150 2,
151 $delimiter,
152 $ignoreEmpty,
153 ...$args
154 );
155 }
156
157 $delimiter ??= '';
158 $ignoreEmpty ??= true;
159 /** @var mixed[] */
160 $aArgs = Functions::flattenArray($args);
161 $returnValue = self::evaluateTextJoinArray($ignoreEmpty, $aArgs);
162
163 /** @var string[] $aArgs */
164 $returnValue ??= implode($delimiter, $aArgs);
165 if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) {
166 $returnValue = ExcelError::CALC();
167 }
168
169 return $returnValue;
170 }
171
172 /** @param mixed[] $aArgs */
173 private static function evaluateTextJoinArray(bool $ignoreEmpty, array &$aArgs): ?string
174 {
175 foreach ($aArgs as $key => &$arg) {
176 $value = Helpers::extractString($arg);
177 if (ErrorValue::isError($value, true)) {
178 return $value;
179 }
180
181 if ($ignoreEmpty === true && ((is_string($arg) && trim($arg) === '') || $arg === null)) {
182 unset($aArgs[$key]);
183 } elseif (is_bool($arg)) {
184 $arg = Helpers::convertBooleanValue($arg);
185 }
186 }
187
188 return null;
189 }
190
191 /**
192 * REPT.
193 *
194 * Returns the result of builtin function round after validating args.
195 *
196 * @param mixed $stringValue The value to repeat
197 * Or can be an array of values
198 * @param mixed $repeatCount The number of times the string value should be repeated
199 * Or can be an array of values
200 *
201 * @return array<mixed>|string The repeated string
202 * If an array of values is passed for the $stringValue or $repeatCount arguments, then the returned result
203 * will also be an array with matching dimensions
204 */
205 public static function builtinREPT($stringValue, $repeatCount)
206 {
207 if (is_array($stringValue) || is_array($repeatCount)) {
208 return self::evaluateArrayArguments([self::class, __FUNCTION__], $stringValue, $repeatCount);
209 }
210
211 $stringValue = Helpers::extractString($stringValue);
212
213 if (!is_numeric($repeatCount) || $repeatCount < 0) {
214 $returnValue = ExcelError::VALUE();
215 } elseif (ErrorValue::isError($stringValue, true)) {
216 $returnValue = $stringValue;
217 } else {
218 $returnValue = str_repeat($stringValue, (int) $repeatCount);
219 if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) {
220 $returnValue = ExcelError::VALUE(); // note VALUE not CALC
221 }
222 }
223
224 return $returnValue;
225 }
226 }
227