Skip to content

Commit 1439211

Browse files
authored
Merge pull request #4544 from oleibman/replacedummy
Allow Replace of Dummy Function with Custom Function
2 parents 09442da + dfb9411 commit 1439211

File tree

4 files changed

+56
-1
lines changed

4 files changed

+56
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
3535
- Recognize application/x-empty mimetype. [Issue #4521](https://github.com/PHPOffice/PhpSpreadsheet/issues/4521) [PR #4524](https://github.com/PHPOffice/PhpSpreadsheet/pull/4524)
3636
- Micro-optimization in getSheetByName. [PR #4499](https://github.com/PHPOffice/PhpSpreadsheet/pull/4499)
3737
- Bug in resizeMatricesExtend. [Issue #4451](https://github.com/PHPOffice/PhpSpreadsheet/issues/4451) [PR #4474](https://github.com/PHPOffice/PhpSpreadsheet/pull/4474)
38+
- Allow Replace of Dummy Function with Custom Function. [PR #4544](https://github.com/PHPOffice/PhpSpreadsheet/pull/4544)
3839
- Preserve 0x0a in Strings if Desired. [Issue #347](https://github.com/PHPOffice/PhpSpreadsheet/issues/347) [PR #4536](https://github.com/PHPOffice/PhpSpreadsheet/pull/4536)
3940

4041
## 2025-06-22 - 4.4.0

src/PhpSpreadsheet/Calculation/CalculationBase.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ protected static function &getFunctionsAddress(): array
3030
public static function addFunction(string $key, array $value): bool
3131
{
3232
$key = strtoupper($key);
33-
if (array_key_exists($key, FunctionArray::$phpSpreadsheetFunctions)) {
33+
if (
34+
array_key_exists($key, FunctionArray::$phpSpreadsheetFunctions)
35+
&& !self::isDummy($key)
36+
) {
3437
return false;
3538
}
3639
$value['custom'] = true;
@@ -39,6 +42,20 @@ public static function addFunction(string $key, array $value): bool
3942
return true;
4043
}
4144

45+
private static function isDummy(string $key): bool
46+
{
47+
// key is already known to exist
48+
$functionCall = FunctionArray::$phpSpreadsheetFunctions[$key]['functionCall'] ?? null;
49+
if (!is_array($functionCall)) {
50+
return false;
51+
}
52+
if (($functionCall[1] ?? '') !== 'DUMMY') {
53+
return false;
54+
}
55+
56+
return true;
57+
}
58+
4259
public static function removeFunction(string $key): bool
4360
{
4461
$key = strtoupper($key);

tests/PhpSpreadsheetTests/Calculation/CustomFunction.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcException;
88
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Helpers;
9+
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
910

1011
class CustomFunction
1112
{
@@ -19,4 +20,25 @@ public static function fourthPower(mixed $number): float|int|string
1920

2021
return $number ** 4;
2122
}
23+
24+
/**
25+
* ASC.
26+
* Converts full-width (double-byte) characters to half-width (single-byte) characters.
27+
* There are many difficulties with implementing this into PhpSpreadsheet.
28+
*/
29+
public static function ASC(mixed $stringValue): string
30+
{
31+
/*if (is_array($stringValue)) {
32+
return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $stringValue);
33+
}*/
34+
$stringValue = StringHelper::convertToString($stringValue, convertBool: true);
35+
if (function_exists('mb_convert_kana')) {
36+
return mb_convert_kana($stringValue, 'a', 'UTF-8');
37+
}
38+
// Fallback if mb_convert_kana is not available.
39+
// PhpSpreadsheet heavily relies on mbstring, so this is more of a theoretical fallback.
40+
// A comprehensive manual conversion is extensive.
41+
42+
return $stringValue;
43+
}
2244
}

tests/PhpSpreadsheetTests/Calculation/CustomFunctionTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,19 @@ public static function testCustomFunction(): void
3131
self::assertSame('#NAME?', $calculation->calculateFormula('=FOURTHPOWER(3)'));
3232
self::assertFalse(Calculation::removeFunction('WHATEVER'));
3333
}
34+
35+
public static function testReplaceDummyFunction(): void
36+
{
37+
$functions = Calculation::getFunctions();
38+
$key = 'ASC';
39+
$oldValue = $functions[$key] ?? null;
40+
self::assertIsArray($oldValue);
41+
$calculation = Calculation::getInstance();
42+
$value = $oldValue;
43+
$value['functionCall'] = [CustomFunction::class, 'ASC'];
44+
self::assertTrue(Calculation::addFunction($key, $value));
45+
self::assertSame('ABC', $calculation->calculateFormula('=ASC("ABC")'));
46+
self::assertTrue(Calculation::removeFunction('ASC'));
47+
self::assertTrue(Calculation::addFunction($key, $oldValue));
48+
}
3449
}

0 commit comments

Comments
 (0)