Resolve #3591829: Coalesce multi-bundle references with differing per-bundle fields

Low-level prop-expression infrastructure for authoring multi-target-bundle content-entity-reference picks whose per-bundle field selections differ. Blocks #3591656, which exposes and renders the feature and owns the constraint/validator changes and the CER integration tests.

What this MR does

  • Parser + serializer (FieldObjectPropsExpression): round-trips a bundle-specific branch nested in an object prop (label↝entity␜[branch][branch]). Nested branching stays rejected via the existing parseBranches() depth guard.
  • Coalescer: groups standalone references by their referencer field and coalesces each bundle's picks. When every bundle contributes a single referenced expression the result stays a field-level reference or branch (unchanged). When a bundle picks multiple fields — which no single-field branch member can represent — the picks combine into one object on the reference field, grouped by developer-facing key: a key picked in several bundles becomes a bundle-specific branch prop, a key in one bundle a plain reference prop. coalesce(), expand() and idempotency stay lossless.

Everything is dormant on 1.x until #3591656 exposes multi-bundle browsing and removes the save-time constraint.

Testing instructions

  • composer run phpunit -- tests/src/Unit/CoalescerTest.php
  • composer run phpunit -- tests/src/Unit/PropExpressionTest.php
  • composer run phpunit -- tests/src/Kernel/Entity/JavaScriptComponentUpdateFromClientSideTest.php
  • composer run phpunit -- tests/src/Kernel/Config/JavaScriptComponentValidationTest.php
  • composer run lint (PHPCS + PHPStan)

Notes for reviewers

  • The render half is verified end to end on top of #3591656's buildReferencePayload: news_item → {body,label}, blog_post → {label, owner}, bundle-specific props omitted for the non-matching bundle.

AI usage disclosure

Implemented with AI assistance (Claude Code, Claude Opus 4.8), reviewed by the contributor before pushing, per Drupal.org's Policy on the use of AI.

Edited by Christian López Espínola

Merge request reports

Loading