Commit 6f9fc447 authored by webchick's avatar webchick

Issue #2037979 by Gábor Hojtsy, Sweetchuck, jhodgdon, dawehner: Fixed 'Current...

Issue #2037979 by Gábor Hojtsy, Sweetchuck, jhodgdon, dawehner: Fixed 'Current user's language' views filter label is named very misleading.
parent 84dfd06d
...@@ -78,6 +78,31 @@ public function getLanguageTypes() { ...@@ -78,6 +78,31 @@ public function getLanguageTypes() {
return array(LanguageInterface::TYPE_INTERFACE, LanguageInterface::TYPE_CONTENT, LanguageInterface::TYPE_URL); return array(LanguageInterface::TYPE_INTERFACE, LanguageInterface::TYPE_CONTENT, LanguageInterface::TYPE_URL);
} }
/**
* {@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} * {@inheritdoc}
*/ */
...@@ -120,7 +145,9 @@ public function getLanguages($flags = LanguageInterface::STATE_CONFIGURABLE) { ...@@ -120,7 +145,9 @@ public function getLanguages($flags = LanguageInterface::STATE_CONFIGURABLE) {
// Add the site's default language if flagged as allowed value. // Add the site's default language if flagged as allowed value.
if ($flags & LanguageInterface::STATE_SITE_DEFAULT) { if ($flags & LanguageInterface::STATE_SITE_DEFAULT) {
$default = isset($default) ? $default : $this->getDefaultLanguage(); $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)); $default->name = $this->t("Site's default language (@lang_name)", array('@lang_name' => $default->name));
$filtered_languages['site_default'] = $default; $filtered_languages['site_default'] = $default;
} }
......
...@@ -34,19 +34,32 @@ public function isMultilingual(); ...@@ -34,19 +34,32 @@ public function isMultilingual();
* Returns an array of the available language types. * Returns an array of the available language types.
* *
* @return array * @return array
* An array of language type names. * An array of language type machine names.
*/ */
public function getLanguageTypes(); 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. * Returns the current language for the given type.
* *
* @param string $type * @param string $type
* (optional) The language type, e.g. the interface or the content language. * (optional) The language type; e.g., the interface or the content
* Defaults to \Drupal\Core\Language\LanguageInterface::TYPE_INTERFACE. * language. Defaults to
* \Drupal\Core\Language\LanguageInterface::TYPE_INTERFACE.
* *
* @return \Drupal\Core\Language\LanguageInterface * @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); public function getCurrentLanguage($type = LanguageInterface::TYPE_INTERFACE);
......
...@@ -228,7 +228,7 @@ display: ...@@ -228,7 +228,7 @@ display:
content: 'No comments available.' content: 'No comments available.'
tokenize: false tokenize: false
plugin_id: text_custom plugin_id: text_custom
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
block_1: block_1:
provider: views provider: views
...@@ -239,7 +239,7 @@ display: ...@@ -239,7 +239,7 @@ display:
display_options: display_options:
block_description: 'Recent comments' block_description: 'Recent comments'
block_category: 'Lists (Views)' block_category: 'Lists (Views)'
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
allow: allow:
items_per_page: true items_per_page: true
...@@ -160,7 +160,7 @@ display: ...@@ -160,7 +160,7 @@ display:
footer: { } footer: { }
empty: { } empty: { }
arguments: { } arguments: { }
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
page_tc: page_tc:
display_plugin: page display_plugin: page
...@@ -169,7 +169,7 @@ display: ...@@ -169,7 +169,7 @@ display:
position: 1 position: 1
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
path: test-title-filter path: test-title-filter
display_description: '' display_description: ''
...@@ -180,7 +180,7 @@ display: ...@@ -180,7 +180,7 @@ display:
position: 1 position: 1
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
path: test-body-paris path: test-body-paris
display_description: '' display_description: ''
...@@ -241,7 +241,7 @@ display: ...@@ -241,7 +241,7 @@ display:
position: 1 position: 1
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
path: test-title-paris path: test-title-paris
display_description: '' display_description: ''
...@@ -301,7 +301,7 @@ display: ...@@ -301,7 +301,7 @@ display:
position: 1 position: 1
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
path: test-body-filter path: test-body-filter
display_description: '' display_description: ''
......
...@@ -289,20 +289,18 @@ public function query($use_groupby = FALSE) { ...@@ -289,20 +289,18 @@ public function query($use_groupby = FALSE) {
$this->ensureMyTable(); $this->ensureMyTable();
$this->addAdditionalFields($fields); $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; $field = $field_definition;
if ($field->isTranslatable() && !empty($this->view->display_handler->options['field_langcode_add_to_query'])) { if ($field->isTranslatable() && !empty($this->view->display_handler->options['field_langcode_add_to_query'])) {
$column = $this->tableAlias . '.langcode'; $column = $this->tableAlias . '.langcode';
// By the same reason as field_language the field might be $langcode = $this->view->display_handler->options['field_langcode'];
// LanguageInterface::LANGCODE_NOT_SPECIFIED in reality so allow it as $substitutions = static::queryLanguageSubstitutions();
// well. if (isset($substitutions[$langcode])) {
// @see this::field_langcode() $langcode = $substitutions[$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']
);
$placeholder = $this->placeholder(); $placeholder = $this->placeholder();
$langcode_fallback_candidates = $this->languageManager->getFallbackCandidates(array('langcode' => $langcode, 'operation' => 'views_query', 'data' => $this)); $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)); $this->query->addWhereExpression(0, "$column IN($placeholder) OR $column IS NULL", array($placeholder => $langcode_fallback_candidates));
...@@ -917,12 +915,11 @@ protected function addSelfTokens(&$tokens, $item) { ...@@ -917,12 +915,11 @@ protected function addSelfTokens(&$tokens, $item) {
*/ */
function field_langcode(EntityInterface $entity) { function field_langcode(EntityInterface $entity) {
if ($this->getFieldDefinition()->isTranslatable()) { if ($this->getFieldDefinition()->isTranslatable()) {
$default_langcode = language_default()->id; $langcode = $this->view->display_handler->options['field_langcode'];
$langcode = str_replace( $substitutions = static::queryLanguageSubstitutions();
array('***CURRENT_LANGUAGE***', '***DEFAULT_LANGUAGE***'), if (isset($substitutions[$langcode])) {
array($this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->id, $default_langcode), $langcode = $substitutions[$langcode];
$this->view->display_handler->options['field_langcode'] }
);
// Give the Entity Field API a chance to fallback to a different language // Give the Entity Field API a chance to fallback to a different language
// (or LanguageInterface::LANGCODE_NOT_SPECIFIED), in case the field has // (or LanguageInterface::LANGCODE_NOT_SPECIFIED), in case the field has
......
...@@ -44,21 +44,10 @@ public function setNegotiator(LanguageNegotiatorInterface $negotiator); ...@@ -44,21 +44,10 @@ public function setNegotiator(LanguageNegotiatorInterface $negotiator);
* through the user interface. * through the user interface.
* *
* @return array * @return array
* An array of language type names. * An array of language type machine names.
*/ */
public function getDefinedLanguageTypes(); 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. * Stores language types configuration.
* *
......
...@@ -536,7 +536,7 @@ display: ...@@ -536,7 +536,7 @@ display:
operator: AND operator: AND
groups: groups:
1: AND 1: AND
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
display_plugin: default display_plugin: default
display_title: Master display_title: Master
...@@ -558,7 +558,7 @@ display: ...@@ -558,7 +558,7 @@ display:
description: 'Find and manage content' description: 'Find and manage content'
menu_name: admin menu_name: admin
weight: -10 weight: -10
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
display_plugin: page display_plugin: page
display_title: Page display_title: Page
......
...@@ -130,7 +130,7 @@ display: ...@@ -130,7 +130,7 @@ display:
- views - views
operator: in operator: in
value: value:
'***CURRENT_LANGUAGE***': '***CURRENT_LANGUAGE***' '***LANGUAGE_language_content***': '***LANGUAGE_language_content***'
group: 1 group: 1
exposed: false exposed: false
expose: expose:
...@@ -240,7 +240,7 @@ display: ...@@ -240,7 +240,7 @@ display:
relationships: { } relationships: { }
fields: { } fields: { }
arguments: { } arguments: { }
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
display_plugin: default display_plugin: default
display_title: Master display_title: Master
...@@ -249,7 +249,7 @@ display: ...@@ -249,7 +249,7 @@ display:
page_1: page_1:
display_options: display_options:
path: node path: node
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
display_plugin: page display_plugin: page
display_title: Page display_title: Page
...@@ -286,5 +286,5 @@ display: ...@@ -286,5 +286,5 @@ display:
view_mode: rss view_mode: rss
links: false links: false
provider: views provider: views
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
...@@ -184,5 +184,52 @@ public function testLanguages() { ...@@ -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');
}
}
}
} }
} }
...@@ -173,7 +173,7 @@ display: ...@@ -173,7 +173,7 @@ display:
empty: { } empty: { }
relationships: { } relationships: { }
arguments: { } arguments: { }
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
page_tf: page_tf:
display_plugin: page display_plugin: page
...@@ -182,7 +182,7 @@ display: ...@@ -182,7 +182,7 @@ display:
position: 1 position: 1
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
path: test-title-filter path: test-title-filter
display_description: '' display_description: ''
...@@ -255,7 +255,7 @@ display: ...@@ -255,7 +255,7 @@ display:
position: 1 position: 1
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
path: test-body-filter path: test-body-filter
display_description: '' display_description: ''
...@@ -326,7 +326,7 @@ display: ...@@ -326,7 +326,7 @@ display:
position: 1 position: 1
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
path: test-body-paris path: test-body-paris
display_description: '' display_description: ''
...@@ -398,7 +398,7 @@ display: ...@@ -398,7 +398,7 @@ display:
position: 1 position: 1
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
path: test-title-paris path: test-title-paris
display_description: '' display_description: ''
......
...@@ -300,7 +300,7 @@ display: ...@@ -300,7 +300,7 @@ display:
validate_options: { } validate_options: { }
plugin_id: language plugin_id: language
provider: views provider: views
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
page_1: page_1:
display_plugin: page display_plugin: page
...@@ -309,6 +309,6 @@ display: ...@@ -309,6 +309,6 @@ display:
position: 1 position: 1
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
path: test-language path: test-language
...@@ -145,7 +145,7 @@ display: ...@@ -145,7 +145,7 @@ display:
empty: { } empty: { }
relationships: { } relationships: { }
arguments: { } arguments: { }
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
page_dc: page_dc:
display_plugin: page display_plugin: page
...@@ -154,7 +154,7 @@ display: ...@@ -154,7 +154,7 @@ display:
position: 3 position: 3
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
display_description: '' display_description: ''
path: test-desc-filter path: test-desc-filter
...@@ -215,7 +215,7 @@ display: ...@@ -215,7 +215,7 @@ display:
position: 3 position: 3
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
display_description: '' display_description: ''
path: test-desc-paris path: test-desc-paris
...@@ -277,7 +277,7 @@ display: ...@@ -277,7 +277,7 @@ display:
position: 1 position: 1
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
path: test-name-filter path: test-name-filter
display_description: '' display_description: ''
...@@ -288,7 +288,7 @@ display: ...@@ -288,7 +288,7 @@ display:
position: 1 position: 1
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
path: test-name-paris path: test-name-paris
display_description: '' display_description: ''
...@@ -348,7 +348,7 @@ display: ...@@ -348,7 +348,7 @@ display:
position: 3 position: 3
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
display_description: '' display_description: ''
path: test-field-paris path: test-field-paris
...@@ -410,7 +410,7 @@ display: ...@@ -410,7 +410,7 @@ display:
position: 3 position: 3
provider: views provider: views
display_options: display_options:
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
display_description: '' display_description: ''
path: test-field-filter path: test-field-filter
......
...@@ -172,5 +172,5 @@ display: ...@@ -172,5 +172,5 @@ display:
empty: { } empty: { }
relationships: { } relationships: { }
arguments: { } arguments: { }
field_langcode: '***CURRENT_LANGUAGE***' field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null field_langcode_add_to_query: null
...@@ -2,13 +2,14 @@ ...@@ -2,13 +2,14 @@
/** /**
* @file * @file
* Definition of Drupal\views\Plugin\views\PluginBase. * Contains \Drupal\views\Plugin\views\PluginBase.
*/ */
namespace Drupal\views\Plugin\views; namespace Drupal\views\Plugin\views;
use Drupal\Component\Utility\String; use Drupal\Component\Utility\String;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginBase as ComponentPluginBase; use Drupal\Core\Plugin\PluginBase as ComponentPluginBase;
use Drupal\Core\Render\Element; use Drupal\Core\Render\Element;
...@@ -43,6 +44,13 @@ ...@@ -43,6 +44,13 @@
*/ */
abstract class PluginBase extends ComponentPluginBase implements ContainerFactoryPluginInterface { 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. * Options for this plugin will be held here.
* *
...@@ -439,4 +447,86 @@ public function getDependencies() { ...@@ -439,4 +447,86 @@ public function getDependencies() {
return array(); 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);