diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php index e4b41b8..9590d8d 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php @@ -122,9 +122,11 @@ protected function viewValue(FieldItemInterface $item) { // storage by LanguageManager::getLanguages()) or in its native language // name. That only depends on formatter settings and no language condition. $languages = $this->getSetting('native_language') ? $this->languageManager->getNativeLanguages(LanguageInterface::STATE_ALL) : $this->languageManager->getLanguages(LanguageInterface::STATE_ALL); - return [ - '#plain_text' => $item->language && isset($languages[$item->language->getId()]) ? $languages[$item->language->getId()]->getName() : '' - ]; + // Values like \Drupal\Core\Language\LanguageInterface::LANGCODE_NOT_SPECIFIED + // and \Drupal\Core\Language\LanguageInterface::LANGCODE_NOT_APPLICABLE are + // not returned from the language manager above. + $name = isset($languages[$item->language->getId()]) ? $languages[$item->language->getId()]->getName() : $item->language->getId(); + return $item->language ? ['#plain_text' => $name] : ''; } } diff --git a/core/modules/node/config/optional/views.view.content.yml b/core/modules/node/config/optional/views.view.content.yml index 526c484..349871c 100644 --- a/core/modules/node/config/optional/views.view.content.yml +++ b/core/modules/node/config/optional/views.view.content.yml @@ -60,10 +60,8 @@ display: name: name status: status changed: changed - edit_node: edit_node - delete_node: delete_node - dropbutton: dropbutton - timestamp: title + langcode: langcode + operations: operations info: node_bulk_form: align: '' @@ -105,28 +103,14 @@ display: separator: '' empty_column: false responsive: priority-low - edit_node: + langcode: sortable: false default_sort_order: asc align: '' separator: '' empty_column: false responsive: '' - delete_node: - sortable: false - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - dropbutton: - sortable: false - default_sort_order: asc - align: '' - separator: '' - empty_column: false - responsive: '' - timestamp: + operations: sortable: false default_sort_order: asc align: '' @@ -302,6 +286,72 @@ display: plugin_id: field entity_type: node entity_field: changed + langcode: + id: langcode + table: node_field_data + field: langcode + relationship: none + group_type: group + admin_label: '' + label: Language + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: true + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: language + settings: + link_to_entity: false + native_language: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: node + entity_field: langcode + plugin_id: field operations: id: operations table: node diff --git a/core/modules/node/src/Tests/NodeAdminTest.php b/core/modules/node/src/Tests/NodeAdminTest.php index 8484421..dfa9488 100644 --- a/core/modules/node/src/Tests/NodeAdminTest.php +++ b/core/modules/node/src/Tests/NodeAdminTest.php @@ -7,6 +7,8 @@ namespace Drupal\node\Tests; +use Drupal\Core\Language\Language; +use Drupal\language\Entity\ConfigurableLanguage; use Drupal\user\RoleInterface; /** @@ -204,6 +206,62 @@ function testContentAdminPages() { $this->assertLinkByHref('node/' . $node->id() . '/edit'); $this->assertLinkByHref('node/' . $node->id() . '/delete'); } + + // Ensure that both the language table column as well as the language + // exposed filter are just visible on multilingual sites. + $this->assertNoFieldByName('langcode'); + $this->assertEqual(0, count($this->cssSelect('td.views-field-langcode'))); + $this->assertEqual(0, count($this->cssSelect('td.views-field-langcode'))); + } + + public function testContentAdminPageMultilingual() { + $this->drupalLogin($this->adminUser); + + \Drupal::service('module_installer')->install(['language']); + ConfigurableLanguage::create([ + 'id' => 'es', + 'label' => 'Spain', + ])->save(); + + $node = $this->drupalCreateNode(['type' => 'page', 'title' => 'English title']); + $node = $node->addTranslation('es'); + $node->title[0]->value = 'Spain title'; + $node->save(); + + $this->drupalGet('admin/content'); + + // Ensure that both the language table column as well as the language + // exposed filter are visible on multilingual sites. + $this->assertFieldByName('langcode'); + $this->assertEqual(2, count($this->cssSelect('td.views-field-langcode'))); + $this->assertEqual(2, count($this->cssSelect('td.views-field-langcode'))); + + $this->assertText('English title'); + $this->assertText('Spain title'); + + $this->drupalGet('admin/content', ['query' => ['langcode' => '***LANGUAGE_site_default***']]); + $this->assertText('English title'); + $this->assertNoText('Spain title'); + + $this->drupalGet('admin/content', ['query' => ['langcode' => 'en']]); + $this->assertText('English title'); + $this->assertNoText('Spain title'); + + $this->drupalGet('admin/content', ['query' => ['langcode' => 'und']]); + $this->assertNoText('English title'); + $this->assertNoText('Spain title'); + + $this->drupalGet('admin/content', ['query' => ['langcode' => 'zxx']]); + $this->assertNoText('English title'); + $this->assertNoText('Spain title'); + + $this->drupalGet('admin/content', ['query' => ['langcode' => html_entity_decode('***LANGUAGE_language_interface***')]]); + $this->assertText('English title'); + $this->assertNoText('Spain title'); + + $this->drupalGet('es/admin/content', ['query' => ['langcode' => html_entity_decode('***LANGUAGE_language_interface***')]]); + $this->assertNoText('English title'); + $this->assertText('Spain title'); } } diff --git a/core/modules/user/src/Tests/Views/UserViewsFieldAccessTest.php b/core/modules/user/src/Tests/Views/UserViewsFieldAccessTest.php index f3e4dc7..0356143 100644 --- a/core/modules/user/src/Tests/Views/UserViewsFieldAccessTest.php +++ b/core/modules/user/src/Tests/Views/UserViewsFieldAccessTest.php @@ -34,10 +34,6 @@ protected function setUp($import_test_views = TRUE) { public function testUserFields() { ConfigurableLanguage::create([ - 'id' => 'es', - 'name' => 'Spanish', - ])->save(); - ConfigurableLanguage::create([ 'id' => 'fr', 'name' => 'French', ])->save(); diff --git a/core/modules/views/src/EntityViewsData.php b/core/modules/views/src/EntityViewsData.php index 4dc23d8..43fde0c 100644 --- a/core/modules/views/src/EntityViewsData.php +++ b/core/modules/views/src/EntityViewsData.php @@ -392,7 +392,7 @@ protected function mapSingleFieldViewsData($table, $field_name, $field_type, $co break; case 'language': - $views_field['field']['id'] = 'field'; + $views_field['field']['id'] = 'field_language'; $views_field['argument']['id'] = 'language'; $views_field['filter']['id'] = 'language'; $views_field['sort']['id'] = 'standard'; diff --git a/core/modules/views/src/Plugin/views/field/FieldLanguage.php b/core/modules/views/src/Plugin/views/field/FieldLanguage.php new file mode 100644 index 0000000..4a8117a --- /dev/null +++ b/core/modules/views/src/Plugin/views/field/FieldLanguage.php @@ -0,0 +1,34 @@ +languageManager->isMultilingual()) { + return FALSE; + } + + return parent::access($account); + } + +} diff --git a/core/modules/views/src/Plugin/views/filter/LanguageFilter.php b/core/modules/views/src/Plugin/views/filter/LanguageFilter.php index f7eefb9..e6b0e76 100644 --- a/core/modules/views/src/Plugin/views/filter/LanguageFilter.php +++ b/core/modules/views/src/Plugin/views/filter/LanguageFilter.php @@ -10,6 +10,7 @@ use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Session\AccountInterface; use Drupal\views\Plugin\views\PluginBase; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -75,13 +76,14 @@ public function getValueOptions() { /** * {@inheritdoc} */ - public function query() { - // Don't filter by language in case the site is not multilingual, because + public function access(AccountInterface $account) { + // Don't display the filter in case the site is not multilingual, because // there is no point in doing so. if (!$this->languageManager->isMultilingual()) { - return; + return FALSE; } - parent::query(); + return parent::access($account); } + } diff --git a/core/modules/views/src/Tests/Handler/FieldFieldAccessTestBase.php b/core/modules/views/src/Tests/Handler/FieldFieldAccessTestBase.php index 48bd00c..12bac83 100644 --- a/core/modules/views/src/Tests/Handler/FieldFieldAccessTestBase.php +++ b/core/modules/views/src/Tests/Handler/FieldFieldAccessTestBase.php @@ -7,6 +7,7 @@ namespace Drupal\views\Tests\Handler; +use Drupal\language\Entity\ConfigurableLanguage; use Drupal\user\Entity\Role; use Drupal\user\Entity\User; use Drupal\views\Entity\View; @@ -35,7 +36,7 @@ /** * {@inheritdoc} */ - public static $modules = ['user']; + public static $modules = ['user', 'language']; /** * {@inheritdoc} @@ -43,6 +44,10 @@ protected function setUp($import_test_views = TRUE) { parent::setUp($import_test_views); + // Make the site at least multilingual to have a working language field + // handler. + ConfigurableLanguage::create(['id' => 'es', 'title' => 'Spain title'])->save(); + $this->installEntitySchema('user'); $role_with_access = Role::create([ diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php index 67771b5..46055bf 100644 --- a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php +++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php @@ -909,7 +909,7 @@ protected function assertNumericField($data) { * The views data to check. */ protected function assertLanguageField($data) { - $this->assertEquals('field', $data['field']['id']); + $this->assertEquals('field_language', $data['field']['id']); $this->assertEquals('language', $data['filter']['id']); $this->assertEquals('language', $data['argument']['id']); $this->assertEquals('standard', $data['sort']['id']);