<?php
|
|
namespace PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
|
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue;
|
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
|
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
|
class Concatenate
|
{
|
use ArrayEnabled;
|
|
/**
|
* CONCATENATE.
|
*
|
* @param array $args
|
*/
|
public static function CONCATENATE(...$args): string
|
{
|
$returnValue = '';
|
|
// Loop through arguments
|
$aArgs = Functions::flattenArray($args);
|
|
foreach ($aArgs as $arg) {
|
$value = Helpers::extractString($arg);
|
if (ErrorValue::isError($value)) {
|
$returnValue = $value;
|
|
break;
|
}
|
$returnValue .= Helpers::extractString($arg);
|
if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) {
|
$returnValue = ExcelError::CALC();
|
|
break;
|
}
|
}
|
|
return $returnValue;
|
}
|
|
/**
|
* TEXTJOIN.
|
*
|
* @param mixed $delimiter The delimter to use between the joined arguments
|
* Or can be an array of values
|
* @param mixed $ignoreEmpty true/false Flag indicating whether empty arguments should be skipped
|
* Or can be an array of values
|
* @param mixed $args The values to join
|
*
|
* @return array|string The joined string
|
* If an array of values is passed for the $delimiter or $ignoreEmpty arguments, then the returned result
|
* will also be an array with matching dimensions
|
*/
|
public static function TEXTJOIN(mixed $delimiter = '', mixed $ignoreEmpty = true, mixed ...$args): array|string
|
{
|
if (is_array($delimiter) || is_array($ignoreEmpty)) {
|
return self::evaluateArrayArgumentsSubset(
|
[self::class, __FUNCTION__],
|
2,
|
$delimiter,
|
$ignoreEmpty,
|
...$args
|
);
|
}
|
|
$delimiter ??= '';
|
$ignoreEmpty ??= true;
|
$aArgs = Functions::flattenArray($args);
|
$returnValue = self::evaluateTextJoinArray($ignoreEmpty, $aArgs);
|
|
$returnValue ??= implode($delimiter, $aArgs);
|
if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) {
|
$returnValue = ExcelError::CALC();
|
}
|
|
return $returnValue;
|
}
|
|
private static function evaluateTextJoinArray(bool $ignoreEmpty, array &$aArgs): ?string
|
{
|
foreach ($aArgs as $key => &$arg) {
|
$value = Helpers::extractString($arg);
|
if (ErrorValue::isError($value)) {
|
return $value;
|
}
|
|
if ($ignoreEmpty === true && ((is_string($arg) && trim($arg) === '') || $arg === null)) {
|
unset($aArgs[$key]);
|
} elseif (is_bool($arg)) {
|
$arg = Helpers::convertBooleanValue($arg);
|
}
|
}
|
|
return null;
|
}
|
|
/**
|
* REPT.
|
*
|
* Returns the result of builtin function round after validating args.
|
*
|
* @param mixed $stringValue The value to repeat
|
* Or can be an array of values
|
* @param mixed $repeatCount The number of times the string value should be repeated
|
* Or can be an array of values
|
*
|
* @return array|string The repeated string
|
* If an array of values is passed for the $stringValue or $repeatCount arguments, then the returned result
|
* will also be an array with matching dimensions
|
*/
|
public static function builtinREPT(mixed $stringValue, mixed $repeatCount): array|string
|
{
|
if (is_array($stringValue) || is_array($repeatCount)) {
|
return self::evaluateArrayArguments([self::class, __FUNCTION__], $stringValue, $repeatCount);
|
}
|
|
$stringValue = Helpers::extractString($stringValue);
|
|
if (!is_numeric($repeatCount) || $repeatCount < 0) {
|
$returnValue = ExcelError::VALUE();
|
} elseif (ErrorValue::isError($stringValue)) {
|
$returnValue = $stringValue;
|
} else {
|
$returnValue = str_repeat($stringValue, (int) $repeatCount);
|
if (StringHelper::countCharacters($returnValue) > DataType::MAX_STRING_LENGTH) {
|
$returnValue = ExcelError::VALUE(); // note VALUE not CALC
|
}
|
}
|
|
return $returnValue;
|
}
|
}
|