# This is the 1st commit message:
Integrated unit test to capture the bug.
# This is the commit message #2:
Added Date.safeModify() method for secure DateTime modifications and integrated exception handling - Fixed#4840.
# This is the commit message #3:
PHPCS Fixes.
# This is the commit message #4:
PHPCS Fixes.
# This is the commit message #5:
Codestyle fix.
# This is the commit message #6:
Added description to CHANGELOG.md.
# This is the commit message #7:
Enhanced Date.safeModify() to ensure consistent exception handling across PHP versions, addressing changes in DateTime::modify() behavior in PHP 8.3 - #4840.
# This is the commit message #8:
Confusion Checking for Union Arguments
Fix#4832. PR #4657 added support for passing union arguments to functions. User reports a problem with a peculiar formula afterwards. See issue for details - the very loose restrictions placed on worksheet names can lead to an ambiguous situation for the parser.
This problem arose with a function whose first argument was a cell address *including sheet name*. Parser is changed to try to avoid this situation. If the regular expression which tells us we have a potential need for union has a left parenthesis in the "sheet name" without a right parenthesis, then it will no longer try to treat the formula as containing union arguments except in the unlikely event that "sheet name" truly is a worksheet title in the spreadsheet. This feels pretty kludgey, but it solves the problem at hand, and seems unlikely to cause problems. There may still be edge cases more subtle than the one in the issue; I am satisfied to wait for reports of such.
# This is the commit message #9:
Weird Regexp Difference between Php8.4+ and Php8.3-
Specify codeCoverageIgnore for now, remove later.
# This is the commit message #10:
Move Test to More Sensible Location
# This is the commit message #11:
Ods Reader/Writer Support for Integer Styles with Leading Zero
Fix#1606, which went stale and is now reopened. PR #4806 supplied support for some Number Formats for Ods, but did not directly address this issue. This PR does. In addition to the original issue, this could be useful for zip codes. As I stated in 4806, I may be amenable to adding some unsupported styles to the built-in list, but the custom style option will always be around in case I am being slow or unreasonable.
# This is the commit message #12:
A Bit More Flexibility
And some more tests.
# This is the commit message #13:
Update CHANGELOG.md
Xlsx Writer Support Data URI for Images
Fix#4823. When writing a spreadsheet to Html, a data Uri can be used if `embedImages` is true. Reading such an Html spreadsheet and attempting to write it to Xlsx results in an Exception. It should be noted that Excel itself cannot open the Html properly; none of the images are present.
The PhpSpreadsheet problem arises not with the inclusion of the image, but rather with attempting to include the appropriate entry in `[ContentTypes].xml`. This PR corrects that problem.
For the record, Xls Writer does not have a problem with this situation. Just to demonstrate that, a parallel test for Xls Writer is added in addition to the new Xlsx Writer test.
Update CHANGELOG.md
Update CHANGELOG.md
Added phpcs and php-cs-fixer corrections #4840.
Updated DateTest to handle DateMalformedStringException for PHP 8.3 in excelToDateTimeObject exception tests.
Fixed phpcs issues.
Fixed php-cs-fixer issue.
Updated DateTest so to not directly reference DateMalformedStringException class which is not existing prior to PHP 8.3.
Refactored DateTest to dynamically set the expected exception class, ensuring compatibility across PHP versions.
Removed unused Throwable import and updated expected exception type in DateTest for consistency with PHP version handling.
Added DateMalformedStringException polyfill to solve the phpstan issue.
Fixed phpcs issue.
Fix#4838. Some processing of Html Conditional Formatting which worked with PhpSpreadsheet 5.3 does not work with 5.4. There are 2 problems. The first was caused by PR 4763, which moved some code out of Html Writer to an easier-to-access location. One of the intermediate variables in Html Writer was not available in the new location; its simulation turned out to be imperfect.
When evaluating Colorscale, the cells in question need to be ranked. This was done using `rangesToArray` with the formatting option set to `true`. This code, inherited from 5.3, was a mistake; it should have been set to `false`. As coded, it created problems for cells formatted as percentages (it is not clear why 5.3 did not suffer a similar fate). Making that change fixes the problem. The fix is demonstrated in the first new test `testPercentages`.
A second problem affected 5.3. The code to assign a colorscale color to a cell concatenated the alpha, red, green, and blue colors expressed in hex digits. But it did not properly handle the case when any of those was only 1 digit long. The second new test `testPercentages2` demonstrates that this problem is now fixed.
Fix#4836, an issue which I was about to dismiss out-of-hand, but I decided that we could and should be making it a bit easier for our users to avoid problems. To that end, I have changed most of the private properties in Reader/Csv from `private` to `protected`. This allows users to extend the class easily; it is a better option than the existing `constructorCallback` - less awkward, not reliant on static settings, etc. (I know more now than I did when I introduced it.) Taking advantage of the new extendability, a new class `Reader\CsvNoEscape` is added which forces the use of null-string as the escape character, and prevents the use of auto-detection of Mac line-endings; both of these are schedule for removal with Php9.
This actually makes `CsvNoEscape` a better option than `Csv`;
it should probably be used for all new development.
Because `IOFactory` is heavily used for loading files, it has some changes to better accommodate `CsvNoEscape` (and other classes). In particular, methods `createReader`, `load`, `identify`, and `createReaderForFile` now allow a new `mergeArray` parameter, where that parameter is merged with the static `IOFactory::$readers` array when deciding on a Reader class to be used. This allows the user to override the default Csv Reader, without having to change a static array, and without affecting IOFactory's ability to find other matching readers if no suitable entry is found in `mergeArray`.
Fix#4832. PR #4657 added support for passing union arguments to functions. User reports a problem with a peculiar formula afterwards. See issue for details - the very loose restrictions placed on worksheet names can lead to an ambiguous situation for the parser.
This problem arose with a function whose first argument was a cell address *including sheet name*. Parser is changed to try to avoid this situation. If the regular expression which tells us we have a potential need for union has a left parenthesis in the "sheet name" without a right parenthesis, then it will no longer try to treat the formula as containing union arguments except in the unlikely event that "sheet name" truly is a worksheet title in the spreadsheet. This feels pretty kludgey, but it solves the problem at hand, and seems unlikely to cause problems. There may still be edge cases more subtle than the one in the issue; I am satisfied to wait for reports of such.
Fix#4823. When writing a spreadsheet to Html, a data Uri can be used if `embedImages` is true. Reading such an Html spreadsheet and attempting to write it to Xlsx results in an Exception. It should be noted that Excel itself cannot open the Html properly; none of the images are present.
The PhpSpreadsheet problem arises not with the inclusion of the image, but rather with attempting to include the appropriate entry in `[ContentTypes].xml`. This PR corrects that problem.
For the record, Xls Writer does not have a problem with this situation. Just to demonstrate that, a parallel test for Xls Writer is added in addition to the new Xlsx Writer test.
Fix#1606, which went stale and is now reopened. PR #4806 supplied support for some Number Formats for Ods, but did not directly address this issue. This PR does. In addition to the original issue, this could be useful for zip codes. As I stated in 4806, I may be amenable to adding some unsupported styles to the built-in list, but the custom style option will always be around in case I am being slow or unreasonable.
We have identical constants defined in several places, and use literals in others. We aren't consistent in checking limits. This PR makes the use of the constants in Cell/AddressRange the "official" source, deprecates all other constants, and substitutes the constants wherever literals are used. A number of different edge case tests are added.
During testing, I discovered that `columnIndexFromString` correctly throws an exception for 4-character string, but allows `XFE` through `ZZZ`, all of which are also invalid. There are similar inconsistencies with related routines, and this PR attempts to make them operate consistently. One suprise is that throwing for `row=0` causes serious regression problems, so it continues to be permitted (but the high row limit is enforced).
Further, Reference Helper sometimes dips into negative numbers, resulting in totally unexpected results (-1 affects column Z, -2 column Y, etc.). It is changed to ignore rows and columns outside the limits.
Dependabot day is tomorrow, so get a jump on that by upgrading composer.lock.
Phpstan newly flagged a method in Writer/Xls/Worksheet which is not used internally, and seems impossible to be used by user programs. Deprecate it and some associates. No code changes.
Continuing the work of PR #4810 and PR #4813 and PR #4814. According to the spec for LibreOffice, the xml for both coluns and rows allow a `default-cell-style-name` attribute. However, my testing indicates that using that attribute with a row doesn't result in the results I would expect; furthermore, LibreOffice doesn't seem to use that attribute in association with a row (it does use it for columns). For rows, it fills the unpopulated rows in the cell with a repeated table cell with the appropriate style. These filler cells have been a source of problems for us, and I'm not willing to add them at this time (maybe in future). So, if a style is applied to a row in PhpSpreadsheet, it will be reflected in all cells in that row until `highestDataColumn`, but no further.
Since LibreOffice does support adding a style to a column both in the UI and the Xml, it should be a little easier. But its support is imcomplete as well - when reading a spreadsheet, the UI will apply the style only to the rows that are defined in the xml. Again, this requires filler rows for the rows beyond `highestDataRow`, and, again, I am not willing to add those. However, it is important to process the column style when reading because, unlike the case with rows, the cells which are defined in the column may omit style data altogether if the style matches the column style.
There has till now been no support for `ReadDataOnly` (default false) and `ReadEmptyCells` (default true) for Ods Reader. These are now added. ReadEmptyCells is especially important and it would be sensible to usually set it to false. The reason is that LibreOffice usually supplies a width for all the columns mentioned in its row fillers, and PhpSpreadsheet needs to create ColumnDimensions for each of those as a result, resulting in much larger xml than one would expect when the spreadsheet is saved. This arose when I was testing this change - it has always been the case, but nobody has raised an issue about it. We avoid this problem by ignoring the extra columns for ReadEmptyCells false. But this requires a little redundancy in the code. We need to define styles for an entire column before we define styles for the cells in the column, but we don't need to define column widths beforehand. So, if ReadEmptyCells is false, we need to process the columns for styles, then process the cell data (so that we know what `highDataColumn` is), then process the columns again but this time for widths (ignoring columns beyond highDataColumn). If ReadEmptyCells is true, we can process column styles and widths in a single pass.
Continuing the work of PR #4810 and PR #4813. All "real" borders are implemented. Pseudo-borders (outline, vertical, horizontal, inside, and allBorders) are not because I'm not really sure how, or even if, Ods handles them. However, Sample20_Read_Ods demonstrates a way to emulate `outline` using just the real borders. In template OOCalcTest.ods cells B18:C19 are merged, and the merged cell has multi-colored borders, something which `outline` isn't able to do. Ods Reader handles this by assigning the border style first to cell B18 (which is what Ods wants, and it doesn't hurt Xlsx/Xls) and then to cells B18:C19 (which is what Xlsx and Xls want, and it doesn't hurt Ods).
Ods Reader changes still to come
- Style applied to entire row
- Style applied to entire column
- Parent styles?
Ods Writer changes still to come
- Style applied to entire row
- Style applied to entire column
- Parent styles?
Not currently on my to-do list
- Pseudo-borders
- Subscript and superscript fonts (these really only make sense for RichText, and I'm not sure how Ods handles RichText)
- Default border, alignment, and protection. I'm not convinced there's a use case. Ods handles its defaults in two different manners, and I don't want to spend the time trying to understand it without justification.