Fix#1641. Excel allows explicit hiding of row after filter is applied, but PhpSpreadsheet automatically invokes showHideRows on all auto-filters, preventing users from doing the same. Change to invoke showHideRows only if it hasn't already been invoked, or if filter criteria have changed since it was last invoked. Autofilters read in from an existing spreadsheet are assumed to be already invoked.
This is potentially a breaking change, probably a minor one. The conditions to set up 1641 are probably uncommon, but users who meet those conditions and are happy with the current behavior will see a break. The new behavior is closer to how Excel itself behaves. A new method `reevaluateAutoFilters` is added to `Spreadsheet`; this can be used to restore the old behavior if desired. The new method is added to the documentation, along with a description of how the situation described in 1641 is handled in Excel and PhpSpreadsheet.
While examining Excel's behavior, it became evident that, although a filter is applied to an entire column, it is actually applied only to the rows that are populated when the filter is defined, as can be verified by examining the XML definition of the filter. When you re-apply the filter, rows that have been added since are considered. It would be useful to provide PhpSpreadsheet with a method to do the same. I have added, and documented, `setRangeToMaxRow` to `AutoFilter`.
`ReferenceHelper::insertNewBefore` copies data from one cell to another when adding/removing rows or columns.
It now also respects the data type set for that cell and does not use value binder again.
* Handle a wildcard match that contains a forward slash in the pattern by adding / to the delimiter list of preg_quote
* Fix SUMIF doing a wildcard match on empty cells (NULL)
* Fix compare logic to return false when value is an empty string or NULL (Verified against LibreOffice SUMIF and MATCH handling of empty cells)
As configured, Phpstan running under Php7 reports no errors. However, running under Php8, it reports 218 (!) errors. The vast majority of these are due to two reasons:
- renaming parameters in Php builtin functions in preparation for named parameters.
- using the new class `GdImage` rather than type `resource` as the argument type for many image-based functions.
Regardless of the cause, this will be a problem sooner or later. This PR is an attempt to get ahead of that problem. It tweaks only the Phpstan configuration files, without changing any PhpSpreadsheet code. Php7 continues to report no errors, and the number of errors for Php8 is reduced to 13. Although those 13 can also be tweaked, there is a case to be made that code corrections might be better in at least some of those instances. I will attend to those as one or more PRs after this one.
Because this involves no changes to code, and because Phpstan baseline is a common cause of merge difficulties, I will probably merge this in a day or two, more quickly than I customarily do.
Fix#1691. PhpSpreadsheet allows the setting of different page size and orientation on each worksheet. It also allows the setting of page size and orientation on the PDF writer. It isn't clear which is supposed to prevail when the two are in conflict. In the cited issue, the user expects the PDF writer setting to prevail, and I tend to agree. Code is changed to do this, and handling things in this manner is now explicitly documented.
PhpSpreadsheet uses a default paper size of Letter, and a default orientation of Default (which Excel treats as Portrait). New static routines are added to change the default for sheets created subsequent to such calls. This could allow users to configure these defaults better for their environments. The new functions are added to the documentation.
Fix#2387. Fix#2075. There was substantial refactoring of Writer Xlsx styles in 18.0. An existing static property `$theme` was intended to be shared by both Writer Xlsx and the new Writer Xlsx Styles. However, the initialization of the property in the latter happened later than it should have. This PR makes that initialization happen as soon as the theme has been read. Also, declaring that property as static seems questionable; I have made it an instance member. This small re-factoring makes it possible to now support Themes in tab colors.
Since this PR changes Reader/Xlsx/Styles, add type-hinting throughout that module to eliminate Phpstan/Scrutinizer problems. I also removed method readStyle from Reader/Xlsx, since it was essentially duplicated in Reader/Xlsx/Styles. And I added a small number of tests to ensure that Styles is 100% covered. All of this is necessary in preparation for Namespacing phase 2.
Fix#2385. NumberFormatter is using sprintf on a float, and is seeing inconsistent rounding as a result (it will also occasionally result in `-0`). Change to round the number before presenting it to sprintf.
oleibman said:
The results of uncommenting the statements will often not be successful.
In Excel, if I enter `=MINVERSE({2,0;0,1})` into cell A1, you will get a
`dynamic array` (which we do not yet support) - A1 will contain 0.5, A2
and B1 will contain 0, and B2 will contain 1. There are also `spill`
implications for such a formula. The XML for these cells will be:
``` xml
<row r="1" spans="1:2" x14ac:dyDescent="0.3">
<c r="A1" cm="1">
<f t="array" ref="A1:B2">MINVERSE({2,0;0,1})</f>
<v>0.5</v>
</c>
<c r="B1">
<v>0</v>
</c>
</row>
<row r="2" spans="1:2" x14ac:dyDescent="0.3">
<c r="A2">
<v>0</v>
</c>
<c r="B2">
<v>1</v>
</c>
</row>
```
I believe that the PhpSpreadsheet equivalent of doing this (with the statements
uncommented) is:
```php
$spreadsheet = new Spreadsheet();
$calculation = Calculation::getInstance($spreadsheet);
$calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_ARRAY);
$sheet = $spreadsheet->getActiveSheet();
$sheet->getCell('A1')->setValue('=MINVERSE({2,0;0,1})');
$writer = new Xlsx($spreadsheet);
$oufil = 'issue.2343.xlsx';
$writer->save($oufil);
```
But our output file only fills in A1:
```xml
<row r="1" spans="1:1">
<c r="A1">
<f>MINVERSE({2,0;0,1})</f>
<v>0.5</v>
</c>
</row>
```
And, even though A1 has its correct value, note that its `f` tag does not have
a `t` attribute. This is because we never set any formula attributes, except
in Xlsx Reader (see next paragraph), so we do not encounter the `'array'`
condtion for a formula newly added to a spreadsheet.
We do slightly better when we read the first file (as opposed to creating a new
spreadsheet), but we succeed only by accident. Because B1, A2, and B2 are
assigned values in the XML, all 4 cells will have the expected values. But they
are now independent of each other, not part of a dynamic array. When we write
this out, it is almost correct:
```xml
<row r="1" spans="1:2">
<c r="A1">
<f>MINVERSE({2,0;0,1})</f>
<v>0.5</v>
</c>
<c r="B1">
<v>0</v>
</c>
</row>
<row r="2" spans="1:2">
<c r="A2">
<v>0</v>
</c>
<c r="B2">
<v>1</v>
</c>
</row>
```
Again, the `f` tag has no `t` attribute, and it doesn't seem to matter whether we set
RETURN_TYPE_ARRAY or not. I think this particular aspect of the problem might be
relatively easy to fix.
When the fill color property of `DataSeries.plotLabel` using a
DataSeriesValues on a line chart is set, the XLSX file written
is corrupted, and MSExcel2016 removes the drawing1.xml if forced open.
This problem was already documented on issue #589 along with a possible
solution. So all credits go to @madrussa. I am only submitting the PR.
Fixes#589Closes#1930
* Allow Skipping One Unit Test
Alone in the test suite, URLImageTest needs to access the internet. It's a little fragile (the site that it's looking for may go away or change), but no real problem. However, on my system, it runs afoul of my proxy. Rather than jumping through hoops when I run the test suite (which happens very often), I am changing the test to skip if an environment variable is set to a specific value. This should not adversely affect anyone, and the test will still run in github, but it will help me a lot.
* Scrutinizer
It complained that my one new if statement made the module too complex. There actually were a number of if-then-else situations that could be handled just as well with assertions. I have changed it accordingly.
After upgrading, Phpunit indicates that the current schema is deprecated. Used Phpunit's own `--migrate-configuration` option to create current version.
* AutoFilter Improvements
Fix issue #2378. The following changes are made:
- NotEqual tests must be part of a custom filter. Documentation has been changed to indicate that.
- Method setAndOr was replaced by setJoin some time ago. Documentation now reflects that change.
- Documentation to indicate that string filters are not case-sensitive, same as in Excel.
- Filters testing against numeric value now include a numeric test (not numeric for not equal, numeric for all others).
- String filter had previously treated everything as a test for "equal". It now handles "not equal" and the variants of "greater/less" with or without "equal".
- Documentation correctly stated that no more than 2 rules are allowed in a custom filter. Code did not enforce this restriction. It now does, throwing an exception if an attempt is made to add a third rule.
- Deleted a lot of comments in Rule.php to make it easier to see what is not yet implemented (between, begins with, etc.). I may take these on in future.
- Added a number of tests for the new functionality.
* Not Sure Why Phpstan Results Differ Local vs Github
Let's see if this change suffices.
* Phpstan Still
Not sure how to convince it. Let's try this.
* Phpstan Solved
Figured out the problem on my local machine. Expect this to work.
Fix#2389. Hyperlinks referring to cells in the spreadsheet itself are not being handled properly. This is the first namespacing regression identified for release 19. Usual cause and fix - need to take greater care with attributes than was previously the case.
* Support Data Validations in More Versions of Excel
Attempt to deal with #2368, this time for good. Some deleted code was accidentally restored just before release 19, causing errors in spreadsheets with Data Validations. PR #2369 removed the duplicated code, and the fix was confirmed in current versions of Excel for Windows, Google sheets, and other versions of Excel. However, there were problems reported in earlier version of Excel for Windows, and some, versions of Excel for Mac, not all but including a recent one. This change, which is simpler than the original (no need for extLst) fix for DataValidations, is tested with Excel 2007 and Excel 2003 as well as more recent versions. I do not have a Mac on which to test.
* Multiple Identical Data Validation Lists
Using the same Data Validation List in multiple places on a worksheet caused them all to be merged into the same range. This was because sqref was not part of the hash code; it is now, avoiding this problem.
* Must Write Data Validations Before Hyperlinks
See discussion in #2389.
* ZipArchive and "Inconsistent" Zip File
Fix#2362. I added test for zip file inconsistency when dealing with a particularly nasty PHP/libzip bug affecting zero-length files. However, we also now verify that the file starts with a valid zip signature, so the consistency test is not really needed, and, from what I've read on the web, isn't particularly useful. The file with a problem, for example, opens just fine with Excel and zip, despite Php reporting it as inconsistent (when asked to check consistency). So, remove the consistency check.
* Update Issue2362Test.php
Latest Phpstan does not allow cast from 'mixed' to 'string'.
* Update Issue2362Test.php
See the discussion in PR #2232 which came about 3 months after it was merged. It caused a problem in an unusual situation which did not come to light until the change was part of the new release version. The original PR changed PhpSpreadsheet's behavior to match Excel's for (not case sensitive) strings `TRUE` and `FALSE`. Excel treats the values as boolean, and now so does PhpSpreadsheet.
When StringValueBinder is used, this becomes a tricky situation. The user wants the original strings preserved, including the case of all the letters. This PR changes the behavior of CSV reader as follows:
- If StringValueBinder is not in effect, convert to boolean.
- If StringValueBinder (actually any binder with method getBooleanConversion) is in effect, and the result of getBooleanConversion is true (which is the default in StringValueBinder), leave the value coming out of Csv Reader as the unchanged string.
- Otherwise, convert to boolean.
This should mean that there are no regression problems with StringValueBinder, while allowing PhpSpreadsheet to continue to match Excel in the default situation. No new settings are required.
* Update Some Doc Block Annotations
See PR #2010. That PR was never completed, and has gone stale. However, it was correct in identifying a situation where the doc block was not entirely accurate. It did not go far enough - several closely-related methods have similar problems. This PR attempts to fix the original problem and its close relations. Aside from the doc block changes, there are very minor changes to executable code. It also changes some of the unit tests targeted at the methods in question to eliminate mocking in favor of 'real' tests.
* Change Method to Static
Otherwise Scrutinizer will complain, even though Phpstan doesn't.
* Scrutinizer
Various clean-up activities.
* Scrutinizer
@#&$(*#&$ Got complexity down from 53 to (I think) 50. Don't really know what the target is.
* Code Changes Suggested By Review
Some improvements suggested in review by @PowerKiKi.
* Update Cells.php
* Merge Conflict
A change to a parameter name caused several problems when trying to fix it on Github. Fixing it locally should do the trick.
* Merge Conflicts in Phpstan Baseline
PR #2382 made a large number of changes to Phpstan Baseline, some of which conflicted with the Phpstan Baseline changes in this PR. This should resolve them all.
Dependabot opened PR #2365 to upgrade php-cs-fixer from 2.19.2 to 3.2.1. Changes are required before that can be merged successfully. I believe all the necessary changes are in this PR.
One of the changes is to replace .php_cs.dist with .php-cs-fixer.dist.php. I have made those two identical for this PR so that there will be a meaningful delta listing. After this change is merged, master can be merged into 2365, which will hopefully pass all tests and be mergeable at that point. We can delete the unneeded file after that merge.
Spacing is changed in a handful of source members because of extra stringency in 3.2.1.
Example: right shift shared formula: IF(A$1=0,0,A1/A$1)
Expected value: IF(B$1=0,0,B1/B$1)
Actual value: IF(B$1=0,0,A1/B$1)
Similar behavior is observed when copying formulas vertically.
This issue occurs because a fixed and a non-fixed cell hit the same element of the $newCellTokens array by index $cellIndex
* Update Doc Blocks to Discourage Use of Unix Timestamps
This was suggested by issue #2347. Unix timestamps have clear disadvantages compared with the alternate methods of supplying date and time to PhpSpreadsheet - DateTime objects, Excel date time fields, and strings. In particular, Unix timestamp is not Y2038-safe on a 32-bit system, and it reflects the time in UTC, which may come as a surprise to the end-user (as it did in the cited issue). The alternate methods do not come with such baggage. This change updates some doc blocks to note that Unix timestamps are discoburage (N.B. - not deprecated). No executable code is changed.
* Document in Code As Well as Commmit Message
Per suggestion from @PowerKiKi.
* Missed One DocBlock
Including it now.
Co-authored-by: Adrien Crivelli <adrien.crivelli@gmail.com>
Fix issue #2368. PR #2265 moved the place where data validations were written to the worksheet. PR #1694 was installed afterwards, and accidentally restored the original location, so validations are now being written twice.
See issue #2315. It is nominally solved by PR #2312, but that PR is completely unsuitable for merging. This one-line change is a replacement for that PR.
As with many problems of this type, it is not clear how how to create a spreadsheet with this sort of harmless corruption in the wild. An example was supplied with the issue, and I have tested manually against it. However, the file is huge and not suitable for a formal unit test. I do not understand BIFF well enough to try and craft a suitable example on my own.
Co-authored-by: Adrien Crivelli <adrien.crivelli@gmail.com>
PR #1844 fixes it, but changes were requested. It has been almost 3 months and those changes have not been made. This PR replaces that one; it should be suitable for all supported releases of PHP through 8.1, and includes a formal unit test.
Fixes#1685Closes#1844