diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index ab06260c965c4f12f52d7fc8cd57a5e5869d8d91..7d5451d9a78b8853e0f6ec7549e11367fad831f2 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -2609,7 +2609,7 @@ function get_t() { * Initializes all the defined language types. */ function drupal_language_initialize() { - $types = language_types(); + $types = language_types_get_all(); // Ensure the language is correctly returned, even without multilanguage // support. Also make sure we have a $language fallback, in case a language @@ -2622,7 +2622,7 @@ function drupal_language_initialize() { if (language_multilingual()) { include_once DRUPAL_ROOT . '/core/includes/language.inc'; foreach ($types as $type) { - $GLOBALS[$type] = language_initialize($type); + $GLOBALS[$type] = language_types_initialize($type); } // Allow modules to react on language system initialization in multilingual // environments. @@ -2630,14 +2630,20 @@ function drupal_language_initialize() { } } +/** + * Returns an array of the available language types. + */ +function language_types_get_all() { + return array_keys(variable_get('language_types', language_types_get_default())); +} /** * Returns a list of the built-in language types. * * @return - * An array of key-values pairs where the key is the language type and the - * value is its configurability. + * An array of key-values pairs where the key is the language type name and + * the value is its configurability (TRUE/FALSE). */ -function drupal_language_types() { +function language_types_get_default() { return array( LANGUAGE_TYPE_INTERFACE => TRUE, LANGUAGE_TYPE_CONTENT => FALSE, @@ -2655,13 +2661,6 @@ function language_multilingual() { return variable_get('language_count', 1) > 1; } -/** - * Returns an array of the available language types. - */ -function language_types() { - return array_keys(variable_get('language_types', drupal_language_types())); -} - /** * Returns a list of configured languages. * diff --git a/core/includes/common.inc b/core/includes/common.inc index 9c6564774974c8771de6aaf184835ecc99dcbead..ef0778ac9f797e2ecd3444c18638a06dff364d76 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -6191,7 +6191,7 @@ function drupal_render_cid_parts($granularity = NULL) { // If Locale is enabled but we have only one language we do not need it as cid // part. if (language_multilingual()) { - foreach (language_types_configurable() as $language_type) { + foreach (language_types_get_configurable() as $language_type) { $cid_parts[] = $GLOBALS[$language_type]->langcode; } } diff --git a/core/includes/language.inc b/core/includes/language.inc index 46280532597bb3e4195d58f7bfc51e581027079d..f12f34afa6d2813cb0cc345b0820c9ff454d8df9 100644 --- a/core/includes/language.inc +++ b/core/includes/language.inc @@ -11,11 +11,42 @@ const LANGUAGE_NEGOTIATION_DEFAULT = 'language-default'; /** - * Return all the defined language types. + * Chooses a language for the given type based on language negotiation settings. + * + * @param $type + * The language type key. + * + * @return + * The negotiated language object. + */ +function language_types_initialize($type) { + // Execute the language providers in the order they were set up and return the + // first valid language found. + $negotiation = variable_get("language_negotiation_$type", array()); + + foreach ($negotiation as $provider_id => $provider) { + $language = language_provider_invoke($provider_id, $provider); + if ($language) { + // Remember the provider key used to detect the language. + $language->provider = $provider_id; + return $language; + } + } + + // If no other language was found use the default one. + $language = language_default(); + $language->provider = LANGUAGE_NEGOTIATION_DEFAULT; + return $language; +} + +/** + * Returns information about all defined language types. * * @return - * An array of language type names. The name will be used as the global - * variable name the language value will be stored in. + * 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__); @@ -30,7 +61,7 @@ function language_types_info() { } /** - * Return only the configurable language types. + * Returns only the configurable language types. * * A language type maybe configurable or fixed. A fixed language type is a type * whose negotiation values are unchangeable and defined while defining the @@ -46,11 +77,11 @@ function language_types_info() { * @return * An array of language type names. */ -function language_types_configurable($stored = TRUE) { +function language_types_get_configurable($stored = TRUE) { $configurable = &drupal_static(__FUNCTION__); if ($stored && !isset($configurable)) { - $types = variable_get('language_types', drupal_language_types()); + $types = variable_get('language_types', language_types_get_default()); $configurable = array_keys(array_filter($types)); } @@ -74,7 +105,7 @@ function language_types_configurable($stored = TRUE) { * An array of language types. */ function language_types_disable($types) { - $enabled_types = variable_get('language_types', drupal_language_types()); + $enabled_types = variable_get('language_types', language_types_get_default()); foreach ($types as $type) { unset($enabled_types[$type]); @@ -96,6 +127,7 @@ function language_types_set() { // Determine which language types are configurable and which not by checking // whether the 'fixed' key is defined. Non-configurable (fixed) language types // have their language negotiation settings stored there. + $language_types = array(); $defined_providers = language_negotiation_info(); foreach (language_types_info() as $type => $info) { if (isset($info['fixed'])) { @@ -113,12 +145,12 @@ function language_types_set() { } } - // Save language types. + // Save enabled language types. variable_set('language_types', $language_types); - // Ensure that subsequent calls of language_types_configurable() return the - // updated language type information. - drupal_static_reset('language_types_configurable'); + // Ensure that subsequent calls of language_types_get_configurable() return + // the updated language type information. + drupal_static_reset('language_types_get_configurable'); } /** @@ -166,7 +198,7 @@ function language_negotiation_get($type, $provider_id = NULL) { * provider is enabled, FALSE otherwise. */ function language_negotiation_get_any($provider_id) { - foreach (language_types_configurable() as $type) { + foreach (language_types_get_configurable() as $type) { if (language_negotiation_get($type, $provider_id)) { return TRUE; } @@ -250,7 +282,7 @@ function language_negotiation_set($type, $language_providers) { $negotiation = array(); $providers_weight = array(); $defined_providers = language_negotiation_info(); - $default_types = language_types_configurable(FALSE); + $default_types = language_types_get_configurable(FALSE); // Initialize the providers weight list. foreach ($language_providers as $id => $provider) { @@ -369,34 +401,6 @@ function language_provider_weight($provider) { return isset($provider['weight']) && is_numeric($provider['weight']) ? $provider['weight'] : $default; } -/** - * Choose a language for the given type based on language negotiation settings. - * - * @param $type - * The language type. - * - * @return - * The negotiated language object. - */ -function language_initialize($type) { - // Execute the language providers in the order they were set up and return the - // first valid language found. - $negotiation = variable_get("language_negotiation_$type", array()); - - foreach ($negotiation as $provider_id => $provider) { - $language = language_provider_invoke($provider_id, $provider); - if ($language) { - $language->provider = $provider_id; - return $language; - } - } - - // If no other language was found use the default one. - $language = language_default(); - $language->provider = LANGUAGE_NEGOTIATION_DEFAULT; - return $language; -} - /** * Default language provider. * diff --git a/core/includes/update.inc b/core/includes/update.inc index 9dd1e5d708bfe909ced2088612623a8298beb4a6..be9788fec614469823b905a1e6f5f6f73113a8ec 100644 --- a/core/includes/update.inc +++ b/core/includes/update.inc @@ -138,7 +138,7 @@ function update_prepare_d8_bootstrap() { */ function update_prepare_stored_includes() { // Update language negotiation settings. - foreach (language_types() as $language_type) { + foreach (language_types_get_all() as $language_type) { $negotiation = variable_get("language_negotiation_$language_type", array()); foreach ($negotiation as $id => &$provider) { if (isset($negotiation[$id]['file']) && $negotiation[$id]['file'] == 'includes/locale.inc') { diff --git a/core/modules/locale/locale.admin.inc b/core/modules/locale/locale.admin.inc index 072dba19b37683ca6d0e548fc8c807defa86cd61..2c78e17699e64c18635cf3b930e7c06c192e23f5 100644 --- a/core/modules/locale/locale.admin.inc +++ b/core/modules/locale/locale.admin.inc @@ -14,7 +14,7 @@ function language_negotiation_configure_form() { $form = array( '#submit' => array('language_negotiation_configure_form_submit'), '#theme' => 'language_negotiation_configure_form', - '#language_types' => language_types_configurable(FALSE), + '#language_types' => language_types_get_configurable(FALSE), '#language_types_info' => language_types_info(), '#language_providers' => language_negotiation_info(), ); diff --git a/core/modules/locale/locale.api.php b/core/modules/locale/locale.api.php index 4ed22a8daa75c6c758c2bb099ed684576506f043..1fb5973d97d6f55ae07a8e15ba2c5900f78086a0 100644 --- a/core/modules/locale/locale.api.php +++ b/core/modules/locale/locale.api.php @@ -65,13 +65,19 @@ function hook_language_switch_links_alter(array &$links, $type, $path) { * Allow modules to define their own language types. * * @return - * An array of language type definitions. Each language type has an identifier - * key. The language type definition is an associative array that may contain - * the following key-value pairs: + * An associative array of language type definitions. + * + * Each language type has an identifier key which is used as the name for the + * global variable corresponding to the language type in the bootstrap phase. + * + * The language type definition is an associative array that may contain the + * following key-value pairs: * - "name": The human-readable language type identifier. * - "description": A description of the language type. - * - "fixed": An array of language provider identifiers. Defining this key - * makes the language type non-configurable. + * - "fixed": A fixed array of language provider identifiers to use to + * initialize this language. Defining this key makes the language type + * non-configurable and will always use the specified providers in the given + * priority order. */ function hook_language_types_info() { return array( @@ -88,6 +94,8 @@ function hook_language_types_info() { /** * Perform alterations on language types. * + * @see hook_language_types_info(). + * * @param $language_types * Array of language type definitions. */ diff --git a/core/modules/locale/locale.install b/core/modules/locale/locale.install index 0ee7907cdd5954c255c0fac7809ce143c8459045..c4fc445e4735dd08c1754f851de3ae4b90576739 100644 --- a/core/modules/locale/locale.install +++ b/core/modules/locale/locale.install @@ -29,7 +29,7 @@ function locale_install() { } // Enable URL language detection for each (core) configurable language type. - foreach (language_types_configurable() as $type) { + foreach (language_types_get_configurable() as $type) { variable_set("language_negotiation_$type", $negotiation); } } @@ -97,7 +97,7 @@ function locale_uninstall() { variable_del('locale_translation_plurals'); variable_del('locale_translation_javascript'); - foreach (language_types() as $type) { + foreach (language_types_get_all() as $type) { variable_del("language_negotiation_$type"); variable_del("locale_language_providers_weight_$type"); } diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index d50684e02e4b9bbb4fafb796379f8a4d110b0dac..cfd4a26e65c19c402bd19815bc59ffa35b098a13 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -876,7 +876,7 @@ function locale_block_info() { include_once DRUPAL_ROOT . '/core/includes/language.inc'; $block = array(); $info = language_types_info(); - foreach (language_types_configurable(FALSE) as $type) { + foreach (language_types_get_configurable(FALSE) as $type) { $block[$type] = array( 'info' => t('Language switcher (@type)', array('@type' => $info[$type]['name'])), // Not worth caching. @@ -934,7 +934,7 @@ function locale_url_outbound_alter(&$path, &$options, $original_path) { $callbacks = array(); include_once DRUPAL_ROOT . '/core/includes/language.inc'; - foreach (language_types_configurable() as $type) { + foreach (language_types_get_configurable() as $type) { // Get url rewriter callbacks only from enabled language providers. $negotiation = variable_get("language_negotiation_$type", array()); diff --git a/core/modules/locale/locale.test b/core/modules/locale/locale.test index 42a0fbd68516fe3af5d7dd8a31e1d64b17670289..306741f7462fcae97e3f42605403aaf6ae731cca 100644 --- a/core/modules/locale/locale.test +++ b/core/modules/locale/locale.test @@ -1251,7 +1251,7 @@ class LocaleUninstallFunctionalTest extends DrupalWebTestCase { // Change language negotiation options. drupal_load('module', 'locale'); - variable_set('language_types', drupal_language_types() + array('language_custom' => TRUE)); + variable_set('language_types', language_types_get_default() + array('language_custom' => TRUE)); variable_set('language_negotiation_' . LANGUAGE_TYPE_INTERFACE, locale_language_negotiation_info()); variable_set('language_negotiation_' . LANGUAGE_TYPE_CONTENT, locale_language_negotiation_info()); variable_set('language_negotiation_' . LANGUAGE_TYPE_URL, locale_language_negotiation_info()); @@ -1280,7 +1280,7 @@ class LocaleUninstallFunctionalTest extends DrupalWebTestCase { // Check language negotiation. require_once DRUPAL_ROOT . '/core/includes/language.inc'; - $this->assertTrue(count(language_types()) == count(drupal_language_types()), t('Language types reset')); + $this->assertTrue(count(language_types_get_all()) == count(language_types_get_default()), t('Language types reset')); $language_negotiation = language_negotiation_get(LANGUAGE_TYPE_INTERFACE) == LANGUAGE_NEGOTIATION_DEFAULT; $this->assertTrue($language_negotiation, t('Interface language negotiation: %setting', array('%setting' => t($language_negotiation ? 'none' : 'set')))); $language_negotiation = language_negotiation_get(LANGUAGE_TYPE_CONTENT) == LANGUAGE_NEGOTIATION_DEFAULT; @@ -2795,7 +2795,7 @@ class LocaleLanguageNegotiationInfoFunctionalTest extends DrupalWebTestCase { variable_set('locale_test_content_language_type', TRUE); $this->languageNegotiationUpdate(); $type = LANGUAGE_TYPE_CONTENT; - $language_types = variable_get('language_types', drupal_language_types()); + $language_types = variable_get('language_types', language_types_get_default()); $this->assertTrue($language_types[$type], t('Content language type is configurable.')); // Enable some core and custom language providers. The test language type is @@ -2821,7 +2821,7 @@ class LocaleLanguageNegotiationInfoFunctionalTest extends DrupalWebTestCase { // Check that type-specific language providers can be assigned only to the // corresponding language types. - foreach (language_types_configurable() as $type) { + foreach (language_types_get_configurable() as $type) { $form_field = $type . '[enabled][test_language_provider_ts]'; if ($type == $test_type) { $this->assertFieldByXPath("//input[@name=\"$form_field\"]", NULL, t('Type-specific test language provider available for %type.', array('%type' => $type))); @@ -2834,7 +2834,7 @@ class LocaleLanguageNegotiationInfoFunctionalTest extends DrupalWebTestCase { // Check language negotiation results. $this->drupalGet(''); $last = variable_get('locale_test_language_negotiation_last', array()); - foreach (language_types() as $type) { + foreach (language_types_get_all() as $type) { $langcode = $last[$type]; $value = $type == LANGUAGE_TYPE_CONTENT || strpos($type, 'test') !== FALSE ? 'it' : 'en'; $this->assertEqual($langcode, $value, t('The negotiated language for %type is %language', array('%type' => $type, '%language' => $langcode))); @@ -2845,7 +2845,7 @@ class LocaleLanguageNegotiationInfoFunctionalTest extends DrupalWebTestCase { $this->languageNegotiationUpdate('disable'); // Check that only the core language types are available. - foreach (language_types() as $type) { + foreach (language_types_get_all() as $type) { $this->assertTrue(strpos($type, 'test') === FALSE, t('The %type language is still available', array('%type' => $type))); } diff --git a/core/modules/locale/tests/locale_test.module b/core/modules/locale/tests/locale_test.module index c7bc6e34811c098d042d93f9959e75fe341a6eb3..92081d1bb650aa8912d167f259565e315d5518c2 100644 --- a/core/modules/locale/tests/locale_test.module +++ b/core/modules/locale/tests/locale_test.module @@ -94,7 +94,7 @@ function locale_test_language_negotiation_info_alter(array &$language_providers) */ function locale_test_store_language_negotiation() { $last = array(); - foreach (language_types() as $type) { + foreach (language_types_get_all() as $type) { $last[$type] = $GLOBALS[$type]->langcode; } variable_set('locale_test_language_negotiation_last', $last);