Problem/Motivation
Drupal 11.4 added a computed, read-only resolvable_uri property to LinkItem, see #3066751: Add resolvable_uri property to LinkItem for APIs. It is written to the export files, and importing it overwrites the uri it was derived from.
Two things combine:
ContentEntityNormalizer::getFieldsToNormalize()filters whole fields only, and resolvable_uri is a property of a normal, writable link field.getValueFromProperty()tests !isComputed() in its last branch, but a computed property that is a primitive matches the earlier instanceof Uri branch and is exported.
On import, setFieldValues() sets each property separately, so LinkItem::onChange('resolvable_uri') runs and rewrites uri. The guard in LinkItem::setValue(), which only acts when uri is absent, never applies.
Steps to reproduce
- On drupal core >= 11.4
- Export content containing menu links or link fields. The files gain resolvable_uri and uri is unchanged, so the diff looks harmless.
- Install a fresh site that imports those files.
- The stored URIs are rewritten.
Measured on a multilingual site, after a single export and import, 14 of 14 internal menu link uris changed: internal:/news became internal:/en/news, and internal:/ became internal:/en/node/1. The four front page links now point at a raw, unaliased node path, so the home link renders /en/node/1 instead of /en on every page.
Proposed resolution
In getValueFromProperty(), skip a property when its definition explicitly declares read-only:
if (!empty($property->getDataDefinition()->toArray()['read-only'])) {
return NULL;
}
Read the definition array rather than calling isReadOnly(): DataDefinition::isReadOnly() falls back to isComputed(), so it also matches pathauto's pathauto property, which is computed, carries no explicit flag, and is exported on purpose. That is the same reason getFieldsToNormalize() reads the array for fields.
Remaining tasks
Patch and test coverage.
User interface changes
None.
API changes
None.
Data model changes
None.
Comments
Comment #2
herved commented