6576 Commits

Author SHA1 Message Date
oleibman 11645d54ac Merge pull request #4972 from oleibman/doctypo
Minor Documentation Updates
2026-08-22 05:00:37 +00:00
oleibman b9f5c37ec4 Minor Documentation Updates 2026-08-21 21:55:09 -07:00
oleibman 1f3ed4977a Merge pull request #4960 from oleibman/odsmoredates
Slight Improvement in Ods Reader Date Handling
2026-08-20 03:26:27 +00:00
oleibman 7a4832f59f Update CHANGELOG.md 2026-08-19 20:22:41 -07:00
oleibman f0e7a67c3d Merge branch 'master' into odsmoredates 2026-08-19 20:13:24 -07:00
oleibman 5619827ae9 Merge pull request #4956 from oleibman/odsdrawings2
Drawings for ODS
2026-08-20 03:05:23 +00:00
oleibman 56631e36d3 Merge pull request #4962 from saifulferoz/fix/issue-4454-ods-strings
Ods Writer: do not convert inside string literals
2026-08-20 03:03:56 +00:00
oleibman 16c49b80db Merge pull request #4958 from JulienChavee/master
Avoid getStyle on every setValueExplicit quote-prefix check
2026-08-20 01:10:00 +00:00
Julien Chavée 241635d8c9 Fix quote-prefix numeric test to cover clearing behavior 2026-08-19 22:23:29 +02:00
Julien Chavée 5083bf023f Merge branch 'master' into master 2026-08-19 22:01:59 +02:00
oleibman 930293a32a Merge pull request #4965 from oleibman/reflect86
Php8.6 Deprecation in Reflection::invokeArgs
2026-08-17 04:01:42 +00:00
oleibman 96d442ab66 Php8.6 Deprecation in Reflection::invokeArgs
Affects one test member, no source code.
2026-08-16 20:55:28 -07:00
oleibman 746430695c Merge branch 'master' into odsmoredates 2026-08-16 20:09:53 -07:00
oleibman 3b6f63599e Handle Dates A Bit Better 2026-08-16 19:41:14 -07:00
saifulislamferoz 416cc52a94 Assert round-tripped values rather than Ods xml
Rewrite the test to write the spreadsheet, read it back and check
getValue() and getCalculatedValue(), following DurationTest, instead of
matching against the generated content.xml.
2026-08-15 15:28:08 +06:00
saifulislamferoz d3ae79dfaf Ods Writer: do not convert inside string literals
convertFormula() ran the cell reference, defined name and function name
conversions over the whole formula, so anything that looked like a reference
inside a quoted string was rewritten: ="THIS IS E1" was written out as
="THIS IS [.E1]". The comma to semicolon replacement had the same problem,
turning =IF(A1>1,"yes, really","no") into a formula whose text reads
"yes; really".

Split the formula on string literals and convert only the segments outside
of them. A range cannot be interrupted by a string literal, so every
reference still sees the context the conversion relies on.

Fixes #4454
2026-08-15 10:28:48 +06:00
oleibman 65b080eef4 Merge pull request #4952 from oleibman/stancomments
Update Phpstan and Tcpdf
2026-08-11 22:20:21 +00:00
oleibman 84de45c2f4 Slight Improvement in Ods Reader Date Handling
Based on recent discussions in #2938, it can do a bit better with date cells that do not use a recognized date style. Improve differentiating `date` from `date+time`, and in deciding whether 4-digit years have been used in the input cells. This causes a change to one test, where the old result incorrectly expected a 2-digit year (you can verify by opening the spreadsheet in question that it is saved with a 4-digit year).
2026-08-11 14:09:12 -07:00
oleibman 3431af42f9 Reorder Some Tests in RowCellIterator
Prevent exceptions in obscure situations.

Accommodate some differences with Ods format saved by Excel.
2026-08-11 11:45:03 -07:00
oleibman 538ede3aa0 Merge pull request #4959 from oleibman/fix861
First Php8.6 (Extremely Minor) Problem
2026-08-11 04:34:49 +00:00
oleibman ffac2cbe29 First Php8.6 (Extremely Minor) Problem
In 8.6, XmlWriter is declared non-serializable. This changes the result of one unit test (we receive a different exception than we had expected).
2026-08-10 21:27:15 -07:00
oleibman 50654a3e69 Add Xls to Sample 25 2026-08-10 07:14:22 -07:00
Julien Chavée bf9a0210e2 Avoid getStyle on every setValueExplicit quote-prefix check 2026-08-10 11:21:39 +02:00
oleibman e3af14f762 Coverage Tweak
Comment out some uncovered code while I figure out how to execute it.
2026-08-10 01:14:00 -07:00
oleibman 5f40cd3a06 Fix Problem with Multiple Images on Multiple Sheets
Sample 25 now provides better coverage.
2026-08-10 00:40:26 -07:00
oleibman 229ae783df Address Some Coverage Issues
I hoped to address more in Sample 25, but there were some peculiar problems. I will continue to work on those, but no reason to delay what is working.
2026-08-09 18:45:41 -07:00
oleibman 78221785c1 Add Memory Drawing Sample 2026-08-09 09:09:35 -07:00
oleibman cf709f3d3f Drawings for ODS
Fix #4809. This initial work for this PR was done by @xxltomcat-ux in PR #4812. That PR needed some work, and was accidentally closed in a manner that caused all its work to be lost. As compared with that version, this version corrects a write bug when Ods output is added to 27_Images_Xlsx, adds limited support for Read, and adds some tests (more are probably needed). What follows here is the original description from the closed PR.

# Summary

Currently, the ODS writer in PhpSpreadsheet does not support exporting images. Images (Drawing or MemoryDrawing objects) are completely ignored in ODS exports, though they work correctly for XLSX. This issue proposes and provides a full implementation to add support for image/drawing export in ODS, bringing feature parity with the XLSX writer.

# Problem

- ODS exports silently drop images and worksheet graphics
- This is a required feature for interoperability with LibreOffice/OpenOffice users

# Key Implementation:

- Update: Writer/Ods.php to collect/package images into the export ZIP
- Update: Writer/Ods/Content.php to integrate images into content.xml and table cells
- New: Writer/Ods/Drawing.php to manage extraction & XML for worksheet images (Drawing & MemoryDrawing)
- Update: Writer/Ods/MetaInf.php to list all Pictures/ images in the manifest
- Update: Reader/Ods.php to read drawing-related Xml and add those which meet certain criteria to spreadsheet.

# Features

- Exports all worksheet images (Drawing, MemoryDrawing)
- Embeds images in Pictures/ directory inside ODS
- Writes <draw:frame> and <draw:image> elements linked to cell positions
- Updates META-INF/manifest.xml with all images
- Handles cell/row mapping & coordinates
- Supports PNG, JPEG, GIF, BMP
2026-08-09 08:37:59 -07:00
oleibman 585d3c0ce4 Merge branch 'master' into stancomments 2026-08-09 02:42:11 -07:00
oleibman b9f6ba4667 2.2.7 Reported Internal Error on Win11 - Upgrade to 2.2.8 2026-08-09 02:25:59 -07:00
oleibman 33e837480c Tweaks 2026-08-09 01:20:05 -07:00
oleibman 49affe510f Merge pull request #4954 from gaoflow/fix-betainv-underflow-false-convergence
Fix BETAINV false convergence when the Beta CDF underflows
2026-08-09 07:03:04 +00:00
oleibman 3518d40436 Merge branch 'master' into fix-betainv-underflow-false-convergence 2026-08-08 23:59:16 -07:00
oleibman e91b33a638 Merge pull request #4953 from gaoflow/fix-gamma-large-shape
Fix gamma-family overflow for large shape parameters
2026-08-09 03:57:53 +00:00
oleibman 5278916aab Merge pull request #4935 from kemo/perf/xlsx-writer-cell-fetch
Reduce redundant cell lookups in Xlsx writer hot path
2026-08-09 03:49:27 +00:00
oleibman d46c2ff387 Merge pull request #4955 from PHPOffice/dependabot/composer/squizlabs/php_codesniffer-3.13.6
Bump squizlabs/php_codesniffer from 3.13.5 to 3.13.6
2026-08-08 14:52:10 +00:00
dependabot[bot] 688c44f4db Bump squizlabs/php_codesniffer from 3.13.5 to 3.13.6
Bumps [squizlabs/php_codesniffer](https://github.com/PHPCSStandards/PHP_CodeSniffer) from 3.13.5 to 3.13.6.
- [Release notes](https://github.com/PHPCSStandards/PHP_CodeSniffer/releases)
- [Changelog](https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/4.x/CHANGELOG-3.x.md)
- [Commits](https://github.com/PHPCSStandards/PHP_CodeSniffer/compare/3.13.5...3.13.6)

---
updated-dependencies:
- dependency-name: squizlabs/php_codesniffer
  dependency-version: 3.13.6
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-08 08:27:06 +00:00
Vincent Gao 52da37f4a7 Fix gamma-family overflow for large shape parameters
GAMMA.INV silently returned the first bisection midpoint for alpha in
~[143, 171.62] (e.g. GAMMA.INV(0.5, 143, 1) gave 358.0 instead of
142.667) and #NUM! above that, because the Newton-step pdf evaluates
Gamma(a), b**a and value**(a-1) in linear domain, all of which overflow
even though the density itself is a small representable number. The same
pattern breaks the GAMMA.DIST, CHISQ.DIST and F.DIST densities and
GAMMALN, which computed log(Gamma(x)) through Gamma(x).

Evaluate these in log domain via the existing logGamma, and scale the
incomplete-gamma series/continued-fraction iteration cap as O(sqrt(a)),
which both expansions need to converge near x ~ a once the shape is
large (GAMMA.INV drifted from the true quantile above alpha ~5000 and
returned alpha+1 by alpha=10000; same for CHISQ.INV at high df).
2026-08-07 01:14:45 +02:00
Vincent Gao 3046ce9214 Add changelog entry for #4954 2026-08-05 12:29:20 +02:00
Vincent Gao f687d261e8 Fix BETAINV false convergence when the Beta CDF underflows
calculateInverse() treated a CDF value of exactly 0.0 as "the guess is the
root" and collapsed the bracket with $b = $a, ending the search. inverse()
already rejects probability <= 0, so a CDF of 0.0 inside the bisection can
only be a float64 underflow at a guess far below the root - never an exact
hit. It is just an ordinary "guess too low" and belongs in the existing
else branch.

The underflow is reached whenever a probe lands many standard deviations
from the mean, so the search collapses after two or three iterations and
returns whichever midpoint it was holding. BETAINV(0.5, 5000, 5000) gave
0.25, though Beta(a, a) is symmetric and its median is exactly 0.5;
BETAINV(0.5, 20000, 3) gave 0.5 against a true 0.99986. Onset is around
alpha = 1080 for beta = 1, where the closed form 0.5 ** (1 / alpha) is
available to check against.

That test also happened to stop the search for shapes where incompleteBeta
declines to evaluate at all and returns 0 for every x, so inverse() now
rejects alpha + beta above that documented limit up front: the CDF is
identically zero there, so no quantile exists to search for.

Tests cover a shape x probability grid against scipy reference values plus
three checks that need no external oracle: the symmetric median, the
Beta(alpha, 1) closed form, and the BETADIST round trip / mirror identity.
2026-08-05 12:28:05 +02:00
oleibman 7e7c5eb2c8 Add Some @var Doc Blocks 2026-08-04 22:34:04 -07:00
oleibman 608da6024e Merge branch 'master' into stancomments 2026-08-04 20:56:58 -07:00
oleibman 3006859ecb Merge pull request #4942 from saifulferoz/feature/pivot-table-read
Feature/pivot table read
2026-08-05 03:22:00 +00:00
oleibman 47aca381d8 Merge pull request #4945 from gaoflow/fix-incomplete-gamma-convergence
Fix incomplete gamma convergence for GAMMA.DIST / CHISQ.DIST
2026-08-05 03:12:07 +00:00
Vincent Gao a0e67af496 Update the now-reachable extreme-tail case for GAMMA.INV
Merging #4946 (bracket expansion) with #4945 (accurate incomplete
gamma) means p=0.9999999 no longer hits the alpha*beta*5 safety
ceiling -- the corrected regularizedGammaP/Q resolve the true root.
Fold it into the extreme-tail data provider against the closed-form
-ln(1-p) check instead of asserting the stale clamped bound.
2026-08-04 08:28:27 +02:00
Vincent Gao 270456a20e test: cover GammaBase::incompleteGamma() directly
It has no remaining callers (kept only for BC) so nothing else exercises
it. Values checked against mpmath's gammainc(a, 0, x); the deep-tail case
(a=4, x=80) reproduces the convergence bug this PR fixes.
2026-08-04 08:25:52 +02:00
gaoflow b3023fd66c Update CHANGELOG for #4945 2026-08-04 08:25:51 +02:00
gaoflow e88cd615cc Fix incomplete gamma convergence for GAMMA.DIST / CHISQ.DIST
The incomplete gamma primitive used a fixed 32-term power series with no
convergence test, so GAMMA.DIST, GAMMADIST, CHISQ.DIST(.RT), GAMMAINV and
CHISQ.INV were grossly wrong once the series argument reached ~32
(e.g. CHISQ.DIST.RT(80, 4) returned 0.806 instead of 1.74e-16).

Replace it with the standard convergence-tested regularized incomplete
gamma: series P(a,x) for x < a+1, continued fraction Q(a,x) for x >= a+1.
CHISQ.DIST.RT now uses Q directly so the right tail stays free of
1 - P cancellation. Consolidates the duplicate copy that already existed
privately in ChiSquared onto the shared primitive.
2026-08-04 08:25:36 +02:00
oleibman a32a22a481 Merge branch 'master' into stancomments 2026-08-03 22:42:32 -07:00
oleibman 8b4b934011 Merge pull request #4946 from gaoflow/fix-gammainv-tail-bracket-clamp
Expand GAMMAINV bracket so tail quantiles are not clamped
2026-08-04 02:43:29 +00:00