Add interpretation-stage events: PreInterpretFileEvent and PreQueueRowEvent - #680
Add interpretation-stage events: PreInterpretFileEvent and PreQueueRowEvent#680alexbaat wants to merge 3 commits into
Conversation
…wEvent Listeners can now normalize the source file, and modify, skip, or fan out extracted rows before they are queued - covering row filtering, cross-row state, synthetic resolver columns, and 1-to-N imports without writing a custom interpreter. Both events are mirrored into the Studio preview so the mapping UI shows the columns an actual import would produce. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
One or more custom setup steps configured for this repository failed during this Copilot code review run: Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review. Note You can configure setup steps for Copilot code review separately from Copilot cloud agent with a |
There was a problem hiding this comment.
Pull request overview
Adds interpretation-stage extension points to modify source files and rows without custom interpreters, addressing platform-version#340.
Changes:
- Adds file and row events with modify, skip, cleanup-preservation, and fan-out support.
- Integrates events into imports and Studio previews.
- Adds documentation and regression tests.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
src/Event/PreInterpretFileEvent.php |
Defines source-path replacement event. |
src/Event/PreQueueRowEvent.php |
Defines row modification, skipping, and fan-out event. |
src/DataSource/Interpreter/AbstractInterpreter.php |
Dispatches events during interpretation. |
src/DependencyInjection/CompilerPass/InterpreterConfigurationFactoryPass.php |
Injects dispatchers into supported interpreters. |
src/Preview/PreviewEventApplier.php |
Applies events to Studio previews. |
src/Hydrator/PreviewHydrator.php |
Adds event-aware column previews. |
src/Service/Studio/PreviewDataService.php |
Adds event-aware data previews. |
src/Service/Studio/TransformationService.php |
Adds event-aware transformation previews. |
src/Resources/config/services.yml |
Registers the preview event service. |
doc/06_Extending/02_Events.md |
Documents the new extension points. |
tests/unit/PreQueueRowEventTest.php |
Tests row-event state and operations. |
tests/unit/InterpreterRowEventTest.php |
Tests interpreter integration and wiring. |
tests/unit/PreviewEventApplierTest.php |
Tests preview behavior. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Add declare(strict_types=1) to both new event classes. - PreviewEventApplier: skip dispatch for empty preview records, display the first fan-out row exactly as queued (no value merging from later rows), and drop headers for columns no resulting row contains. - Document that the preview dispatches only the displayed record (stateful listeners should branch on isPreview()) and that interpreters not extending AbstractInterpreter must dispatch the events themselves. - Replace the reflection-based dispatcher-wiring test with a container-level compiler-pass test (fixes Sonar php:S3011, removes the broad Throwable catch). - Add end-to-end regression tests for skipRow() cleanup interaction using a stub load strategy: kept identifier survives cleanup, dropped one does not. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Extract label building out of applyToPreviewData (cognitive complexity), comment the intentionally empty stub methods, and drop the unused closure parameter in the empty-record preview test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|



Changes in this pull request
Resolves pimcore/platform-version#340
Adds two events at the interpretation stage (file → rows), so projects can adjust import rows with a small listener instead of copying a whole interpreter (all shipped interpreters are
final, so today even one line of row logic means duplicating the CSV/XLSX/JSON/XML reading code,fileValid(),previewData(),setSettings(), and a Studio UI dynamic type).PreQueueRowEventDispatched in
AbstractInterpreter::processImportRow()for every extracted row, before the delta check, identifier cache, and queueing — i.e. early enough that changed values (including the ID column) affect the resolver, the delta check, and the path/location strategies. Listeners can:$event->setRows([$changedRow])— e.g. add computed key/path columns for the resolver$event->skipRow()— withskipRow(keepInCleanupIdentifierCache: true)the original row's identifier is still registered, so an active cleanup strategy does not delete/unpublish the row's existing element (an easy trap to fall into otherwise; covered in docs and tests)$event->setRows([$rowA, $rowB, $rowC])— each row is queued and imported as its own element (1 source row → N elements is impossible at the mapping stage by construction)Cross-row state (e.g. SAP-style exports where a group marker row applies to all following rows) works naturally: dispatches are sequential within one
interpretFile()run, andPreInterpretFileEventdoubles as a per-run reset signal.PreInterpretFileEventDispatched at the start of
interpretFile()with a settable path: normalize the file (transcode, strip a report preamble, rewrite delimiters) while keeping the standard interpreter.Studio preview parity
Both events are also dispatched (flagged
isPreview()) in the preview/column-header/transformation-preview code paths via a new internalPreviewEventApplier, so the mapping UI shows exactly the columns an actual import produces — listener-added synthetic columns are visible and mappable. Skipped rows stay visible in the preview; a fan-out shows the first resulting row and exposes the columns of all resulting rows.Wiring & BC
AbstractInterpretergets a null-guardedsetEventDispatcher()(constructor unchanged — no BC break for existing custom interpreters).setEventDispatchercall to every tagged interpreter service that supports it, so built-in and custom interpreters dispatch the events.CsvEncodingInterpreterTest).Additional info
doc/06_Extending/02_Events.md("More events to come when needed (just provide PRs ;-)"), which this PR also extends with full documentation of both events including the cleanup-interaction warning.PreQueueRowEventlisteners on the stock CSV interpreter with these events.PreQueueRowEventTest(event API),InterpreterRowEventTest(end-to-end throughCsvFileInterpreter+ realQueueService: unchanged baseline, modify, skip, fan-out, file replacement, compiler-pass wiring),PreviewEventApplierTest(preview parity). Verified locally: unit suite green,php-cs-fixerclean,phpstan(repo config) clean.🤖 Generated with Claude Code