fix(polyfill): bind the Compat surface eagerly at bootstrap#3
Open
saifulferoz wants to merge 10 commits into
Open
fix(polyfill): bind the Compat surface eagerly at bootstrap#3saifulferoz wants to merge 10 commits into
saifulferoz wants to merge 10 commits into
Conversation
Lazy aliasing left two holes the autoloader cannot close: 1. PHP never autoloads for parameter/return/instanceof checks. A Compat object passed to consumer code type-hinted with the PhpOffice name (e.g. `function f(Worksheet $ws)`) threw "TypeError: ... must be of type PhpOffice\...\Worksheet, EasyExcel\Compat\Worksheet\Worksheet given" unless something had happened to reference the class name first. 2. composer prepends its own autoloader, so a polyfill bootstrap loaded before vendor/autoload.php silently lost the PhpOffice\* namespace to a co-installed real phpoffice/phpspreadsheet. eagerAliasCompat() now class_aliases every implemented name at bootstrap (~60 classes, ~12 ms cold, one-time per process), enumerated by scanning the Compat tree (not .compat-surface.json, which tracks the full upstream surface including unimplemented classes). The prepended autoloader stays as the strict-mode tripwire for unimplemented classes. Already-defined names are skipped; EASY_EXCEL_EAGER=0 restores lazy-only aliasing. Found migrating a report pipeline whose SheetContext constructor type-hints Worksheet: creating the context fataled under strict mode. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fix(polyfill): bind the Compat surface eagerly at bootstrap
Worksheet::getDefaultRowDimension()->setRowHeight() and getDefaultColumnDimension()->setWidth() were unimplemented, so the only way to get uniform row heights was one RowDimension per row — and per-row heights on a streamed sheet replay at save (measured 487 ms save / 215 MB RSS @10k rows vs 33 ms / 98 MB with the sheet default; a real ERP's report configs use a uniform rowHeight in 40 of 123 reports). Native side: SetDefaultRowHeight / SetDefaultColWidth map to excelize SetSheetProps (sheetFormatPr defaultRowHeight+customHeight / defaultColWidth). Called before the first streamed row they ride the worksheet preamble for free; after that the StreamWriter has snapshotted the preamble, so the call queues a save-time op like any other mutation of written state (correctness over speed, covered by TestDefaultDimensionsMidStreamReplay). Compat side: RowDimension/ColumnDimension accept a null index — as PhpSpreadsheet's default dimensions do — and route to the new natives; Worksheet::getDefaultRowDimension()/getDefaultColumnDimension() hand out the cached instance. setAutoSize on the default column dimension is state-only, matching PhpSpreadsheet's writer, which never consumes it. Verified against the built extension: sheetFormatPr lands in the saved worksheet XML, values read back intact, save time equals the unstyled baseline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(dims): sheet-wide default row height / column width
Saving a report to a stream-wrapper target (gaufrette://, s3://, ...) failed with "unsupported workbook file format": the shim stages wrapped targets through tempnam(), which produces no file extension, and excelize's SaveAs validates the extension. Direct extension-less paths hit the same wall — PhpSpreadsheet writes to any filename, so consumer code relies on that parity. (The auto-filter patch path already knew: it staged via abs+".unpatched.xlsx".) Shim: stage wrapped targets under tempnam()+".xlsx". Native: SaveXlsx routes non-workbook-extension paths through a staged .eexcel.xlsx sibling and renames into place (same directory, so the rename cannot cross devices); known extensions save directly as before. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fix(save): support extension-less target paths
… eager alias surface Three PhpSpreadsheet-parity gaps hit by a real ERP report suite: - Spreadsheet::setValueBinder()/getValueBinder(): the PhpSpreadsheet >= 2.x workbook-level binder API. The workbook binder wins over the legacy static Cell::setValueBinder(); setCellValue()/fromArray() route through it. - new Worksheet() may now be constructed detached (both ctor args optional) and attached later via the new Spreadsheet::addSheet($sheet, ?$index) — the FilterLoopReportRunner/multi-sheet idiom. Title get/set work while detached; native-touching calls throw a clear message via workbookHandle(). rebindParent() rejects cross-workbook moves. - aliasCompatSurface(): eagerly alias every Compat class at bootstrap. The engine skips autoloading for instanceof and typed-parameter checks, so a lazily-aliased class that was only ever *returned* (never explicitly loaded) failed type hints like function (Worksheet $ws): the alias did not exist yet. Lazy aliasing stays for unimplemented classes (strict throw / fallback defer). Validated against the ERP report generator suite under EASY_EXCEL_ALIAS=strict: 19/19 tests pass (previously 6 binder errors + 1 ctor error + latent type-check failures). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mirrors PhpSpreadsheet's StringValueBinder (per-type conversion suppression, DateTime/RichText/Stringable object binding). Callers that call $spreadsheet->setValueBinder(new StringValueBinder()) previously hit UnsupportedApiException under strict aliasing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…add-sheet feat(polyfill): detached Worksheet + addSheet, eager alias surface, value binder, IOFactory registration
…able The compat-surface CI gate resolves phpoffice/phpspreadsheet fresh; a new upstream release added Chart\DataTable, which showed up as a NEW uncovered class vs the frozen baseline and failed the gate on every PR. Regenerated with tools/compat-surface-diff.php --update-baseline inside the same compat-surface-deps image (470 missing classes, +1). Deliberate bump per the COMPAT.md protocol; no Compat behavior change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.