Problem/Motivation
When a new language is created in the user interface, \Drupal\language\Config\LanguageConfigFactoryOverride::installLanguageOverrides() is called with the language code of the newly created language so that all language overrides for that language that may be available in any shipped modules or, in particular, the install profile get installed.
If a language is being created during a config sync, this should not happen, however, because any language overrides that should end up in the target storage should be part of the sync.
But on top of just being unnecessary CPU this actually causes a problem resulting in the entire config sync failing: If a module or profile ships a language override for a config entity and that override will also be created as part of the config sync, then a
Deleted and replaced configuration entity
error will be raised.
Steps to reproduce
- Have a site without the German language and a with a body field on the article node type
- Add the German language and translate the body field (for example using Config Translation)
- Export the configuration and attempt to import it on another instance of the site
You should see something like
+-------------+----------------------------------------+-----------+ | Collection | Config | Operation | +-------------+----------------------------------------+-----------+ | | language.entity.de | Create | | language.de | field.field.node.article.body | Create | +-------------+----------------------------------------+-----------+as output of
drush cim
You will be greeted with:
The import failed due to the following reasons:
Deleted and replaced configuration entity "field.field.node.article.body"
Instead of the import succeeding.
Proposed resolution
Explicitly check that no config sync is happening in \Drupal\language\Entity\ConfigurableLanguage::postSave() before calling \Drupal\language\Config\LanguageConfigFactoryOverride::installLanguageOverrides().
Remaining tasks
User interface changes
-
Introduced terminology
-
API changes
-
Data model changes
-
Release notes snippet
Issue fork drupal-3545595
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
tstoecklerComment #4
tstoecklerThis needs some tests before landing, but would like some confirmation on the fix before delving into that so marking "Needs review".
Comment #5
smustgrave commentedI don't see any issue with the approach.
Only question is if it gets to this point will it attempt to install the language overrides later (after config import). Just want to make sure Drupal does just go "we tried" and moves on.
Else that's my only concern. Hope that helps.
Comment #6
tstoecklerSo the scenario I had on my project was the one described in the issue summary so the language overrides did end up being installed (as part of the config import). If they had not been part of the to-be-imported configuration presumably the site would have ended up without the overrides, which then is the expected outcome (but to be clear I did not verify that as of yet). I don't see any point that the language overrides would be re-added later.
Comment #9
tuutti commentedWe've been having this issue on a site install from existing configuration as well. Our modules ship language overrides in
config/install/language/fi. When the import creates thefilanguage,postSave()installs those overrides, and when the importer then processes thelanguage.ficollection, every one of them hits the "Deleted and replaced" branch inConfigImporter::checkOp().A fresh install logged 274 "Deleted and replaced" errors, and because of #3633776, the config import batch adds the same errors to its results again on every batch call, so these 274 errors were reported about 185,000 times, drush printed 554,285 error lines, and the install took about 29 minutes. With the MR, the same install logged no errors and took about 13 minutes.