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