diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php index 88e2363..31864d1 100644 --- a/core/lib/Drupal/Core/Language/LanguageManager.php +++ b/core/lib/Drupal/Core/Language/LanguageManager.php @@ -81,6 +81,31 @@ public function getLanguageTypes() { /** * {@inheritdoc} */ + public function getDefinedLanguageTypesInfo() { + // This needs to have the same return value as + // language_language_type_info(), so that even if the Language module is + // not defined, users of this information, such as the Views module, can + // access names and descriptions of the default language types. + return array( + LanguageInterface::TYPE_INTERFACE => array( + 'name' => t('User interface text'), + 'description' => t('Order of language detection methods for user interface text. If a translation of user interface text is available in the detected language, it will be displayed.'), + 'locked' => TRUE, + ), + LanguageInterface::TYPE_CONTENT => array( + 'name' => t('Content'), + 'description' => t('Order of language detection methods for content. If a version of content is available in the detected language, it will be displayed.'), + 'locked' => TRUE, + ), + LanguageInterface::TYPE_URL => array( + 'locked' => TRUE, + ), + ); + } + + /** + * {@inheritdoc} + */ public function getCurrentLanguage($type = LanguageInterface::TYPE_INTERFACE) { return $this->getDefaultLanguage(); } @@ -120,7 +145,9 @@ public function getLanguages($flags = LanguageInterface::STATE_CONFIGURABLE) { // Add the site's default language if flagged as allowed value. if ($flags & LanguageInterface::STATE_SITE_DEFAULT) { $default = isset($default) ? $default : $this->getDefaultLanguage(); - // Rename the default language. + // Rename the default language. But we do not want to do this globally, + // if we're acting on a global object, so clone the object first. + $default = clone $default; $default->name = $this->t("Site's default language (@lang_name)", array('@lang_name' => $default->name)); $filtered_languages['site_default'] = $default; } diff --git a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php index 1a28f18..0bbf453 100644 --- a/core/lib/Drupal/Core/Language/LanguageManagerInterface.php +++ b/core/lib/Drupal/Core/Language/LanguageManagerInterface.php @@ -34,19 +34,32 @@ public function isMultilingual(); * Returns an array of the available language types. * * @return array - * An array of language type names. + * An array of language type machine names. */ public function getLanguageTypes(); /** + * Returns information about all defined language types. + * + * @return array + * An associative array of language type information arrays keyed by + * language type machine name, in the format of + * hook_language_types_info(). In some implementing classes, this is based + * on information from hook_language_types_info() and + * hook_language_types_info_alter(). + */ + public function getDefinedLanguageTypesInfo(); + + /** * Returns the current language for the given type. * * @param string $type - * (optional) The language type, e.g. the interface or the content language. - * Defaults to \Drupal\Core\Language\LanguageInterface::TYPE_INTERFACE. + * (optional) The language type; e.g., the interface or the content + * language. Defaults to + * \Drupal\Core\Language\LanguageInterface::TYPE_INTERFACE. * * @return \Drupal\Core\Language\LanguageInterface - * A language object for the given type. + * The current language object for the given type of language. */ public function getCurrentLanguage($type = LanguageInterface::TYPE_INTERFACE); diff --git a/core/modules/comment/config/install/views.view.comments_recent.yml b/core/modules/comment/config/install/views.view.comments_recent.yml index 9023ae7..7a4b559 100644 --- a/core/modules/comment/config/install/views.view.comments_recent.yml +++ b/core/modules/comment/config/install/views.view.comments_recent.yml @@ -228,7 +228,7 @@ display: content: 'No comments available.' tokenize: false plugin_id: text_custom - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null block_1: provider: views @@ -239,7 +239,7 @@ display: display_options: block_description: 'Recent comments' block_category: 'Lists (Views)' - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null allow: items_per_page: true diff --git a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_field_filters.yml b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_field_filters.yml index 692c5d5..aa73012 100644 --- a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_field_filters.yml +++ b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_field_filters.yml @@ -160,7 +160,7 @@ display: footer: { } empty: { } arguments: { } - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null page_tc: display_plugin: page @@ -169,7 +169,7 @@ display: position: 1 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null path: test-title-filter display_description: '' @@ -180,7 +180,7 @@ display: position: 1 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null path: test-body-paris display_description: '' @@ -241,7 +241,7 @@ display: position: 1 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null path: test-title-paris display_description: '' @@ -301,7 +301,7 @@ display: position: 1 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null path: test-body-filter display_description: '' diff --git a/core/modules/field/src/Plugin/views/field/Field.php b/core/modules/field/src/Plugin/views/field/Field.php index 04976b4..02e396e 100644 --- a/core/modules/field/src/Plugin/views/field/Field.php +++ b/core/modules/field/src/Plugin/views/field/Field.php @@ -290,20 +290,18 @@ public function query($use_groupby = FALSE) { $this->ensureMyTable(); $this->addAdditionalFields($fields); - // Filter by langcode, if field translation is enabled. + // If we are grouping by something on this field, we want to group by + // the displayed value, which is translated. So, we need to figure out + // which language should be used to translate the value. See also + // $this->field_langcode(). $field = $field_definition; if ($field->isTranslatable() && !empty($this->view->display_handler->options['field_langcode_add_to_query'])) { $column = $this->tableAlias . '.langcode'; - // By the same reason as field_language the field might be - // LanguageInterface::LANGCODE_NOT_SPECIFIED in reality so allow it as - // well. - // @see this::field_langcode() - $default_langcode = language_default()->id; - $langcode = str_replace( - array('***CURRENT_LANGUAGE***', '***DEFAULT_LANGUAGE***'), - array($this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT), $default_langcode), - $this->view->display_handler->options['field_langcode'] - ); + $langcode = $this->view->display_handler->options['field_langcode']; + $substitutions = static::queryLanguageSubstitutions(); + if (isset($substitutions[$langcode])) { + $langcode = $substitutions[$langcode]; + } $placeholder = $this->placeholder(); $langcode_fallback_candidates = $this->languageManager->getFallbackCandidates(array('langcode' => $langcode, 'operation' => 'views_query', 'data' => $this)); $this->query->addWhereExpression(0, "$column IN($placeholder) OR $column IS NULL", array($placeholder => $langcode_fallback_candidates)); @@ -915,12 +913,11 @@ protected function addSelfTokens(&$tokens, $item) { */ function field_langcode(EntityInterface $entity) { if ($this->getFieldDefinition()->isTranslatable()) { - $default_langcode = language_default()->id; - $langcode = str_replace( - array('***CURRENT_LANGUAGE***', '***DEFAULT_LANGUAGE***'), - array($this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->id, $default_langcode), - $this->view->display_handler->options['field_langcode'] - ); + $langcode = $this->view->display_handler->options['field_langcode']; + $substitutions = static::queryLanguageSubstitutions(); + if (isset($substitutions[$langcode])) { + $langcode = $substitutions[$langcode]; + } // Give the Entity Field API a chance to fallback to a different language // (or LanguageInterface::LANGCODE_NOT_SPECIFIED), in case the field has diff --git a/core/modules/language/src/ConfigurableLanguageManagerInterface.php b/core/modules/language/src/ConfigurableLanguageManagerInterface.php index 3b52cd4..f3b2ff2 100644 --- a/core/modules/language/src/ConfigurableLanguageManagerInterface.php +++ b/core/modules/language/src/ConfigurableLanguageManagerInterface.php @@ -44,22 +44,11 @@ public function setNegotiator(LanguageNegotiatorInterface $negotiator); * through the user interface. * * @return array - * An array of language type names. + * An array of language type machine names. */ public function getDefinedLanguageTypes(); /** - * Returns information about all defined language types. - * - * @return array - * 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() - */ - public function getDefinedLanguageTypesInfo(); - - /** * Stores language types configuration. * * @param array diff --git a/core/modules/node/config/install/views.view.content.yml b/core/modules/node/config/install/views.view.content.yml index 132ffee..229fed6 100644 --- a/core/modules/node/config/install/views.view.content.yml +++ b/core/modules/node/config/install/views.view.content.yml @@ -536,7 +536,7 @@ display: operator: AND groups: 1: AND - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null display_plugin: default display_title: Master @@ -558,7 +558,7 @@ display: description: 'Find and manage content' menu_name: admin weight: -10 - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null display_plugin: page display_title: Page diff --git a/core/modules/node/config/install/views.view.frontpage.yml b/core/modules/node/config/install/views.view.frontpage.yml index 1e27e9c..2fad370 100644 --- a/core/modules/node/config/install/views.view.frontpage.yml +++ b/core/modules/node/config/install/views.view.frontpage.yml @@ -130,7 +130,7 @@ display: - views operator: in value: - '***CURRENT_LANGUAGE***': '***CURRENT_LANGUAGE***' + ***LANGUAGE_language_content***: '***LANGUAGE_language_content***' group: 1 exposed: false expose: @@ -240,7 +240,7 @@ display: relationships: { } fields: { } arguments: { } - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null display_plugin: default display_title: Master @@ -249,7 +249,7 @@ display: page_1: display_options: path: node - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null display_plugin: page display_title: Page @@ -286,5 +286,5 @@ display: view_mode: rss links: false provider: views - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null diff --git a/core/modules/node/src/Tests/Views/NodeLanguageTest.php b/core/modules/node/src/Tests/Views/NodeLanguageTest.php index 11a17b3..8300ad0 100644 --- a/core/modules/node/src/Tests/Views/NodeLanguageTest.php +++ b/core/modules/node/src/Tests/Views/NodeLanguageTest.php @@ -184,5 +184,52 @@ public function testLanguages() { } } } + + // Override the config for the front page view, so that the language + // filter is set to the site default language instead. This should just + // show the English nodes, no matter what the content language is. + $config = \Drupal::config('views.view.frontpage'); + $config->set('display.default.display_options.filters.langcode.value', array('***LANGUAGE_site_default***' => '***LANGUAGE_site_default***')); + $config->save(); + foreach ($this->node_titles as $langcode => $titles) { + $this->drupalGet(($langcode == 'en' ? '' : "$langcode/") . 'node'); + foreach ($this->node_titles as $control_langcode => $control_titles) { + foreach ($control_titles as $title) { + if ($control_langcode == 'en') { + $this->assertText($title, 'English title is shown when filtering is site default'); + } + else { + $this->assertNoText($title, 'Non-English title is not shown when filtering is site default'); + } + } + } + } + + // Override the config so that the language filter is set to the UI + // language, and make that have a fixed value of 'es'. + // + // IMPORTANT: Make sure this part of the test is last -- it is changing + // language configuration! + $config->set('display.default.display_options.filters.langcode.value', array('***LANGUAGE_language_interface***' => '***LANGUAGE_language_interface***')); + $config->save(); + $language_config = \Drupal::config('language.types'); + $language_config->set('negotiation.language_interface.enabled', array('language-selected' => 1)); + $language_config->save(); + $language_config = \Drupal::config('language.negotiation'); + $language_config->set('selected_langcode', 'es'); + $language_config->save(); + + // With a fixed language selected, there is no language-based URL. + $this->drupalGet('node'); + foreach ($this->node_titles as $control_langcode => $control_titles) { + foreach ($control_titles as $title) { + if ($control_langcode == 'es') { + $this->assertText($title, 'Spanish title is shown when filtering is fixed UI language'); + } + else { + $this->assertNoText($title, 'Non-Spanish title is not shown when filtering is fixed UI language'); + } + } + } } } diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_field_filters.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_field_filters.yml index 410622a..30626e1 100644 --- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_field_filters.yml +++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_field_filters.yml @@ -173,7 +173,7 @@ display: empty: { } relationships: { } arguments: { } - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null page_tf: display_plugin: page @@ -182,7 +182,7 @@ display: position: 1 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null path: test-title-filter display_description: '' @@ -255,7 +255,7 @@ display: position: 1 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null path: test-body-filter display_description: '' @@ -326,7 +326,7 @@ display: position: 1 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null path: test-body-paris display_description: '' @@ -398,7 +398,7 @@ display: position: 1 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null path: test-title-paris display_description: '' diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml index 68fb2d5..c21e026 100644 --- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml +++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml @@ -300,7 +300,7 @@ display: validate_options: { } plugin_id: language provider: views - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null page_1: display_plugin: page @@ -309,6 +309,6 @@ display: position: 1 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null path: test-language diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_field_filters.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_field_filters.yml index 372c0f5..664f316 100644 --- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_field_filters.yml +++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_field_filters.yml @@ -145,7 +145,7 @@ display: empty: { } relationships: { } arguments: { } - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null page_dc: display_plugin: page @@ -154,7 +154,7 @@ display: position: 3 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null display_description: '' path: test-desc-filter @@ -215,7 +215,7 @@ display: position: 3 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null display_description: '' path: test-desc-paris @@ -277,7 +277,7 @@ display: position: 1 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null path: test-name-filter display_description: '' @@ -288,7 +288,7 @@ display: position: 1 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null path: test-name-paris display_description: '' @@ -348,7 +348,7 @@ display: position: 3 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null display_description: '' path: test-field-paris @@ -410,7 +410,7 @@ display: position: 3 provider: views display_options: - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null display_description: '' path: test-field-filter diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_tid_field.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_tid_field.yml index 6f2bf4f..ed3e033 100644 --- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_tid_field.yml +++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_tid_field.yml @@ -172,5 +172,5 @@ display: empty: { } relationships: { } arguments: { } - field_langcode: '***CURRENT_LANGUAGE***' + field_langcode: '***LANGUAGE_language_content***' field_langcode_add_to_query: null diff --git a/core/modules/views/src/Plugin/views/PluginBase.php b/core/modules/views/src/Plugin/views/PluginBase.php index 132ceec..b66578b 100644 --- a/core/modules/views/src/Plugin/views/PluginBase.php +++ b/core/modules/views/src/Plugin/views/PluginBase.php @@ -2,13 +2,14 @@ /** * @file - * Definition of Drupal\views\Plugin\views\PluginBase. + * Contains \Drupal\views\Plugin\views\PluginBase. */ namespace Drupal\views\Plugin\views; use Drupal\Component\Utility\String; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Plugin\PluginBase as ComponentPluginBase; use Drupal\Core\Render\Element; @@ -44,6 +45,13 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactoryPluginInterface { /** + * Include negotiated languages when listing languages. + * + * @see \Drupal\views\Plugin\views\PluginBase::listLanguages() + */ + const INCLUDE_NEGOTIATED = 16; + + /** * Options for this plugin will be held here. * * @var array @@ -439,4 +447,86 @@ public function getDependencies() { return array(); } + /** + * Makes an array of languages, optionally including special languages. + * + * @param int $flags + * (optional) Flags for which languages to return (additive). Options: + * - \Drupal\Core\Language::STATE_ALL (default): All languages + * (configurable and default). + * - \Drupal\Core\Language::STATE_CONFIGURABLE: Configurable languages. + * - \Drupal\Core\Language::STATE_LOCKED: Locked languages. + * - \Drupal\Core\Language::STATE_SITE_DEFAULT: Add site default language; + * note that this is not included in STATE_ALL. + * - \Drupal\views\Plugin\views\PluginBase::INCLUDE_NEGOTIATED: Add + * negotiated language types. + * + * @return array + * An array of language names, keyed by the language code. Negotiated and + * special languages have special codes that are substituted in queries by + * static::queryLanguageSubstitutions(). + */ + protected function listLanguages($flags = LanguageInterface::STATE_ALL) { + $manager = \Drupal::languageManager(); + $list = array(); + + // The Language Manager class takes care of the STATE_SITE_DEFAULT case. + // It comes in with ID set to 'site_default'. Since this is not a real + // language, surround it by '***LANGUAGE_...***', like the negotiated + // languages below. + $languages = $manager->getLanguages($flags); + foreach ($languages as $id => $language) { + if ($id == 'site_default') { + $id = '***LANGUAGE_' . $id . '***'; + } + $list[$id] = t($language->name); + } + + // Add in negotiated languages, if requested. + if ($flags & PluginBase::INCLUDE_NEGOTIATED) { + $types = $manager->getDefinedLanguageTypesInfo(); + foreach ($types as $id => $type) { + // Omit unnamed types. These are things like language_url, which are + // not configurable and do not need to be in this list. And surround + // IDs by '***LANGUAGE_...***', to avoid query collisions. + if (isset($type['name'])) { + $id = '***LANGUAGE_' . $id . '***'; + $list[$id] = t('Language selected for !type', array('!type' => $type['name'])); + } + } + } + + return $list; + } + + /** + * Returns substitutions for Views queries for languages. + * + * This is needed so that the language options returned by + * $this->listLanguages() are able to be used in queries. It is called + * by the Views module implementation of hook_views_query_substitutions() + * to get the language-related substitutions. + * + * @return array + * An array in the format of hook_views_query_substitutions() that gives + * the query substitutions needed for the special language types. + */ + public static function queryLanguageSubstitutions() { + $changes = array(); + $manager = \Drupal::languageManager(); + + // Handle default language. + $default = $manager->getDefaultLanguage()->id; + $changes['***LANGUAGE_site_default***'] = $default; + + // Handle negotiated languages. + $types = $manager->getDefinedLanguageTypesInfo(); + foreach ($types as $id => $type) { + if (isset($type['name'])) { + $changes['***LANGUAGE_' . $id . '***'] = $manager->getCurrentLanguage($id)->id; + } + } + + return $changes; + } } diff --git a/core/modules/views/src/Plugin/views/argument/LanguageArgument.php b/core/modules/views/src/Plugin/views/argument/LanguageArgument.php index c73ca6b..f6b9687 100644 --- a/core/modules/views/src/Plugin/views/argument/LanguageArgument.php +++ b/core/modules/views/src/Plugin/views/argument/LanguageArgument.php @@ -46,7 +46,7 @@ function title() { * language was not found. */ function language($langcode) { - $languages = views_language_list(); + $languages = $this->listLanguages(); return isset($languages[$langcode]) ? $languages[$langcode] : t('Unknown language'); } diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php index 31f30bc..3ab78fd 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php @@ -579,7 +579,7 @@ protected function defineOptions() { 'bool' => TRUE, ), 'field_langcode' => array( - 'default' => '***CURRENT_LANGUAGE***', + 'default' => LanguageInterface::TYPE_CONTENT, ), 'field_langcode_add_to_query' => array( 'default' => TRUE, @@ -1245,19 +1245,13 @@ public function optionsSummary(&$categories, &$options) { 'desc' => t('Allow to set some advanced settings for the query plugin'), ); - $languages = array( - '***CURRENT_LANGUAGE***' => t("Current user's language"), - '***DEFAULT_LANGUAGE***' => t("Default site language"), - LanguageInterface::LANGCODE_NOT_SPECIFIED => t('Language neutral'), - ); - if (\Drupal::moduleHandler()->moduleExists('language')) { - $languages = array_merge($languages, language_list()); - } + $language_options = $this->listLanguages(LanguageInterface::STATE_ALL | LanguageInterface::STATE_SITE_DEFAULT | PluginBase::INCLUDE_NEGOTIATED); + $options['field_langcode'] = array( 'category' => 'other', 'title' => t('Field Language'), - 'value' => $languages[$this->getOption('field_langcode')], - 'desc' => t('All fields which support translations will be displayed in the selected language.'), + 'value' => $language_options[$this->getOption('field_langcode')], + 'desc' => t('All fields that support translations will be displayed in the selected language.'), ); $access_plugin = $this->getPlugin('access'); @@ -1619,12 +1613,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // an entity base table. Also, we make sure that there's at least one // entity type with a translation handler attached. if (in_array($this->view->storage->get('base_table'), $translatable_entity_tables)) { - $languages = array( - '***CURRENT_LANGUAGE***' => t("Current user's language"), - '***DEFAULT_LANGUAGE***' => t("Default site language"), - LanguageInterface::LANGCODE_NOT_SPECIFIED => t('Language neutral'), - ); - $languages = array_merge($languages, views_language_list()); + $languages = $this->listLanguages(LanguageInterface::STATE_ALL | LanguageInterface::STATE_SITE_DEFAULT | PluginBase::INCLUDE_NEGOTIATED); $form['field_langcode'] = array( '#type' => 'select', diff --git a/core/modules/views/src/Plugin/views/filter/LanguageFilter.php b/core/modules/views/src/Plugin/views/filter/LanguageFilter.php index 8b08f33..67d6a4f 100644 --- a/core/modules/views/src/Plugin/views/filter/LanguageFilter.php +++ b/core/modules/views/src/Plugin/views/filter/LanguageFilter.php @@ -7,6 +7,9 @@ namespace Drupal\views\Plugin\views\filter; +use Drupal\Core\Language\LanguageInterface; +use Drupal\views\Plugin\views\PluginBase; + /** * Provides filtering by language. * @@ -16,16 +19,13 @@ */ class LanguageFilter extends InOperator { + /** + * {@inheritdoc} + */ public function getValueOptions() { if (!isset($this->value_options)) { $this->value_title = t('Language'); - $languages = array( - '***CURRENT_LANGUAGE***' => t("Current user's language"), - '***DEFAULT_LANGUAGE***' => t("Default site language"), - ); - $languages = array_merge($languages, views_language_list()); - $this->value_options = $languages; + $this->value_options = $this->listLanguages(LanguageInterface::STATE_ALL |LanguageInterface::STATE_SITE_DEFAULT | PluginBase::INCLUDE_NEGOTIATED); } } - } diff --git a/core/modules/views/views.api.php b/core/modules/views/views.api.php index e5c8c50..6527b2d 100644 --- a/core/modules/views/views.api.php +++ b/core/modules/views/views.api.php @@ -569,8 +569,8 @@ function hook_views_query_substitutions(ViewExecutable $view) { return array( '***CURRENT_VERSION***' => \Drupal::VERSION, '***CURRENT_TIME***' => REQUEST_TIME, - '***CURRENT_LANGUAGE***' => \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->id, - '***DEFAULT_LANGUAGE***' => \Drupal::languageManager()->getDefaultLanguage()->id, + LanguageInterface::TYPE_CONTENT => \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->id, + 'site_default' => \Drupal::languageManager()->getDefaultLanguage()->id, ); } diff --git a/core/modules/views/views.module b/core/modules/views/views.module index 3294836..8ecf065 100644 --- a/core/modules/views/views.module +++ b/core/modules/views/views.module @@ -13,7 +13,6 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Database\Query\AlterableInterface; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Render\Element; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\views\Plugin\Derivative\ViewsLocalTask; @@ -481,34 +480,6 @@ function views_add_contextual_links(&$render_element, $location, ViewExecutable } /** - * Prepares a list of language names. - * - * This is a wrapper around \Drupal::languageManager()->getLanguages() to return - * a plain key value array. - * - * @param string $field - * The field of the language object which should be used as the value of the - * array. - * @param int $flags - * (optional) Specifies the state of the languages that have to be returned. - * It can be: LanguageInterface::STATE_CONFIGURABLE, - * LanguageInterface::STATE_LOCKED, LanguageInterface::STATE_ALL. - * - * @return array - * An array of language names (or $field) keyed by the langcode. - * - * @see locale_language_list() - */ -function views_language_list($field = 'name', $flags = LanguageInterface::STATE_ALL) { - $languages = \Drupal::languageManager()->getLanguages($flags); - $list = array(); - foreach ($languages as $language) { - $list[$language->id] = ($field == 'name') ? t($language->name) : $language->$field; - } - return $list; -} - -/** * Implements hook_ENTITY_TYPE_create() for 'field_instance_config'. */ function views_field_instance_config_create(FieldInstanceConfigInterface $field_instance) { diff --git a/core/modules/views/views.views_execution.inc b/core/modules/views/views.views_execution.inc index 96b5006..4796f6c 100644 --- a/core/modules/views/views.views_execution.inc +++ b/core/modules/views/views.views_execution.inc @@ -5,19 +5,23 @@ * Provides views runtime hooks for views.module. */ -use Drupal\Core\Language\LanguageInterface; use Drupal\views\ViewExecutable; +use Drupal\views\Plugin\views\PluginBase; /** * Implements hook_views_query_substitutions(). * - * Substitute current time; this works with cached queries. + * Makes the following substitutions: + * - Current time; this works with cached queries. + * - Drupal version. + * - Special language codes; see + * \Drupal\views\Plugin\views\PluginBase::listLanguages(). */ function views_views_query_substitutions(ViewExecutable $view) { - return array( + $substitutions = array( '***CURRENT_VERSION***' => \Drupal::VERSION, '***CURRENT_TIME***' => REQUEST_TIME, - '***CURRENT_LANGUAGE***' => \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->id, - '***DEFAULT_LANGUAGE***' => \Drupal::languageManager()->getDefaultLanguage()->id, - ); + ) + PluginBase::queryLanguageSubstitutions(); + + return $substitutions; } diff --git a/core/modules/views_ui/src/Tests/ViewEditTest.php b/core/modules/views_ui/src/Tests/ViewEditTest.php index b88ed43..77db0a3 100644 --- a/core/modules/views_ui/src/Tests/ViewEditTest.php +++ b/core/modules/views_ui/src/Tests/ViewEditTest.php @@ -94,7 +94,7 @@ public function testEditFormOtherOptions() { $this->drupalGet('admin/structure/views/view/test_view'); $langcode_url = 'admin/structure/views/nojs/display/test_view/default/field_langcode'; $this->assertLinkByHref($langcode_url); - $this->assertLink(t("Current user's language")); + $this->assertLink(t('Language selected for !type', array('!type' => t('Content')))); // Click the link and check the form before language is added. $this->drupalGet($langcode_url); $this->assertResponse(200); @@ -106,7 +106,7 @@ public function testEditFormOtherOptions() { $this->drupalGet('admin/structure/views/nojs/display/test_display/page_1/field_langcode'); $this->assertResponse(200); - $this->assertFieldByName('field_langcode', '***CURRENT_LANGUAGE***'); + $this->assertFieldByName('field_langcode', 'language_content'); $this->assertFieldByName('field_langcode_add_to_query', TRUE); }