From d18fcfd7a4eba20ade58b38b859b101e8499bd15 Mon Sep 17 00:00:00 2001 From: Kristiaan Van den Eynde Date: Fri, 14 Apr 2017 13:49:45 +0200 Subject: [PATCH] Issue #2744069 by achton, kristiaanvandeneynde: views_query_views_alter() does not handle IN queries --- .../src/Kernel/Plugin/RelationshipJoinInTest.php | 130 +++++++++++++++++++++ core/modules/views/views.module | 13 ++- 2 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinInTest.php diff --git a/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinInTest.php b/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinInTest.php new file mode 100644 index 0000000..82b787c --- /dev/null +++ b/core/modules/views/tests/src/Kernel/Plugin/RelationshipJoinInTest.php @@ -0,0 +1,130 @@ + 'name', + 'users_field_data_views_test_data_uid' => 'uid', + ]; + + /** + * Tests the query result of a view with a relationship with an IN condition. + */ + public function testRelationshipInQuery() { + // Update the first two Beatles to be authored by Kristiaan. + $account_k = $this->createUser([], 'Kristiaan'); + db_query("UPDATE {views_test_data} SET uid = :uid WHERE id IN (1,2)", [':uid' => $account_k->id()]); + + // Update the other two Beatles to be authored by Django. + $account_d = $this->createUser([], 'Django'); + db_query("UPDATE {views_test_data} SET uid = :uid WHERE id IN (3,4)", [':uid' => $account_d->id()]); + + // Update Meredith to be authored by Silvie. + $account_s = $this->createUser([], 'Silvie'); + db_query("UPDATE {views_test_data} SET uid = :uid WHERE id = 5", [':uid' => $account_s->id()]); + + $view = Views::getView('test_view'); + $view->setDisplay(); + + $view->displayHandlers->get('default')->overrideOption('relationships', [ + 'uid' => [ + 'id' => 'uid', + 'table' => 'views_test_data', + 'field' => 'uid', + 'required' => TRUE, + ], + ]); + + $view->displayHandlers->get('default')->overrideOption('filters', [ + 'uid' => [ + 'id' => 'uid', + 'table' => 'users_field_data', + 'field' => 'uid', + 'relationship' => 'uid', + ], + ]); + + $fields = $view->displayHandlers->get('default')->getOption('fields'); + $view->displayHandlers->get('default')->overrideOption('fields', $fields + [ + 'uid' => [ + 'id' => 'uid', + 'table' => 'users_field_data', + 'field' => 'uid', + 'relationship' => 'uid', + ], + ]); + + // Check for all beatles created by Kristiaan. + $view->initHandlers(); + $view->filter['uid']->value = [$account_k->id()]; + $this->executeView($view); + + $expected_result = [ + ['name' => 'John', 'uid' => $account_k->id()], + ['name' => 'George', 'uid' => $account_k->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); + $view->destroy(); + + // Check for all beatles created by Django. This should not return anything + // as the 'extra' option on the join prohibits relating to any authors but + // Kristiaan or Silvie. + $view->initHandlers(); + $view->filter['uid']->value = [$account_d->id()]; + $this->executeView($view); + + $expected_result = []; + $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); + $view->destroy(); + + // Check for all people created by anyone. + $view->initHandlers(); + $this->executeView($view); + $expected_result = [ + ['name' => 'John', 'uid' => $account_k->id()], + ['name' => 'George', 'uid' => $account_k->id()], + ['name' => 'Meredith', 'uid' => $account_s->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->columnMap); + $view->destroy(); + } + + /** + * Adds an IN condition for the user name. + */ + protected function viewsData() { + $data = parent::viewsData(); + // Only relate if the author's name is Kristiaan or Silvie. + $data['views_test_data']['uid']['relationship']['extra'][] = [ + 'field' => 'name', + 'value' => ['Kristiaan', 'Silvie'], + ]; + return $data; + } + +} diff --git a/core/modules/views/views.module b/core/modules/views/views.module index f9bd098..f6b4f79 100644 --- a/core/modules/views/views.module +++ b/core/modules/views/views.module @@ -660,8 +660,17 @@ function views_query_views_alter(AlterableInterface $query) { // Replaces substitutions in tables. foreach ($tables as $table_name => $table_metadata) { foreach ($table_metadata['arguments'] as $replacement_key => $value) { - if (isset($substitutions[$value])) { - $tables[$table_name]['arguments'][$replacement_key] = $substitutions[$value]; + if (!is_array($value)) { + if (isset($substitutions[$value])) { + $tables[$table_name]['arguments'][$replacement_key] = $substitutions[$value]; + } + } + else { + foreach ($value as $sub_key => $sub_value) { + if (isset($substitutions[$sub_value])) { + $tables[$table_name]['arguments'][$replacement_key][$sub_key] = $substitutions[$sub_value]; + } + } } } } -- 2.8.1