Commit 0b55dcd8 authored by catch's avatar catch

Issue #1862202 by plach, Berdir, katbailey, ParisLiakos, alexpott, chx, sun,...

Issue #1862202 by plach, Berdir, katbailey, ParisLiakos, alexpott, chx, sun, larowlan, Gábor Hojtsy, cosmicdreams, vijaycs85, YesCT, penyaskito, andypost, Albert Volkman, joelpitett: Objectify the language system.
parent 37723a56
......@@ -225,7 +225,6 @@ services:
arguments: ['@event_dispatcher', '@service_container', '@controller_resolver']
language_manager:
class: Drupal\Core\Language\LanguageManager
arguments: ['@state', '@module_handler']
string_translator.custom_strings:
class: Drupal\Core\StringTranslation\Translator\CustomStrings
arguments: ['@settings']
......@@ -233,6 +232,9 @@ services:
- { name: string_translator, priority: 30 }
string_translation:
class: Drupal\Core\StringTranslation\TranslationManager
arguments: ['@language_manager']
calls:
- [initLanguageManager]
database.slave:
class: Drupal\Core\Database\Connection
factory_class: Drupal\Core\Database\Database
......@@ -518,11 +520,6 @@ services:
tags:
- { name: event_subscriber }
arguments: ['@config.storage', '@config.storage.snapshot']
language_request_subscriber:
class: Drupal\Core\EventSubscriber\LanguageRequestSubscriber
tags:
- { name: event_subscriber }
arguments: ['@language_manager', '@string_translation']
exception_controller:
class: Drupal\Core\Controller\ExceptionController
arguments: ['@content_negotiation', '@string_translation', '@title_resolver', '@html_page_renderer']
......
......@@ -2331,7 +2331,7 @@ function drupal_installation_attempted() {
function drupal_language_initialize() {
$language_manager = \Drupal::languageManager();
$language_manager->init();
\Drupal::translation()->setDefaultLangcode($language_manager->getLanguage(Language::TYPE_INTERFACE)->id);
\Drupal::translation()->setDefaultLangcode($language_manager->getCurrentLanguage()->id);
}
/**
......@@ -2343,47 +2343,10 @@ function drupal_language_initialize() {
* The type of language object needed, e.g. Language::TYPE_INTERFACE.
*
* @deprecated as of Drupal 8.0. Use
* \Drupal::languageManager()->getLanguage($type).
* \Drupal::languageManager()->getCurrentLanguage().
*/
function language($type) {
return \Drupal::languageManager()->getLanguage($type);
}
/**
* Returns an array of the available language types.
*
* @return array
* An array of all language types where the keys of each are the language type
* name and its value is its configurability (TRUE/FALSE).
*/
function language_types_get_all() {
$types = \Drupal::config('system.language.types')->get('all');
return $types ? $types : array_keys(language_types_get_default());
}
/**
* Returns a list of the built-in language types.
*
* @return array
* An array of key-values pairs where the key is the language type name and
* the value is its configurability (TRUE/FALSE).
*/
function language_types_get_default() {
return array(
Language::TYPE_INTERFACE => TRUE,
Language::TYPE_CONTENT => FALSE,
Language::TYPE_URL => FALSE,
);
}
/**
* Returns TRUE if there is more than one language enabled.
*
* @return bool
* TRUE if more than one language is enabled.
*/
function language_multilingual() {
return \Drupal::languageManager()->isMultilingual();
return \Drupal::languageManager()->getCurrentLanguage($type);
}
/**
......@@ -2397,101 +2360,12 @@ function language_multilingual() {
* @return array
* An associative array of languages, keyed by the language code, ordered by
* weight ascending and name ascending.
*/
function language_list($flags = Language::STATE_CONFIGURABLE) {
$languages = &drupal_static(__FUNCTION__);
// Initialize master language list.
if (!isset($languages)) {
// Initialize local language list cache.
$languages = array();
// Fill in master language list based on current configuration.
$default = language_default();
if (language_multilingual() || \Drupal::moduleHandler()->moduleExists('language')) {
// Use language module configuration if available.
$language_entities = config_get_storage_names_with_prefix('language.entity.');
// Initialize default property so callers have an easy reference and can
// save the same object without data loss.
foreach ($language_entities as $langcode_config_name) {
$langcode = substr($langcode_config_name, strlen('language.entity.'));
$info = \Drupal::config($langcode_config_name)->get();
$languages[$langcode] = new Language(array(
'default' => ($info['id'] == $default->id),
'name' => $info['label'],
'id' => $info['id'],
'direction' => $info['direction'],
'locked' => $info['locked'],
'weight' => $info['weight'],
));
}
Language::sort($languages);
}
// If the language module is enabled but the configuration has not been
// written yet, returning an empty language list will cause errors. For
// example the cache clear in search_module_preinstall().
if (empty($languages)) {
// No language module, so use the default language only.
$languages = array($default->id => $default);
// Add the special languages, they will be filtered later if needed.
$languages += language_default_locked_languages($default->weight);
}
}
// Filter the full list of languages based on the value of the $all flag. By
// default we remove the locked languages, but the caller may request for
// those languages to be added as well.
$filtered_languages = array();
// Add the site's default language if flagged as allowed value.
if ($flags & Language::STATE_SITE_DEFAULT) {
$default = isset($default) ? $default : language_default();
// Rename the default language.
$default->name = t("Site's default language (@lang_name)", array('@lang_name' => $default->name));
$filtered_languages['site_default'] = $default;
}
foreach ($languages as $langcode => $language) {
if (($language->locked && !($flags & Language::STATE_LOCKED)) || (!$language->locked && !($flags & Language::STATE_CONFIGURABLE))) {
continue;
}
$filtered_languages[$langcode] = $language;
}
return $filtered_languages;
}
/**
* Returns a list of the default locked languages.
*
* @param int $weight
* An integer value that is used as the start value for the weights of the
* locked languages.
*
* @return array
* An array of language objects.
* @deprecated as of Drupal 8.0. Use
* \Drupal::languageManager()->getLanguages() instead.
*/
function language_default_locked_languages($weight = 0) {
$locked_language = array(
'default' => FALSE,
'locked' => TRUE,
'enabled' => TRUE,
);
$languages = array();
$languages[Language::LANGCODE_NOT_SPECIFIED] = new Language(array(
'id' => Language::LANGCODE_NOT_SPECIFIED,
'name' => t('Not specified'),
'weight' => ++$weight,
) + $locked_language);
$languages[Language::LANGCODE_NOT_APPLICABLE] = new Language(array(
'id' => Language::LANGCODE_NOT_APPLICABLE,
'name' => t('Not applicable'),
'weight' => ++$weight,
) + $locked_language);
return $languages;
function language_list($flags = Language::STATE_CONFIGURABLE) {
return \Drupal::languageManager()->getLanguages($flags);
}
/**
......@@ -2502,47 +2376,14 @@ function language_default_locked_languages($weight = 0) {
*
* @return \Drupal\core\Language\Language|null
* A fully-populated language object or NULL.
*/
function language_load($langcode) {
$languages = language_list(Language::STATE_ALL);
return isset($languages[$langcode]) ? $languages[$langcode] : NULL;
}
/**
* Produced the printed name for a language for display.
*
* @param string $langcode
* The language code.
* @see \Drupal\Core\Language\LanguageManager::getLanguage()
*
* @return string
* The printed name of the language.
* @deprecated as of Drupal 8.0. Use \Drupal::languageManager()->getLanguage()
* instead.
*/
function language_name($langcode) {
if ($langcode == Language::LANGCODE_NOT_SPECIFIED) {
return t('None');
}
if ($language = language_load($langcode)) {
return $language->name;
}
if (empty($langcode)) {
return t('Unknown');
}
return t('Unknown (@langcode)', array('@langcode' => $langcode));
}
/**
* Checks if a language is locked.
*
* @param string $langcode
* The language code.
*
* @return bool
* Returns whether the language is locked.
*/
function language_is_locked($langcode) {
$language = language_load($langcode);
return ($language ? $language->locked : FALSE);
function language_load($langcode) {
return \Drupal::languageManager()->getLanguage($langcode);
}
/**
......@@ -2550,35 +2391,12 @@ function language_is_locked($langcode) {
*
* @return \Drupal\Core\Language\Language
* A language object.
*/
function language_default() {
$info = variable_get('language_default', array(
'id' => 'en',
'name' => 'English',
'direction' => 0,
'weight' => 0,
'locked' => 0,
));
$info['default'] = TRUE;
return new Language($info);
}
/**
* Stores or retrieves the path derived during language negotiation.
*
* @param string $new_path
* The altered path.
*
* @todo Replace this with a path processor in language module. See
* http://drupal.org/node/1888424.
* @deprecated as of Drupal 8.0. Use
* \Drupal::languageManager()->getDefaultLanguage() instead.
*/
function _language_resolved_path($new_path = NULL) {
$path = &drupal_static(__FUNCTION__, NULL);
if ($new_path === NULL) {
return $path;
}
$path = $new_path;
return $path;
function language_default() {
return \Drupal::languageManager()->getDefaultLanguage();
}
/**
......
......@@ -4531,11 +4531,12 @@ function drupal_render_cid_parts($granularity = NULL) {
global $theme, $base_root, $user;
$cid_parts[] = $theme;
// If Locale is enabled but we have only one language we do not need it as cid
// part.
if (language_multilingual()) {
foreach (language_types_get_configurable() as $language_type) {
$cid_parts[] = language($language_type)->id;
// If we have only one language enabled we do not need it as cid part.
$language_manager = \Drupal::languageManager();
if ($language_manager->isMultilingual()) {
foreach ($language_manager->getLanguageTypes() as $type) {
$cid_parts[] = $language_manager->getCurrentLanguage($type)->id;
}
}
......
<?php
use Drupal\Component\Utility\UserAgent;
use Drupal\Component\Utility\Crypt;
use Drupal\Component\Utility\Settings;
......@@ -300,6 +301,9 @@ function install_begin_request(&$install_state) {
exit;
}
// Register the 'language_manager' service.
$container->register('language_manager', 'Drupal\Core\Language\LanguageManager');
// If we have a language selected and it is not yet saved in the system
// (eg. pre-database data screens we are unable to persistently store
// the default language), we should set language_default so the proper
......@@ -370,7 +374,6 @@ function install_begin_request(&$install_state) {
else {
// @todo Move into a proper Drupal\Core\DependencyInjection\InstallContainerBuilder.
$container = new ContainerBuilder();
$container->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher');
$container->register('config.storage', 'Drupal\Core\Config\InstallStorage');
......@@ -388,9 +391,7 @@ function install_begin_request(&$install_state) {
->addArgument(new Reference('config.typed'));
// Register the 'language_manager' service.
$container
->register('language_manager', 'Drupal\Core\Language\LanguageManager')
->addArgument(NULL);
$container->register('language_manager', 'Drupal\Core\Language\LanguageManager');
// Register the translation services.
install_register_translation_service($container);
......@@ -1505,6 +1506,7 @@ function install_register_translation_service(ContainerBuilder $container) {
$container->register('string_translator.custom_strings', 'Drupal\Core\StringTranslation\Translator\CustomStrings')
->addArgument(settings());
$container->register('string_translation', 'Drupal\Core\StringTranslation\TranslationManager')
->addArgument(new Reference('language_manager'))
->addMethodCall('addTranslator', array(new Reference('string_translator.file_translation')))
->addMethodCall('addTranslator', array(new Reference('string_translator.custom_strings')));
}
......@@ -1582,9 +1584,6 @@ function install_select_language(&$install_state) {
* @ingroup forms
*/
function install_select_language_form($form, &$form_state, $files = array()) {
include_once __DIR__ . '/../modules/language/language.module';
include_once __DIR__ . '/../modules/language/language.negotiation.inc';
$standard_languages = LanguageManager::getStandardLanguageList();
$select_options = array();
$browser_options = array();
......@@ -1596,22 +1595,19 @@ function install_select_language_form($form, &$form_state, $files = array()) {
// Select lists based on available language files.
foreach ($files as $langcode => $uri) {
$select_options[$langcode] = isset($standard_languages[$langcode]) ? $standard_languages[$langcode][1] : $langcode;
$browser_options[$langcode] = new Language(array(
'id' => $langcode,
));
$browser_options[] = $langcode;
}
}
else {
// Select lists based on all standard languages.
foreach ($standard_languages as $langcode => $language_names) {
$select_options[$langcode] = $language_names[1];
$browser_options[$langcode] = new Language(array(
'id' => $langcode,
));
$browser_options[] = $langcode;
}
}
$browser_langcode = language_from_browser($browser_options);
$request = Request::createFromGlobals();
$browser_langcode = UserAgent::getBestMatchingLangcode($request->server->get('HTTP_ACCEPT_LANGUAGE'), $browser_options);
$form['langcode'] = array(
'#type' => 'select',
'#title' => t('Choose language'),
......
<?php
/**
* @file
* Language Negotiation API.
*
* @see http://drupal.org/node/1497272
*/
use Drupal\Core\Language\Language;
/**
* No language negotiation. The default language is used.
*/
const LANGUAGE_NEGOTIATION_SELECTED = 'language-selected';
/**
* The language is determined using the current interface language.
*/
const LANGUAGE_NEGOTIATION_INTERFACE = 'language-interface';
/**
* @defgroup language_negotiation Language Negotiation API functionality
* @{
* Functions to customize the language types and the negotiation process.
*
* The language negotiation API is based on two major concepts:
* - Language types: types of translatable data (the types of data that a user
* can view or request).
* - Language negotiation methods: functions for determining which language to
* use to present a particular piece of data to the user.
* Both language types and language negotiation methods are customizable.
*
* Drupal defines three built-in language types:
* - Interface language: The page's main language, used to present translated
* user interface elements such as titles, labels, help text, and messages.
* - Content language: The language used to present content that is available
* in more than one language (see
* @link field_language Field Language API @endlink for details).
* - URL language: The language associated with URLs. When generating a URL,
* this value will be used by url() as a default if no explicit preference is
* provided.
* Modules can define additional language types through
* hook_language_types_info(), and alter existing language type definitions
* through hook_language_types_info_alter().
*
* Language types may be configurable or fixed. The language negotiation
* methods associated with a configurable language type can be explicitly
* set through the user interface. A fixed language type has predetermined
* (module-defined) language negotiation settings and, thus, does not appear in
* the configuration page. Here is a code snippet that makes the content
* language (which by default inherits the interface language's values)
* configurable:
* @code
* function mymodule_language_types_info_alter(&$language_types) {
* unset($language_types[Language::TYPE_CONTENT]['fixed']);
* }
* @endcode
*
* The locked configuration property prevents one language type from being
* switched from customized to not customized, and vice versa.
* @see language_types_set()
*
* Every language type can have a different set of language negotiation methods
* assigned to it. Different language types often share the same language
* negotiation settings, but they can have independent settings if needed. If
* two language types are configured the same way, their language switcher
* configuration will be functionally identical and the same settings will act
* on both language types.
*
* Drupal defines the following built-in language negotiation methods:
* - URL: Determine the language from the URL (path prefix or domain).
* - Session: Determine the language from a request/session parameter.
* - User: Follow the user's language preference.
* - Browser: Determine the language from the browser's language settings.
* - Default language: Use the default site language.
* Language negotiation methods are simple callback functions that implement a
* particular logic to return a language code. For instance, the URL method
* searches for a valid path prefix or domain name in the current request URL.
* If a language negotiation method does not return a valid language code, the
* next method associated to the language type (based on method weight) is
* invoked.
*
* Modules can define additional language negotiation methods through
* hook_language_negotiation_info(), and alter existing methods through
* hook_language_negotiation_info_alter(). Here is an example snippet that lets
* path prefixes be ignored for administrative paths:
* @code
* function mymodule_language_negotiation_info_alter(&$negotiation_info) {
* // Replace the core function with our own function.
* module_load_include('language', 'inc', 'language.negotiation');
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['callbacks']['negotiation'] = 'mymodule_from_url';
* $negotiation_info[LANGUAGE_NEGOTIATION_URL]['file'] = drupal_get_path('module', 'mymodule') . '/mymodule.module';
* }
*
* function mymodule_from_url($languages) {
* // Use the core URL language negotiation method to get a valid language
* // code.
* module_load_include('language', 'inc', 'language.negotiation');
* $langcode = language_from_url($languages);
*
* // If we are on an administrative path, override with the default language.
* $query = \Drupal::request()->query;
* if ($query->has('q') && strtok($query->get('q'), '/') == 'admin') {
* return language_default()->id;
* }
* return $langcode;
* }
* ?>
* @endcode
*
* For more information, see
* @link http://drupal.org/node/1497272 Language Negotiation API @endlink
*/
/**
* Chooses a language based on language negotiation method settings.
*
* @param $type
* The language type key to find the language for.
*
* @param $request
* The HttpReqeust object representing the current request.
*
* @return
* The negotiated language object.
*/
function language_types_initialize($type, $request = NULL) {
// Execute the language negotiation methods in the order they were set up and
// return the first valid language found.
$negotiation = variable_get("language_negotiation_$type", array());
foreach ($negotiation as $method_id => $method) {
// Skip negotiation methods not appropriate for this type.
if (isset($method['types']) && !in_array($type, $method['types'])) {
continue;
}
$language = language_negotiation_method_invoke($method_id, $method, $request);
if ($language) {
// Remember the method ID used to detect the language.
$language->method_id = $method_id;
return $language;
}
}
// If no other language was found use the default one.
$language = language_default();
$language->method_id = LANGUAGE_NEGOTIATION_SELECTED;
return $language;
}
/**
* Returns information about all defined language types.
*
* @return
* An associative array of language type information arrays keyed by type
* names. Based on information from hook_language_types_info().
*
* @see hook_language_types_info().
*/
function language_types_info() {
$language_types = &drupal_static(__FUNCTION__);
if (!isset($language_types)) {
$language_types = \Drupal::moduleHandler()->invokeAll('language_types_info');
// Let other modules alter the list of language types.
drupal_alter('language_types_info', $language_types);
}
return $language_types;
}
/**
* Returns only the configurable language types.
*
* A language type maybe configurable or fixed. A fixed language type is a type
* whose language negotiation methods are module-defined and not altered through
* the user interface.
*
* @return
* An array of language type names.
*/
function language_types_get_configurable() {
$configurable = \Drupal::config('system.language.types')->get('configurable');
return $configurable ? $configurable : array();
}
/**
* Disables the given language types.
*
* @param $types
* An array of language types.
*/
function language_types_disable($types) {
$configurable = language_types_get_configurable();
\Drupal::config('system.language.types')->set('configurable', array_diff($configurable, $types))->save();
}
/**
* Updates the language type configuration.
*