While reviewing the DefaultValueBinder::dataTypeForValue() method, I noticed that a new Calculation instance is being created for every single cell validation.
Since the Calculation class is quite heavy (initializing components like CyclicReferenceStack and BranchPruner), instantiating it repeatedly causes unnecessary memory and CPU overhead, especially during bulk imports of large spreadsheets.
Changes:
Switched from new Calculation() to Calculation::getInstance() to leverage the existing singleton.
Added state preservation logic for branchPruning to ensure the shared instance remains consistent for other parts of the application.
Wrapped the logic in a finally block to guarantee that the pruning state is restored regardless of success or failure.
No changes were made to the public API, so this is fully backward compatible. I've also added a unit test to verify that formula detection and state isolation work as expected.
Tests:
Added tests/PhpSpreadsheetTests/Cell/DefaultValueBinderTest.php.
The table attributes `border`, `cellspacing`, and `cellpadding` are used in Html Writer. They are deprecated in Html5 in favor of css attributes. Further, their use is redundant or outright wrong. Their use is eliminated. A sample is added to show how equivalents might be used.
It currently always uses PHP_EOL, which, of course, works, but you get slightly different results in Windows and Unix. User can now set line ending to `\n` or `\r\n` to ensure consistent results regardless of environment. Default remains PHP_EOL. We already do this for CSV.
Fix#4773. Mpdf is applying cell style only to the first line of a multi-line string. Explanation - Html Writer replaces newlines with `<br />` by calling `nl2br`, at least that was the intention. However, `nl2br` doesn't replace - it prepends. This doesn't do any harm in Html, Dompdf, or Tcpdf. However, Mpdf is known to be subject to occasional regexp backtracking errors when parsing large blocks of html. To avoid this, we chunk the html by splitting it at newlines, but this causes the styling to be lost for rich text elements following a newline.
The solution to this problem seems easy enough - replace `nl2br` with a routine that replaces rather than prepends. Unfortunately, Html Reader needs the newlines intact in order to parse things correctly. So a solution where the `nl2br` calls are used for non-Mpdf and using a substitute routine for Mpdf ought to work. However, doing my testing uncovered another bug - rich text with newlines can result in multiple `<br />` tags (see new Html test). The solution to this is a bit kludgey, but it does seem to fix both the Mpdf problem and the newly discovered Html problem. It will also tend to avoid the very minor problem of generating different line endings on Windows systems.
Fix#606 (marked stale in 2018, but now reopened). User reports that, under some circumstances, `oldCalculatedValue` will be used as the result when an unsupported function is part of a formula (this seems like a sensible treatment), but, in other cases, the unsupported function is ignored, or has an unpredictable effect on the result.
To explain a little further, an unsupported function will return a "magic" value which will eventually be replaced by `oldCalculatedValue` (or null if there is none). However, the magic value is not being propagated. In the issue, there are 3 places where this propagation is currently omitted - when performing a binary comparison, when evaluating the condition in the `IF` function, and when evaluating the `SUM` function. This PR causes propagation to happen in all of those places, and a few others (MIN, MINA, MAX, MAXA, ROWS, COLUMNS). I would not be surprised to have missed one or more of the other situations.