When installing drupal and using it with more than one language, some actions may not work for the language that is not the default one, such as, access the alias urls for the second language.
Reproduce
- Install drupal 8.6
- Enable locale, language and pathauto modules
- Install a second language such as spanish
- Set the language negotiation to:
> Interface text language detection
- User
- Selected language (spanish)
- Enable the option "Customize Content language detection to differ from Interface text language detection settings"
> Content language detection
- Content language
- User
- Selected Language (spanish)
- Create any content and set its language to spanish
- Using a user that has spanish language as its preference, try to access this new content.
- The page is not found.
I found some functions that are using the negotiation type url as default (LanguageInterface::TYPE_URL) when asking for the current language for the language manager service. This way, the service only looks for the language code in the url/domain and does not consider other types of negotiation.
Here is the list of files and functions that I found these problems
- file core/lib/Drupal/Core/Routing/RouteProvider.php at line 473
return $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId();
- file core/lib/Drupal/Core/Path/AliasManager.php at line 156 and 192
$langcode = $langcode ?: $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId();
After removing the parameter type for the function getCurrentLanguage the system started working properly and resolved the url for both languages.
Other places that execute the same process and may break the system:
- core/lib/Drupal/Core/EventSubscriber/ActiveLinkResponseFilter.php at line 95
- core/modules/contextual/contextual.module at line 177
- core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php at line 134
- core/modules/system/system.module at line 737
If the system really needs to have this negotiation as the default fallback I believe that the method getCurrentLanguage should the main responsible for setting this option inside its logic.