Project

General

Profile

Actions

Bug #92488

open

Default language does not support fallback language ids

Added by Xavier Perseguers about 4 years ago. Updated about 1 month ago.

Status:
Under Review
Priority:
Should have
Assignee:
-
Category:
Localization
Target version:
-
Start date:
2020-10-06
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
9
PHP Version:
Tags:
Complexity:
Is Regression:
Sprint Focus:

Description

Problematic

I have a multi-site install where the default language can be semantically any of English, French, German or Italian.

Some pages are shared and mounted from a common shared "subsite" (in the context of TYPO3 v9, for the sake of being able to properly create slugs but conceptually, just a bunch of pages in an outside page tree). Those shared pages have arbitrarily their default language in English and are then translated (=overlaid) into French, German and Italian.

In the database we have pages and content with sys_language_uid=0..4 since:

  • sys_language_uid=0 is any semantic default language
  • sys_language_uid=1 is German
  • sys_language_uid=2 is French
  • sys_language_uid=3 is Italian
  • sys_language_uid=4 is English

E.g., when sys_language_uid=0 represents English, then sys_language_uid=4 is not used.

Up to TYPO3 v8 inclusive, the trick to have everything work properly was to never configure a Frontend website to use sys_language_uid=0 but only 1 to 4 and rely on fallback chain to read 0 if the corresponding language is undefined. This way, content from a website in any default language (and translated) can use a common set of shared pages where the default language is semantically English (thus possibly another one).

TYPO3 v9

To do that in TYPO3 v9, the language configuration for a German-first website needs to be this one:

languages:
  -
    title: Deutsch
    enabled: true
    base: /de/
    typo3Language: de
    locale: 'de_CH.utf8,de_CH.UTF-8'
    iso-639-1: de
    websiteTitle: ''
    navigationTitle: Deutsch
    hreflang: de-CH
    direction: ''
    fallbackType: fallback
    fallbacks: '0'
    flag: de
    languageId: '1'
  -
    title: Français
    enabled: true
    base: /fr/
    typo3Language: fr
    locale: 'fr_CH.utf8,fr_CH.UTF-8'
    iso-639-1: fr
    websiteTitle: ''
    navigationTitle: Français
    hreflang: fr-CH
    direction: ''
    fallbackType: fallback
    fallbacks: '0'
    flag: fr
    languageId: '2'
  -
    title: Italiano
    enabled: true
    base: /it/
    typo3Language: it
    locale: 'it_CH.utf8,it_CH.UTF-8'
    iso-639-1: it
    websiteTitle: ''
    navigationTitle: Italiano
    hreflang: it-CH
    direction: ''
    fallbackType: fallback
    fallbacks: '0'
    flag: it
    languageId: '3'
  -
    title: English
    enabled: true
    base: /en/
    typo3Language: default
    locale: 'en_GB.utf8,en_GB.UTF-8'
    iso-639-1: en
    websiteTitle: ''
    navigationTitle: English
    hreflang: en-GB
    direction: ''
    fallbackType: fallback
    fallbacks: '0'
    flag: en-us-gb
    languageId: '4'

but the problem we face is that asking for generating a link for sys_language_uid=0 (in whichever context, for instance an API) leads to an internal catched exception when invoking typolink_URL(). It throws InvalidArgumentException 1522960188 which is "Language 0 does not exist on site xyz.".

What is expected

In such context, logically speaking the default language (thus the first one in the definition) should be checked for "fallbacks", something that is normally not expected to happen because TYPO3 wrongly thinks the default language is always 0.

Suggestion

diff --git a/typo3/sysext/core/Classes/Site/Entity/Site.php b/typo3/sysext/core/Classes/Site/Entity/Site.php
index 3d20c20f2a..ea7748b533 100644
--- a/typo3/sysext/core/Classes/Site/Entity/Site.php
+++ b/typo3/sysext/core/Classes/Site/Entity/Site.php
@@ -242,6 +242,11 @@ class Site implements SiteInterface
     {
         if (isset($this->languages[$languageId])) {
             return $this->languages[$languageId];
+        } else {
+            $defaultLanguage = $this->getDefaultLanguage();
+            if (in_array($languageId, $defaultLanguage->getFallbackLanguageIds(), true)) {
+                return $defaultLanguage;
+            }
         }
         throw new \InvalidArgumentException(
             'Language ' . $languageId . ' does not exist on site ' . $this->identifier . '.',
Actions

Also available in: Atom PDF