Problem/Motivation
In 2010 in Drupal 6 I introduced protection for plural formulas already on the site in #566390: Apply locale import protection to the plural forms unless explicitly requested to overwrite translations and the plural formula. Unfortunately due to dead code this feature was lost in Drupal 8. PoDatabaseWriter::setHeader() currently has this check:
$locale_plurals = \Drupal::state()->get('locale.translation.plurals', []); ... if (array_sum($overwrite_options) || empty($locale_plurals[$langcode]['plurals'])) { // Get and store the plural formula if available. $plural = $header->getPluralForms(); if (isset($plural) && $p = $header->parsePluralForms($plural)) { [$nplurals, $formula] = $p; \Drupal::service('locale.plural.formula')->setPluralFormula($langcode, $nplurals, $formula); } }
Unfortunately this uses the wrong state key, so while it intends to protect the overwrite it does not work.
Since #2571375: Remove TranslationManager dependency from LanguageManager (Drupal 8.0.0), PluralFormula stores the plural formulae in the state locale.translation.formulae. Core does not set locale.translation.plurals any more, so $locale_plurals is always empty, and every import replaces the language's plural formula. This includes imports with "Overwrite non-customized translations" and "Overwrite existing customized translations" off, and drush locale:import --override=none.
locale_uninstall() also deletes the nonexistent locale.translation.plurals, not locale.translation.formulae. So uninstalling Locale leaves the plural formulae in the state.
This combined with the exported files always getting one hardcoded plural formula of nplurals=2; plural=(n > 1); means that even if you already had the plural formula properly set up, importing an exported translation back will break your plural setup. Core does not even have a UI to fix this or any UI that tells you something is broken now.
Steps to reproduce
- Add the Hungarian language.
- At Administer » Configuration » Regional and language » User interface translation » Import, import a Hungarian .po file with
"Plural-Forms: nplurals=2; plural=(n != 1);\n"in its header. - Import a Hungarian .po file with
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;\n"in its header, with "Overwrite non-customized translations" and "Overwrite existing customized translations" off. \Drupal::service('locale.plural.formula')->getNumberOfPlurals('hu')is 3. It should be 2.
This is even worse if the file does not have a plural formula or has an invalid plural formula.
Proposed resolution
Properly check if the language already has a plural formula and protect it where we should.
Remaining tasks
Implement the fix.
User interface changes
None.
Introduced terminology
None.
API changes
None.
Data model changes
None.
Release notes snippet
None.
LLM disclosure
LLM was used to find and fix this issue. With human review.
| Comment | File | Size | Author |
|---|
Issue fork drupal-3631998
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
gábor hojtsyComment #4
gábor hojtsyComment #5
penyaskitoWonder if
PluralFormulaInterface::classshould be preferred over the service name (which would have avoided this if we had done that in the past).Anyway I'd be fine if we decide to not do that for consistency with surrounding code, so RTBC.
Comment #6
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.