Conversation
| public function createExistingFieldsInNewVersion(Content $content, ?string $editedLanguageCode = null): void | ||
| { | ||
| foreach ($content->fields as $field) { | ||
| if ($field->id === null) { | ||
| // Virtual field with default value, skip creating field as it has no id | ||
| continue; | ||
| } | ||
| $this->createExistingFieldInNewVersion($field, $content); | ||
|
|
||
| $referenceOnly = $editedLanguageCode !== null && $field->languageCode !== $editedLanguageCode; | ||
| $this->createExistingFieldInNewVersion($field, $content, $referenceOnly); | ||
| } |
There was a problem hiding this comment.
What still worries me is what's gonna happen if a published version had e.g., one translation and the new version draft provides 2 new translations (possible via PHP API). I don't see integration coverage here, so the question is if we cover this anywhere else (ATM of writing this, haven't reviewed the other PRs).
It's especially relevant if all 3 version translations are actually different and should be stored separately.
There was a problem hiding this comment.
I'll add it this test to https://github.com/ibexa/fieldtype-page/pull/191 (there is integration set there but without this case)
There was a problem hiding this comment.
I'm a bit confused, what do you mean by "draft providing 2 new translations"? According to https://github.com/ibexa/core/blob/4.6/src/contracts/Repository/ContentService.php#L244 we can only pass 1 language when creating a new draft. Maybe you meant publishing version with two languages instead (the test for this case is already there in fieldtype-page)? Am I missing something here?
There was a problem hiding this comment.
I'm a bit confused, what do you mean by "draft providing 2 new translations"? According to https://github.com/ibexa/core/blob/4.6/src/contracts/Repository/ContentService.php#L244 we can only pass 1 language when creating a new draft. Maybe you meant publishing version with two languages instead (the test for this case is already there in
fieldtype-page)? Am I missing something here?
Regardless of initialLanguageCode setting, you can pass multiple \Ibexa\Contracts\Core\Repository\Values\Content\Fields with different language codes to \Ibexa\Core\Repository\Values\Content\ContentUpdateStruct::$fields. API should save a draft with all new translations and I'm wondering how this is affecting current changes in PB.
Context:
The $language parameter was added as an attempt to fix validation issues and glue what API expects and offers and what UI has been offering since eZ Publish. So while it can show only one translation, it's quite possible that update operation added or affected more than one translation.
Ref.: ezsystems/ezpublish-kernel#2875
initialLanguageCode itself was added with initial import of "the new" kernel, with its history reaching probably eZ Publish v4 (based on PHPDoc). However the behavior was not consistent with the overall shape of VersionInfo API, hence the attempts to fix it via e.g., the mentioned PR.
There was a problem hiding this comment.
@alongosz right, I see, thank you for the explanation.
https://github.com/ibexa/fieldtype-page/pull/191 - I've added the test case in the last commit, I'm not sure the case you mentioned would affect anything though, because external storage is flooded when creating a new draft, not when updating it. Update "lives" its own life, but let me know if this is the case you wanted to see tested.
|
Hey @barw4, fixed on 4.6 one of the unrelated PHPStan issues that popped up here, you can rebase :) |
|



Related PRs:
ibexa/admin-ui#1856
https://github.com/ibexa/fieldtype-page/pull/191
https://github.com/ibexa/installer/pull/207
Description:
Problem
When creating a new content version (draft), all field external storage data is fully copied for every translation — even translations not being edited. For field types with complex external storage (e.g. Page Builder with zones, blocks, attributes across multiple tables), this causes thousands of redundant queries per draft creation.
Solution
A new
ReferenceAwareExternalStorageinterface allows field types to opt out of copying external data for untouched translations during draft creation. Instead of duplicating data, the storage creates a lightweight reference to the source version's data and resolves it transparently on read.For QA:
Documentation: