jb-data.de/lib/PhpSpreadsheet/Calculation/TextData/Concatenate.php
2025-08-11 22:23:30 +02:00

137 lines
4.6 KiB
PHP

<?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;
}
}