First phase of refactoring the Excel Text functions (#1945)
* Refactoring the Excel Text functions * More unit tests for utf-8 handling, for edge cases, and for argument validations
This commit is contained in:
parent
5ad5f787ab
commit
1a7b9a446a
|
|
@ -483,7 +483,7 @@ class Calculation
|
|||
],
|
||||
'CHAR' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'CHARACTER'],
|
||||
'functionCall' => [TextData\CharacterConvert::class, 'character'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'CHIDIST' => [
|
||||
|
|
@ -533,12 +533,12 @@ class Calculation
|
|||
],
|
||||
'CLEAN' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'TRIMNONPRINTABLE'],
|
||||
'functionCall' => [TextData\Trim::class, 'nonPrintable'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'CODE' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'ASCIICODE'],
|
||||
'functionCall' => [TextData\CharacterConvert::class, 'code'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'COLUMN' => [
|
||||
|
|
@ -570,12 +570,12 @@ class Calculation
|
|||
],
|
||||
'CONCAT' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'CONCATENATE'],
|
||||
'functionCall' => [TextData\Concatenate::class, 'CONCATENATE'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'CONCATENATE' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'CONCATENATE'],
|
||||
'functionCall' => [TextData\Concatenate::class, 'CONCATENATE'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'CONFIDENCE' => [
|
||||
|
|
@ -870,7 +870,7 @@ class Calculation
|
|||
],
|
||||
'DOLLAR' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'DOLLAR'],
|
||||
'functionCall' => [TextData\Format::class, 'DOLLAR'],
|
||||
'argumentCount' => '1,2',
|
||||
],
|
||||
'DOLLARDE' => [
|
||||
|
|
@ -970,7 +970,7 @@ class Calculation
|
|||
],
|
||||
'EXACT' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'EXACT'],
|
||||
'functionCall' => [TextData\Text::class, 'exact'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'EXP' => [
|
||||
|
|
@ -1030,12 +1030,12 @@ class Calculation
|
|||
],
|
||||
'FIND' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'SEARCHSENSITIVE'],
|
||||
'functionCall' => [TextData\Search::class, 'sensitive'],
|
||||
'argumentCount' => '2,3',
|
||||
],
|
||||
'FINDB' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'SEARCHSENSITIVE'],
|
||||
'functionCall' => [TextData\Search::class, 'sensitive'],
|
||||
'argumentCount' => '2,3',
|
||||
],
|
||||
'FINV' => [
|
||||
|
|
@ -1065,7 +1065,7 @@ class Calculation
|
|||
],
|
||||
'FIXED' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'FIXEDFORMAT'],
|
||||
'functionCall' => [TextData\Format::class, 'FIXEDFORMAT'],
|
||||
'argumentCount' => '1-3',
|
||||
],
|
||||
'FLOOR' => [
|
||||
|
|
@ -1541,22 +1541,22 @@ class Calculation
|
|||
],
|
||||
'LEFT' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'LEFT'],
|
||||
'functionCall' => [TextData\Extract::class, 'left'],
|
||||
'argumentCount' => '1,2',
|
||||
],
|
||||
'LEFTB' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'LEFT'],
|
||||
'functionCall' => [TextData\Extract::class, 'left'],
|
||||
'argumentCount' => '1,2',
|
||||
],
|
||||
'LEN' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'STRINGLENGTH'],
|
||||
'functionCall' => [TextData\Text::class, 'length'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'LENB' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'STRINGLENGTH'],
|
||||
'functionCall' => [TextData\Text::class, 'length'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'LINEST' => [
|
||||
|
|
@ -1611,7 +1611,7 @@ class Calculation
|
|||
],
|
||||
'LOWER' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'LOWERCASE'],
|
||||
'functionCall' => [TextData\CaseConvert::class, 'lower'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'MATCH' => [
|
||||
|
|
@ -1656,12 +1656,12 @@ class Calculation
|
|||
],
|
||||
'MID' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'MID'],
|
||||
'functionCall' => [TextData\Extract::class, 'mid'],
|
||||
'argumentCount' => '3',
|
||||
],
|
||||
'MIDB' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'MID'],
|
||||
'functionCall' => [TextData\Extract::class, 'mid'],
|
||||
'argumentCount' => '3',
|
||||
],
|
||||
'MIN' => [
|
||||
|
|
@ -1836,7 +1836,7 @@ class Calculation
|
|||
],
|
||||
'NUMBERVALUE' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'NUMBERVALUE'],
|
||||
'functionCall' => [TextData\Format::class, 'NUMBERVALUE'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'OCT2BIN' => [
|
||||
|
|
@ -2008,7 +2008,7 @@ class Calculation
|
|||
],
|
||||
'PROPER' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'PROPERCASE'],
|
||||
'functionCall' => [TextData\CaseConvert::class, 'proper'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'PV' => [
|
||||
|
|
@ -2083,27 +2083,27 @@ class Calculation
|
|||
],
|
||||
'REPLACE' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'REPLACE'],
|
||||
'functionCall' => [TextData\Replace::class, 'replace'],
|
||||
'argumentCount' => '4',
|
||||
],
|
||||
'REPLACEB' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'REPLACE'],
|
||||
'functionCall' => [TextData\Replace::class, 'replace'],
|
||||
'argumentCount' => '4',
|
||||
],
|
||||
'REPT' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'builtinREPT'],
|
||||
'functionCall' => [TextData\Concatenate::class, 'builtinREPT'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'RIGHT' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'RIGHT'],
|
||||
'functionCall' => [TextData\Extract::class, 'right'],
|
||||
'argumentCount' => '1,2',
|
||||
],
|
||||
'RIGHTB' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'RIGHT'],
|
||||
'functionCall' => [TextData\Extract::class, 'right'],
|
||||
'argumentCount' => '1,2',
|
||||
],
|
||||
'ROMAN' => [
|
||||
|
|
@ -2155,12 +2155,12 @@ class Calculation
|
|||
],
|
||||
'SEARCH' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'SEARCHINSENSITIVE'],
|
||||
'functionCall' => [TextData\Search::class, 'insensitive'],
|
||||
'argumentCount' => '2,3',
|
||||
],
|
||||
'SEARCHB' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'SEARCHINSENSITIVE'],
|
||||
'functionCall' => [TextData\Search::class, 'insensitive'],
|
||||
'argumentCount' => '2,3',
|
||||
],
|
||||
'SEC' => [
|
||||
|
|
@ -2300,7 +2300,7 @@ class Calculation
|
|||
],
|
||||
'SUBSTITUTE' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'SUBSTITUTE'],
|
||||
'functionCall' => [TextData\Replace::class, 'substitute'],
|
||||
'argumentCount' => '3,4',
|
||||
],
|
||||
'SUBTOTAL' => [
|
||||
|
|
@ -2361,7 +2361,7 @@ class Calculation
|
|||
],
|
||||
'T' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'RETURNSTRING'],
|
||||
'functionCall' => [TextData\Text::class, 'test'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'TAN' => [
|
||||
|
|
@ -2411,7 +2411,7 @@ class Calculation
|
|||
],
|
||||
'TEXT' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'TEXTFORMAT'],
|
||||
'functionCall' => [TextData\Format::class, 'TEXTFORMAT'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'TEXTJOIN' => [
|
||||
|
|
@ -2461,7 +2461,7 @@ class Calculation
|
|||
],
|
||||
'TRIM' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'TRIMSPACES'],
|
||||
'functionCall' => [TextData\Trim::class, 'spaces'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'TRIMMEAN' => [
|
||||
|
|
@ -2496,12 +2496,12 @@ class Calculation
|
|||
],
|
||||
'UNICHAR' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'CHARACTER'],
|
||||
'functionCall' => [TextData\CharacterConvert::class, 'character'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'UNICODE' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'ASCIICODE'],
|
||||
'functionCall' => [TextData\CharacterConvert::class, 'code'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'UNIQUE' => [
|
||||
|
|
@ -2511,7 +2511,7 @@ class Calculation
|
|||
],
|
||||
'UPPER' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'UPPERCASE'],
|
||||
'functionCall' => [TextData\CaseConvert::class, 'upper'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'USDOLLAR' => [
|
||||
|
|
@ -2521,7 +2521,7 @@ class Calculation
|
|||
],
|
||||
'VALUE' => [
|
||||
'category' => Category::CATEGORY_TEXT_AND_DATA,
|
||||
'functionCall' => [TextData::class, 'VALUE'],
|
||||
'functionCall' => [TextData\Format::class, 'VALUE'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'VAR' => [
|
||||
|
|
|
|||
|
|
@ -3,141 +3,88 @@
|
|||
namespace PhpOffice\PhpSpreadsheet\Calculation;
|
||||
|
||||
use DateTimeInterface;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
||||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
|
||||
class TextData
|
||||
{
|
||||
private static $invalidChars;
|
||||
|
||||
private static function unicodeToOrd($character)
|
||||
{
|
||||
return unpack('V', iconv('UTF-8', 'UCS-4LE', $character))[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 1.18.0
|
||||
*/
|
||||
class TextData
|
||||
{
|
||||
/**
|
||||
* CHARACTER.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the character() method in the TextData\CharacterConvert class instead
|
||||
*
|
||||
* @param string $character Value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function CHARACTER($character)
|
||||
{
|
||||
$character = Functions::flattenSingleValue($character);
|
||||
|
||||
if (!is_numeric($character)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$character = (int) $character;
|
||||
if ($character < 1 || $character > 255) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
return iconv('UCS-4LE', 'UTF-8', pack('V', $character));
|
||||
return TextData\CharacterConvert::character($character);
|
||||
}
|
||||
|
||||
/**
|
||||
* TRIMNONPRINTABLE.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the nonPrintable() method in the TextData\Trim class instead
|
||||
*
|
||||
* @param mixed $stringValue Value to check
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function TRIMNONPRINTABLE($stringValue = '')
|
||||
{
|
||||
$stringValue = Functions::flattenSingleValue($stringValue);
|
||||
|
||||
if (is_bool($stringValue)) {
|
||||
return ($stringValue) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
if (self::$invalidChars === null) {
|
||||
self::$invalidChars = range(chr(0), chr(31));
|
||||
}
|
||||
|
||||
if (is_string($stringValue) || is_numeric($stringValue)) {
|
||||
return str_replace(self::$invalidChars, '', trim($stringValue, "\x00..\x1F"));
|
||||
}
|
||||
|
||||
return null;
|
||||
return TextData\Trim::nonPrintable($stringValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* TRIMSPACES.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the spaces() method in the TextData\Trim class instead
|
||||
*
|
||||
* @param mixed $stringValue Value to check
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function TRIMSPACES($stringValue = '')
|
||||
{
|
||||
$stringValue = Functions::flattenSingleValue($stringValue);
|
||||
if (is_bool($stringValue)) {
|
||||
return ($stringValue) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
if (is_string($stringValue) || is_numeric($stringValue)) {
|
||||
return trim(preg_replace('/ +/', ' ', trim($stringValue, ' ')), ' ');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function convertBooleanValue($value)
|
||||
{
|
||||
if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) {
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
return ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
return TextData\Trim::spaces($stringValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* ASCIICODE.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the code() method in the TextData\CharacterConvert class instead
|
||||
*
|
||||
* @param string $characters Value
|
||||
*
|
||||
* @return int|string A string if arguments are invalid
|
||||
*/
|
||||
public static function ASCIICODE($characters)
|
||||
{
|
||||
if (($characters === null) || ($characters === '')) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$characters = Functions::flattenSingleValue($characters);
|
||||
if (is_bool($characters)) {
|
||||
$characters = self::convertBooleanValue($characters);
|
||||
}
|
||||
|
||||
$character = $characters;
|
||||
if (mb_strlen($characters, 'UTF-8') > 1) {
|
||||
$character = mb_substr($characters, 0, 1, 'UTF-8');
|
||||
}
|
||||
|
||||
return self::unicodeToOrd($character);
|
||||
return TextData\CharacterConvert::code($characters);
|
||||
}
|
||||
|
||||
/**
|
||||
* CONCATENATE.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the CONCATENATE() method in the TextData\Concatenate class instead
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function CONCATENATE(...$args)
|
||||
{
|
||||
$returnValue = '';
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $arg) {
|
||||
if (is_bool($arg)) {
|
||||
$arg = self::convertBooleanValue($arg);
|
||||
}
|
||||
$returnValue .= $arg;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
return TextData\Concatenate::CONCATENATE(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -146,6 +93,10 @@ class TextData
|
|||
* This function converts a number to text using currency format, with the decimals rounded to the specified place.
|
||||
* The format used is $#,##0.00_);($#,##0.00)..
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the DOLLAR() method in the TextData\Format class instead
|
||||
*
|
||||
* @param float $value The value to format
|
||||
* @param int $decimals The number of digits to display to the right of the decimal point.
|
||||
* If decimals is negative, number is rounded to the left of the decimal point.
|
||||
|
|
@ -155,33 +106,16 @@ class TextData
|
|||
*/
|
||||
public static function DOLLAR($value = 0, $decimals = 2)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$decimals = $decimals === null ? 0 : Functions::flattenSingleValue($decimals);
|
||||
|
||||
// Validate parameters
|
||||
if (!is_numeric($value) || !is_numeric($decimals)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$decimals = (int) $decimals;
|
||||
|
||||
$mask = '$#,##0';
|
||||
if ($decimals > 0) {
|
||||
$mask .= '.' . str_repeat('0', $decimals);
|
||||
} else {
|
||||
$round = 10 ** abs($decimals);
|
||||
if ($value < 0) {
|
||||
$round = 0 - $round;
|
||||
}
|
||||
$value = MathTrig\Mround::funcMround($value, $round);
|
||||
}
|
||||
$mask = "$mask;($mask)";
|
||||
|
||||
return NumberFormat::toFormattedString($value, $mask);
|
||||
return TextData\Format::DOLLAR($value, $decimals);
|
||||
}
|
||||
|
||||
/**
|
||||
* SEARCHSENSITIVE.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the sensitive() method in the TextData\Search class instead
|
||||
*
|
||||
* @param string $needle The string to look for
|
||||
* @param string $haystack The string in which to look
|
||||
* @param int $offset Offset within $haystack
|
||||
|
|
@ -190,33 +124,16 @@ class TextData
|
|||
*/
|
||||
public static function SEARCHSENSITIVE($needle, $haystack, $offset = 1)
|
||||
{
|
||||
$needle = Functions::flattenSingleValue($needle);
|
||||
$haystack = Functions::flattenSingleValue($haystack);
|
||||
$offset = Functions::flattenSingleValue($offset);
|
||||
|
||||
if (!is_bool($needle)) {
|
||||
if (is_bool($haystack)) {
|
||||
$haystack = ($haystack) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
if (($offset > 0) && (StringHelper::countCharacters($haystack) > $offset)) {
|
||||
if (StringHelper::countCharacters($needle) === 0) {
|
||||
return $offset;
|
||||
}
|
||||
|
||||
$pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8');
|
||||
if ($pos !== false) {
|
||||
return ++$pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
return TextData\Search::sensitive($needle, $haystack, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* SEARCHINSENSITIVE.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the insensitive() method in the TextData\Search class instead
|
||||
*
|
||||
* @param string $needle The string to look for
|
||||
* @param string $haystack The string in which to look
|
||||
* @param int $offset Offset within $haystack
|
||||
|
|
@ -225,33 +142,16 @@ class TextData
|
|||
*/
|
||||
public static function SEARCHINSENSITIVE($needle, $haystack, $offset = 1)
|
||||
{
|
||||
$needle = Functions::flattenSingleValue($needle);
|
||||
$haystack = Functions::flattenSingleValue($haystack);
|
||||
$offset = Functions::flattenSingleValue($offset);
|
||||
|
||||
if (!is_bool($needle)) {
|
||||
if (is_bool($haystack)) {
|
||||
$haystack = ($haystack) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
if (($offset > 0) && (StringHelper::countCharacters($haystack) > $offset)) {
|
||||
if (StringHelper::countCharacters($needle) === 0) {
|
||||
return $offset;
|
||||
}
|
||||
|
||||
$pos = mb_stripos($haystack, $needle, --$offset, 'UTF-8');
|
||||
if ($pos !== false) {
|
||||
return ++$pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
return TextData\Search::insensitive($needle, $haystack, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXEDFORMAT.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the FIXEDFORMAT() method in the TextData\Format class instead
|
||||
*
|
||||
* @param mixed $value Value to check
|
||||
* @param int $decimals
|
||||
* @param bool $no_commas
|
||||
|
|
@ -260,35 +160,16 @@ class TextData
|
|||
*/
|
||||
public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = false)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$decimals = Functions::flattenSingleValue($decimals);
|
||||
$no_commas = Functions::flattenSingleValue($no_commas);
|
||||
|
||||
// Validate parameters
|
||||
if (!is_numeric($value) || !is_numeric($decimals)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$decimals = (int) floor($decimals);
|
||||
|
||||
$valueResult = round($value, $decimals);
|
||||
if ($decimals < 0) {
|
||||
$decimals = 0;
|
||||
}
|
||||
if (!$no_commas) {
|
||||
$valueResult = number_format(
|
||||
$valueResult,
|
||||
$decimals,
|
||||
StringHelper::getDecimalSeparator(),
|
||||
StringHelper::getThousandsSeparator()
|
||||
);
|
||||
}
|
||||
|
||||
return (string) $valueResult;
|
||||
return TextData\Format::FIXEDFORMAT($value, $decimals, $no_commas);
|
||||
}
|
||||
|
||||
/**
|
||||
* LEFT.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the left() method in the TextData\Extract class instead
|
||||
*
|
||||
* @param string $value Value
|
||||
* @param int $chars Number of characters
|
||||
*
|
||||
|
|
@ -296,23 +177,16 @@ class TextData
|
|||
*/
|
||||
public static function LEFT($value = '', $chars = 1)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$chars = Functions::flattenSingleValue($chars);
|
||||
|
||||
if (!is_numeric($chars) || $chars < 0) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
if (is_bool($value)) {
|
||||
$value = ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return mb_substr($value, 0, $chars, 'UTF-8');
|
||||
return TextData\Extract::left($value, $chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* MID.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the mid() method in the TextData\Extract class instead
|
||||
*
|
||||
* @param string $value Value
|
||||
* @param int $start Start character
|
||||
* @param int $chars Number of characters
|
||||
|
|
@ -321,24 +195,16 @@ class TextData
|
|||
*/
|
||||
public static function MID($value = '', $start = 1, $chars = null)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$start = Functions::flattenSingleValue($start);
|
||||
$chars = Functions::flattenSingleValue($chars);
|
||||
|
||||
if (!is_numeric($start) || $start < 1 || !is_numeric($chars) || $chars < 0) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
if (is_bool($value)) {
|
||||
$value = ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return mb_substr($value, --$start, $chars, 'UTF-8');
|
||||
return TextData\Extract::mid($value, $start, $chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* RIGHT.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the right() method in the TextData\Extract class instead
|
||||
*
|
||||
* @param string $value Value
|
||||
* @param int $chars Number of characters
|
||||
*
|
||||
|
|
@ -346,36 +212,23 @@ class TextData
|
|||
*/
|
||||
public static function RIGHT($value = '', $chars = 1)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$chars = Functions::flattenSingleValue($chars);
|
||||
|
||||
if (!is_numeric($chars) || $chars < 0) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
if (is_bool($value)) {
|
||||
$value = ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8');
|
||||
return TextData\Extract::right($value, $chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* STRINGLENGTH.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the length() method in the TextData\Text class instead
|
||||
*
|
||||
* @param string $value Value
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function STRINGLENGTH($value = '')
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
|
||||
if (is_bool($value)) {
|
||||
$value = ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return mb_strlen($value, 'UTF-8');
|
||||
return TextData\Text::length($value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -383,19 +236,17 @@ class TextData
|
|||
*
|
||||
* Converts a string value to upper case.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the lower() method in the TextData\CaseConvert class instead
|
||||
*
|
||||
* @param string $mixedCaseString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function LOWERCASE($mixedCaseString)
|
||||
{
|
||||
$mixedCaseString = Functions::flattenSingleValue($mixedCaseString);
|
||||
|
||||
if (is_bool($mixedCaseString)) {
|
||||
$mixedCaseString = ($mixedCaseString) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return StringHelper::strToLower($mixedCaseString);
|
||||
return TextData\CaseConvert::lower($mixedCaseString);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -403,19 +254,17 @@ class TextData
|
|||
*
|
||||
* Converts a string value to upper case.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the upper() method in the TextData\CaseConvert class instead
|
||||
*
|
||||
* @param string $mixedCaseString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function UPPERCASE($mixedCaseString)
|
||||
{
|
||||
$mixedCaseString = Functions::flattenSingleValue($mixedCaseString);
|
||||
|
||||
if (is_bool($mixedCaseString)) {
|
||||
$mixedCaseString = ($mixedCaseString) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return StringHelper::strToUpper($mixedCaseString);
|
||||
return TextData\CaseConvert::upper($mixedCaseString);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -423,24 +272,26 @@ class TextData
|
|||
*
|
||||
* Converts a string value to upper case.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the proper() method in the TextData\CaseConvert class instead
|
||||
*
|
||||
* @param string $mixedCaseString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function PROPERCASE($mixedCaseString)
|
||||
{
|
||||
$mixedCaseString = Functions::flattenSingleValue($mixedCaseString);
|
||||
|
||||
if (is_bool($mixedCaseString)) {
|
||||
$mixedCaseString = ($mixedCaseString) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return StringHelper::strToTitle($mixedCaseString);
|
||||
return TextData\CaseConvert::proper($mixedCaseString);
|
||||
}
|
||||
|
||||
/**
|
||||
* REPLACE.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the replace() method in the TextData\Replace class instead
|
||||
*
|
||||
* @param string $oldText String to modify
|
||||
* @param int $start Start character
|
||||
* @param int $chars Number of characters
|
||||
|
|
@ -450,20 +301,16 @@ class TextData
|
|||
*/
|
||||
public static function REPLACE($oldText, $start, $chars, $newText)
|
||||
{
|
||||
$oldText = Functions::flattenSingleValue($oldText);
|
||||
$start = Functions::flattenSingleValue($start);
|
||||
$chars = Functions::flattenSingleValue($chars);
|
||||
$newText = Functions::flattenSingleValue($newText);
|
||||
|
||||
$left = self::LEFT($oldText, $start - 1);
|
||||
$right = self::RIGHT($oldText, self::STRINGLENGTH($oldText) - ($start + $chars) + 1);
|
||||
|
||||
return $left . $newText . $right;
|
||||
return TextData\Replace::replace($oldText, $start, $chars, $newText);
|
||||
}
|
||||
|
||||
/**
|
||||
* SUBSTITUTE.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the substitute() method in the TextData\Replace class instead
|
||||
*
|
||||
* @param string $text Value
|
||||
* @param string $fromText From Value
|
||||
* @param string $toText To Value
|
||||
|
|
@ -473,52 +320,32 @@ class TextData
|
|||
*/
|
||||
public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0)
|
||||
{
|
||||
$text = Functions::flattenSingleValue($text);
|
||||
$fromText = Functions::flattenSingleValue($fromText);
|
||||
$toText = Functions::flattenSingleValue($toText);
|
||||
$instance = floor(Functions::flattenSingleValue($instance));
|
||||
|
||||
if ($instance == 0) {
|
||||
return str_replace($fromText, $toText, $text);
|
||||
}
|
||||
|
||||
$pos = -1;
|
||||
while ($instance > 0) {
|
||||
$pos = mb_strpos($text, $fromText, $pos + 1, 'UTF-8');
|
||||
if ($pos === false) {
|
||||
break;
|
||||
}
|
||||
--$instance;
|
||||
}
|
||||
|
||||
if ($pos !== false) {
|
||||
return self::REPLACE($text, ++$pos, mb_strlen($fromText, 'UTF-8'), $toText);
|
||||
}
|
||||
|
||||
return $text;
|
||||
return TextData\Replace::substitute($text, $fromText, $toText, $instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* RETURNSTRING.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the test() method in the TextData\Text class instead
|
||||
*
|
||||
* @param mixed $testValue Value to check
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function RETURNSTRING($testValue = '')
|
||||
{
|
||||
$testValue = Functions::flattenSingleValue($testValue);
|
||||
|
||||
if (is_string($testValue)) {
|
||||
return $testValue;
|
||||
}
|
||||
|
||||
return null;
|
||||
return TextData\Text::test($testValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* TEXTFORMAT.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the TEXTFORMAT() method in the TextData\Format class instead
|
||||
*
|
||||
* @param mixed $value Value to check
|
||||
* @param string $format Format mask to use
|
||||
*
|
||||
|
|
@ -526,65 +353,32 @@ class TextData
|
|||
*/
|
||||
public static function TEXTFORMAT($value, $format)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$format = Functions::flattenSingleValue($format);
|
||||
|
||||
if ((is_string($value)) && (!is_numeric($value)) && Date::isDateTimeFormatCode($format)) {
|
||||
$value = DateTime::DATEVALUE($value);
|
||||
}
|
||||
|
||||
return (string) NumberFormat::toFormattedString($value, $format);
|
||||
return TextData\Format::TEXTFORMAT($value, $format);
|
||||
}
|
||||
|
||||
/**
|
||||
* VALUE.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the VALUE() method in the TextData\Format class instead
|
||||
*
|
||||
* @param mixed $value Value to check
|
||||
*
|
||||
* @return DateTimeInterface|float|int|string A string if arguments are invalid
|
||||
*/
|
||||
public static function VALUE($value = '')
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
|
||||
if (!is_numeric($value)) {
|
||||
$numberValue = str_replace(
|
||||
StringHelper::getThousandsSeparator(),
|
||||
'',
|
||||
trim($value, " \t\n\r\0\x0B" . StringHelper::getCurrencyCode())
|
||||
);
|
||||
if (is_numeric($numberValue)) {
|
||||
return (float) $numberValue;
|
||||
}
|
||||
|
||||
$dateSetting = Functions::getReturnDateType();
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
|
||||
if (strpos($value, ':') !== false) {
|
||||
$timeValue = DateTime::TIMEVALUE($value);
|
||||
if ($timeValue !== Functions::VALUE()) {
|
||||
Functions::setReturnDateType($dateSetting);
|
||||
|
||||
return $timeValue;
|
||||
}
|
||||
}
|
||||
$dateValue = DateTime::DATEVALUE($value);
|
||||
if ($dateValue !== Functions::VALUE()) {
|
||||
Functions::setReturnDateType($dateSetting);
|
||||
|
||||
return $dateValue;
|
||||
}
|
||||
Functions::setReturnDateType($dateSetting);
|
||||
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
return (float) $value;
|
||||
return TextData\Format::VALUE($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* NUMBERVALUE.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the NUMBERVALUE() method in the TextData\Format class instead
|
||||
*
|
||||
* @param mixed $value Value to check
|
||||
* @param string $decimalSeparator decimal separator, defaults to locale defined value
|
||||
* @param string $groupSeparator group/thosands separator, defaults to locale defined value
|
||||
|
|
@ -593,39 +387,7 @@ class TextData
|
|||
*/
|
||||
public static function NUMBERVALUE($value = '', $decimalSeparator = null, $groupSeparator = null)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$decimalSeparator = Functions::flattenSingleValue($decimalSeparator);
|
||||
$groupSeparator = Functions::flattenSingleValue($groupSeparator);
|
||||
|
||||
if (!is_numeric($value)) {
|
||||
$decimalSeparator = empty($decimalSeparator) ? StringHelper::getDecimalSeparator() : $decimalSeparator;
|
||||
$groupSeparator = empty($groupSeparator) ? StringHelper::getThousandsSeparator() : $groupSeparator;
|
||||
|
||||
$decimalPositions = preg_match_all('/' . preg_quote($decimalSeparator) . '/', $value, $matches, PREG_OFFSET_CAPTURE);
|
||||
if ($decimalPositions > 1) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$decimalOffset = array_pop($matches[0])[1];
|
||||
if (strpos($value, $groupSeparator, $decimalOffset) !== false) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$value = str_replace([$groupSeparator, $decimalSeparator], ['', '.'], $value);
|
||||
|
||||
// Handle the special case of trailing % signs
|
||||
$percentageString = rtrim($value, '%');
|
||||
if (!is_numeric($percentageString)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$percentageAdjustment = strlen($value) - strlen($percentageString);
|
||||
if ($percentageAdjustment) {
|
||||
$value = (float) $percentageString;
|
||||
$value /= 10 ** ($percentageAdjustment * 2);
|
||||
}
|
||||
}
|
||||
|
||||
return (float) $value;
|
||||
return TextData\Format::NUMBERVALUE($value, $decimalSeparator, $groupSeparator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -633,6 +395,10 @@ class TextData
|
|||
* EXACT is case-sensitive but ignores formatting differences.
|
||||
* Use EXACT to test text being entered into a document.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the exact() method in the TextData\Text class instead
|
||||
*
|
||||
* @param $value1
|
||||
* @param $value2
|
||||
*
|
||||
|
|
@ -640,15 +406,16 @@ class TextData
|
|||
*/
|
||||
public static function EXACT($value1, $value2)
|
||||
{
|
||||
$value1 = Functions::flattenSingleValue($value1);
|
||||
$value2 = Functions::flattenSingleValue($value2);
|
||||
|
||||
return (string) $value2 === (string) $value1;
|
||||
return TextData\Text::exact($value1, $value2);
|
||||
}
|
||||
|
||||
/**
|
||||
* TEXTJOIN.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the TEXTJOIN() method in the TextData\Concatenate class instead
|
||||
*
|
||||
* @param mixed $delimiter
|
||||
* @param mixed $ignoreEmpty
|
||||
* @param mixed $args
|
||||
|
|
@ -657,23 +424,17 @@ class TextData
|
|||
*/
|
||||
public static function TEXTJOIN($delimiter, $ignoreEmpty, ...$args)
|
||||
{
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $key => &$arg) {
|
||||
if ($ignoreEmpty && trim($arg) == '') {
|
||||
unset($aArgs[$key]);
|
||||
} elseif (is_bool($arg)) {
|
||||
$arg = self::convertBooleanValue($arg);
|
||||
}
|
||||
}
|
||||
|
||||
return implode($delimiter, $aArgs);
|
||||
return TextData\Concatenate::TEXTJOIN($delimiter, $ignoreEmpty, ...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
* REPT.
|
||||
*
|
||||
* Returns the result of builtin function round after validating args.
|
||||
* Returns the result of builtin function repeat after validating args.
|
||||
*
|
||||
* @Deprecated 1.18.0
|
||||
*
|
||||
* @see Use the builtinREPT() method in the TextData\Concatenate class instead
|
||||
*
|
||||
* @param string $str Should be numeric
|
||||
* @param mixed $number Should be int
|
||||
|
|
@ -682,12 +443,6 @@ class TextData
|
|||
*/
|
||||
public static function builtinREPT($str, $number)
|
||||
{
|
||||
$number = Functions::flattenSingleValue($number);
|
||||
|
||||
if (!is_numeric($number) || $number < 0) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
return str_repeat($str, $number);
|
||||
return TextData\Concatenate::builtinREPT($str, $number);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
||||
|
||||
class CaseConvert
|
||||
{
|
||||
/**
|
||||
* LOWERCASE.
|
||||
*
|
||||
* Converts a string value to upper case.
|
||||
*
|
||||
* @param string $mixedCaseValue
|
||||
*/
|
||||
public static function lower($mixedCaseValue): string
|
||||
{
|
||||
$mixedCaseValue = Functions::flattenSingleValue($mixedCaseValue);
|
||||
|
||||
if (is_bool($mixedCaseValue)) {
|
||||
$mixedCaseValue = ($mixedCaseValue === true) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return StringHelper::strToLower($mixedCaseValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* UPPERCASE.
|
||||
*
|
||||
* Converts a string value to upper case.
|
||||
*
|
||||
* @param string $mixedCaseValue
|
||||
*/
|
||||
public static function upper($mixedCaseValue): string
|
||||
{
|
||||
$mixedCaseValue = Functions::flattenSingleValue($mixedCaseValue);
|
||||
|
||||
if (is_bool($mixedCaseValue)) {
|
||||
$mixedCaseValue = ($mixedCaseValue === true) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return StringHelper::strToUpper($mixedCaseValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* PROPERCASE.
|
||||
*
|
||||
* Converts a string value to upper case.
|
||||
*
|
||||
* @param string $mixedCaseValue
|
||||
*/
|
||||
public static function proper($mixedCaseValue): string
|
||||
{
|
||||
$mixedCaseValue = Functions::flattenSingleValue($mixedCaseValue);
|
||||
|
||||
if (is_bool($mixedCaseValue)) {
|
||||
$mixedCaseValue = ($mixedCaseValue === true) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return StringHelper::strToTitle($mixedCaseValue);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class CharacterConvert
|
||||
{
|
||||
/**
|
||||
* CHARACTER.
|
||||
*
|
||||
* @param string $character Value
|
||||
*/
|
||||
public static function character($character): string
|
||||
{
|
||||
$character = Functions::flattenSingleValue($character);
|
||||
|
||||
if (!is_numeric($character)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$character = (int) $character;
|
||||
if ($character < 1 || $character > 255) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
return iconv('UCS-4LE', 'UTF-8', pack('V', $character));
|
||||
}
|
||||
|
||||
/**
|
||||
* ASCIICODE.
|
||||
*
|
||||
* @param string $characters Value
|
||||
*
|
||||
* @return int|string A string if arguments are invalid
|
||||
*/
|
||||
public static function code($characters)
|
||||
{
|
||||
if (($characters === null) || ($characters === '')) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$characters = Functions::flattenSingleValue($characters);
|
||||
if (is_bool($characters)) {
|
||||
$characters = self::convertBooleanValue($characters);
|
||||
}
|
||||
|
||||
$character = $characters;
|
||||
if (mb_strlen($characters, 'UTF-8') > 1) {
|
||||
$character = mb_substr($characters, 0, 1, 'UTF-8');
|
||||
}
|
||||
|
||||
return self::unicodeToOrd($character);
|
||||
}
|
||||
|
||||
private static function unicodeToOrd($character)
|
||||
{
|
||||
return unpack('V', iconv('UTF-8', 'UCS-4LE', $character))[1];
|
||||
}
|
||||
|
||||
private static function convertBooleanValue($value)
|
||||
{
|
||||
if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) {
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
return ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Concatenate
|
||||
{
|
||||
/**
|
||||
* CONCATENATE.
|
||||
*/
|
||||
public static function CONCATENATE(...$args): string
|
||||
{
|
||||
$returnValue = '';
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $arg) {
|
||||
if (is_bool($arg)) {
|
||||
$arg = self::convertBooleanValue($arg);
|
||||
}
|
||||
$returnValue .= $arg;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* TEXTJOIN.
|
||||
*
|
||||
* @param mixed $delimiter
|
||||
* @param mixed $ignoreEmpty
|
||||
* @param mixed $args
|
||||
*/
|
||||
public static function TEXTJOIN($delimiter, $ignoreEmpty, ...$args): string
|
||||
{
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $key => &$arg) {
|
||||
if ($ignoreEmpty === true && is_string($arg) && trim($arg) === '') {
|
||||
unset($aArgs[$key]);
|
||||
} elseif (is_bool($arg)) {
|
||||
$arg = self::convertBooleanValue($arg);
|
||||
}
|
||||
}
|
||||
|
||||
return implode($delimiter, $aArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* REPT.
|
||||
*
|
||||
* Returns the result of builtin function round after validating args.
|
||||
*
|
||||
* @param mixed $stringValue The value to repeat
|
||||
* @param mixed $repeatCount The number of times the string value should be repeated
|
||||
*/
|
||||
public static function builtinREPT($stringValue, $repeatCount): string
|
||||
{
|
||||
$repeatCount = Functions::flattenSingleValue($repeatCount);
|
||||
|
||||
if (!is_numeric($repeatCount) || $repeatCount < 0) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
if (is_bool($stringValue)) {
|
||||
$stringValue = self::convertBooleanValue($stringValue);
|
||||
}
|
||||
|
||||
return str_repeat($stringValue, (int) $repeatCount);
|
||||
}
|
||||
|
||||
private static function convertBooleanValue($value)
|
||||
{
|
||||
if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE) {
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
return ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Extract
|
||||
{
|
||||
/**
|
||||
* LEFT.
|
||||
*
|
||||
* @param string $value Value
|
||||
* @param int $chars Number of characters
|
||||
*/
|
||||
public static function left($value = '', $chars = 1): string
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$chars = Functions::flattenSingleValue($chars);
|
||||
|
||||
if (!is_numeric($chars) || $chars < 0) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
if (is_bool($value)) {
|
||||
$value = ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return mb_substr($value, 0, $chars, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* MID.
|
||||
*
|
||||
* @param string $value Value
|
||||
* @param int $start Start character
|
||||
* @param int $chars Number of characters
|
||||
*/
|
||||
public static function mid($value = '', $start = 1, $chars = null): string
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$start = Functions::flattenSingleValue($start);
|
||||
$chars = Functions::flattenSingleValue($chars);
|
||||
|
||||
if (!is_numeric($start) || $start < 1 || !is_numeric($chars) || $chars < 0) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
if (is_bool($value)) {
|
||||
$value = ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return mb_substr($value, --$start, $chars, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* RIGHT.
|
||||
*
|
||||
* @param string $value Value
|
||||
* @param int $chars Number of characters
|
||||
*/
|
||||
public static function right($value = '', $chars = 1): string
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$chars = Functions::flattenSingleValue($chars);
|
||||
|
||||
if (!is_numeric($chars) || $chars < 0) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
if (is_bool($value)) {
|
||||
$value = ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,196 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
|
||||
use DateTimeInterface;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
||||
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
|
||||
|
||||
class Format
|
||||
{
|
||||
/**
|
||||
* DOLLAR.
|
||||
*
|
||||
* This function converts a number to text using currency format, with the decimals rounded to the specified place.
|
||||
* The format used is $#,##0.00_);($#,##0.00)..
|
||||
*
|
||||
* @param float $value The value to format
|
||||
* @param int $decimals The number of digits to display to the right of the decimal point.
|
||||
* If decimals is negative, number is rounded to the left of the decimal point.
|
||||
* If you omit decimals, it is assumed to be 2
|
||||
*/
|
||||
public static function DOLLAR($value = 0, $decimals = 2): string
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$decimals = $decimals === null ? 2 : Functions::flattenSingleValue($decimals);
|
||||
|
||||
// Validate parameters
|
||||
if (!is_numeric($value) || !is_numeric($decimals)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$decimals = (int) $decimals;
|
||||
|
||||
$mask = '$#,##0';
|
||||
if ($decimals > 0) {
|
||||
$mask .= '.' . str_repeat('0', $decimals);
|
||||
} else {
|
||||
$round = 10 ** abs($decimals);
|
||||
if ($value < 0) {
|
||||
$round = 0 - $round;
|
||||
}
|
||||
$value = MathTrig\Mround::funcMround($value, $round);
|
||||
}
|
||||
$mask = "$mask;($mask)";
|
||||
|
||||
return NumberFormat::toFormattedString($value, $mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXEDFORMAT.
|
||||
*
|
||||
* @param mixed $value Value to check
|
||||
* @param mixed $decimals
|
||||
* @param bool $noCommas
|
||||
*/
|
||||
public static function FIXEDFORMAT($value, $decimals = 2, $noCommas = false): string
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$decimals = $decimals === null ? 2 : Functions::flattenSingleValue($decimals);
|
||||
$noCommas = Functions::flattenSingleValue($noCommas);
|
||||
|
||||
// Validate parameters
|
||||
if (!is_numeric($value) || !is_numeric($decimals)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$decimals = (int) floor($decimals);
|
||||
|
||||
$valueResult = round($value, $decimals);
|
||||
if ($decimals < 0) {
|
||||
$decimals = 0;
|
||||
}
|
||||
if (!$noCommas) {
|
||||
$valueResult = number_format(
|
||||
$valueResult,
|
||||
$decimals,
|
||||
StringHelper::getDecimalSeparator(),
|
||||
StringHelper::getThousandsSeparator()
|
||||
);
|
||||
}
|
||||
|
||||
return (string) $valueResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* TEXTFORMAT.
|
||||
*
|
||||
* @param mixed $value Value to check
|
||||
* @param string $format Format mask to use
|
||||
*/
|
||||
public static function TEXTFORMAT($value, $format): string
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$format = Functions::flattenSingleValue($format);
|
||||
|
||||
if ((is_string($value)) && (!is_numeric($value)) && Date::isDateTimeFormatCode($format)) {
|
||||
$value = DateTime::DATEVALUE($value);
|
||||
}
|
||||
|
||||
return (string) NumberFormat::toFormattedString($value, $format);
|
||||
}
|
||||
|
||||
/**
|
||||
* VALUE.
|
||||
*
|
||||
* @param mixed $value Value to check
|
||||
*
|
||||
* @return DateTimeInterface|float|int|string A string if arguments are invalid
|
||||
*/
|
||||
public static function VALUE($value = '')
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
|
||||
if (!is_numeric($value)) {
|
||||
$numberValue = str_replace(
|
||||
StringHelper::getThousandsSeparator(),
|
||||
'',
|
||||
trim($value, " \t\n\r\0\x0B" . StringHelper::getCurrencyCode())
|
||||
);
|
||||
if (is_numeric($numberValue)) {
|
||||
return (float) $numberValue;
|
||||
}
|
||||
|
||||
$dateSetting = Functions::getReturnDateType();
|
||||
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
|
||||
|
||||
if (strpos($value, ':') !== false) {
|
||||
$timeValue = DateTime::TIMEVALUE($value);
|
||||
if ($timeValue !== Functions::VALUE()) {
|
||||
Functions::setReturnDateType($dateSetting);
|
||||
|
||||
return $timeValue;
|
||||
}
|
||||
}
|
||||
$dateValue = DateTime::DATEVALUE($value);
|
||||
if ($dateValue !== Functions::VALUE()) {
|
||||
Functions::setReturnDateType($dateSetting);
|
||||
|
||||
return $dateValue;
|
||||
}
|
||||
Functions::setReturnDateType($dateSetting);
|
||||
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
return (float) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* NUMBERVALUE.
|
||||
*
|
||||
* @param mixed $value Value to check
|
||||
* @param string $decimalSeparator decimal separator, defaults to locale defined value
|
||||
* @param string $groupSeparator group/thosands separator, defaults to locale defined value
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function NUMBERVALUE($value = '', $decimalSeparator = null, $groupSeparator = null)
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
$decimalSeparator = Functions::flattenSingleValue($decimalSeparator);
|
||||
$groupSeparator = Functions::flattenSingleValue($groupSeparator);
|
||||
|
||||
if (!is_numeric($value)) {
|
||||
$decimalSeparator = empty($decimalSeparator) ? StringHelper::getDecimalSeparator() : $decimalSeparator;
|
||||
$groupSeparator = empty($groupSeparator) ? StringHelper::getThousandsSeparator() : $groupSeparator;
|
||||
|
||||
$decimalPositions = preg_match_all('/' . preg_quote($decimalSeparator) . '/', $value, $matches, PREG_OFFSET_CAPTURE);
|
||||
if ($decimalPositions > 1) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
$decimalOffset = array_pop($matches[0])[1];
|
||||
if (strpos($value, $groupSeparator, $decimalOffset) !== false) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$value = str_replace([$groupSeparator, $decimalSeparator], ['', '.'], $value);
|
||||
|
||||
// Handle the special case of trailing % signs
|
||||
$percentageString = rtrim($value, '%');
|
||||
if (!is_numeric($percentageString)) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$percentageAdjustment = strlen($value) - strlen($percentageString);
|
||||
if ($percentageAdjustment) {
|
||||
$value = (float) $percentageString;
|
||||
$value /= 10 ** ($percentageAdjustment * 2);
|
||||
}
|
||||
}
|
||||
|
||||
return (float) $value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
|
||||
class Replace
|
||||
{
|
||||
/**
|
||||
* REPLACE.
|
||||
*
|
||||
* @param string $oldText String to modify
|
||||
* @param int $start Start character
|
||||
* @param int $chars Number of characters
|
||||
* @param string $newText String to replace in defined position
|
||||
*/
|
||||
public static function replace($oldText, $start, $chars, $newText): string
|
||||
{
|
||||
$oldText = Functions::flattenSingleValue($oldText);
|
||||
$start = Functions::flattenSingleValue($start);
|
||||
$chars = Functions::flattenSingleValue($chars);
|
||||
$newText = Functions::flattenSingleValue($newText);
|
||||
|
||||
$left = Extract::left($oldText, $start - 1);
|
||||
$right = Extract::right($oldText, TextData::STRINGLENGTH($oldText) - ($start + $chars) + 1);
|
||||
|
||||
return $left . $newText . $right;
|
||||
}
|
||||
|
||||
/**
|
||||
* SUBSTITUTE.
|
||||
*
|
||||
* @param string $text Value
|
||||
* @param string $fromText From Value
|
||||
* @param string $toText To Value
|
||||
* @param int $instance Instance Number
|
||||
*/
|
||||
public static function substitute($text = '', $fromText = '', $toText = '', $instance = 0): string
|
||||
{
|
||||
$text = Functions::flattenSingleValue($text);
|
||||
$fromText = Functions::flattenSingleValue($fromText);
|
||||
$toText = Functions::flattenSingleValue($toText);
|
||||
$instance = floor(Functions::flattenSingleValue($instance));
|
||||
|
||||
if ($instance == 0) {
|
||||
return str_replace($fromText, $toText, $text);
|
||||
}
|
||||
|
||||
$pos = -1;
|
||||
while ($instance > 0) {
|
||||
$pos = mb_strpos($text, $fromText, $pos + 1, 'UTF-8');
|
||||
if ($pos === false) {
|
||||
break;
|
||||
}
|
||||
--$instance;
|
||||
}
|
||||
|
||||
if ($pos !== false) {
|
||||
return self::REPLACE($text, ++$pos, mb_strlen($fromText, 'UTF-8'), $toText);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
|
||||
|
||||
class Search
|
||||
{
|
||||
/**
|
||||
* SEARCHSENSITIVE.
|
||||
*
|
||||
* @param string $needle The string to look for
|
||||
* @param string $haystack The string in which to look
|
||||
* @param int $offset Offset within $haystack
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
public static function sensitive($needle, $haystack, $offset = 1)
|
||||
{
|
||||
$needle = Functions::flattenSingleValue($needle);
|
||||
$haystack = Functions::flattenSingleValue($haystack);
|
||||
$offset = Functions::flattenSingleValue($offset);
|
||||
|
||||
if (!is_bool($needle)) {
|
||||
if (is_bool($haystack)) {
|
||||
$haystack = ($haystack) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
if (($offset > 0) && (StringHelper::countCharacters($haystack) > $offset)) {
|
||||
if (StringHelper::countCharacters($needle) === 0) {
|
||||
return $offset;
|
||||
}
|
||||
|
||||
$pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8');
|
||||
if ($pos !== false) {
|
||||
return ++$pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* SEARCHINSENSITIVE.
|
||||
*
|
||||
* @param string $needle The string to look for
|
||||
* @param string $haystack The string in which to look
|
||||
* @param int $offset Offset within $haystack
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
public static function insensitive($needle, $haystack, $offset = 1)
|
||||
{
|
||||
$needle = Functions::flattenSingleValue($needle);
|
||||
$haystack = Functions::flattenSingleValue($haystack);
|
||||
$offset = Functions::flattenSingleValue($offset);
|
||||
|
||||
if (!is_bool($needle)) {
|
||||
if (is_bool($haystack)) {
|
||||
$haystack = ($haystack) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
if (($offset > 0) && (StringHelper::countCharacters($haystack) > $offset)) {
|
||||
if (StringHelper::countCharacters($needle) === 0) {
|
||||
return $offset;
|
||||
}
|
||||
|
||||
$pos = mb_stripos($haystack, $needle, --$offset, 'UTF-8');
|
||||
if ($pos !== false) {
|
||||
return ++$pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Text
|
||||
{
|
||||
/**
|
||||
* STRINGLENGTH.
|
||||
*
|
||||
* @param string $value Value
|
||||
*/
|
||||
public static function length($value = ''): int
|
||||
{
|
||||
$value = Functions::flattenSingleValue($value);
|
||||
|
||||
if (is_bool($value)) {
|
||||
$value = ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
return mb_strlen($value, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two text strings and returns TRUE if they are exactly the same, FALSE otherwise.
|
||||
* EXACT is case-sensitive but ignores formatting differences.
|
||||
* Use EXACT to test text being entered into a document.
|
||||
*
|
||||
* @param $value1
|
||||
* @param $value2
|
||||
*/
|
||||
public static function exact($value1, $value2): bool
|
||||
{
|
||||
$value1 = Functions::flattenSingleValue($value1);
|
||||
$value2 = Functions::flattenSingleValue($value2);
|
||||
|
||||
return ((string) $value2) === ((string) $value1);
|
||||
}
|
||||
|
||||
/**
|
||||
* RETURNSTRING.
|
||||
*
|
||||
* @param mixed $testValue Value to check
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function test($testValue = '')
|
||||
{
|
||||
$testValue = Functions::flattenSingleValue($testValue);
|
||||
|
||||
if (is_string($testValue)) {
|
||||
return $testValue;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Trim
|
||||
{
|
||||
private static $invalidChars;
|
||||
|
||||
/**
|
||||
* TRIMNONPRINTABLE.
|
||||
*
|
||||
* @param mixed $stringValue Value to check
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function nonPrintable($stringValue = '')
|
||||
{
|
||||
$stringValue = Functions::flattenSingleValue($stringValue);
|
||||
|
||||
if (is_bool($stringValue)) {
|
||||
return ($stringValue) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
if (self::$invalidChars === null) {
|
||||
self::$invalidChars = range(chr(0), chr(31));
|
||||
}
|
||||
|
||||
if (is_string($stringValue) || is_numeric($stringValue)) {
|
||||
return str_replace(self::$invalidChars, '', trim($stringValue, "\x00..\x1F"));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TRIMSPACES.
|
||||
*
|
||||
* @param mixed $stringValue Value to check
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function spaces($stringValue = '')
|
||||
{
|
||||
$stringValue = Functions::flattenSingleValue($stringValue);
|
||||
if (is_bool($stringValue)) {
|
||||
return ($stringValue) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
|
||||
if (is_string($stringValue) || is_numeric($stringValue)) {
|
||||
return trim(preg_replace('/ +/', ' ', trim($stringValue, ' ')), ' ');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,10 +3,16 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class LeftTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Settings::setLocale('en_US');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLEFT
|
||||
*
|
||||
|
|
@ -22,4 +28,40 @@ class LeftTest extends TestCase
|
|||
{
|
||||
return require 'tests/data/Calculation/TextData/LEFT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLocaleLEFT
|
||||
*
|
||||
* @param string $expectedResult
|
||||
* @param $value
|
||||
* @param mixed $locale
|
||||
* @param mixed $characters
|
||||
*/
|
||||
public function testLowerWithLocaleBoolean($expectedResult, $locale, $value, $characters): void
|
||||
{
|
||||
$newLocale = Settings::setLocale($locale);
|
||||
if ($newLocale === false) {
|
||||
Settings::setLocale('en_US');
|
||||
self::markTestSkipped('Unable to set locale for locale-specific test');
|
||||
}
|
||||
|
||||
$result = TextData::LEFT($value, $characters);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
|
||||
Settings::setLocale('en_US');
|
||||
}
|
||||
|
||||
public function providerLocaleLEFT()
|
||||
{
|
||||
return [
|
||||
['VR', 'fr_FR', true, 2],
|
||||
['WA', 'nl_NL', true, 2],
|
||||
['TO', 'fi', true, 2],
|
||||
['ИСТ', 'bg', true, 3],
|
||||
['FA', 'fr_FR', false, 2],
|
||||
['ON', 'nl_NL', false, 2],
|
||||
['EPÄT', 'fi', false, 4],
|
||||
['ЛОЖ', 'bg', false, 3],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,16 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class LowerTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Settings::setLocale('en_US');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLOWER
|
||||
*
|
||||
|
|
@ -23,4 +29,39 @@ class LowerTest extends TestCase
|
|||
{
|
||||
return require 'tests/data/Calculation/TextData/LOWER.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLocaleLOWER
|
||||
*
|
||||
* @param string $expectedResult
|
||||
* @param $value
|
||||
* @param mixed $locale
|
||||
*/
|
||||
public function testLowerWithLocaleBoolean($expectedResult, $locale, $value): void
|
||||
{
|
||||
$newLocale = Settings::setLocale($locale);
|
||||
if ($newLocale === false) {
|
||||
Settings::setLocale('en_US');
|
||||
self::markTestSkipped('Unable to set locale for locale-specific test');
|
||||
}
|
||||
|
||||
$result = TextData::LOWERCASE($value);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
|
||||
Settings::setLocale('en_US');
|
||||
}
|
||||
|
||||
public function providerLocaleLOWER()
|
||||
{
|
||||
return [
|
||||
['vrai', 'fr_FR', true],
|
||||
['waar', 'nl_NL', true],
|
||||
['tosi', 'fi', true],
|
||||
['истина', 'bg', true],
|
||||
['faux', 'fr_FR', false],
|
||||
['onwaar', 'nl_NL', false],
|
||||
['epätosi', 'fi', false],
|
||||
['ложь', 'bg', false],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,16 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class MidTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Settings::setLocale('en_US');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMID
|
||||
*
|
||||
|
|
@ -22,4 +28,41 @@ class MidTest extends TestCase
|
|||
{
|
||||
return require 'tests/data/Calculation/TextData/MID.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLocaleMID
|
||||
*
|
||||
* @param string $expectedResult
|
||||
* @param $value
|
||||
* @param mixed $locale
|
||||
* @param mixed $offset
|
||||
* @param mixed $characters
|
||||
*/
|
||||
public function testLowerWithLocaleBoolean($expectedResult, $locale, $value, $offset, $characters): void
|
||||
{
|
||||
$newLocale = Settings::setLocale($locale);
|
||||
if ($newLocale === false) {
|
||||
Settings::setLocale('en_US');
|
||||
self::markTestSkipped('Unable to set locale for locale-specific test');
|
||||
}
|
||||
|
||||
$result = TextData::MID($value, $offset, $characters);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
|
||||
Settings::setLocale('en_US');
|
||||
}
|
||||
|
||||
public function providerLocaleMID()
|
||||
{
|
||||
return [
|
||||
['RA', 'fr_FR', true, 2, 2],
|
||||
['AA', 'nl_NL', true, 2, 2],
|
||||
['OS', 'fi', true, 2, 2],
|
||||
['СТИН', 'bg', true, 2, 4],
|
||||
['AU', 'fr_FR', false, 2, 2],
|
||||
['NWA', 'nl_NL', false, 2, 3],
|
||||
['PÄTO', 'fi', false, 2, 4],
|
||||
['ОЖ', 'bg', false, 2, 2],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,16 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ProperTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Settings::setLocale('en_US');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerPROPER
|
||||
*
|
||||
|
|
@ -23,4 +29,39 @@ class ProperTest extends TestCase
|
|||
{
|
||||
return require 'tests/data/Calculation/TextData/PROPER.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLocaleLOWER
|
||||
*
|
||||
* @param string $expectedResult
|
||||
* @param $value
|
||||
* @param mixed $locale
|
||||
*/
|
||||
public function testLowerWithLocaleBoolean($expectedResult, $locale, $value): void
|
||||
{
|
||||
$newLocale = Settings::setLocale($locale);
|
||||
if ($newLocale === false) {
|
||||
Settings::setLocale('en_US');
|
||||
self::markTestSkipped('Unable to set locale for locale-specific test');
|
||||
}
|
||||
|
||||
$result = TextData::PROPERCASE($value);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
|
||||
Settings::setLocale('en_US');
|
||||
}
|
||||
|
||||
public function providerLocaleLOWER()
|
||||
{
|
||||
return [
|
||||
['Vrai', 'fr_FR', true],
|
||||
['Waar', 'nl_NL', true],
|
||||
['Tosi', 'fi', true],
|
||||
['Истина', 'bg', true],
|
||||
['Faux', 'fr_FR', false],
|
||||
['Onwaar', 'nl_NL', false],
|
||||
['Epätosi', 'fi', false],
|
||||
['Ложь', 'bg', false],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\TextData\Concatenate;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
|
|
@ -15,7 +17,20 @@ class ReptTest extends TestCase
|
|||
* @param mixed $val
|
||||
* @param mixed $rpt
|
||||
*/
|
||||
public function testRound($expectedResult, $val = null, $rpt = null): void
|
||||
public function testReptDirect($expectedResult, $val = null, $rpt = null): void
|
||||
{
|
||||
$result = Concatenate::builtinREPT(is_string($val) ? trim($val, '"') : $val, $rpt);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerREPT
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $val
|
||||
* @param mixed $rpt
|
||||
*/
|
||||
public function testReptThroughEngine($expectedResult, $val = null, $rpt = null): void
|
||||
{
|
||||
if ($val === null) {
|
||||
$this->expectException(CalcExp::class);
|
||||
|
|
@ -24,6 +39,9 @@ class ReptTest extends TestCase
|
|||
$this->expectException(CalcExp::class);
|
||||
$formula = "=REPT($val)";
|
||||
} else {
|
||||
if (is_bool($val)) {
|
||||
$val = ($val) ? Calculation::getTRUE() : Calculation::getFALSE();
|
||||
}
|
||||
$formula = "=REPT($val, $rpt)";
|
||||
}
|
||||
$spreadsheet = new Spreadsheet();
|
||||
|
|
|
|||
|
|
@ -3,10 +3,16 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class RightTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Settings::setLocale('en_US');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerRIGHT
|
||||
*
|
||||
|
|
@ -22,4 +28,40 @@ class RightTest extends TestCase
|
|||
{
|
||||
return require 'tests/data/Calculation/TextData/RIGHT.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLocaleRIGHT
|
||||
*
|
||||
* @param string $expectedResult
|
||||
* @param $value
|
||||
* @param mixed $locale
|
||||
* @param mixed $characters
|
||||
*/
|
||||
public function testLowerWithLocaleBoolean($expectedResult, $locale, $value, $characters): void
|
||||
{
|
||||
$newLocale = Settings::setLocale($locale);
|
||||
if ($newLocale === false) {
|
||||
Settings::setLocale('en_US');
|
||||
self::markTestSkipped('Unable to set locale for locale-specific test');
|
||||
}
|
||||
|
||||
$result = TextData::RIGHT($value, $characters);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
|
||||
Settings::setLocale('en_US');
|
||||
}
|
||||
|
||||
public function providerLocaleRIGHT()
|
||||
{
|
||||
return [
|
||||
['RAI', 'fr_FR', true, 3],
|
||||
['AAR', 'nl_NL', true, 3],
|
||||
['OSI', 'fi', true, 3],
|
||||
['ИНА', 'bg', true, 3],
|
||||
['UX', 'fr_FR', false, 2],
|
||||
['WAAR', 'nl_NL', false, 4],
|
||||
['ÄTOSI', 'fi', false, 5],
|
||||
['ЖЬ', 'bg', false, 2],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,16 @@
|
|||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\TextData;
|
||||
use PhpOffice\PhpSpreadsheet\Settings;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class UpperTest extends TestCase
|
||||
{
|
||||
protected function tearDown(): void
|
||||
{
|
||||
Settings::setLocale('en_US');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerUPPER
|
||||
*
|
||||
|
|
@ -23,4 +29,39 @@ class UpperTest extends TestCase
|
|||
{
|
||||
return require 'tests/data/Calculation/TextData/UPPER.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerLocaleLOWER
|
||||
*
|
||||
* @param string $expectedResult
|
||||
* @param $value
|
||||
* @param mixed $locale
|
||||
*/
|
||||
public function testLowerWithLocaleBoolean($expectedResult, $locale, $value): void
|
||||
{
|
||||
$newLocale = Settings::setLocale($locale);
|
||||
if ($newLocale === false) {
|
||||
Settings::setLocale('en_US');
|
||||
self::markTestSkipped('Unable to set locale for locale-specific test');
|
||||
}
|
||||
|
||||
$result = TextData::UPPERCASE($value);
|
||||
self::assertEquals($expectedResult, $result);
|
||||
|
||||
Settings::setLocale('en_US');
|
||||
}
|
||||
|
||||
public function providerLocaleLOWER()
|
||||
{
|
||||
return [
|
||||
['VRAI', 'fr_FR', true],
|
||||
['WAAR', 'nl_NL', true],
|
||||
['TOSI', 'fi', true],
|
||||
['ИСТИНА', 'bg', true],
|
||||
['FAUX', 'fr_FR', false],
|
||||
['ONWAAR', 'nl_NL', false],
|
||||
['EPÄTOSI', 'fi', false],
|
||||
['ЛОЖЬ', 'bg', false],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ return [
|
|||
'HELLO ',
|
||||
'HELLO ',
|
||||
],
|
||||
[
|
||||
' HELLO ',
|
||||
' HELLO ',
|
||||
],
|
||||
[
|
||||
'HELLO',
|
||||
' HELLO',
|
||||
|
|
|
|||
|
|
@ -31,6 +31,36 @@ return [
|
|||
'A',
|
||||
'MARK BAKER',
|
||||
],
|
||||
[
|
||||
1,
|
||||
'Ενα',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
],
|
||||
[
|
||||
9,
|
||||
'τρία',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
],
|
||||
[
|
||||
22,
|
||||
'πέντε',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
],
|
||||
[
|
||||
1,
|
||||
'ΕΝΑ',
|
||||
'ΕΝΑ ΔΎΟ ΤΡΊΑ ΤΈΣΣΕΡΑ ΠΈΝΤΕ',
|
||||
],
|
||||
[
|
||||
9,
|
||||
'ΤΡΊΑ',
|
||||
'ΕΝΑ ΔΎΟ ΤΡΊΑ ΤΈΣΣΕΡΑ ΠΈΝΤΕ',
|
||||
],
|
||||
[
|
||||
22,
|
||||
'ΠΈΝΤΕ',
|
||||
'ΕΝΑ ΔΎΟ ΤΡΊΑ ΤΈΣΣΕΡΑ ΠΈΝΤΕ',
|
||||
],
|
||||
[
|
||||
2,
|
||||
'a',
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ return [
|
|||
'',
|
||||
1,
|
||||
],
|
||||
[
|
||||
'',
|
||||
'ABC',
|
||||
0,
|
||||
],
|
||||
[
|
||||
'#VALUE!',
|
||||
'QWERTYUIOP',
|
||||
|
|
@ -31,6 +36,21 @@ return [
|
|||
'ABCDEFGHI',
|
||||
3,
|
||||
],
|
||||
[
|
||||
'Ενα',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
3,
|
||||
],
|
||||
[
|
||||
'Ενα δύο',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
7,
|
||||
],
|
||||
[
|
||||
'Ενα δύο τρία',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
12,
|
||||
],
|
||||
[
|
||||
'TR',
|
||||
true,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,18 @@ return [
|
|||
'mark baker',
|
||||
'MARK BAKER',
|
||||
],
|
||||
[
|
||||
'buenos días',
|
||||
'BUENOS DÍAS',
|
||||
],
|
||||
[
|
||||
'καλημερα',
|
||||
'ΚΑΛΗΜΕΡΑ',
|
||||
],
|
||||
[
|
||||
'доброе утро',
|
||||
'ДОБРОЕ УТРО',
|
||||
],
|
||||
[
|
||||
'true',
|
||||
true,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ return [
|
|||
[
|
||||
'#VALUE!',
|
||||
'QWERTYUIOP',
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
],
|
||||
[
|
||||
|
|
@ -48,12 +48,36 @@ return [
|
|||
8,
|
||||
20,
|
||||
],
|
||||
[
|
||||
'',
|
||||
'QWERTYUIOP',
|
||||
999,
|
||||
2,
|
||||
],
|
||||
[
|
||||
'DEF',
|
||||
'ABCDEFGHI',
|
||||
4,
|
||||
3,
|
||||
],
|
||||
[
|
||||
'δύο',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
5,
|
||||
3,
|
||||
],
|
||||
[
|
||||
'δύο τρία',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
5,
|
||||
8,
|
||||
],
|
||||
[
|
||||
'τρία τέσσερα',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
9,
|
||||
12,
|
||||
],
|
||||
[
|
||||
'R',
|
||||
true,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,18 @@ return [
|
|||
'Mark Baker',
|
||||
'MARK BAKER',
|
||||
],
|
||||
[
|
||||
'Buenos Días',
|
||||
'BUENOS DÍAS',
|
||||
],
|
||||
[
|
||||
'Καλημερα',
|
||||
'ΚΑΛΗΜΕΡΑ',
|
||||
],
|
||||
[
|
||||
'Доброе Утро',
|
||||
'ДОБРОЕ УТРО',
|
||||
],
|
||||
[
|
||||
'True',
|
||||
true,
|
||||
|
|
|
|||
|
|
@ -29,4 +29,32 @@ return [
|
|||
0,
|
||||
'DFG',
|
||||
],
|
||||
[
|
||||
'Ενα δύοτρίατέσσεραπέντε',
|
||||
'Εναδύοτρίατέσσεραπέντε',
|
||||
4,
|
||||
0,
|
||||
' ',
|
||||
],
|
||||
[
|
||||
'Ενα δύο τρίατέσσεραπέντε',
|
||||
'Ενα δύοτρίατέσσεραπέντε',
|
||||
8,
|
||||
0,
|
||||
' ',
|
||||
],
|
||||
[
|
||||
'Ενα δύο τρία τέσσεραπέντε',
|
||||
'Ενα δύο τρίατέσσεραπέντε',
|
||||
13,
|
||||
0,
|
||||
' ',
|
||||
],
|
||||
[
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
'Ενα δύο τρία τέσσεραπέντε',
|
||||
21,
|
||||
0,
|
||||
' ',
|
||||
],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -7,5 +7,8 @@ return [
|
|||
['ABCABCABC', '"ABC"', 3],
|
||||
['ABCABC', '"ABC"', 2.2],
|
||||
['', '"ABC"', 0],
|
||||
['TRUETRUE', true, 2],
|
||||
['111', 1, 3],
|
||||
['δύο δύο ', '"δύο "', 2],
|
||||
['#VALUE!', '"ABC"', -1],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -31,6 +31,26 @@ return [
|
|||
'ABCDEFGHI',
|
||||
3,
|
||||
],
|
||||
[
|
||||
'',
|
||||
'ABCDEFGHI',
|
||||
0,
|
||||
],
|
||||
[
|
||||
'πέντε',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
5,
|
||||
],
|
||||
[
|
||||
'τέσσερα πέντε',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
13,
|
||||
],
|
||||
[
|
||||
'τρία τέσσερα πέντε',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
18,
|
||||
],
|
||||
[
|
||||
'UE',
|
||||
true,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,36 @@ return [
|
|||
'',
|
||||
'Mark Baker',
|
||||
],
|
||||
[
|
||||
1,
|
||||
'Ενα',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
],
|
||||
[
|
||||
9,
|
||||
'τρία',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
],
|
||||
[
|
||||
22,
|
||||
'πέντε',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
],
|
||||
[
|
||||
1,
|
||||
'Ενα',
|
||||
'ΕΝΑ ΔΥΟ ΤΡΙΑ ΤΕΣΣΕΡΑ ΠΕΝΤΕ',
|
||||
],
|
||||
[
|
||||
9,
|
||||
'τρία',
|
||||
'ΕΝΑ ΔΎΟ ΤΡΊΑ ΤΈΣΣΕΡΑ ΠΈΝΤΕ',
|
||||
],
|
||||
[
|
||||
22,
|
||||
'πέντε',
|
||||
'ΕΝΑ ΔΎΟ ΤΡΊΑ ΤΈΣΣΕΡΑ ΠΈΝΤΕ',
|
||||
],
|
||||
[
|
||||
'#VALUE!',
|
||||
'BITE',
|
||||
|
|
|
|||
|
|
@ -20,6 +20,20 @@ return [
|
|||
'x',
|
||||
1,
|
||||
],
|
||||
[
|
||||
'Mark Bxker',
|
||||
'Mark Baker',
|
||||
'a',
|
||||
'x',
|
||||
2,
|
||||
],
|
||||
[
|
||||
'Mark Bakker',
|
||||
'Mark Baker',
|
||||
'k',
|
||||
'kk',
|
||||
2,
|
||||
],
|
||||
[
|
||||
'Mark Baker',
|
||||
'Mark Baker',
|
||||
|
|
@ -27,6 +41,26 @@ return [
|
|||
'a',
|
||||
1,
|
||||
],
|
||||
[
|
||||
'Ενα δύο αρία αέσσερα πέναε',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
'τ',
|
||||
'α',
|
||||
],
|
||||
[
|
||||
'Ενα δύο τρία αέσσερα πέντε',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
'τ',
|
||||
'α',
|
||||
2,
|
||||
],
|
||||
[
|
||||
'Ενα δύο τρία ατέσσερα πέντε',
|
||||
'Ενα δύο τρία τέσσερα πέντε',
|
||||
'τ',
|
||||
'ατ',
|
||||
2,
|
||||
],
|
||||
'Unicode equivalence is not supported' => [
|
||||
"\u{0061}\u{030A}",
|
||||
"\u{0061}\u{030A}",
|
||||
|
|
|
|||
|
|
@ -5,10 +5,22 @@ return [
|
|||
'ABCDE,FGHIJ',
|
||||
[',', true, 'ABCDE', 'FGHIJ'],
|
||||
],
|
||||
[
|
||||
'ABCDEFGHIJ',
|
||||
['', true, 'ABCDE', 'FGHIJ'],
|
||||
],
|
||||
[
|
||||
'1-2-3',
|
||||
['-', true, 1, 2, 3],
|
||||
],
|
||||
[
|
||||
'<<::>>',
|
||||
['::', true, '<<', '>>'],
|
||||
],
|
||||
[
|
||||
'Καλό απόγευμα',
|
||||
[' ', true, 'Καλό', 'απόγευμα'],
|
||||
],
|
||||
[
|
||||
'Boolean-TRUE',
|
||||
['-', true, 'Boolean', '', true],
|
||||
|
|
|
|||
|
|
@ -9,6 +9,18 @@ return [
|
|||
'MARK BAKER',
|
||||
'mark baker',
|
||||
],
|
||||
[
|
||||
'BUENOS DÍAS',
|
||||
'buenos días',
|
||||
],
|
||||
[
|
||||
'ΚΑΛΗΜΕΡΑ',
|
||||
'Καλημερα',
|
||||
],
|
||||
[
|
||||
'ДОБРОЕ УТРО',
|
||||
'доброе утро',
|
||||
],
|
||||
[
|
||||
'TRUE',
|
||||
true,
|
||||
|
|
|
|||
Loading…
Reference in New Issue