Skip to content

Commit 132c374

Browse files
authored
Merge branch 'master' into bit32b
2 parents 5cfe66e + a83e9fb commit 132c374

File tree

155 files changed

+1193
-703
lines changed

Some content is hidden

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

155 files changed

+1193
-703
lines changed

CHANGELOG.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org).
77

88
## Unreleased - TBD
99

10-
### MINOR BREAKING CHANGE
10+
### BREAKING CHANGE
1111

12-
- Typing was strengthened by leveraging native typing. While this should not change any behavior, it might need minor
13-
adaption of your code if you use static analysis tools such as PHPStan or
14-
Psalm. [PR #3718](https://github.com/PHPOffice/PhpSpreadsheet/pull/3718)
12+
- Typing was strengthened by leveraging native typing. This should not change any behavior. However, if you implement
13+
any interfaces or inherit from any classes, you will need to adapt your typing accordingly. If you use static analysis
14+
tools such as PHPStan or Psalm, new errors might be found. If you find actual bugs because of the new typing, please
15+
open a PR that fixes it with a **detailed** explanation of the reason. We'll try to merge and release typing-related
16+
fixes quickly in the coming days. [PR #3718](https://github.com/PHPOffice/PhpSpreadsheet/pull/3718)
17+
- All deprecated things have been removed, for details, see [816b91d0b4](https://github.com/PHPOffice/PhpSpreadsheet/commit/816b91d0b4a0c7285a9e3fc88c58f7730d922044)
1518

1619
### Added
1720

@@ -28,11 +31,12 @@ and this project adheres to [Semantic Versioning](https://semver.org).
2831
- Check if Coordinate is Inside Range [PR #3779](https://github.com/PHPOffice/PhpSpreadsheet/pull/3779)
2932
- Flipping Images [Issue #731](https://github.com/PHPOffice/PhpSpreadsheet/issues/731) [PR #3801](https://github.com/PHPOffice/PhpSpreadsheet/pull/3801)
3033
- Chart Dynamic Title and Font Properties [Issue #3797](https://github.com/PHPOffice/PhpSpreadsheet/issues/3797) [PR #3800](https://github.com/PHPOffice/PhpSpreadsheet/pull/3800)
31-
- Chart Axis Display Units and Logarithmic Scale. [Issue #3833](https://github.com/PHPOffice/PhpSpreadsheet/pull/3833) [PR #3836](https://github.com/PHPOffice/PhpSpreadsheet/pull/3836)
34+
- Chart Axis Display Units and Logarithmic Scale. [Issue #3833](https://github.com/PHPOffice/PhpSpreadsheet/issues/3833) [PR #3836](https://github.com/PHPOffice/PhpSpreadsheet/pull/3836)
35+
- Partial Support of Fill Handles. [Discussion #3847](https://github.com/PHPOffice/PhpSpreadsheet/discussions/3847) [PR #3855](https://github.com/PHPOffice/PhpSpreadsheet/pull/3855)
3236

3337
### Changed
3438

35-
- Drop support for PHP 7.4, according to https://phpspreadsheet.readthedocs.io/en/latest/#php-version-support [PR #3713](https://github.com/PHPOffice/PhpSpreadsheet/pull/3713)
39+
- **Drop support for PHP 7.4**, according to https://phpspreadsheet.readthedocs.io/en/latest/#php-version-support [PR #3713](https://github.com/PHPOffice/PhpSpreadsheet/pull/3713)
3640
- RLM Added to NumberFormatter Currency. This happens depending on release of ICU which Php is using (it does not yet happen with any official release). PhpSpreadsheet will continue to use the value returned by Php, but a method is added to keep the result unchanged from release to release. [Issue #3571](https://github.com/PHPOffice/PhpSpreadsheet/issues/3571) [PR #3640](https://github.com/PHPOffice/PhpSpreadsheet/pull/3640)
3741
- `toFormattedString` will now always return a string. This was introduced with 1.28.0, but was not properly documented at the time. This can affect the results of `toArray`, `namedRangeToArray`, and `rangeToArray`. [PR #3304](https://github.com/PHPOffice/PhpSpreadsheet/pull/3304)
3842
- Value of constants FORMAT_CURRENCY_EUR and FORMAT_CURRENCY_USD was changed in 1.28.0, but was not properly documented at the time. [Issue #3577](https://github.com/PHPOffice/PhpSpreadsheet/issues/3577)
@@ -85,10 +89,14 @@ and this project adheres to [Semantic Versioning](https://semver.org).
8589
- COUNTIFS Does Not Require xlfn. [Issue #3819](https://github.com/PHPOffice/PhpSpreadsheet/issues/3819) [PR #3827](https://github.com/PHPOffice/PhpSpreadsheet/pull/3827)
8690
- Strip `xlfn.` and `xlws.` from Formula Translations. [Issue #3819](https://github.com/PHPOffice/PhpSpreadsheet/issues/3819) [PR #3828](https://github.com/PHPOffice/PhpSpreadsheet/pull/3828)
8791
- Recurse directories searching for font file. [Issue #2809](https://github.com/PHPOffice/PhpSpreadsheet/issues/2809) [PR #3830](https://github.com/PHPOffice/PhpSpreadsheet/pull/3830)
88-
- Reduce memory consumption of Worksheet::rangeToArray() when many empty rows are read. [Issue #3814](https://github.com/PHPOffice/PhpSpreadsheet/pull/3814) [PR #3834](https://github.com/PHPOffice/PhpSpreadsheet/pull/3834)
92+
- Reduce memory consumption of Worksheet::rangeToArray() when many empty rows are read. [Issue #3814](https://github.com/PHPOffice/PhpSpreadsheet/issues/3814) [PR #3834](https://github.com/PHPOffice/PhpSpreadsheet/pull/3834)
8993
- Reduce time used by Worksheet::rangeToArray() when many empty rows are read. [PR #3839](https://github.com/PHPOffice/PhpSpreadsheet/pull/3839)
9094
- Html Reader Tolerate Invalid Sheet Title. [PR #3845](https://github.com/PHPOffice/PhpSpreadsheet/pull/3845)
91-
- Do not include unparsed drawings when new drawing added. [Issue #3843](https://github.com/PHPOffice/PhpSpreadsheet/pull/3843) [PR #3846](https://github.com/PHPOffice/PhpSpreadsheet/pull/3846)
95+
- Do not include unparsed drawings when new drawing added. [Issue #3843](https://github.com/PHPOffice/PhpSpreadsheet/issues/3843) [PR #3846](https://github.com/PHPOffice/PhpSpreadsheet/pull/3846)
96+
- Do not include unparsed drawings when new drawing added. [Issue #3861](https://github.com/PHPOffice/PhpSpreadsheet/issues/3861) [PR #3862](https://github.com/PHPOffice/PhpSpreadsheet/pull/3862)
97+
- Excel omits `between` operator for data validation. [Issue #3863](https://github.com/PHPOffice/PhpSpreadsheet/issues/3863) [PR #3865](https://github.com/PHPOffice/PhpSpreadsheet/pull/3865)
98+
- Use less space when inserting rows and columns. [Issue #3687](https://github.com/PHPOffice/PhpSpreadsheet/issues/3687) [PR #3856](https://github.com/PHPOffice/PhpSpreadsheet/pull/3856)
99+
- Excel inconsistent handling of MIN/MAX/MINA/MAXA. [Issue #3866](https://github.com/PHPOffice/PhpSpreadsheet/issues/3866) [PR #3868](https://github.com/PHPOffice/PhpSpreadsheet/pull/3868)
92100

93101
## 1.29.0 - 2023-06-15
94102

docs/topics/recipes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ At present, the following locale settings are supported:
415415

416416
Language | | Locale Code
417417
---------------------|----------------------|-------------
418+
Bulgarian | български | bg
418419
Czech | Ceština | cs
419420
Danish | Dansk | da
420421
German | Deutsch | de

infra/LocaleGenerator.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,13 @@ public function generateLocales(): void
8686
protected function buildConfigFileForLocale(string $column, string $locale): void
8787
{
8888
$language = $this->localeTranslations->getCell($column . self::ENGLISH_LANGUAGE_NAME_ROW)->getValue();
89+
if (!is_string($language)) {
90+
throw new Exception('Non-string language value at ' . $column . self::ENGLISH_LANGUAGE_NAME_ROW);
91+
}
8992
$localeLanguage = $this->localeTranslations->getCell($column . self::LOCALE_LANGUAGE_NAME_ROW)->getValue();
93+
if (!is_string($localeLanguage)) {
94+
throw new Exception('Non-string locale language value at ' . $column . self::LOCALE_LANGUAGE_NAME_ROW);
95+
}
9096
$configFile = $this->openConfigFile($locale, $language, $localeLanguage);
9197

9298
$this->writeConfigArgumentSeparator($configFile, $column);
@@ -96,6 +102,9 @@ protected function buildConfigFileForLocale(string $column, string $locale): voi
96102
foreach ($this->errorCodeMap as $errorCode => $row) {
97103
$translationCell = $this->localeTranslations->getCell($column . $row);
98104
$translationValue = $translationCell->getValue();
105+
if ($translationValue !== null && !is_string($translationValue)) {
106+
throw new Exception('Non-string translation value at ' . $column . $row);
107+
}
99108
if (!empty($translationValue)) {
100109
$errorCodeTranslation = "{$errorCode} = {$translationValue}" . self::EOL;
101110
fwrite($configFile, $errorCodeTranslation);
@@ -114,6 +123,9 @@ protected function writeConfigArgumentSeparator($configFile, string $column): vo
114123
{
115124
$translationCell = $this->localeTranslations->getCell($column . self::ARGUMENT_SEPARATOR_ROW);
116125
$localeValue = $translationCell->getValue();
126+
if ($localeValue !== null && !is_string($localeValue)) {
127+
throw new Exception('Non-string locale value at ' . $column . self::CURRENCY_SYMBOL_ROW);
128+
}
117129
if (!empty($localeValue)) {
118130
$functionTranslation = "ArgumentSeparator = {$localeValue}" . self::EOL;
119131
fwrite($configFile, $functionTranslation);
@@ -127,6 +139,9 @@ protected function writeConfigCurrencySymbol($configFile, string $column): void
127139
{
128140
$translationCell = $this->localeTranslations->getCell($column . self::CURRENCY_SYMBOL_ROW);
129141
$localeValue = $translationCell->getValue();
142+
if ($localeValue !== null && !is_string($localeValue)) {
143+
throw new Exception('Non-string locale value at ' . $column . self::CURRENCY_SYMBOL_ROW);
144+
}
130145
if (!empty($localeValue)) {
131146
$functionTranslation = "currencySymbol = {$localeValue}" . self::EOL;
132147
fwrite($configFile, '##' . self::EOL);
@@ -141,13 +156,22 @@ protected function writeConfigCurrencySymbol($configFile, string $column): void
141156
protected function buildFunctionsFileForLocale(string $column, string $locale): void
142157
{
143158
$language = $this->functionNameTranslations->getCell($column . self::ENGLISH_LANGUAGE_NAME_ROW)->getValue();
159+
if (!is_string($language)) {
160+
throw new Exception('Non-string language value at ' . $column . self::ENGLISH_LANGUAGE_NAME_ROW);
161+
}
144162
$localeLanguage = $this->functionNameTranslations->getCell($column . self::LOCALE_LANGUAGE_NAME_ROW)
145163
->getValue();
164+
if (!is_string($localeLanguage)) {
165+
throw new Exception('Non-string locale language value at ' . $column . self::LOCALE_LANGUAGE_NAME_ROW);
166+
}
146167
$functionFile = $this->openFunctionNameFile($locale, $language, $localeLanguage);
147168

148169
foreach ($this->functionNameMap as $functionName => $row) {
149170
$translationCell = $this->functionNameTranslations->getCell($column . $row);
150171
$translationValue = $translationCell->getValue();
172+
if ($translationValue !== null && !is_string($translationValue)) {
173+
throw new Exception('Non-string translation value at ' . $column . $row);
174+
}
151175
if ($this->isFunctionCategoryEntry($translationCell)) {
152176
$this->writeFileSectionHeader($functionFile, "{$translationValue} ({$functionName})");
153177
} elseif (!array_key_exists($functionName, $this->phpSpreadsheetFunctions) && substr($functionName, 0, 1) !== '*') {

phpstan.neon.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ parameters:
2323
parallel:
2424
processTimeout: 300.0
2525
checkMissingIterableValueType: false
26+
checkGenericClassInNonGenericObjectType: false
2627
ignoreErrors:
2728
# Accept a bit anything for assert methods
2829
- '~^Parameter \#2 .* of static method PHPUnit\\Framework\\Assert\:\:assert\w+\(\) expects .*, .* given\.$~'

samples/Basic/13_Calculation.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,9 @@
157157
$helper->log('Calculated data');
158158
for ($col = 'B'; $col != 'G'; ++$col) {
159159
for ($row = 14; $row <= 41; ++$row) {
160+
$formula = $spreadsheet->getActiveSheet()->getCell($col . $row)->getValue();
160161
if (
161-
(($formula = $spreadsheet->getActiveSheet()->getCell($col . $row)->getValue()) !== null)
162+
is_string($formula)
162163
&& ($formula[0] == '=')
163164
) {
164165
$helper->log('Value of ' . $col . $row . ' [' . $formula . ']: ' . $spreadsheet->getActiveSheet()->getCell($col . $row)->getCalculatedValue());

samples/Basic/13_CalculationCyclicFormulae.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@
2222
$helper->log('Calculated data');
2323
for ($row = 1; $row <= 2; ++$row) {
2424
for ($col = 'A'; $col != 'C'; ++$col) {
25+
$formula = $spreadsheet->getActiveSheet()->getCell($col . $row)->getValue();
2526
if (
26-
(($formula = $spreadsheet->getActiveSheet()->getCell($col . $row)->getValue()) !== null)
27+
is_string($formula)
2728
&& ($formula[0] == '=')
2829
) {
2930
$helper->log('Value of ' . $col . $row . ' [' . $formula . ']: ' . $spreadsheet->getActiveSheet()->getCell($col . $row)->getCalculatedValue());

samples/Basic/31_Document_properties_write.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
$propertyValue = $spreadsheet->getProperties()->getCustomPropertyValue($customProperty);
5757
$propertyType = $spreadsheet->getProperties()->getCustomPropertyType($customProperty);
5858
if ($propertyType == Properties::PROPERTY_TYPE_DATE) {
59-
$formattedValue = date('d-M-Y H:i:s', (int) $propertyValue);
59+
$formattedValue = is_numeric($propertyValue) ? date('d-M-Y H:i:s', (int) $propertyValue) : '*****INVALID*****';
6060
} elseif ($propertyType == Properties::PROPERTY_TYPE_BOOLEAN) {
6161
$formattedValue = $propertyValue ? 'TRUE' : 'FALSE';
6262
} else {

samples/Basic/31_Document_properties_write_xls.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
$propertyValue = $spreadsheet->getProperties()->getCustomPropertyValue($customProperty);
5757
$propertyType = $spreadsheet->getProperties()->getCustomPropertyType($customProperty);
5858
if ($propertyType == Properties::PROPERTY_TYPE_DATE) {
59-
$formattedValue = date('d-M-Y H:i:s', (int) $propertyValue);
59+
$formattedValue = is_numeric($propertyValue) ? date('d-M-Y H:i:s', (int) $propertyValue) : '*****INVALID*****';
6060
} elseif ($propertyType == Properties::PROPERTY_TYPE_BOOLEAN) {
6161
$formattedValue = $propertyValue ? 'TRUE' : 'FALSE';
6262
} else {

samples/Basic/45_Quadratic_equation_solver.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,12 @@
5959
$r1Formula = '=IMDIV(IMSUM(-' . $_POST['B'] . ',IMSQRT(' . $discriminant . ')),2 * ' . $_POST['A'] . ')';
6060
$r2Formula = '=IF(' . $discriminant . '=0,"Only one root",IMDIV(IMSUB(-' . $_POST['B'] . ',IMSQRT(' . $discriminant . ')),2 * ' . $_POST['A'] . '))';
6161

62-
$helper->log(Calculation::getInstance()->calculateFormula($r1Formula));
63-
$helper->log(Calculation::getInstance()->calculateFormula($r2Formula));
62+
/** @var string */
63+
$output = Calculation::getInstance()->calculateFormula($r1Formula);
64+
$helper->log("$output");
65+
/** @var string */
66+
$output = Calculation::getInstance()->calculateFormula($r2Formula);
67+
$helper->log("$output");
6468
$callEndTime = microtime(true);
6569
$helper->logEndingNotes();
6670
}

samples/Calculations/DateTime/DAYS360.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@
4949
$worksheet->getCell('E' . $row)->getFormattedValue(),
5050
$worksheet->getCell('F' . $row)->getFormattedValue()
5151
));
52-
$helper->log(sprintf(
53-
'Days: %d (US) %d (European)',
54-
$worksheet->getCell('G' . $row)->getCalculatedValue(),
55-
$worksheet->getCell('H' . $row)->getCalculatedValue()
56-
));
52+
$helper->log(
53+
'Days: '
54+
. $worksheet->getCell('G' . $row)->getCalculatedValue()
55+
. ' (US) '
56+
. $worksheet->getCell('H' . $row)->getCalculatedValue()
57+
. ' (European)'
58+
);
5759
}

0 commit comments

Comments
 (0)