Skip to content

Commit fff2373

Browse files
authored
Merge branch 'master' into issue4584
2 parents ecc6f2f + f467ac5 commit fff2373

File tree

99 files changed

+1397
-193
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+1397
-193
lines changed

.github/workflows/main.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ jobs:
8181
- name: Setup PHP, with composer and extensions
8282
uses: shivammathur/setup-php@v2
8383
with:
84-
php-version: 8.3
84+
php-version: 8.4
8585
extensions: ctype, dom, gd, iconv, fileinfo, libxml, mbstring, simplexml, xml, xmlreader, xmlwriter, zip, zlib
8686
coverage: none
8787

@@ -98,7 +98,7 @@ jobs:
9898
- name: Setup PHP, with composer and extensions
9999
uses: shivammathur/setup-php@v2
100100
with:
101-
php-version: 8.3
101+
php-version: 8.4
102102
extensions: ctype, dom, gd, iconv, fileinfo, libxml, mbstring, simplexml, xml, xmlreader, xmlwriter, zip, zlib
103103
coverage: none
104104
tools: cs2pr
@@ -129,7 +129,7 @@ jobs:
129129
- name: Setup PHP, with composer and extensions
130130
uses: shivammathur/setup-php@v2
131131
with:
132-
php-version: 8.3
132+
php-version: 8.4
133133
extensions: ctype, dom, gd, iconv, fileinfo, libxml, mbstring, simplexml, xml, xmlreader, xmlwriter, zip, zlib
134134
coverage: none
135135
tools: cs2pr
@@ -160,7 +160,7 @@ jobs:
160160
- name: Setup PHP, with composer and extensions
161161
uses: shivammathur/setup-php@v2
162162
with:
163-
php-version: 8.3
163+
php-version: 8.4
164164
extensions: ctype, dom, gd, iconv, fileinfo, libxml, mbstring, simplexml, xml, xmlreader, xmlwriter, zip, zlib
165165
coverage: none
166166
tools: cs2pr
@@ -191,7 +191,7 @@ jobs:
191191
- name: Setup PHP, with composer and extensions
192192
uses: shivammathur/setup-php@v2
193193
with:
194-
php-version: 8.3
194+
php-version: 8.4
195195
extensions: ctype, dom, gd, iconv, fileinfo, libxml, mbstring, simplexml, xml, xmlreader, xmlwriter, zip, zlib
196196
coverage: none
197197
tools: cs2pr
@@ -230,7 +230,7 @@ jobs:
230230
- name: Setup PHP, with composer and extensions
231231
uses: shivammathur/setup-php@v2
232232
with:
233-
php-version: 8.3
233+
php-version: 8.4
234234
extensions: ctype, dom, gd, iconv, fileinfo, libxml, mbstring, simplexml, xml, xmlreader, xmlwriter, zip, zlib
235235
coverage: pcov
236236

.php-cs-fixer.dist.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@
166166
'php_unit_test_class_requires_covers' => false, // We don't care as much as we should about coverage
167167
'phpdoc_add_missing_param_annotation' => false, // Don't add things that bring no value
168168
'phpdoc_align' => false, // Waste of time
169-
'phpdoc_annotation_without_dot' => true,
169+
'phpdoc_annotation_without_dot' => false,
170170
'phpdoc_indent' => true,
171171
'phpdoc_line_span' => false, // Unfortunately our old comments turn even uglier with this
172172
'phpdoc_no_access' => true,

CHANGELOG.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org). Thia is a
99

1010
### Added
1111

12-
- Nothing yet.
12+
- Option to display numbers with less precision. [Issue #4626](https://github.com/PHPOffice/PhpSpreadsheet/issues/4626) [PR #4640](https://github.com/PHPOffice/PhpSpreadsheet/pull/4640)
1313

1414
### Removed
1515

@@ -25,12 +25,19 @@ and this project adheres to [Semantic Versioning](https://semver.org). Thia is a
2525

2626
### Deprecated
2727

28-
- Nothing yet.
28+
- Worksheet::getHashInt serves no useful purpose. No replacement.
29+
- Spreadsheet::getId serves no useful purpose. No replacement.
2930

3031
### Fixed
3132

33+
- Performance improvement when working with large amounts of cells. [Issue #4607](https://github.com/PHPOffice/PhpSpreadsheet/issues/4607) [PR #4609](https://github.com/PHPOffice/PhpSpreadsheet/pull/4609)
34+
- Minor improvements to Calculation coverage. [PR #4624](https://github.com/PHPOffice/PhpSpreadsheet/pull/4624)
35+
- Conditional formatting in extLst. [Issue #4629](https://github.com/PHPOffice/PhpSpreadsheet/issues/4629) [PR #4633](https://github.com/PHPOffice/PhpSpreadsheet/pull/4633)
3236
- Php8.5 deprecates use of null as array index. [PR #4634](https://github.com/PHPOffice/PhpSpreadsheet/pull/4634)
3337
- Wrapped cells and default row height. [Issue #4584](https://github.com/PHPOffice/PhpSpreadsheet/issues/4584) [PR #4645](https://github.com/PHPOffice/PhpSpreadsheet/pull/4645)
38+
- For Php8.5, replace one of our two uses of `__wakeup` with `__unserialize`, and eliminate the other. [PR #4639](https://github.com/PHPOffice/PhpSpreadsheet/pull/4639)
39+
- Use prefix _xlfn for BASE function. [Issue #4638](https://github.com/PHPOffice/PhpSpreadsheet/issues/4638) [PR #4641](https://github.com/PHPOffice/PhpSpreadsheet/pull/4641)
40+
- Additional support for union and intersection. [PR #4596](https://github.com/PHPOffice/PhpSpreadsheet/pull/4596)
3441

3542
## 2025-09-03 - 5.1.0
3643

composer.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/topics/Looping the Loop.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ It can return the raw cell value (which isn't particularly useful if the cell co
5757
| $calculateFormulas | boolean | false | Flag to indicate if formula values should be calculated before returning. |
5858
| $formatData | boolean | false | Flag to request that values should be formatting before returning. |
5959
| $returnCellRef | boolean | false | False - Return a simple enumerated array of rows and columns (indexed by number counting from zero)<br />True - Return rows and columns indexed by their actual row and column IDs. |
60+
| $ignoreHidden | boolean | false | True - Ignore hidden rows and columns. |
61+
| $reduceArrays | boolean | false | True - If calculated value is an array, reduce it to top leftmost value. |
62+
| $lessFloatPrecision | boolean | false | True - PhpSpreadsheet 5.2+ - Floats, if formatted, will display as a more human-friendly but possibly less accurate value. |
6063

6164
### Dealing with empty rows
6265

infra/LocaleGenerator.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ protected function mapErrorCodeRows(): void
327327
foreach ($cells as $cell) {
328328
if ($cell->getValue() != '') {
329329
$this->log($cell->getRow() . ' -> ' . $cell->getValueString());
330-
$this->errorCodeMap[$cell->getValue()] = $cell->getRow();
330+
$this->errorCodeMap[$cell->getValueString()] = $cell->getRow();
331331
}
332332
}
333333
}
@@ -345,7 +345,7 @@ protected function mapFunctionNameRows(): void
345345
if ($this->isFunctionCategoryEntry($cell)) {
346346
if (!empty($cell->getValue())) {
347347
$this->log('CATEGORY: ' . $cell->getValueString());
348-
$this->functionNameMap[$cell->getValue()] = $cell->getRow();
348+
$this->functionNameMap[$cell->getValueString()] = $cell->getRow();
349349
}
350350

351351
continue;
@@ -356,7 +356,7 @@ protected function mapFunctionNameRows(): void
356356
$this->functionNameMap[($cell->getValue() ? 'TRUE' : 'FALSE')] = $cell->getRow();
357357
} else {
358358
$this->log($cell->getRow() . ' -> ' . $cell->getValueString());
359-
$this->functionNameMap[$cell->getValue()] = $cell->getRow();
359+
$this->functionNameMap[$cell->getValueString()] = $cell->getRow();
360360
}
361361
}
362362
}

samples/Wizards/NumberFormat/Currency.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
$helper->log('Unrecognized currency symbol');
105105
} else {
106106
try {
107-
$negative = $negatives[$_POST['negative']] ?? CurrencyNegative::minus;
107+
$negative = $negatives[$_POST['negative']] ?? CurrencyNegative::minus; //* @phpstan-ignore-line
108108
$wizard = new Wizard\Currency($_POST['currency'], (int) $_POST['decimals'], isset($_POST['thousands']), (bool) $_POST['position']);
109109
$wizard->setNegative($negative);
110110
$mask = $wizard->format();
@@ -118,7 +118,7 @@
118118
. ', Wizard\Currency::' . (((bool) $_POST['position']) ? 'LEADING_SYMBOL' : 'TRAILING_SYMBOL')
119119
. ');'
120120
);
121-
$helper->log('$wizard->setNegative(' . $negativesString[$_POST['negative']] . ');');
121+
$helper->log('$wizard->setNegative(' . $negativesString[$_POST['negative']] . ');'); //* @phpstan-ignore-line
122122
$helper->log('$mask = $wizard->format();');
123123
$helper->log('<br />echo (string) $mask;');
124124
$helper->log('<hr /><b>Mask:</b><br />');
-272 Bytes
Binary file not shown.

src/PhpSpreadsheet/Calculation/Calculation.php

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,7 @@ private static function resizeMatricesExtend(array &$matrix1, array &$matrix2, i
888888
}
889889
}
890890
if ($matrix1Rows < $matrix2Rows) {
891-
$x = ($matrix1Rows === 1) ? $matrix1[0] : array_fill(0, $matrix1Columns, null);
891+
$x = ($matrix1Rows === 1) ? $matrix1[0] : array_fill(0, $matrix2Columns, null);
892892
for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) {
893893
$matrix1[$i] = $x;
894894
}
@@ -1095,6 +1095,10 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
10951095
$this->branchPruner->initialiseForLoop();
10961096

10971097
$opCharacter = $formula[$index]; // Get the first character of the value at the current index position
1098+
if ($opCharacter === "\xe2") { // intersection or union
1099+
$opCharacter .= $formula[++$index];
1100+
$opCharacter .= $formula[++$index];
1101+
}
10981102

10991103
// Check for two-character operators (e.g. >=, <=, <>)
11001104
if ((isset(self::COMPARISON_OPERATORS[$opCharacter])) && (strlen($formula) > $index) && isset($formula[$index + 1], self::COMPARISON_OPERATORS[$formula[$index + 1]])) {
@@ -1115,7 +1119,7 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
11151119
++$index;
11161120
} elseif ($opCharacter === '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded?
11171121
++$index; // Drop the redundant plus symbol
1118-
} elseif ((($opCharacter === '~') || ($opCharacter === '') || ($opCharacter === '')) && (!$isOperandOrFunction)) {
1122+
} elseif ((($opCharacter === '~') /*|| ($opCharacter === '∩') || ($opCharacter === '∪')*/) && (!$isOperandOrFunction)) {
11191123
// We have to explicitly deny a tilde, union or intersect because they are legal
11201124
return $this->raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression
11211125
} elseif ((isset(self::CALCULATION_OPERATORS[$opCharacter]) || $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack?
@@ -1233,6 +1237,15 @@ private function internalParseFormula(string $formula, ?Cell $cell = null): bool
12331237
// MS Excel allows this if the content is cell references; but doesn't allow actual values,
12341238
// but at this point, we can't differentiate (so allow both)
12351239
return $this->raiseFormulaError('Formula Error: Unexpected ,');
1240+
/* The following code may be a better choice, but, with
1241+
the other changes for this PR, I can no longer come up
1242+
with a test case that gets here
1243+
$stack->push('Binary Operator', '∪');
1244+
1245+
++$index;
1246+
$expectingOperator = false;
1247+
1248+
continue;*/
12361249
}
12371250

12381251
/** @var array<string, int> $d */
@@ -1699,7 +1712,7 @@ private function processTokenStack(false|array $tokens, ?string $cellID = null,
16991712
return $this->raiseFormulaError($e->getMessage(), $e->getCode(), $e);
17001713
}
17011714
}
1702-
} elseif (!is_numeric($token) && !is_object($token) && isset($token, self::BINARY_OPERATORS[$token])) {
1715+
} elseif (!is_numeric($token) && !is_object($token) && isset($token, self::BINARY_OPERATORS[$token])) { //* @phpstan-ignore-line
17031716
// if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack
17041717
// We must have two operands, error if we don't
17051718
$operand2Data = $stack->pop();
@@ -1927,6 +1940,14 @@ private function processTokenStack(false|array $tokens, ?string $cellID = null,
19271940
$stack->push('Value', $cellIntersect, $cellRef);
19281941
}
19291942

1943+
break;
1944+
case '': // union
1945+
/** @var mixed[][] $operand1 */
1946+
/** @var mixed[][] $operand2 */
1947+
$cellUnion = array_merge($operand1, $operand2);
1948+
$this->debugLog->writeDebugLog('Evaluation Result is %s', $this->showTypeDetails($cellUnion));
1949+
$stack->push('Value', $cellUnion, 'A1');
1950+
19301951
break;
19311952
}
19321953
} elseif (($token === '~') || ($token === '%')) {
@@ -2792,6 +2813,14 @@ private function evaluateDefinedName(Cell $cell, DefinedName $namedRange, Worksh
27922813

27932814
$definedNameValue = $namedRange->getValue();
27942815
$definedNameType = $namedRange->isFormula() ? 'Formula' : 'Range';
2816+
if ($definedNameType === 'Range') {
2817+
if (preg_match('/^(.*!)?(.*)$/', $definedNameValue, $matches) === 1) {
2818+
$matches2 = trim($matches[2]);
2819+
$matches2 = preg_replace('/ +/', '', $matches2) ?? $matches2;
2820+
$matches2 = preg_replace('/,/', '', $matches2) ?? $matches2;
2821+
$definedNameValue = $matches[1] . $matches2;
2822+
}
2823+
}
27952824
$definedNameWorksheet = $namedRange->getWorksheet();
27962825

27972826
if ($definedNameValue[0] !== '=') {
@@ -2879,6 +2908,7 @@ private static function swapOperands(Stack $stack, string $opCharacter): bool
28792908
if ($stack->count() > 0) {
28802909
$o2 = $stack->last();
28812910
if ($o2) {
2911+
/** @var array{value: string} $o2 */
28822912
if (isset(self::CALCULATION_OPERATORS[$o2['value']])) {
28832913
$retVal = (self::OPERATOR_PRECEDENCE[$opCharacter] ?? 0) <= self::OPERATOR_PRECEDENCE[$o2['value']];
28842914
}

src/PhpSpreadsheet/Calculation/CalculationLocale.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ protected static function loadLocales(): void
6363
$filename = substr($filename, strlen($localeFileDirectory));
6464
if ($filename != 'en') {
6565
self::$validLocaleLanguages[] = $filename;
66+
$subdirs = glob("$localeFileDirectory$filename/*", GLOB_ONLYDIR) ?: [];
67+
foreach ($subdirs as $subdir) {
68+
$subdirx = basename($subdir);
69+
self::$validLocaleLanguages[] = "{$filename}_{$subdirx}";
70+
}
6671
}
6772
}
6873
}

0 commit comments

Comments
 (0)