From 0ec00a5012edb7b6e0f5acf9c7748aecdff099e3 Mon Sep 17 00:00:00 2001
From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org>
Date: Tue, 15 Mar 2016 09:32:12 +0900
Subject: [PATCH] Issue #2669590 by Lendude, joe_carvajal:
 IntegrityConstraintViolationException using an entity reference in a view
 with a entity reference display

---
 .../Plugin/views/display/EntityReference.php  |  8 ++-
 .../Plugin/DisplayEntityReferenceTest.php     | 67 +++++++++++++++++++
 2 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/core/modules/views/src/Plugin/views/display/EntityReference.php b/core/modules/views/src/Plugin/views/display/EntityReference.php
index 38d8f290bbbc..6f72ce9c6776 100644
--- a/core/modules/views/src/Plugin/views/display/EntityReference.php
+++ b/core/modules/views/src/Plugin/views/display/EntityReference.php
@@ -119,7 +119,8 @@ public function query() {
 
     // Make sure the id field is included in the results.
     $id_field = $this->view->storage->get('base_field');
-    $this->id_field_alias = $this->view->query->addField($this->view->storage->get('base_table'), $id_field);
+    $id_table = $this->view->storage->get('base_table');
+    $this->id_field_alias = $this->view->query->addField($id_table, $id_field);
 
     $options = $this->getOption('entity_reference_options');
 
@@ -139,7 +140,8 @@ public function query() {
         if (!empty($field_id)) {
           // Get the table and field names for the checked field.
           $field_handler = $this->view->field[$field_id];
-          $field_alias = $this->view->query->addField($field_handler->table, $field_handler->realField);
+          $table_alias = $this->view->query->ensureTable($field_handler->table, $field_handler->relationship);
+          $field_alias = $this->view->query->addField($table_alias, $field_handler->realField);
           $field = $this->view->query->fields[$field_alias];
           // Add an OR condition for the field.
           $conditions->condition($field['table'] . '.' . $field['field'], $value, 'LIKE');
@@ -151,7 +153,7 @@ public function query() {
 
     // Add an IN condition for validation.
     if (!empty($options['ids'])) {
-      $this->view->query->addWhere(0, $id_field, $options['ids'], 'IN');
+      $this->view->query->addWhere(0, $id_table . '.' . $id_field, $options['ids'], 'IN');
     }
 
     $this->view->setItemsPerPage($options['limit']);
diff --git a/core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php b/core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php
index 29f09f4ee2f3..43a389dbfdc6 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php
+++ b/core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php
@@ -10,6 +10,7 @@
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
 use Drupal\views\Views;
 
 /**
@@ -21,6 +22,8 @@
  */
 class DisplayEntityReferenceTest extends PluginTestBase {
 
+  use EntityReferenceTestTrait;
+
   /**
    * Views used by this test.
    *
@@ -42,6 +45,13 @@ class DisplayEntityReferenceTest extends PluginTestBase {
    */
   protected $fieldName;
 
+  /**
+   * The used entity reference field name in the test.
+   *
+   * @var string
+   */
+  protected $entityRefFieldName;
+
   /**
    * The field storage.
    *
@@ -80,6 +90,10 @@ protected function setUp() {
     ]);
     $this->field->save();
 
+    // Add an entity reference field to reference the same base table.
+    $this->entityRefFieldName = 'field_test_entity_ref_entity_ref';
+    $this->createEntityReferenceField('entity_test', 'entity_test', $this->entityRefFieldName, NULL, 'entity_test');
+
     // Create some entities to search. Add a common string to the name and
     // the text field in two entities so we can test that we can search in both.
     for ($i = 0; $i < 5; $i++) {
@@ -129,6 +143,59 @@ public function testEntityReferenceDisplay() {
 
     // Test that we have searched in both fields.
     $this->assertEqual(count($view->result), 2, 'Search returned two rows');
+    $view->destroy();
+
+    // Add a relationship and a field using that relationship.
+    $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_display_entity_reference/default/relationship', ['name[entity_test.user_id]' => TRUE], t('Add and configure relationships'));
+    $this->drupalPostForm(NULL, [], t('Apply'));
+
+    $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_display_entity_reference/default/field', ['name[users_field_data.uid]' => TRUE], t('Add and configure fields'));
+    $this->drupalPostForm(NULL, [], t('Apply'));
+
+    // Add the new field to the search fields.
+    $this->drupalPostForm('admin/structure/views/nojs/display/test_display_entity_reference/entity_reference_1/style_options', ['style_options[search_fields][uid]' => 'uid'], t('Apply'));
+    $this->drupalPostForm(NULL, [], t('Save'));
+
+    // Test that the search still works with the ralated field.
+    $view = Views::getView('test_display_entity_reference');
+    $view->setDisplay('entity_reference_1');
+
+    // Add the required settings to test a search operation.
+    $options = [
+      'match' => '2',
+      'match_operator' => 'CONTAINS',
+      'limit' => 0,
+      'ids' => NULL,
+    ];
+    $view->display_handler->setOption('entity_reference_options', $options);
+
+    $this->executeView($view);
+
+    // Run validation when using a relationship to the same base table.
+    $this->assertEqual(count($view->result), 2, 'Search returned two rows');
+    $view->destroy();
+
+    $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_display_entity_reference/default/relationship', ['name[entity_test__field_test_entity_ref_entity_ref.field_test_entity_ref_entity_ref]' => TRUE], t('Add and configure relationships'));
+    $this->drupalPostForm(NULL, [], t('Apply'));
+
+    $this->drupalPostForm(NULL, [], t('Save'));
+
+    // Test that the search still works with the related field.
+    $view = Views::getView('test_display_entity_reference');
+    $view->setDisplay('entity_reference_1');
+
+    // Add IDs to trigger validation.
+    $options = [
+      'match' => '1',
+      'match_operator' => 'CONTAINS',
+      'limit' => 0,
+      'ids' => [1, 2],
+    ];
+    $view->display_handler->setOption('entity_reference_options', $options);
+
+    $this->executeView($view);
+
+    $this->assertEqual(count($view->result), 2, 'Search returned two rows');
   }
 
 }
-- 
GitLab