From 5bf482fcb257000549cc8dc16bcbfa6cc89ba4a4 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Tue, 11 Jun 2013 14:22:15 +0100
Subject: [PATCH] Issue #1995868 by JoshuaRogers, dawehner, xjm: Fixed Fatal
 when using a role contextual filter.

---
 core/lib/Drupal/Core/Entity/Entity.php        |   2 +-
 .../user/Plugin/views/argument/RolesRid.php   |  49 +++++++-
 .../user/Views/Argument/RolesRidTest.php      | 106 ++++++++++++++++++
 core/tests/Drupal/Tests/UnitTestCase.php      |  36 +++++-
 4 files changed, 188 insertions(+), 5 deletions(-)
 create mode 100644 core/modules/user/tests/Drupal/Tests/user/Views/Argument/RolesRidTest.php

diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index 9798515b1e49..c61bc6ff8df8 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -364,7 +364,7 @@ public function createDuplicate() {
    * Implements \Drupal\Core\Entity\EntityInterface::entityInfo().
    */
   public function entityInfo() {
-    return entity_get_info($this->entityType);
+    return \Drupal::entityManager()->getDefinition($this->entityType());
   }
 
   /**
diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/argument/RolesRid.php b/core/modules/user/lib/Drupal/user/Plugin/views/argument/RolesRid.php
index 6a878ea8634d..f6570906ebf4 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/views/argument/RolesRid.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/views/argument/RolesRid.php
@@ -2,13 +2,16 @@
 
 /**
  * @file
- * Definition of views_handler_argument_users_roles_rid.
+ * Contains \Drupal\user\Plugin\views\argument\RolesRid.
  */
 
 namespace Drupal\user\Plugin\views\argument;
 
 use Drupal\Component\Annotation\PluginID;
+use Drupal\Component\Utility\String;
+use Drupal\Core\Entity\EntityManager;
 use Drupal\views\Plugin\views\argument\ManyToOne;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Allow role ID(s) as argument.
@@ -19,8 +22,48 @@
  */
 class RolesRid extends ManyToOne {
 
-  public function titleQuery() {
-    return array(entity_load('user_role', $this->value)->label());
+  /**
+   * The role entity storage controller
+   *
+   * @var \Drupal\user\RoleStorageController
+   */
+  protected $roleStorageController;
+
+  /**
+   * Constructs a \Drupal\user\Plugin\views\argument\RolesRid object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityManager $entity_manager
+   *   The entity manager.
+   */
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityManager $entity_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->roleStorageController = $entity_manager->getStorageController('user_role');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
+    return parent::create($container, $configuration, $plugin_id, $plugin_definition, $container->get('plugin.manager.entity'));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function title_query() {
+    $entities = $this->roleStorageController->load($this->value);
+    $titles = array();
+    foreach ($entities as $entity) {
+      $titles[] = String::checkPlain($entity->label());
+    }
+    return $titles;
   }
 
 }
diff --git a/core/modules/user/tests/Drupal/Tests/user/Views/Argument/RolesRidTest.php b/core/modules/user/tests/Drupal/Tests/user/Views/Argument/RolesRidTest.php
new file mode 100644
index 000000000000..d5bbf592d3d3
--- /dev/null
+++ b/core/modules/user/tests/Drupal/Tests/user/Views/Argument/RolesRidTest.php
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\user\Views\Argument\RolesRidTest.
+ */
+
+namespace Drupal\Tests\user\Views\Argument;
+
+use Drupal\Component\Utility\String;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Tests\UnitTestCase;
+use Drupal\user\Plugin\views\argument\RolesRid;
+
+/**
+ * Tests the roles argument handler.
+ *
+ * @see \Drupal\user\Plugin\views\argument\RolesRid
+ */
+class RolesRidTest extends UnitTestCase {
+
+  /**
+   * Entity info used by the test.
+   *
+   * @var array
+   */
+  public static $entityInfo = array(
+    'entity_keys' => array(
+      'id' => 'id',
+      'label' => 'label',
+    ),
+    'config_prefix' => 'user.role',
+    'class' => 'Drupal\user\Plugin\Core\Entity\Role',
+  );
+
+  public static function getInfo() {
+    return array(
+      'name' => 'User: Roles Rid Argument',
+      'description' => 'Tests the role argument handler.',
+      'group' => 'Views module integration',
+    );
+  }
+
+  /**
+   * Tests the title_query method.
+   *
+   * @see \Drupal\user\Plugin\views\argument\RolesRid::title_query()
+   */
+  public function testTitleQuery() {
+    $config = array(
+      'user.role.test_rid_1' => array(
+        'id' => 'test_rid_1',
+        'label' => 'test rid 1'
+      ),
+      'user.role.test_rid_2' => array(
+        'id' => 'test_rid_2',
+        'label' => 'test <strong>rid 2</strong>',
+      ),
+    );
+    $config_factory = $this->getConfigFactoryStub($config);
+    $config_storage = $this->getConfigStorageStub($config);
+
+    // Creates a stub role storage controller and replace the attachLoad()
+    // method with an empty version, because attachLoad() calls
+    // module_implements().
+    $role_storage_controller = $this->getMock('Drupal\user\RoleStorageController', array('attachLoad'), array('user_role', static::$entityInfo, $config_factory, $config_storage));
+
+
+    $entity_manager = $this->getMockBuilder('Drupal\Core\Entity\EntityManager')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $entity_manager->expects($this->any())
+      ->method('getDefinition')
+      ->with($this->equalTo('user_role'))
+      ->will($this->returnValue(static::$entityInfo));
+
+    $entity_manager
+      ->expects($this->once())
+      ->method('getStorageController')
+      ->with($this->equalTo('user_role'))
+      ->will($this->returnValue($role_storage_controller));
+
+    // @todo \Drupal\Core\Entity\Entity::entityInfo() uses a global call to
+    //   entity_get_info(), which in turn wraps \Drupal::entityManager(). Set
+    //   the entity manager until this is fixed.
+    $container = new ContainerBuilder();
+    $container->set('plugin.manager.entity', $entity_manager);
+    \Drupal::setContainer($container);
+
+    $roles_rid_argument = new RolesRid($config, 'users_roles_rid', array(), $entity_manager);
+
+    $roles_rid_argument->value = array();
+    $titles = $roles_rid_argument->title_query();
+    $this->assertEquals(array(), $titles);
+
+    $roles_rid_argument->value = array('test_rid_1');
+    $titles = $roles_rid_argument->title_query();
+    $this->assertEquals(array('test rid 1'), $titles);
+
+    $roles_rid_argument->value = array('test_rid_1', 'test_rid_2');
+    $titles = $roles_rid_argument->title_query();
+    $this->assertEquals(array('test rid 1', String::checkPlain('test <strong>rid 2</strong>')), $titles);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php
index c03d125b6955..185601163d55 100644
--- a/core/tests/Drupal/Tests/UnitTestCase.php
+++ b/core/tests/Drupal/Tests/UnitTestCase.php
@@ -7,7 +7,10 @@
 
 namespace Drupal\Tests;
 
-class UnitTestCase extends \PHPUnit_Framework_TestCase {
+/**
+ * Provides a base class and helpers for Drupal unit tests.
+ */
+abstract class UnitTestCase extends \PHPUnit_Framework_TestCase {
 
   /**
    * This method exists to support the simpletest UI runner.
@@ -85,9 +88,13 @@ public function getConfigFactoryStub($configs) {
       foreach ($config_values as $key => $value) {
         $map[] = array($key, $value);
       }
+      // Also allow to pass in no argument.
+      $map[] = array('', $config_values);
+
       $config_object->expects($this->any())
         ->method('get')
         ->will($this->returnValueMap($map));
+
       $config_map[] = array($config_name, $config_object);
     }
     // Construct a config factory with the array of configuration object stubs
@@ -100,4 +107,31 @@ public function getConfigFactoryStub($configs) {
       ->will($this->returnValueMap($config_map));
     return $config_factory;
   }
+
+  /**
+   * Returns a stub config storage that returns the supplied configuration.
+   *
+   * @param array $configs
+   *   An associative array of configuration settings whose keys are
+   *   configuration object names and whose values are key => value arrays
+   *   for the configuration object in question.
+   *
+   * @return \Drupal\Core\Config\StorageInterface
+   *   A mocked config storage.
+   */
+  public function getConfigStorageStub(array $configs) {
+    $config_storage = $this->getMock('Drupal\Core\Config\NullStorage');
+    $config_storage->expects($this->any())
+      ->method('listAll')
+      ->will($this->returnValue(array_keys($configs)));
+
+    foreach ($configs as $name => $config) {
+      $config_storage->expects($this->any())
+        ->method('read')
+        ->with($this->equalTo($name))
+        ->will($this->returnValue($config));
+    }
+    return $config_storage;
+  }
+
 }
-- 
GitLab