Problem/Motivation
We have a site that actively uses fallbacks and some fallback chains have the default Entity language disabled.
For example, we have an Entity with French (fr)
as default language, and allowed fallback chain as Dutch (nl) » German (de)
(both translations are missing).
So, when we're calling the function EntityRepository::getTranslationFromContext($entity, 'nl')
- we're receiving the French (fr)
translation, that is wrong because the buisness logic should disable the fallback convertation from Dutch (nl)
to French (fr)
!
Steps to reproduce
1. Configure three languages: French (fr)
, Dutch (nl)
, German (de)
.
2. Configure a fallback chain from Dutch (nl)
to have a transition to only German (de)
, so make French (fr)
as disabled fallback for it.
3. Create a Node in French (fr)
language.
4. Require a fallback of this Node in Dutch (nl)
language.
You will receive a translation in French (fr)
, which is disabled as a fallback for the Dutch (nl)
language!
Proposed resolution
The problem is located in this part of the code in the function Drupal\Core\Entity\EntityRepository::getTranslationFromContext()
public function getTranslationFromContext(EntityInterface $entity, $langcode = NULL, $context = []) {
...
$candidates = $this->languageManager->getFallbackCandidates($context);
// Ensure the default language has the proper language code.
$default_language = $entity->getUntranslated()->language();
$candidates[$default_language->getId()] = LanguageInterface::LANGCODE_DEFAULT;
...
So we're adding the default language to fallback candidates array always, even if it is missing in the list, received from getFallbackCandidates($context);
!
The proper solution from my perspective should be returning NULL
from the function getTranslationFromContext()
, if no suitable fallback translation is available.
But the current function return value doesn't expect returning NULL
as result. So just returning NULL
breaks a lot of logic in Drupal Core code and contrib modules too.
But what this function can return if the Entity has no allowed translations to the desired language? From my point of view, the NULL
is a good response.
So, to not break the previous behavior, I've added a flag strict_fallback
to the context array, that enables the new mode.
In a follow-up issue, I can add a separate option "Disable returning default translation if it is not available" to the admin panel, to make this "strict_mode" enabled by default.
Remaining tasks
Merge to HEAD.
User interface changes
None.
API changes
Added "strict_fallback" option to the function EntityRepository::getTranslationFromContext() to return NULL if no fallback translations are available.
Data model changes
None.
Release notes snippet
Added "strict_fallback" option to the function EntityRepository::getTranslationFromContext() to return NULL if no fallback translations are available.