PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / trunk
JetBackup – Backup, Restore & Migrate vtrunk
3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / src / JetBackup / 3rdparty / SleekDB / Classes / DocumentReducer.php
backup / src / JetBackup / 3rdparty / SleekDB / Classes Last commit date
.htaccess 1 year ago CacheHandler.php 1 year ago ConditionsHandler.php 1 year ago DocumentFinder.php 1 year ago DocumentReducer.php 1 year ago DocumentUpdater.php 4 months ago IoHelper.php 4 months ago NestedHelper.php 1 year ago index.html 1 year ago web.config 1 year ago
DocumentReducer.php
665 lines
1 <?php
2
3
4 namespace SleekDB\Classes;
5
6
7 use Closure;
8 use SleekDB\Exceptions\InvalidArgumentException;
9 use SleekDB\Exceptions\IOException;
10 use SleekDB\QueryBuilder;
11 use SleekDB\SleekDB;
12
13 /**
14 * Class DocumentReducer
15 * Alters one or multiple documents
16 */
17 class DocumentReducer
18 {
19
20 const SELECT_FUNCTIONS = [
21 "AVG" => "avg",
22 "MAX" => "max",
23 "MIN" => "min",
24 "SUM" => "sum",
25 "ROUND" => "round",
26 "ABS" => "abs",
27 "POSITION" => "position",
28 "UPPER" => "upper",
29 "LOWER" => "lower",
30 "LENGTH" => "length",
31 "CONCAT" => "concat",
32 "CUSTOM" => "custom",
33 ];
34
35 const SELECT_FUNCTIONS_THAT_REDUCE_RESULT = [
36 "AVG" => "avg",
37 "MAX" => "max",
38 "MIN" => "min",
39 "SUM" => "sum"
40 ];
41
42 /**
43 * @param array $found
44 * @param array $fieldsToExclude
45 */
46 public static function excludeFields(array &$found, array $fieldsToExclude){
47 if (empty($fieldsToExclude)) {
48 return;
49 }
50 foreach ($found as $key => &$document) {
51 if(!is_array($document)){
52 continue;
53 }
54 foreach ($fieldsToExclude as $fieldToExclude) {
55 NestedHelper::removeNestedField($document, $fieldToExclude);
56 }
57 }
58 }
59
60 /**
61 * @param array $results
62 * @param array $listOfJoins
63 * @throws IOException
64 * @throws InvalidArgumentException
65 */
66 public static function joinData(array &$results, array $listOfJoins){
67 if(empty($listOfJoins)){
68 return;
69 }
70 // Join data.
71 foreach ($results as $key => $doc) {
72 foreach ($listOfJoins as $join) {
73 // Execute the child query.
74 $joinQuery = ($join['joinFunction'])($doc); // QueryBuilder or result of fetch
75 $propertyName = $join['propertyName'];
76
77 // TODO remove SleekDB check in version 3.0
78 if($joinQuery instanceof QueryBuilder || $joinQuery instanceof SleekDB){
79 $joinResult = $joinQuery->getQuery()->fetch();
80 } else if(is_array($joinQuery)){
81 // user already fetched the query in the join query function
82 $joinResult = $joinQuery;
83 } else {
84 throw new InvalidArgumentException("Invalid join query.");
85 }
86
87 // Add child documents with the current document.
88 $results[$key][$propertyName] = $joinResult;
89 }
90 }
91 }
92
93 /**
94 * @param array $found
95 * @param array $groupBy
96 * @param array $fieldsToSelect
97 * @throws InvalidArgumentException
98 */
99 public static function handleGroupBy(array &$found, array $groupBy, array $fieldsToSelect)
100 {
101 if(empty($groupBy)){
102 return;
103 }
104 // TODO optimize algorithm if possible
105 $groupByFields = $groupBy["groupByFields"];
106 $countKeyName = $groupBy["countKeyName"];
107 $allowEmpty = $groupBy["allowEmpty"];
108
109 $hasSelectFunctionThatNotReduceResult = false;
110 $hasSelectFunctionThatReduceResult = false;
111
112 $pattern = (!empty($fieldsToSelect))? $fieldsToSelect : $groupByFields;
113
114 if(!empty($countKeyName) && empty($fieldsToSelect)){
115 $pattern[] = $countKeyName;
116 }
117
118 // remove duplicates
119 $patternWithOutDuplicates = [];
120 foreach ($pattern as $key => $value){
121 if(array_key_exists($key, $patternWithOutDuplicates) && in_array($value, $patternWithOutDuplicates, true)){
122 continue;
123 }
124 $patternWithOutDuplicates[$key] = $value;
125
126 // validate pattern
127 if(!is_string($key) && !is_string($value)){
128 throw new InvalidArgumentException("You need to format the select correctly when using Group By.");
129 }
130 if(!is_string($value)) {
131
132 if($value instanceof Closure){
133 if($hasSelectFunctionThatNotReduceResult === false){
134 $hasSelectFunctionThatNotReduceResult = true;
135 }
136 if(!in_array($key, $groupByFields, true)){ // key is fieldAlias
137 throw new InvalidArgumentException("You can not select a field \"$key\" that is not grouped by.");
138 }
139 continue;
140 }
141
142 if (!is_array($value) || empty($value)) {
143 throw new InvalidArgumentException("You need to format the select correctly when using Group By.");
144 }
145
146 list($function) = array_keys($value);
147 $functionParameters = $value[$function];
148 self::getFieldNamesOfSelectFunction($function, $functionParameters);
149
150 if(is_string($function) ){
151 if(!in_array(strtolower($function), self::SELECT_FUNCTIONS_THAT_REDUCE_RESULT)){
152 if($hasSelectFunctionThatNotReduceResult === false){
153 $hasSelectFunctionThatNotReduceResult = true;
154 }
155 if(!in_array($key, $groupByFields, true)){ // key is fieldAlias
156 throw new InvalidArgumentException("You can not select a field \"$key\" that is not grouped by.");
157 }
158 } else if($hasSelectFunctionThatReduceResult === false){
159 $hasSelectFunctionThatReduceResult = true;
160 }
161 }
162 } else if($value !== $countKeyName && !in_array($value, $groupByFields, true)) {
163 throw new InvalidArgumentException("You can not select a field that is not grouped by.");
164 }
165 }
166 $pattern = $patternWithOutDuplicates;
167 unset($patternWithOutDuplicates);
168
169 // Apply select functions that do not reduce result before grouping
170 if($hasSelectFunctionThatNotReduceResult){
171 foreach ($found as &$document){
172 foreach ($pattern as $key => $value){
173 if(is_array($value)){
174 list($function) = array_keys($value);
175 $functionParameters = $value[$function];
176 if(in_array(strtolower($function), self::SELECT_FUNCTIONS_THAT_REDUCE_RESULT)){
177 continue;
178 }
179
180 $document[$key] = self::handleSelectFunction($function, $document, $functionParameters);
181 } else if($value instanceof Closure){
182 $function = self::SELECT_FUNCTIONS['CUSTOM'];
183 $functionParameters = $value;
184 $document[$key] = self::handleSelectFunction($function, $document, $functionParameters);
185 }
186 }
187 }
188 unset($document);
189 }
190
191 // GROUP
192 $groupedResult = [];
193 foreach ($found as $foundKey => $document){
194
195 // Prepare hash for group by
196 $values = [];
197 $isEmptyAndEmptyNotAllowed = false;
198 foreach ($groupByFields as $groupByField){
199 $value = NestedHelper::getNestedValue($groupByField, $document);
200 if($allowEmpty === false && is_null($value)){
201 $isEmptyAndEmptyNotAllowed = true;
202 break;
203 }
204 $values[$groupByField] = $value;
205 }
206 if($isEmptyAndEmptyNotAllowed === true){
207 continue;
208 }
209 $valueHash = md5(json_encode($values));
210
211 // is new entry
212 if(!array_key_exists($valueHash, $groupedResult)){
213 $resultDocument = [];
214 foreach ($pattern as $key => $patternValue){
215 $resultFieldName = (is_string($key)) ? $key : $patternValue;
216
217 if($resultFieldName === $countKeyName){
218 // is a counter
219 $attributeValue = 1;
220 } else if(!is_string($patternValue)){
221 // is a function
222 list($function) = array_keys($patternValue);
223 if(in_array(strtolower($function), self::SELECT_FUNCTIONS_THAT_REDUCE_RESULT)){
224 // is a select function that reduce result.
225 $fieldNameToHandle = $patternValue[$function];
226 $currentFieldValue = NestedHelper::getNestedValue($fieldNameToHandle, $document);
227 if(!is_numeric($currentFieldValue)){
228 $attributeValue = [$function => [null]];
229 } else {
230 $attributeValue = [$function => [$currentFieldValue]];
231 }
232 } else {
233 // is a select function that does not reduce result.
234 $attributeValue = $document[$resultFieldName];
235 }
236 } else {
237 // is a normal select
238 $attributeValue = NestedHelper::getNestedValue($patternValue, $document);
239 }
240 $resultDocument[$resultFieldName] = $attributeValue;
241 }
242 $groupedResult[$valueHash] = $resultDocument;
243 continue;
244 }
245
246 // entry exists
247 $currentResult = $groupedResult[$valueHash];
248 foreach ($pattern as $key => $patternValue){
249 $resultFieldName = (is_string($key)) ? $key : $patternValue;
250
251 if($resultFieldName === $countKeyName){
252 $currentResult[$resultFieldName] += 1;
253 continue;
254 }
255
256 if(is_array($patternValue)){
257 list($function) = array_keys($patternValue);
258 if(in_array(strtolower($function), self::SELECT_FUNCTIONS_THAT_REDUCE_RESULT)){
259 $fieldNameToHandle = $patternValue[$function];
260 $currentFieldValue = NestedHelper::getNestedValue($fieldNameToHandle, $document);
261 $currentFieldValue = is_numeric($currentFieldValue) ? $currentFieldValue : null;
262 $currentResult[$resultFieldName][$function][] = $currentFieldValue;
263 }
264 }
265 }
266 $groupedResult[$valueHash] = $currentResult;
267 }
268
269 // Apply select functions that reduce result
270 if($hasSelectFunctionThatReduceResult){
271 foreach ($groupedResult as &$document){
272 foreach ($pattern as $key => $value){
273 if(!is_array($value)){
274 continue;
275 }
276 list($function) = array_keys($value);
277 if(!in_array(strtolower($function), self::SELECT_FUNCTIONS_THAT_REDUCE_RESULT)){
278 continue;
279 }
280 // "price" => ["sum" => [...]]
281 $functionParameters = $key.".".$function;
282 $document[$key] = self::handleSelectFunction($function, $document, $functionParameters);
283 }
284 }
285 unset($document);
286 }
287
288 $found = array_values($groupedResult);
289 }
290
291 /**
292 * @param array $found
293 * @param string $primaryKey
294 * @param array $fieldsToSelect
295 * @throws InvalidArgumentException
296 */
297 public static function selectFields(array &$found, string $primaryKey, array $fieldsToSelect)
298 {
299 if (empty($fieldsToSelect)) {
300 return;
301 }
302
303 $functionsThatReduceResultToSingleResult = self::SELECT_FUNCTIONS_THAT_REDUCE_RESULT;
304 $reducedResult = []; // "fieldName" => ["values",...]
305 $reduceResultToSingleResult = false;
306
307 // check if result should be reduced to single result
308 foreach ($fieldsToSelect as $fieldToSelect){
309 if(!is_array($fieldToSelect)){
310 continue;
311 }
312
313 list($function) = array_keys($fieldToSelect);
314
315 if(in_array(strtolower($function), $functionsThatReduceResultToSingleResult, true)){
316 $reduceResultToSingleResult = true;
317 }
318
319 if($reduceResultToSingleResult === true){
320 break;
321 }
322 }
323
324 // Is not result of group by and contains function that reduces result to single result
325 if($reduceResultToSingleResult === true){
326 foreach ($found as $key => $document) {
327 foreach ($fieldsToSelect as $fieldAlias => $fieldToSelect) {
328 $fieldName = (!is_int($fieldAlias))? $fieldAlias : $fieldToSelect;
329 if(!is_array($fieldToSelect)){
330 continue;
331 }
332
333 // no alias specified and select function (array) used as element
334 if(!is_string($fieldName)){
335 $errorMsg = "You need to specify an alias for the field when using select functions.";
336 throw new InvalidArgumentException($errorMsg);
337 }
338
339 list($function) = array_keys($fieldToSelect);
340 $functionParameters = $fieldToSelect[$function];
341
342 if(in_array(strtolower($function), $functionsThatReduceResultToSingleResult, true)){
343 if(!is_string($functionParameters)){
344 $errorMsg = "When using the function \"$function\" the parameter has to be a string (fieldName).";
345 throw new InvalidArgumentException($errorMsg);
346 }
347
348 $value = NestedHelper::getNestedValue($functionParameters, $document);
349 if(!array_key_exists($fieldName, $reducedResult)){
350 $reducedResult[$fieldName] = [];
351 }
352 $reducedResult[$fieldName][] = $value;
353 }
354 }
355 }
356
357 $newDocument = [];
358 foreach ($fieldsToSelect as $fieldAlias => $fieldToSelect){
359 $fieldName = (!is_int($fieldAlias))? $fieldAlias : $fieldToSelect;
360 if(!is_array($fieldToSelect)){
361 continue;
362 }
363
364 list($function) = array_keys($fieldToSelect);
365 if(in_array(strtolower($function), $functionsThatReduceResultToSingleResult, true)){
366 $newDocument[$fieldName] = self::handleSelectFunction($function, $reducedResult, $fieldName);
367 }
368 }
369 $found = [$newDocument];
370 return;
371 }
372
373 // result should not be reduced to single result
374
375 foreach ($found as $key => &$document) {
376 $newDocument = [];
377
378 $newDocument[$primaryKey] = $document[$primaryKey];
379 foreach ($fieldsToSelect as $fieldAlias => $fieldToSelect) {
380
381 $fieldName = (!is_int($fieldAlias))? $fieldAlias : $fieldToSelect;
382
383 if(!is_string($fieldToSelect) && !is_int($fieldToSelect) && !is_array($fieldToSelect)
384 && !($fieldToSelect instanceof Closure))
385 {
386 $errorMsg = "When using select an array containing fieldNames as strings or select functions has to be given";
387 throw new InvalidArgumentException($errorMsg);
388 }
389
390 // no alias specified and select function (array) used as element
391 if(!is_string($fieldName)){
392 $errorMsg = "You need to specify an alias for the field when using select functions.";
393 throw new InvalidArgumentException($errorMsg);
394 }
395
396 // if the fieldToSelect is an array, the user wants to use a select function
397 if(is_array($fieldToSelect)){
398 // "fieldAlias" => ["function" => "field"]
399 list($function) = array_keys($fieldToSelect);
400 $functionParameters = $fieldToSelect[$function];
401 $newDocument[$fieldName] = self::handleSelectFunction($function, $document, $functionParameters);
402 } else if($fieldToSelect instanceof Closure){
403 $function = self::SELECT_FUNCTIONS['CUSTOM'];
404 $functionParameters = $fieldToSelect;
405 $newDocument[$fieldName] = self::handleSelectFunction($function, $document, $functionParameters);
406 } else {
407 // No select function is used (fieldToSelect is string or int)
408 $fieldValue = NestedHelper::getNestedValue((string) $fieldToSelect, $document);
409 $createdArray = NestedHelper::createNestedArray($fieldName, $fieldValue);
410 if(!empty($createdArray)){
411 $createdArrayKey = array_keys($createdArray)[0];
412 $newDocument[$createdArrayKey] = $createdArray[$createdArrayKey];
413 }
414 }
415 }
416 $document = $newDocument;
417 }
418 }
419
420 /**
421 * @param string $function
422 * @param array $document
423 * @param string|array|int|Closure $functionParameters
424 * @return mixed
425 * @throws InvalidArgumentException
426 */
427 private static function handleSelectFunction(string $function, array $document, $functionParameters){
428
429 if(is_int($functionParameters)){
430 $functionParameters = (string) $functionParameters;
431 }
432
433 switch (strtolower($function)){
434 case self::SELECT_FUNCTIONS["ROUND"]:
435 list($field, $precision) = self::getFieldNamesOfSelectFunction($function, $functionParameters);
436 if(!is_string($field) || !is_int($precision)){
437 $errorMsg = "When using the select function \"$function\" the field parameter has to be a string "
438 ."and the precision parameter has to be an integer";
439 throw new InvalidArgumentException($errorMsg);
440 }
441
442 $data = NestedHelper::getNestedValue($field, $document);
443 if(!is_numeric($data)){
444 return null;
445 }
446 return round((float) $data, $precision);
447 case self::SELECT_FUNCTIONS["ABS"]:
448 list($field) = self::getFieldNamesOfSelectFunction($function, $functionParameters);
449 $data = NestedHelper::getNestedValue($field, $document);
450 if(!is_numeric($data)){
451 return null;
452 }
453 return abs($data);
454 case self::SELECT_FUNCTIONS["POSITION"]:
455 list($field, $subString) = self::getFieldNamesOfSelectFunction($function, $functionParameters);
456 if(!is_string($subString) || !is_string($field)){
457 $errorMsg = "When using the select function \"$function\" the subString and field parameters has to be strings";
458 throw new InvalidArgumentException($errorMsg);
459 }
460
461 $data = NestedHelper::getNestedValue($field, $document);
462 if(!is_string($data)){
463 return null;
464 }
465 $result = strpos($data, $subString);
466 return ($result !== false)? $result + 1 : null;
467 case self::SELECT_FUNCTIONS["UPPER"]:
468 list($field) = self::getFieldNamesOfSelectFunction($function, $functionParameters);
469 $data = NestedHelper::getNestedValue($field, $document);
470 if(!is_string($data)){
471 return null;
472 }
473 return strtoupper($data);
474 case self::SELECT_FUNCTIONS["LOWER"]:
475 list($field) = self::getFieldNamesOfSelectFunction($function, $functionParameters);
476 $data = NestedHelper::getNestedValue($field, $document);
477 if(!is_string($data)){
478 return null;
479 }
480 return strtolower($data);
481 case self::SELECT_FUNCTIONS["LENGTH"]:
482 list($field) = self::getFieldNamesOfSelectFunction($function, $functionParameters);
483 $data = NestedHelper::getNestedValue($field, $document);
484 if(is_string($data)){
485 return strlen($data);
486 }
487 if(is_array($data)){
488 return count($data);
489 }
490 return null;
491 case self::SELECT_FUNCTIONS["CONCAT"]:
492 list($fields, $glue) = self::getFieldNamesOfSelectFunction($function, $functionParameters);
493 $result = "";
494 foreach ($fields as $field){
495 $data = NestedHelper::getNestedValue($field, $document);
496 // convertible to string
497 if(
498 ( !is_array( $data ) )
499 && ($data !== "" && $data !== null)
500 && (
501 ( !is_object( $data ) && settype( $data, 'string' ) !== false )
502 || ( is_object( $data ) && method_exists( $data, '__toString' ) )
503 )
504 )
505 {
506 if($result !== ""){
507 $result .= $glue;
508 }
509 $result .= $data;
510 }
511 }
512 return ($result !== "") ? $result : null;
513 case self::SELECT_FUNCTIONS["SUM"]:
514 list($field) = self::getFieldNamesOfSelectFunction($function, $functionParameters);
515 $data = NestedHelper::getNestedValue($field, $document);
516 if(!is_array($data)){
517 return null;
518 }
519
520 $result = 0;
521 $allEntriesNull = true;
522 foreach ($data as $value){
523 if(!is_null($value)){
524 $result += $value;
525 $allEntriesNull = false;
526 }
527 }
528 if($allEntriesNull === true){
529 return null;
530 }
531 return $result;
532 case self::SELECT_FUNCTIONS["MIN"]:
533 list($field) = self::getFieldNamesOfSelectFunction($function, $functionParameters);
534 $data = NestedHelper::getNestedValue($field, $document);
535 if(!is_array($data)){
536 return null;
537 }
538
539 $result = INF;
540 $allEntriesNull = true;
541 foreach ($data as $value){
542 if(!is_null($value)){
543 if($value < $result){
544 $result = $value;
545 }
546 $allEntriesNull = false;
547 }
548 }
549 if($allEntriesNull === true){
550 return null;
551 }
552 return $result;
553 case self::SELECT_FUNCTIONS["MAX"]:
554 list($field) = self::getFieldNamesOfSelectFunction($function, $functionParameters);
555 $data = NestedHelper::getNestedValue($field, $document);
556 if(!is_array($data)){
557 return null;
558 }
559
560 $result = -INF;
561 $allEntriesNull = true;
562 foreach ($data as $value){
563 if($value > $result && !is_null($value)) {
564 $result = $value;
565 $allEntriesNull = false;
566 }
567 }
568 if($allEntriesNull === true){
569 return null;
570 }
571 return $result;
572 case self::SELECT_FUNCTIONS["AVG"]:
573 list($field) = self::getFieldNamesOfSelectFunction($function, $functionParameters);
574 $data = NestedHelper::getNestedValue($field, $document);
575 if(!is_array($data)){
576 return null;
577 }
578
579 $result = 0;
580 $resultValueAmount = (count($data) + 1);
581 $allEntriesNull = true;
582 foreach ($data as $value){
583 if(!is_null($value)){
584 $result += $value;
585 $allEntriesNull = false;
586 }
587 }
588 if($allEntriesNull === true){
589 return null;
590 }
591 return ($result / $resultValueAmount);
592 case self::SELECT_FUNCTIONS['CUSTOM']:
593 if(!($functionParameters instanceof Closure)){
594 throw new InvalidArgumentException("When using a custom select function you need to provide a closure.");
595 }
596 return $functionParameters($document);
597 default:
598 throw new InvalidArgumentException("The given select function \"$function\" is not supported.");
599 }
600 }
601
602 /**
603 * @param string $function
604 * @param string|array|int $functionParameters
605 * @return array [array|string $fieldNames, $addition]
606 * @throws InvalidArgumentException
607 */
608 private static function getFieldNamesOfSelectFunction(string $function, $functionParameters): array
609 {
610 if(is_int($functionParameters)){
611 $functionParameters = (string) $functionParameters;
612 }
613 $function = strtolower($function);
614 switch ($function){
615 case self::SELECT_FUNCTIONS["ROUND"]:
616 case self::SELECT_FUNCTIONS["POSITION"]:
617 if(!is_array($functionParameters) || count($functionParameters) !== 2){
618 $type = gettype($functionParameters);
619 $length = (is_array($functionParameters)) ? count($functionParameters) : 0;
620 $errorMsg = "When using the select function \"$function\" the parameter "
621 ."has to be an array with length = 2, got $type with length $length";
622 throw new InvalidArgumentException($errorMsg);
623 }
624 list($firstParameter, $secondParameter) = $functionParameters;
625 if($function === self::SELECT_FUNCTIONS["ROUND"]){
626 $field = $firstParameter;
627 $addition = $secondParameter;
628 } else {
629 $field = $secondParameter;
630 $addition = $firstParameter;
631 }
632 return [$field, $addition];
633 case self::SELECT_FUNCTIONS["ABS"]:
634 case self::SELECT_FUNCTIONS["UPPER"]:
635 case self::SELECT_FUNCTIONS["LOWER"]:
636 case self::SELECT_FUNCTIONS["LENGTH"]:
637 case self::SELECT_FUNCTIONS["SUM"]:
638 case self::SELECT_FUNCTIONS["MIN"]:
639 case self::SELECT_FUNCTIONS["MAX"]:
640 case self::SELECT_FUNCTIONS["AVG"]:
641 if(!is_string($functionParameters)){
642 $type = gettype($functionParameters);
643 $errorMsg = "When using the select function \"$function\" the parameter "
644 ."has to be a string, got $type.";
645 throw new InvalidArgumentException($errorMsg);
646 }
647 return [$functionParameters, null];
648 case self::SELECT_FUNCTIONS["CONCAT"]:
649 if(!is_array($functionParameters) || count($functionParameters) < 3){
650 $type = gettype($functionParameters);
651 $length = (is_array($functionParameters)) ? count($functionParameters) : 0;
652 $errorMsg = "When using the select function \"$function\" the parameter "
653 ."has to be an array with length > 3, got $type with length $length";
654 throw new InvalidArgumentException($errorMsg);
655 }
656 list($glue) = $functionParameters;
657 unset($functionParameters[array_keys($functionParameters)[0]]);
658
659 return [$functionParameters, $glue];
660 default:
661 throw new InvalidArgumentException("The given select function \"$function\" is not supported.");
662 }
663 }
664
665 }