summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwebchick2014-08-30 05:17:55 (GMT)
committerwebchick2014-08-30 05:17:55 (GMT)
commit6f9fc447bb224449d07179743248168e0888a7b6 (patch)
tree592f0f8cb71f797f5441e0179df0417102059f58
parent84dfd06d5974310e50060d53a1a19c117be752f6 (diff)
Issue #2037979 by Gábor Hojtsy, Sweetchuck, jhodgdon, dawehner: Fixed 'Current user's language' views filter label is named very misleading.
-rw-r--r--core/lib/Drupal/Core/Language/LanguageManager.php29
-rw-r--r--core/lib/Drupal/Core/Language/LanguageManagerInterface.php21
-rw-r--r--core/modules/comment/config/install/views.view.comments_recent.yml4
-rw-r--r--core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_field_filters.yml10
-rw-r--r--core/modules/field/src/Plugin/views/field/Field.php31
-rw-r--r--core/modules/language/src/ConfigurableLanguageManagerInterface.php13
-rw-r--r--core/modules/node/config/install/views.view.content.yml4
-rw-r--r--core/modules/node/config/install/views.view.frontpage.yml8
-rw-r--r--core/modules/node/src/Tests/Views/NodeLanguageTest.php47
-rw-r--r--core/modules/node/tests/modules/node_test_views/test_views/views.view.test_field_filters.yml10
-rw-r--r--core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml4
-rw-r--r--core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_field_filters.yml14
-rw-r--r--core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_tid_field.yml2
-rw-r--r--core/modules/views/src/Plugin/views/PluginBase.php92
-rw-r--r--core/modules/views/src/Plugin/views/argument/LanguageArgument.php2
-rw-r--r--core/modules/views/src/Plugin/views/display/DisplayPluginBase.php23
-rw-r--r--core/modules/views/src/Plugin/views/filter/LanguageFilter.php14
-rw-r--r--core/modules/views/views.api.php12
-rw-r--r--core/modules/views/views.module29
-rw-r--r--core/modules/views/views.views_execution.inc16
-rw-r--r--core/modules/views_ui/src/Tests/ViewEditTest.php4
21 files changed, 261 insertions, 128 deletions
diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php
index 88e2363..d86789e 100644
--- a/core/lib/Drupal/Core/Language/LanguageManager.php
+++ b/core/lib/Drupal/Core/Language/LanguageManager.php
@@ -81,6 +81,31 @@ class LanguageManager implements LanguageManagerInterface {
/**
* {@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' => $this->t('User interface text'),
+ 'description' => $this->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' => $this->t('Content'),
+ 'description' => $this->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 @@ class LanguageManager implements LanguageManagerInterface {
// 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 @@ interface LanguageManagerInterface {
* 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 a42f4c2..0bd93b2 100644
--- a/core/modules/field/src/Plugin/views/field/Field.php
+++ b/core/modules/field/src/Plugin/views/field/Field.php
@@ -289,20 +289,18 @@ class Field extends FieldPluginBase {
$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));
@@ -917,12 +915,11 @@ class Field extends FieldPluginBase {
*/
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 @@ interface ConfigurableLanguageManagerInterface extends LanguageManagerInterface
* 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..3a3dbcb 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 @@ class NodeLanguageTest extends NodeTestBase {
}
}
}
+
+ // 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 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
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 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
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 @@ class LanguageArgument extends ArgumentPluginBase {
* 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..7d3232f 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 @@ abstract class DisplayPluginBase extends PluginBase {
'bool' => TRUE,
),
'field_langcode' => array(
- 'default' => '***CURRENT_LANGUAGE***',
+ 'default' => '***LANGUAGE_language_content***',
),
'field_langcode_add_to_query' => array(
'default' => TRUE,
@@ -1245,19 +1245,13 @@ abstract class DisplayPluginBase extends PluginBase {
'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 @@ abstract class DisplayPluginBase extends PluginBase {
// 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 @@ namespace Drupal\views\Plugin\views\filter;
*/
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 a54d562..c7e5133 100644
--- a/core/modules/views/views.api.php
+++ b/core/modules/views/views.api.php
@@ -559,20 +559,26 @@ function hook_field_views_data_views_data_alter(array &$data, \Drupal\field\Fiel
/**
* Replace special strings in the query before it is executed.
*
+ * The idea is that certain dynamic values can be placed in a query when it is
+ * built, and substituted at run-time, allowing the query to be cached and
+ * still work correctly when executed.
+ *
* @param \Drupal\views\ViewExecutable $view
* The View being executed.
+ *
* @return array
* An associative array where each key is a string to be replaced, and the
* corresponding value is its replacement. The strings to replace are often
- * surrounded with '***', as illustrated in the example implementation.
+ * surrounded with '***', as illustrated in the example implementation, to
+ * avoid collisions with other values in the query.
*/
function hook_views_query_substitutions(ViewExecutable $view) {
// Example from views_views_query_substitutions().
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,
+ '***LANGUAGE_language_content***' => \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->id,
+ '***LANGUAGE_site_default***' => \Drupal::languageManager()->getDefaultLanguage()->id,
);
}
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index 459ff0a..5a30bf0 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -13,7 +13,6 @@ use Drupal\Component\Utility\String;
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;
@@ -468,34 +467,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..91dead5 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.
+ * - 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..62036f1 100644
--- a/core/modules/views_ui/src/Tests/ViewEditTest.php
+++ b/core/modules/views_ui/src/Tests/ViewEditTest.php
@@ -94,7 +94,7 @@ class ViewEditTest extends UITestBase {
$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 @@ class ViewEditTest extends UITestBase {
$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_language_content***');
$this->assertFieldByName('field_langcode_add_to_query', TRUE);
}