Draft: feat: #3591596 ALTERNATE Propagate component instance updates to content/config translations; introduce `StagedLanguageConfigOverride` to treat both similarly
Alternative approach to !1163 (closed). This was largely AI-generated, with strict guardrails imposed by @wimleers, and instructed to use !1263 as a reference. (See below if interested in seeing the high-level guardrails.)
Comparison with !1163 (closed)
- ~33% smaller:
!1163:15 files, +2987, −136at !1163 (8d2ce541))🆚 this MR25 files changed, 2198 insertions(+), 292 deletions(-)at c01a527d- … but now with an ADR!
- … and more capable, better prepared for the future (see next bullets)
- basically does what @wimleers proposed late on Friday June 19 at !1163 (comment 1263859) and which @penyaskito seemed favorable to
- (one of @penyaskito's concerns was that it'd take too much time to get
StagedLanguageConfigOverrideto work, but it shares a lot of code withStagedConfigUpdate) - also pairs beautifully with !1263!
- (one of @penyaskito's concerns was that it'd take too much time to get
- and also addresses the concerns @wimleers raised on Thursday June 18 at !1163 (comment 1262438), for which this is the tl;dr
What this does
🟢 (same as !1163 (closed)) Propagates component instance version updates symmetrically to all non-default translations, for both content entities and config entities. Before this MR, updating a component's version applied changes only to the default-translation component tree; every non-default translation still held inputs shaped for the old version, violating the ADR #12 invariant.🟢 (same as !1163 (closed)) For content entities: each non-default translation'sComponentTreeItemListis reconciled in-memory immediately after the default-translation update. Removed props are pruned, new props are seeded from the default translation, non-translatable props are synced, translatable props are preserved.🆕 🚀 (different from !1163 (closed)) For config entities: reconciliation stages mutations asStagedLanguageConfigOverrideconfig entities — the same auto-save pattern used byStagedConfigUpdate— so "Spanish translation of page region sidebar" appears explicitly in the review-and-publish UI, not as a silent side effect (NOTE: !1263 will make sure it doesn't appear in the UI anymore, but it'll still be present in the auto-save store. The UI will start showing the auto-saved translations again when either i) Canvas adds asymmetrical translation support or ii) direct editing of translations in the Canvas UI)🟢 (same as !1163 (closed)) When publishing a content entity, publish all auto-saved translations, too. (as of !1271 (448689fa))🆕 🚀 When publishing a config entity, publish all auto-saved translations, too.🆕 🚀 (different from !1163 (closed)) ADR #13 documents all architectural decisions.TranslationPropagationTestBaseextracts the shared test fixture into a base class used by bothConfigEntityTranslationPropagationTestandContentEntityTranslationPropagationTest.
AI use, imposed constraints, and instructed direction
AI use disclosure: significant parts of this MR were authored with AI assistance (Claude Sonnet 4.6) per Drupal.org's AI policy (https://www.drupal.org/docs/develop/issues/issue-procedures-and-etiquette/policy-on-the-use-of-ai-when-contributing-to-drupal). All generated code was reviewed by @wimleers .
This is the direction I (@wimleers) after having thoroughly reviewed @penyaskito's !1263 I thought to be likely viable and simpler:
Based on everything you now know about this MR; create a completely new branch, with the same end result, but a completely different approach, with the following constraints:
1. Do not introduce new services, instead just update *at most* \Drupal\canvas\ComponentSource\ComponentSourceManager::updateComponentInstances() (any signature or logic change alllowed)
2. Modifying the signature of ComponentInstanceInputsConfigSchemaGeneratorInterface (any existing methods, or adding new methods) is allowed
3. Modifying implementations of that interface is allowed
4. Strongly encouraged: expand ComponentTreeItem(List) with additional methods.
Explore in a new branch called `3591596-alt` (already checked out) whether it's viable to achieve the same with those constraints and this general idea:
1. add new methods to ComponentTreeItem(List)
2. update existing infra (per the above constraints) as needed
3. 1+2 to allow the existing updater infra to still target the default translation of a content/config entity, but to then use a ComponentTreeItem::reconcileWithUpdatedDefaultTranslation($item_before, $item_after) method (which throws an exception if it is called on the
non-default translation) to perform the reconciling
IOW: the idea is to "push down" the fundamental logic into the lowest level concept (a component instance, represented by ComponentTreeItem), to maximally leverage existing abstractions instead of inventing new ones.Closes #3591596