From 900784f7fed019cc6c8d9d6b928ad367fc42535e Mon Sep 17 00:00:00 2001
From: Dries <dries@buytaert.net>
Date: Fri, 25 Jul 2014 12:18:22 -0400
Subject: [PATCH] Issue #2217943 by jhodgdon, Wim Leers: Views cannot be
 filtered by language of translation.

---
 core/modules/node/node.views.inc              |  25 +-
 .../node/src/Tests/Views/NodeLanguageTest.php | 146 ++++++++
 .../test_views/views.view.test_language.yml   | 314 ++++++++++++++++++
 3 files changed, 482 insertions(+), 3 deletions(-)
 create mode 100644 core/modules/node/src/Tests/Views/NodeLanguageTest.php
 create mode 100644 core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml

diff --git a/core/modules/node/node.views.inc b/core/modules/node/node.views.inc
index b4ef77cc74e5..9243adf5ab1b 100644
--- a/core/modules/node/node.views.inc
+++ b/core/modules/node/node.views.inc
@@ -126,6 +126,25 @@ function node_views_data() {
     ),
   );
 
+  if (\Drupal::moduleHandler()->moduleExists('language')) {
+    $data['node_field_data']['langcode'] = array(
+      'title' => t('Translation language'),
+      'help' => t('The language of the content or translation.'),
+      'field' => array(
+        'id' => 'node_language',
+      ),
+      'filter' => array(
+        'id' => 'language',
+      ),
+      'argument' => array(
+        'id' => 'language',
+      ),
+      'sort' => array(
+        'id' => 'standard',
+      ),
+    );
+  }
+
   $data['node_field_data']['status'] = array(
     'title' => t('Published status'),
     'help' => t('Whether or not the content is published.'),
@@ -466,8 +485,8 @@ function node_views_data() {
 
   if (\Drupal::moduleHandler()->moduleExists('language')) {
     $data['node_revision']['langcode'] = array(
-      'title' => t('Language'),
-      'help' => t('The language the content is in.'),
+      'title' => t('Original language'),
+      'help' => t('The language the original content is in.'),
       'field' => array(
         'id' => 'node_language',
       ),
@@ -564,7 +583,7 @@ function node_views_data() {
 
   $data['node_field_revision']['changed'] = array(
     'title' => t('Updated date'),
-    'help' => t('The date the node was last updated.'),
+    'help' => t('The date the content was last updated.'),
     'field' => array(
       'id' => 'date',
     ),
diff --git a/core/modules/node/src/Tests/Views/NodeLanguageTest.php b/core/modules/node/src/Tests/Views/NodeLanguageTest.php
new file mode 100644
index 000000000000..fa394b23a2c6
--- /dev/null
+++ b/core/modules/node/src/Tests/Views/NodeLanguageTest.php
@@ -0,0 +1,146 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\node\Tests\Views\NodeLanguageTest.
+ */
+
+namespace Drupal\node\Tests\Views;
+
+use Drupal\Core\Language\Language;
+use Drupal\field\Entity\FieldStorageConfig;
+
+/**
+ * Tests node language fields, filters, and sorting.
+ *
+ * @group node
+ */
+class NodeLanguageTest extends NodeTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = array('language');
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = array('test_language');
+
+  /**
+   * List of node titles by language.
+   *
+   * @var array
+   */
+  public $node_titles = array();
+
+  /**
+   * {@inheritdoc}
+   */
+  function setUp() {
+    parent::setUp();
+
+    // Create Page content type.
+    if ($this->profile != 'standard') {
+      $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
+    }
+
+    // Add two new languages.
+    $language = new Language(array(
+      'id' => 'fr',
+      'name' => 'French',
+    ));
+    language_save($language);
+
+    $language = new Language(array(
+      'id' => 'es',
+      'name' => 'Spanish',
+    ));
+    language_save($language);
+
+    // Make the body field translatable. The title is already translatable by
+    // definition.
+    $field = FieldStorageConfig::loadByName('node', 'body');
+    $field->translatable = TRUE;
+    $field->save();
+
+    // Set up node titles. They should not include the words "French",
+    // "English", or "Spanish", as there is a language field in the view
+    // that prints out those words.
+    $this->node_titles = array(
+      'en' => array(
+        'First node en',
+        'Second node en',
+      ),
+      'es' => array(
+        'Primero nodo es',
+        'Segundo nodo es',
+      ),
+      'fr' => array(
+        'Premier nodule fr',
+      )
+    );
+
+    // Create nodes with translations.
+    foreach ($this->node_titles['en'] as $index => $title) {
+      $node = $this->drupalCreateNode(array('title' => $title, 'langcode' => 'en', 'type' => 'page'));
+      foreach (array('es', 'fr') as $langcode) {
+        if (isset($this->node_titles[$langcode][$index])) {
+          $translation = $node->addTranslation($langcode, array('title' => $this->node_titles[$langcode][$index]));
+          $translation->body->value = $this->randomName(32);
+        }
+      }
+      $node->save();
+    }
+  }
+
+  /**
+   * Tests translation language filter, field, and sort.
+   */
+  public function testLanguages() {
+    // Test the page with no arguments. It is filtered to Spanish and French.
+    // The page shows node titles and languages.
+    $this->drupalGet('test-language');
+    $message = 'French/Spanish page';
+
+    // Test that the correct nodes are shown.
+    foreach ($this->node_titles as $langcode => $list) {
+      foreach ($list as $title) {
+        if ($langcode == 'en') {
+          $this->assertNoText($title, $title . ' does not appear on ' . $message);
+        }
+        else {
+          $this->assertText($title, $title . ' does appear on ' . $message);
+        }
+      }
+    }
+
+    // Test that the language field value is shown.
+    $this->assertNoText('English', 'English language is not shown on ' . $message);
+    $this->assertText('French', 'French language is shown on ' . $message);
+    $this->assertText('Spanish', 'Spanish language is shown on ' . $message);
+
+    // Test page sorting, which is by language code, ascending. So the
+    // Spanish nodes should appear before the French nodes.
+    $page = $this->getTextContent();
+    $pos_es_max = 0;
+    $pos_fr_min = 10000;
+    foreach ($this->node_titles['es'] as $title) {
+      $pos_es_max = max($pos_es_max, strpos($page, $title));
+    }
+    foreach ($this->node_titles['fr'] as $title) {
+      $pos_fr_min = min($pos_fr_min, strpos($page, $title));
+    }
+    $this->assertTrue($pos_es_max < $pos_fr_min, 'Spanish translations appear before French on ' . $message);
+
+    // Test the argument -- filter to just Spanish.
+    $this->drupalGet('test-language/es');
+    // This time, test just the language field.
+    $message = 'Spanish argument page';
+    $this->assertNoText('English', 'English language is not shown on ' . $message);
+    $this->assertNoText('French', 'French language is not shown on ' . $message);
+    $this->assertText('Spanish', 'Spanish language is shown on ' . $message);
+  }
+}
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
new file mode 100644
index 000000000000..68fb2d53efb8
--- /dev/null
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml
@@ -0,0 +1,314 @@
+uuid: 28125171-5b31-4943-9e00-ec0a9ceb0c1a
+langcode: en
+status: true
+dependencies:
+  module:
+    - node
+id: test_language
+label: 'Test language'
+module: views
+description: ''
+tag: ''
+base_table: node
+base_field: nid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    provider: views
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+        provider: user
+        dependencies: {  }
+      cache:
+        type: none
+        options: {  }
+        provider: views
+        dependencies: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: false
+          query_tags: {  }
+        provider: views
+        dependencies: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+        provider: views
+        dependencies: {  }
+      pager:
+        type: none
+        options:
+          items_per_page: 0
+          offset: 0
+      style:
+        type: default
+      row:
+        type: fields
+        options:
+          default_field_elements: true
+          inline: {  }
+          separator: ''
+          hide_empty: false
+        provider: views
+      fields:
+        title:
+          id: title
+          table: node_field_data
+          field: title
+          relationship: none
+          group_type: group
+          admin_label: ''
+          dependencies:
+            module:
+              - node
+          label: ''
+          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: ''
+            word_boundary: false
+            ellipsis: false
+            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: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          link_to_node: 0
+          provider: node
+        langcode:
+          id: langcode
+          table: node_field_data
+          field: langcode
+          relationship: none
+          group_type: group
+          admin_label: ''
+          dependencies:
+            module:
+              - node
+          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: ''
+            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: false
+          empty_zero: false
+          hide_alter_empty: true
+          link_to_node: false
+          native_language: 0
+          plugin_id: node_language
+          provider: node
+      filters:
+        status:
+          value: true
+          table: node_field_data
+          field: status
+          provider: node
+          id: status
+          expose:
+            operator: ''
+          group: 1
+        type:
+          id: type
+          table: node_field_data
+          field: type
+          value:
+            page: page
+        langcode:
+          id: langcode
+          table: node_field_data
+          field: langcode
+          relationship: none
+          group_type: group
+          admin_label: ''
+          dependencies:
+            module:
+              - views
+              - views
+              - views
+              - views
+          operator: in
+          value:
+            fr: fr
+            es: es
+          group: 1
+          exposed: false
+          expose:
+            operator_id: ''
+            label: ''
+            description: ''
+            use_operator: false
+            operator: ''
+            identifier: ''
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+            reduce: false
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          plugin_id: language
+          provider: views
+      sorts:
+        langcode:
+          id: langcode
+          table: node_field_data
+          field: langcode
+          relationship: none
+          group_type: group
+          admin_label: ''
+          dependencies:
+            module:
+              - views
+              - views
+          order: ASC
+          exposed: false
+          expose:
+            label: ''
+          plugin_id: standard
+          provider: views
+      title: 'Language filter test'
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments:
+        langcode:
+          id: langcode
+          table: node_field_data
+          field: langcode
+          relationship: none
+          group_type: group
+          admin_label: ''
+          dependencies:
+            module:
+              - views
+          default_action: ignore
+          exception:
+            value: all
+            title_enable: false
+            title: All
+          title_enable: false
+          title: ''
+          default_argument_type: fixed
+          default_argument_options:
+            argument: ''
+          default_argument_skip_url: false
+          summary_options:
+            base_path: ''
+            count: true
+            items_per_page: 25
+            override: false
+          summary:
+            sort_order: asc
+            number_of_records: 0
+            format: default_summary
+          specify_validation: false
+          validate:
+            type: none
+            fail: 'not found'
+          validate_options: {  }
+          plugin_id: language
+          provider: views
+      field_langcode: '***CURRENT_LANGUAGE***'
+      field_langcode_add_to_query: null
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: 1
+    provider: views
+    display_options:
+      field_langcode: '***CURRENT_LANGUAGE***'
+      field_langcode_add_to_query: null
+      path: test-language
-- 
GitLab