From 0a5a75544801a82d2dfe7dc7824f69045f87d612 Mon Sep 17 00:00:00 2001
From: Kristiaan Van den Eynde <magentix@gmail.com>
Date: Fri, 27 May 2016 10:35:14 +0100
Subject: [PATCH] Issue #2658438 by Torenware, kristiaanvandeneynde: Array
 valued 'extra' values generate invalid SQL in Views joins

---
 .../views/src/Plugin/views/join/JoinPluginBase.php | 26 ++++++++++++----------
 .../views/tests/src/Kernel/Plugin/JoinTest.php     |  6 ++---
 2 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/core/modules/views/src/Plugin/views/join/JoinPluginBase.php b/core/modules/views/src/Plugin/views/join/JoinPluginBase.php
index 36b6e42..8c79be9 100644
--- a/core/modules/views/src/Plugin/views/join/JoinPluginBase.php
+++ b/core/modules/views/src/Plugin/views/join/JoinPluginBase.php
@@ -303,19 +303,15 @@ public function buildJoin($select_query, $table, $view_query) {
           if (is_array($info['value']) && count($info['value']) == 1) {
             $info['value'] = array_shift($info['value']);
           }
-
+          $use_parenthesis = FALSE;
           if (is_array($info['value'])) {
-            // With an array of values, we need multiple placeholders and the
-            // 'IN' operator is implicit.
-            $local_arguments = array();
-            foreach ($info['value'] as $value) {
-              $placeholder_i = ':views_join_condition_' . $select_query->nextPlaceholder();
-              $local_arguments[$placeholder_i] = $value;
-            }
-
+            // We use an SA-CORE-2014-005 conformant placeholder for our array
+            // of values. Also, note that the 'IN' operator is implicit.
+            // @see https://www.drupal.org/node/2401615.
+            $placeholder = ':views_join_condition_' . $select_query->nextPlaceholder() . '[]';
             $operator = !empty($info['operator']) ? $info['operator'] : 'IN';
-            $placeholder = '( ' . implode(', ', array_keys($local_arguments)) . ' )';
-            $arguments += $local_arguments;
+            $arguments[$placeholder] = $info['value'];
+            $use_parenthesis = TRUE;
           }
           else {
             // With a single value, the '=' operator is implicit.
@@ -340,7 +336,13 @@ public function buildJoin($select_query, $table, $view_query) {
             $join_table_field = "$left[alias].$info[left_field]";
             $arguments[$placeholder] = $info['value'];
           }
-          $extras[] = "$join_table_field $operator $placeholder";
+          // Render out the SQL fragment with parameters.
+          if ($use_parenthesis) {
+            $extras[] = "$join_table_field $operator ( $placeholder )";
+          }
+          else {
+            $extras[] = "$join_table_field $operator $placeholder";
+          }
         }
 
         if ($extras) {
diff --git a/core/modules/views/tests/src/Kernel/Plugin/JoinTest.php b/core/modules/views/tests/src/Kernel/Plugin/JoinTest.php
index 2b69948..0b2f549 100644
--- a/core/modules/views/tests/src/Kernel/Plugin/JoinTest.php
+++ b/core/modules/views/tests/src/Kernel/Plugin/JoinTest.php
@@ -172,7 +172,7 @@ public function testBasePlugin() {
     $join_info = $tables['users4'];
     $this->assertTrue(strpos($join_info['condition'], "views_test_data.uid = users4.uid") !== FALSE, 'Make sure the join condition appears in the query.');
     $this->assertTrue(strpos($join_info['condition'], "users4.name = :views_join_condition_2") !== FALSE, 'Make sure the first extra join condition appears in the query.');
-    $this->assertTrue(strpos($join_info['condition'], "users4.name IN ( :views_join_condition_3, :views_join_condition_4, :views_join_condition_5 )") !== FALSE, 'The IN condition for the join is properly formed.');
+    $this->assertTrue(strpos($join_info['condition'], "users4.name IN ( :views_join_condition_3[] )") !== FALSE, 'The IN condition for the join is properly formed.');
 
     // Test that all the conditions are properly built.
     $configuration['extra'] = array(
@@ -197,8 +197,8 @@ public function testBasePlugin() {
     $tables = $query->getTables();
     $join_info = $tables['users5'];
     $this->assertTrue(strpos($join_info['condition'], "views_test_data.uid = users5.uid") !== FALSE, 'Make sure the join condition appears in the query.');
-    $this->assertTrue(strpos($join_info['condition'], "users5.langcode = :views_join_condition_6") !== FALSE, 'Make sure the first extra join condition appears in the query.');
-    $this->assertTrue(strpos($join_info['condition'], "views_test_data.status = :views_join_condition_7") !== FALSE, 'Make sure the second extra join condition appears in the query.');
+    $this->assertTrue(strpos($join_info['condition'], "users5.langcode = :views_join_condition_4") !== FALSE, 'Make sure the first extra join condition appears in the query.');
+    $this->assertTrue(strpos($join_info['condition'], "views_test_data.status = :views_join_condition_5") !== FALSE, 'Make sure the second extra join condition appears in the query.');
     $this->assertTrue(strpos($join_info['condition'], "users5.name = views_test_data.name") !== FALSE, 'Make sure the third extra join condition appears in the query.');
     $this->assertEqual(array_values($join_info['arguments']), array('en', 0), 'Make sure the arguments are in the right order');
   }
-- 
2.4.9 (Apple Git-60)

