From 46841601a7ecfbcaac4d93b15170c3e01b467eaf Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Tue, 19 Jan 2016 10:42:42 +0000
Subject: [PATCH] Issue #2540568 by Lendude, mikeyk, geertvd, DuaelFr,
 pjonckiere, dawehner: ManyToOne 'not' operator throws
 InvalidArgumentException ("Is none of" choice in UI)

---
 .../src/Plugin/views/filter/Permissions.php   |  7 ++++--
 .../Views/HandlerFilterPermissionTest.php     | 25 +++++++++++++++++++
 core/modules/views/src/ManyToOneHelper.php    | 17 ++++++++++---
 3 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/core/modules/user/src/Plugin/views/filter/Permissions.php b/core/modules/user/src/Plugin/views/filter/Permissions.php
index 6cbb703970cd..84f19bf48b68 100644
--- a/core/modules/user/src/Plugin/views/filter/Permissions.php
+++ b/core/modules/user/src/Plugin/views/filter/Permissions.php
@@ -94,11 +94,14 @@ public function getValueOptions() {
   public function query() {
     // @todo user_role_names() should maybe support multiple permissions.
     $rids = array();
-    // Get all roles, that have the configured permissions.
+    // Get all role IDs that have the configured permissions.
     foreach ($this->value as $permission) {
       $roles = user_role_names(FALSE, $permission);
-      $rids += array_keys($roles);
+      // user_role_names() returns an array with the role IDs as keys, so take
+      // the array keys and merge them with previously found role IDs.
+      $rids = array_merge($rids, array_keys($roles));
     }
+    // Remove any duplicate role IDs.
     $rids = array_unique($rids);
     $this->value = $rids;
 
diff --git a/core/modules/user/src/Tests/Views/HandlerFilterPermissionTest.php b/core/modules/user/src/Tests/Views/HandlerFilterPermissionTest.php
index 5cdf6b90ac6f..ac2644bdb74a 100644
--- a/core/modules/user/src/Tests/Views/HandlerFilterPermissionTest.php
+++ b/core/modules/user/src/Tests/Views/HandlerFilterPermissionTest.php
@@ -62,6 +62,31 @@ public function testFilterPermission() {
     $this->assertIdenticalResultset($view, $expected, $column_map);
     $view->destroy();
 
+    // Filter by not a permission.
+    $view->initHandlers();
+    $view->filter['permission']->operator = 'not';
+    $view->filter['permission']->value = array('administer users');
+    $this->executeView($view);
+    $this->assertEqual(count($view->result), 3);
+    $expected = array();
+    $expected[] = array('uid' => 1);
+    $expected[] = array('uid' => 2);
+    $expected[] = array('uid' => 3);
+    $this->assertIdenticalResultset($view, $expected, $column_map);
+    $view->destroy();
+
+    // Filter by not multiple permissions, that are present in multiple roles.
+    $view->initHandlers();
+    $view->filter['permission']->operator = 'not';
+    $view->filter['permission']->value = array('administer users', 'administer permissions');
+    $this->executeView($view);
+    $this->assertEqual(count($view->result), 2);
+    $expected = array();
+    $expected[] = array('uid' => 1);
+    $expected[] = array('uid' => 2);
+    $this->assertIdenticalResultset($view, $expected, $column_map);
+    $view->destroy();
+
     // Filter by another permission of a role with multiple permissions.
     $view->initHandlers();
     $view->filter['permission']->value = array('administer users');
diff --git a/core/modules/views/src/ManyToOneHelper.php b/core/modules/views/src/ManyToOneHelper.php
index e6e31aa611a8..71a49e8bd11a 100644
--- a/core/modules/views/src/ManyToOneHelper.php
+++ b/core/modules/views/src/ManyToOneHelper.php
@@ -236,7 +236,7 @@ public function ensureMyTable() {
         $join = $this->getJoin();
         $join->type = 'LEFT';
         $join->extra = array();
-        $join->extra_type = 'OR';
+        $join->extraOperator = 'OR';
         foreach ($this->handler->value as $value) {
           $join->extra[] = array(
             'field' => $this->handler->realField,
@@ -311,10 +311,21 @@ public function addFilter() {
         $placeholder = $this->placeholder();
         if (count($this->handler->value) > 1) {
           $placeholder .= '[]';
-          $this->handler->query->addWhereExpression(0, "$field $operator($placeholder)", array($placeholder => $value));
+
+          if ($operator == 'IS NULL') {
+            $this->handler->query->addWhereExpression(0, "$field $operator");
+          }
+          else {
+            $this->handler->query->addWhereExpression(0, "$field $operator($placeholder)", array($placeholder => $value));
+          }
         }
         else {
-          $this->handler->query->addWhereExpression(0, "$field $operator $placeholder", array($placeholder => $value));
+          if ($operator == 'IS NULL') {
+            $this->handler->query->addWhereExpression(0, "$field $operator");
+          }
+          else {
+            $this->handler->query->addWhereExpression(0, "$field $operator $placeholder", array($placeholder => $value));
+          }
         }
       }
     }
-- 
GitLab