Issue #1872876 by chx, fubhy, dawehner, alexpott, tim.plunkett: Turn role permission assignments into configuration.

8.0.x
Nathaniel Catchpole 2013-06-24 17:38:32 +01:00
parent 0d20ccb2a7
commit 195849b2a4
42 changed files with 1035 additions and 306 deletions

View File

@ -1542,3 +1542,34 @@ function update_add_cache_columns($table) {
));
}
}
/**
* Replace permissions during update.
*
* This function can replace one permission to several or even delete an old
* one.
*
* @param array $replace
* An associative array. The keys are the old permissions the values are lists
* of new permissions. If the list is an empty array, the old permission is
* removed.
*/
function update_replace_permissions($replace) {
$prefix = 'user.role.';
$cut = strlen($prefix);
$role_names = Drupal::service('config.storage')->listAll($prefix);
foreach ($role_names as $role_name) {
$rid = substr($role_name, $cut);
$config = Drupal::config("user.role.$rid");
$permissions = $config->get('permissions') ?: array();
foreach ($replace as $old_permission => $new_permissions) {
if (($index = array_search($old_permission, $permissions)) !== FALSE) {
unset($permissions[$index]);
$permissions = array_unique(array_merge($permissions, $new_permissions));
}
}
$config
->set('permissions', $permissions)
->save();
}
}

View File

@ -23,11 +23,6 @@ class BlockInterfaceTest extends DrupalUnitTestBase {
);
}
protected function setUp() {
parent::setUp();
$this->installSchema('user', 'role_permission');
}
/**
* Test configuration and subsequent form() and build() method calls.
*

View File

@ -1223,20 +1223,24 @@ function comment_node_update_index(EntityInterface $node, $langcode) {
$index_comments = &drupal_static(__FUNCTION__);
if ($index_comments === NULL) {
// Find and save roles that can 'access comments' or 'search content'.
$perms = array('access comments' => array(), 'search content' => array());
$result = db_query("SELECT rid, permission FROM {role_permission} WHERE permission IN ('access comments', 'search content')");
foreach ($result as $record) {
$perms[$record->permission][$record->rid] = $record->rid;
}
// Prevent indexing of comments if there are any roles that can search but
// not view comments.
// Do not index in the following three cases:
// 1. 'Authenticated user' can search content but can't access comments.
// 2. 'Anonymous user' can search content but can't access comments.
// 3. Any role can search content but can't access comments and access
// comments is not granted by the 'authenticated user' role. In this case
// all users might have both permissions from various roles but it is also
// possible to set up a user to have only search content and so a user
// edit could change the security situation so it is not safe to index the
// comments.
$index_comments = TRUE;
foreach ($perms['search content'] as $rid) {
if (!isset($perms['access comments'][$rid]) && (($rid == DRUPAL_AUTHENTICATED_RID || $rid == DRUPAL_ANONYMOUS_RID) || !isset($perms['access comments'][DRUPAL_AUTHENTICATED_RID]))) {
$index_comments = FALSE;
break;
$roles = Drupal::entityManager()->getStorageController('user_role')->load();
$authenticated_can_access = $roles[DRUPAL_AUTHENTICATED_RID]->hasPermission('access comments');
foreach ($roles as $rid => $role) {
if ($role->hasPermission('search content') && !$role->hasPermission('access comments')) {
if ($rid == DRUPAL_AUTHENTICATED_RID || $rid == DRUPAL_ANONYMOUS_RID || !$authenticated_can_access) {
$index_comments = FALSE;
break;
}
}
}
}

View File

@ -9,39 +9,29 @@
* Upgrade Field UI permissions.
*/
function field_ui_update_8001() {
$permissions = array(
$replace = array(
'administer comments' => array(
'administer comments',
'administer comment fields',
'administer comment display',
),
'administer content types' => array(
'administer content types',
'administer node fields',
'administer node display',
),
'administer users' => array(
'administer users',
'administer user fields',
'administer user display',
),
'administer taxonomy' => array(
'administer taxonomy',
'administer taxonomy_term fields',
'administer taxonomy_term display',
),
);
// We can not call user_permission_get_modules() as that will start
// invoking hooks which we can't during update hooks. Directly query
// for the permissions and insert them into the database.
foreach ($permissions as $old_permission => $new_permissions) {
$results = db_query("SELECT rid FROM {role_permission} WHERE permission = :permission", array(':permission' => $old_permission));
foreach ($results as $record) {
$query = db_insert('role_permission')->fields(array('rid', 'permission', 'module'));
foreach ($new_permissions as $new_permission) {
$query->values(array($record->rid, $new_permission, 'field_ui'));
}
$query->execute();
}
}
update_replace_permissions($replace);
}
/**

View File

@ -30,7 +30,7 @@ class FilterDefaultConfigTest extends DrupalUnitTestBase {
// filter_permission() calls into url() to output a link in the description.
$this->installSchema('system', 'url_alias');
$this->installSchema('user', array('users_roles', 'role_permission'));
$this->installSchema('user', array('users_roles'));
// Install filter_test module, which ships with custom default format.
$this->installConfig(array('user', 'filter_test'));

View File

@ -26,9 +26,7 @@ class NodeAccessTest extends NodeTestBase {
function setUp() {
parent::setUp();
// Clear permissions for authenticated users.
db_delete('role_permission')
->condition('rid', DRUPAL_AUTHENTICATED_RID)
->execute();
$this->container->get('config.factory')->get('user.role.' . DRUPAL_AUTHENTICATED_RID)->set('permissions', array())->save();
}
/**

View File

@ -570,6 +570,15 @@ function _update_7000_node_get_types() {
* @{
*/
/**
* Implements hook_update_dependency().
*/
function node_update_dependency() {
$dependencies['node'][8013] = array(
'user' => 8002,
);
}
/**
* Rename node type language variable names.
*
@ -796,15 +805,11 @@ function node_update_8012() {
* Renames global revision permissions to use the word 'all'.
*/
function node_update_8013() {
$actions = array('view', 'delete', 'revert');
foreach ($actions as $action) {
db_update('role_permission')
->fields(array('permission' => $action . ' all revisions'))
->condition('permission', $action . ' revisions')
->condition('module', 'node')
->execute();
}
update_replace_permissions(array(
'view revisions' => array('view all revisions'),
'revert revisions' => array('revert all revisions'),
'delete revisions' => array('delete all revisions'),
));
}
/**

View File

@ -30,17 +30,11 @@ function node_views_analyze(ViewExecutable $view) {
// check for no access control
$access = $display->getOption('access');
if (empty($access['type']) || $access['type'] == 'none') {
$result = db_select('role_permission', 'p')
->fields('p', array('rid', 'permission'))
->condition('p.rid', array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID), 'IN')
->condition('p.permission', 'access content')
->execute();
foreach ($result as $role) {
$role->safe = TRUE;
$roles[$role->rid] = $role;
}
if (!($roles[DRUPAL_ANONYMOUS_RID]->safe && $roles[DRUPAL_AUTHENTICATED_RID]->safe)) {
$anonymous_role = entity_load('user_role', DRUPAL_ANONYMOUS_RID);
$anonymous_has_access = $anonymous_role && $anonymous_role->hasPermission('access content');
$authenticated_role = entity_load('user_role', DRUPAL_AUTHENTICATED_RID);
$authenticated_has_access = $authenticated_role && $authenticated_role->hasPermission('access content');
if (!$anonymous_has_access || !$authenticated_has_access) {
$ret[] = Analyzer::formatMessage(t('Some roles lack permission to access content, but display %display has no access control.', array('%display' => $display->display['display_title'])), 'warning');
}
$filters = $display->getOption('filters');

View File

@ -560,8 +560,7 @@ abstract class WebTestBase extends TestBase {
// Grant the specified permissions to the role, if any.
if (!empty($permissions)) {
user_role_grant_permissions($role->id(), $permissions);
$assigned_permissions = db_query('SELECT permission FROM {role_permission} WHERE rid = :rid', array(':rid' => $role->id()))->fetchCol();
$assigned_permissions = entity_load('user_role', $role->id())->permissions;
$missing_permissions = array_diff($permissions, $assigned_permissions);
if (!$missing_permissions) {
$this->pass(t('Created permissions: @perms', array('@perms' => implode(', ', $permissions))), t('Role'));

View File

@ -29,7 +29,7 @@ class EntityAccessTest extends EntityUnitTestBase {
function setUp() {
parent::setUp();
$this->installSchema('user', array('role_permission', 'users_roles'));
$this->installSchema('user', array('users_roles'));
$this->installSchema('system', array('variable', 'url_alias'));
$this->installSchema('language', 'language');

View File

@ -31,7 +31,7 @@ class EntityBCDecoratorTest extends EntityUnitTestBase {
public function setUp() {
parent::setUp();
$this->installSchema('user', array('users_roles', 'users_data', 'role_permission'));
$this->installSchema('user', array('users_roles', 'users_data'));
$this->installSchema('node', array('node', 'node_field_data', 'node_field_revision', 'node_type', 'node_access'));
$this->installSchema('comment', array('comment', 'node_comment_statistics'));
}

View File

@ -36,8 +36,7 @@ abstract class EntityUnitTestBase extends DrupalUnitTestBase {
* (optional) The values used to create the entity.
* @param array $permissions
* (optional) Array of permission names to assign to user. The
* role_permission and users_roles tables must be installed before this can
* be used.
* users_roles tables must be installed before this can be used.
*
* @return \Drupal\user\Plugin\Core\Entity\User
* The created user entity.

View File

@ -38,8 +38,7 @@ class UninstallTest extends WebTestBase {
module_disable(array('module_test'));
module_uninstall(array('module_test'));
// Are the perms defined by module_test removed from {role_permission}.
$count = db_query("SELECT COUNT(rid) FROM {role_permission} WHERE permission = :perm", array(':perm' => 'module_test perm'))->fetchField();
$this->assertEqual(0, $count, 'Permissions were all removed.');
// Are the perms defined by module_test removed?
$this->assertFalse(user_roles(FALSE, 'module_test perm'), 'Permissions were all removed.');
}
}

View File

@ -65,11 +65,11 @@ class FieldUIUpgradePathTest extends UpgradePathTestBase {
$role_permissions = user_role_permissions(array($this->normal_role_id, $this->admin_role_id));
foreach ($permissions as $old_permission => $new_permissions) {
$this->assertFalse(isset($role_permissions[$this->normal_role_id][$old_permission]), format_string('%role_name does not have the old %permission permission', array('%role_name' => $this->normal_role_name, '%permission' => $old_permission)));
$this->assertTrue(isset($role_permissions[$this->admin_role_id][$old_permission]), format_string('%role_name still has the old %permission permission', array('%role_name' => $this->admin_role_name, '%permission' => $old_permission)));
$this->assertFalse(in_array($old_permission, $role_permissions[$this->normal_role_id]), format_string('%role_name does not have the old %permission permission', array('%role_name' => $this->normal_role_name, '%permission' => $old_permission)));
$this->assertTrue(in_array($old_permission, $role_permissions[$this->admin_role_id]), format_string('%role_name still has the old %permission permission', array('%role_name' => $this->admin_role_name, '%permission' => $old_permission)));
foreach ($new_permissions as $new_permission) {
$this->assertFalse(isset($role_permissions[$this->normal_role_id][$new_permission]), format_string('%role_name does not have the new %permission permission', array('%role_name' => $this->normal_role_name, '%permission' => $new_permission)));
$this->assertTrue(isset($role_permissions[$this->admin_role_id][$new_permission]), format_string('%role_name has the new %permission permission', array('%role_name' => $this->admin_role_name, '%permission' => $new_permission)));
$this->assertFalse(in_array($new_permission, $role_permissions[$this->normal_role_id]), format_string('%role_name does not have the new %permission permission', array('%role_name' => $this->normal_role_name, '%permission' => $new_permission)));
$this->assertTrue(in_array($new_permission, $role_permissions[$this->admin_role_id]), format_string('%role_name has the new %permission permission', array('%role_name' => $this->admin_role_name, '%permission' => $new_permission)));
}
}
}

View File

@ -191,6 +191,8 @@ class LanguageUpgradePathTest extends UpgradePathTestBase {
* Tests upgrading translations permissions.
*/
public function testLanguagePermissionsUpgrade() {
// Insert a permission into the Drupal 7 database before running the
// upgrade.
db_insert('role_permission')->fields(array(
'rid' => 2,
'permission' => 'translate content',
@ -198,12 +200,8 @@ class LanguageUpgradePathTest extends UpgradePathTestBase {
))->execute();
$this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.');
// Check that translate content role doesn't exist on database.
$old_permission_exists = db_query('SELECT * FROM {role_permission} WHERE permission LIKE ?', array('translate content'))->fetchObject();
$this->assertFalse($old_permission_exists, 'No translate content role left on database.');
$this->assertFalse(user_roles(FALSE, 'translate content'), 'No translate content role left in config.');
// Check that translate content has been renamed to translate all content.
$new_permission_exists = db_query('SELECT * FROM {role_permission} WHERE permission LIKE ?', array('translate all content'))->fetchObject();
$this->assertTrue($new_permission_exists, 'Rename role translate content to translate all content was completed successfully.');
$this->assertTrue(user_roles(FALSE, 'translate all content'), 'Rename role translate content to translate all content was completed successfully.');
}
}

View File

@ -1520,13 +1520,9 @@ function system_update_8020() {
$blocked_ips_exists = db_query_range('SELECT 1 FROM {blocked_ips}', 0, 1)->fetchField();
if ($blocked_ips_exists) {
// Rename the permission name.
db_update('role_permission')
->fields(array(
'permission' => 'ban IP addresses',
'module' => 'ban',
))
->condition('permission', 'block IP addresses')
->execute();
update_replace_permissions(array(
'block IP addresses' => array('ban IP addresses'),
));
// Rename {blocked_ips} table into {ban_ip}.
db_rename_table('blocked_ips', 'ban_ip');
// Remove all references to the removed action callback.

View File

@ -28,7 +28,6 @@ class TextSummaryTest extends DrupalUnitTestBase {
parent::setUp();
$this->installSchema('system', 'url_alias');
$this->installSchema('user', 'role_permission');
$this->installConfig(array('text'));
}

View File

@ -10,10 +10,9 @@
* Rename the translate content permission.
*/
function translation_update_8000() {
db_update('role_permission')
->fields(array('permission' => 'translate all content'))
->condition('permission', 'translate content')
->execute();
update_replace_permissions(array(
'translate content' => array('translate all content'),
));
}
/**

View File

@ -131,6 +131,12 @@ user.role.*:
weight:
type: integer
label: 'User role weight'
permissions:
type: sequence
label: 'Permissions'
sequence:
- type: string
label: 'Permission'
langcode:
type: string
label: 'Default language'

View File

@ -742,7 +742,7 @@ display:
plugin_id: user_roles
permission:
id: permission
table: role_permission
table: users_roles
field: permission
relationship: none
group_type: group

View File

@ -67,6 +67,13 @@ class Role extends ConfigEntityBase implements RoleInterface {
*/
public $weight;
/**
* The permissions belonging to this role.
*
* @var array
*/
public $permissions = array();
/**
* {@inheritdoc}
*/
@ -80,6 +87,38 @@ class Role extends ConfigEntityBase implements RoleInterface {
);
}
/**
* {@inheritdoc}
*/
public function getPermissions() {
return $this->permissions;
}
/**
* {@inheritdoc}
*/
public function hasPermission($permission) {
return in_array($permission, $this->permissions);
}
/**
* {@inheritdoc}
*/
public function grantPermission($permission) {
if (!$this->hasPermission($permission)) {
$this->permissions[] = $permission;
}
return $this;
}
/**
* {@inheritdoc}
*/
public function revokePermission($permission) {
$this->permissions = array_diff($this->permissions, array($permission));
return $this;
}
/**
* {@inheritdoc}
*/

View File

@ -8,7 +8,8 @@
namespace Drupal\user\Plugin\views\field;
use Drupal\Component\Annotation\PluginID;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityManager;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\field\PrerenderList;
@ -24,11 +25,18 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
class Permissions extends PrerenderList {
/**
* Database Service Object.
* The role storage controller.
*
* @var \Drupal\Core\Database\Connection
* @var \Drupal\user\RoleStorageControllerInterface
*/
protected $database;
protected $roleStorageController;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* Constructs a Drupal\Component\Plugin\PluginBase object.
@ -39,20 +47,23 @@ class Permissions extends PrerenderList {
* The plugin_id for the plugin instance.
* @param array $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Database\Connection $database
* Database Service Object.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\Entity\EntityManager $entity_manager
* The entity manager
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition, Connection $database) {
public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler, EntityManager $entity_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->database = $database;
$this->roleStorageController = $entity_manager->getStorageController('user_role');
$this->moduleHandler = $module_handler;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container->get('database'));
return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), $container->get('plugin.manager.entity'));
}
/**
@ -73,27 +84,32 @@ class Permissions extends PrerenderList {
$uids = array();
$this->items = array();
$permission_names = \Drupal::moduleHandler()->invokeAll('permission');
$rids = array();
foreach ($values as $result) {
$uids[] = $this->getValue($result);
$user_rids = $this->getEntity($result)->getRoles();
$uid = $this->getValue($result);
foreach ($user_rids as $rid) {
$rids[$rid][] = $uid;
}
}
if ($uids) {
// Get a list of all the modules implementing a hook_permission() and sort by
// display name.
$module_info = system_get_info('module');
$modules = array();
foreach (module_implements('permission') as $module) {
$modules[$module] = $module_info[$module]['name'];
if ($rids) {
$roles = $this->roleStorageController->load(array_keys($rids));
foreach ($rids as $rid => $role_uids) {
foreach ($roles[$rid]->getPermissions() as $permission) {
foreach ($role_uids as $uid) {
$this->items[$uid][$permission]['permission'] = $permission_names[$permission]['title'];
}
}
}
asort($modules);
$permissions = module_invoke_all('permission');
$result = $this->database->query('SELECT u.uid, u.rid, rp.permission FROM {role_permission} rp INNER JOIN {users_roles} u ON u.rid = rp.rid WHERE u.uid IN (:uids) AND rp.module IN (:modules) ORDER BY rp.permission',
array(':uids' => $uids, ':modules' => array_keys($modules)));
foreach ($result as $perm) {
$this->items[$perm->uid][$perm->permission]['permission'] = $permissions[$perm->permission]['title'];
foreach ($uids as $uid) {
if (isset($this->items[$uid])) {
ksort($this->items[$uid]);
}
}
}
}

View File

@ -8,7 +8,10 @@
namespace Drupal\user\Plugin\views\filter;
use Drupal\Component\Annotation\PluginID;
use Drupal\Component\Utility\String;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\views\Plugin\views\filter\ManyToOne;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Filter handler for user roles.
@ -19,25 +22,83 @@ use Drupal\views\Plugin\views\filter\ManyToOne;
*/
class Permissions extends ManyToOne {
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* Constructs a Permissions 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\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->moduleHandler = $module_handler;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'));
}
public function getValueOptions() {
$module_info = system_get_info('module');
if (!isset($this->value_options)) {
$module_info = system_get_info('module');
// Get a list of all the modules implementing a hook_permission() and sort by
// display name.
$modules = array();
foreach (module_implements('permission') as $module) {
$modules[$module] = $module_info[$module]['name'];
}
asort($modules);
// Get a list of all the modules implementing a hook_permission() and sort by
// display name.
$modules = array();
foreach ($this->moduleHandler->getImplementations('permission') as $module) {
$modules[$module] = $module_info[$module]['name'];
}
asort($modules);
$this->value_options = array();
foreach ($modules as $module => $display_name) {
if ($permissions = module_invoke($module, 'permission')) {
foreach ($permissions as $perm => $perm_item) {
$this->value_options[$display_name][$perm] = check_plain(strip_tags($perm_item['title']));
$this->value_options = array();
foreach ($modules as $module => $display_name) {
if ($permissions = $this->moduleHandler->invoke($module, 'permission')) {
foreach ($permissions as $perm => $perm_item) {
$this->value_options[$display_name][$perm] = String::checkPlain(strip_tags($perm_item['title']));
}
}
}
}
else {
return $this->value_options;
}
}
/**
* {@inheritdoc}
*
* Replace the configured permission with a filter by all roles that have this
* permission.
*/
public function query() {
// @todo user_role_names() should maybe support multiple permissions.
$rids = array();
// Get all roles, that have the configured permissions.
foreach ($this->value as $permission) {
$roles = user_role_names(FALSE, $permission);
$rids += array_keys($roles);
}
$rids = array_unique($rids);
$this->value = $rids;
// $this->value contains the role IDs that have the configured permission.
parent::query();
}
}

View File

@ -14,4 +14,45 @@ use Drupal\Core\Config\Entity\ConfigEntityInterface;
*/
interface RoleInterface extends ConfigEntityInterface {
/**
* Returns a list of permissions assigned to the role.
*
* @return array
* The permissions assigned to the role.
*/
public function getPermissions();
/**
* Checks if the role has a permission.
*
* @param string $permission
* The permission to check for.
*
* @return bool
* TRUE if the role has the permission, FALSE if not.
*/
public function hasPermission($permission);
/**
* Grant permissions to the role.
*
* @param string $permission
* The permission to grant.
*
* @return RoleInterface
* The called object for chaining.
*/
public function grantPermission($permission);
/**
* Revokes a permissions from the user role.
*
* @param string $permission
* The permission to revoke.
*
* @return RoleInterface
* The called object for chaining.
*/
public function revokePermission($permission);
}

View File

@ -19,20 +19,14 @@ class RoleStorageController extends ConfigStorageController implements RoleStora
*/
public function resetCache(array $ids = NULL) {
parent::resetCache($ids);
// Clear the user access cache.
drupal_static_reset('user_access');
drupal_static_reset('user_role_permissions');
}
/**
* {@inheritdoc}
*/
public function deleteRoleReferences(array $rids) {
// Delete permission assignments.
db_delete('role_permission')
->condition('rid', $rids)
->execute();
// Remove the role from all users.
db_delete('users_roles')
->condition('rid', $rids)

View File

@ -8,6 +8,7 @@
namespace Drupal\user\Tests;
use Drupal\simpletest\WebTestBase;
use Drupal\user\RoleStorageController;
class UserPermissionsTest extends WebTestBase {
protected $admin_user;
@ -46,8 +47,8 @@ class UserPermissionsTest extends WebTestBase {
$edit[$rid . '[administer nodes]'] = TRUE;
$this->drupalPost('admin/people/permissions', $edit, t('Save permissions'));
$this->assertText(t('The changes have been saved.'), 'Successful save message displayed.');
drupal_static_reset('user_access');
drupal_static_reset('user_role_permissions');
$storage_controller = $this->container->get('plugin.manager.entity')->getStorageController('user_role');
$storage_controller->resetCache();
$this->assertTrue(user_access('administer nodes', $account), 'User now has "administer nodes" permission.');
// Remove a permission.
@ -56,8 +57,7 @@ class UserPermissionsTest extends WebTestBase {
$edit[$rid . '[access user profiles]'] = FALSE;
$this->drupalPost('admin/people/permissions', $edit, t('Save permissions'));
$this->assertText(t('The changes have been saved.'), 'Successful save message displayed.');
drupal_static_reset('user_access');
drupal_static_reset('user_role_permissions');
$storage_controller->resetCache();
$this->assertFalse(user_access('access user profiles', $account), 'User no longer has "access user profiles" permission.');
}

View File

@ -0,0 +1,66 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Views\HandlerFieldPermissionTest.
*/
namespace Drupal\user\Tests\Views;
use Drupal\views\Tests\ViewTestData;
use Drupal\views\Tests\ViewUnitTestBase;
/**
* Tests the permission field handler.
*
* @see \Drupal\user\Plugin\views\field\Permissions
*/
class HandlerFieldPermissionTest extends UserUnitTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array('test_field_permission');
public static function getInfo() {
return array(
'name' => 'User: Permissions Field',
'description' => 'Tests the permission field handler.',
'group' => 'Views module integration',
);
}
/**
* Tests the permission field handler output.
*/
public function testFieldPermission() {
$this->setupPermissionTestData();
$view = views_get_view('test_field_permission');
$this->executeView($view);
$view->initStyle();
$view->render();
$style_plugin = $view->style_plugin;
$expected_permissions = array();
$expected_permissions[$this->users[0]->id()] = array();
$expected_permissions[$this->users[1]->id()] = array();
$expected_permissions[$this->users[2]->id()][] = t('Administer permissions');
// View user profiles comes first, because we sort by the permission
// machine name.
$expected_permissions[$this->users[3]->id()][] = t('Administer permissions');
$expected_permissions[$this->users[3]->id()][] = t('Administer users');
$expected_permissions[$this->users[3]->id()][] = t('View user profiles');
foreach ($view->result as $index => $row) {
$uid = $view->field['uid']->getValue($row);
$rendered_permission = $style_plugin->getField($index, 'permission');
$expected_output = implode(', ', $expected_permissions[$uid]);
$this->assertEqual($rendered_permission, $expected_output, 'The right permissions are rendered.');
}
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Views\HandlerFilterPermissionTest.
*/
namespace Drupal\user\Tests\Views;
use Drupal\Component\Utility\String;
use Drupal\user\Tests\Views\UserUnitTestBase;
/**
* Tests the permissions filter handler.
*
* @see \Drupal\user\Plugin\views\filter\Permissions
*/
class HandlerFilterPermissionTest extends UserUnitTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array('test_filter_permission');
protected $columnMap;
public static function getInfo() {
return array(
'name' => 'User: Permissions Filter',
'description' => 'Tests the permission filter handler.',
'group' => 'Views module integration',
);
}
/**
* Tests the permission filter handler.
*
* @todo Fix the different commented out tests by fixing the many to one
* handler handling with the NOT operator.
*/
public function testFilterPermission() {
$this->setupPermissionTestData();
$column_map = array('uid' => 'uid');
$view = views_get_view('test_filter_permission');
// Filter by a non existing permission.
$view->initHandlers();
$view->filter['permission']->value = array('non_existent_permission');
$this->executeView($view);
$this->assertEqual(count($view->result), 4, 'A non existent permission is not filtered so everything is the result.');
$expected[] = array('uid' => 1);
$expected[] = array('uid' => 2);
$expected[] = array('uid' => 3);
$expected[] = array('uid' => 4);
$this->assertIdenticalResultset($view, $expected, $column_map);
$view->destroy();
// Filter by a permission.
$view->initHandlers();
$view->filter['permission']->value = array('administer permissions');
$this->executeView($view);
$this->assertEqual(count($view->result), 2);
$expected = array();
$expected[] = array('uid' => 3);
$expected[] = array('uid' => 4);
$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');
$this->executeView($view);
$this->assertEqual(count($view->result), 1);
$expected = array();
$expected[] = array('uid' => 4);
$this->assertIdenticalResultset($view, $expected, $column_map);
$view->destroy();
$view->initDisplay();
$view->initHandlers();
$view->filter['permission']->getValueOptions();
// Test the value options.
$value_options = $view->filter['permission']->getValueOptions();
foreach (array('system' => 'System', 'user' => 'User') as $module => $title) {
$expected = array_map(function ($permission) {
return String::checkPlain(strip_tags($permission['title']));
}, $this->container->get('module_handler')->invoke($module, 'permission'));
$this->assertEqual($expected, $value_options[$title], 'Ensure the all permissions are available');
}
}
}

View File

@ -0,0 +1,96 @@
<?php
/**
* @file
* Contains \Drupal\user\Tests\Views\UserUnitTestBase.
*/
namespace Drupal\user\Tests\Views;
use Drupal\views\Tests\ViewTestData;
use Drupal\views\Tests\ViewUnitTestBase;
/**
* Provides a common test base for user views tests.
*/
abstract class UserUnitTestBase extends ViewUnitTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('user_test_views', 'user', 'system', 'field');
/**
* Users to use during this test.
*
* @var array
*/
protected $users = array();
/**
* The entity storage controller for roles.
*
* @var \Drupal\user\RoleStorageController
*/
protected $roleStorageController;
/**
* The entity storage controller for users.
*
* @var \Drupal\user\UserStorageController
*/
protected $userStorageController;
protected function setUp() {
parent::setUp();
ViewTestData::importTestViews(get_class($this), array('user_test_views'));
$this->installSchema('user', array('users', 'users_roles'));
$this->installSchema('system', 'sequences');
$entity_manager = $this->container->get('plugin.manager.entity');
$this->roleStorageController = $entity_manager->getStorageController('user_role');
$this->userStorageController = $entity_manager->getStorageController('user');
}
/**
* Set some test data for permission related tests.
*/
protected function setupPermissionTestData() {
// Setup a role without any permission.
$this->roleStorageController->create(array('id' => 'authenticated'))
->save();
$this->roleStorageController->create(array('id' => 'no_permission'))
->save();
// Setup a role with just one permission.
$this->roleStorageController->create(array('id' => 'one_permission'))
->save();
user_role_grant_permissions('one_permission', array('administer permissions'));
// Setup a role with multiple permissions.
$this->roleStorageController->create(array('id' => 'multiple_permissions'))
->save();
user_role_grant_permissions('multiple_permissions', array('administer permissions', 'administer users', 'access user profiles'));
// Setup a user without an extra role.
$this->users[] = $account = $this->userStorageController->create(array());
$account->save();
// Setup a user with just the first role (so no permission beside the
// ones from the authenticated role).
$this->users[] = $account = $this->userStorageController->create(array('name' => 'first_role'));
$account->addRole('no_permission');
$account->save();
// Setup a user with just the second role (so one additional permission).
$this->users[] = $account = $this->userStorageController->create(array('name' => 'second_role'));
$account->addRole('one_permission');
$account->save();
// Setup a user with both the second and the third role.
$this->users[] = $account = $this->userStorageController->create(array('name' => 'second_third_role'));
$account->addRole('one_permission');
$account->addRole('multiple_permissions');
$account->save();
}
}

View File

@ -0,0 +1,135 @@
base_field: uid
base_table: users
core: 8.x
description: ''
status: '1'
display:
default:
display_plugin: default
id: default
display_title: Master
position: ''
display_options:
access:
type: none
cache:
type: none
query:
type: views_query
exposed_form:
type: basic
pager:
type: full
style:
type: default
row:
type: fields
fields:
uid:
id: uid
table: users
field: uid
relationship: none
group_type: group
admin_label: ''
label: Uid
exclude: '0'
alter:
alter_text: '0'
text: ''
make_link: '0'
path: ''
absolute: '0'
external: '0'
replace_spaces: '0'
path_case: none
trim_whitespace: '0'
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: '0'
max_length: ''
word_boundary: '1'
ellipsis: '1'
more_link: '0'
more_link_text: ''
more_link_path: ''
strip_tags: '0'
trim: '0'
preserve_tags: ''
html: '0'
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: '1'
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: '1'
empty: ''
hide_empty: '0'
empty_zero: '0'
hide_alter_empty: '1'
link_to_user: '0'
plugin_id: user
permission:
id: permission
table: users_roles
field: permission
relationship: none
group_type: group
admin_label: ''
label: Permission
exclude: '0'
alter:
alter_text: '0'
text: ''
make_link: '0'
path: ''
absolute: '0'
external: '0'
replace_spaces: '0'
path_case: none
trim_whitespace: '0'
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: '0'
max_length: ''
word_boundary: '1'
ellipsis: '1'
more_link: '0'
more_link_text: ''
more_link_path: ''
strip_tags: '0'
trim: '0'
preserve_tags: ''
html: '0'
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: '1'
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: '1'
empty: ''
hide_empty: '0'
empty_zero: '0'
hide_alter_empty: '1'
type: separator
separator: ', '
plugin_id: user_permissions
filters: { }
sorts: { }
human_name: test_field_permission
module: views
id: test_field_permission
tag: ''
langcode: en

View File

@ -0,0 +1,123 @@
base_field: uid
base_table: users
core: 8.x
description: ''
status: '1'
display:
default:
display_plugin: default
id: default
display_title: Master
position: ''
display_options:
access:
type: none
cache:
type: none
query:
type: views_query
exposed_form:
type: basic
pager:
type: full
style:
type: default
row:
type: fields
fields:
uid:
id: uid
table: users
field: uid
relationship: none
group_type: group
admin_label: ''
label: ''
exclude: '0'
alter:
alter_text: '0'
text: ''
make_link: '0'
path: ''
absolute: '0'
external: '0'
replace_spaces: '0'
path_case: none
trim_whitespace: '0'
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: '0'
max_length: ''
word_boundary: '1'
ellipsis: '1'
more_link: '0'
more_link_text: ''
more_link_path: ''
strip_tags: '0'
trim: '0'
preserve_tags: ''
html: '0'
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: '0'
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: '1'
empty: ''
hide_empty: '0'
empty_zero: '0'
hide_alter_empty: '1'
link_to_user: '0'
plugin_id: user
filters:
permission:
id: permission
table: users_roles
field: permission
relationship: none
group_type: group
admin_label: ''
operator: or
value:
'access user profiles': 'access user profiles'
group: '1'
exposed: '0'
expose:
operator_id: '0'
label: ''
description: ''
use_operator: '0'
operator: ''
identifier: ''
required: '0'
remember: '0'
multiple: '0'
remember_roles:
authenticated: authenticated
reduce: '0'
is_grouped: '0'
group_info:
label: ''
description: ''
identifier: ''
optional: '1'
widget: select
multiple: '0'
remember: '0'
default_group: All
default_group_multiple: { }
group_items: { }
reduce_duplicates: '1'
plugin_id: user_permissions
sorts: { }
human_name: test_filter_permission
module: views
id: test_filter_permission
tag: ''
langcode: en

View File

@ -105,7 +105,6 @@ function user_admin_account() {
* @see theme_user_admin_permissions()
*/
function user_admin_permissions($form, $form_state, $rid = NULL) {
// Retrieve role names for columns.
$role_names = user_role_names();
if (isset($rid)) {
@ -158,7 +157,7 @@ function user_admin_permissions($form, $form_state, $rid = NULL) {
);
foreach ($role_names as $rid => $name) {
// Builds arrays for checked boxes for each role
if (isset($role_permissions[$rid][$perm])) {
if (in_array($perm, $role_permissions[$rid])) {
$status[$rid][] = $perm;
}
}

View File

@ -149,42 +149,6 @@ function user_schema() {
),
);
$schema['role_permission'] = array(
'description' => 'Stores the permissions assigned to user roles.',
'fields' => array(
'rid' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'description' => 'Foreign Key: {role}.rid.',
),
'permission' => array(
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
'description' => 'A single permission granted to the role identified by rid.',
),
'module' => array(
'type' => 'varchar',
'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
'not null' => TRUE,
'default' => '',
'description' => "The module declaring the permission.",
),
),
'primary key' => array('rid', 'permission'),
'indexes' => array(
'permission' => array('permission'),
),
'foreign keys' => array(
'role' => array(
'table' => 'role',
'columns' => array('rid' => 'rid'),
),
),
);
$schema['users_data'] = array(
'description' => 'Stores module data as key/value pairs per user.',
'fields' => array(
@ -386,6 +350,7 @@ function user_update_dependencies() {
return $dependencies;
}
/**
* @addtogroup updates-7.x-to-8.x
* @{
@ -451,9 +416,6 @@ function user_update_8002() {
);
db_change_field('role', 'rid', 'rid', $column);
$column['description'] = 'Foreign Key: {role}.rid.';
db_change_field('role_permission', 'rid', 'rid', $column);
$column['description'] = 'Primary Key: {role}.rid for role.';
db_change_field('users_roles', 'rid', 'rid', $column);
@ -470,32 +432,16 @@ function user_update_8002() {
db_drop_unique_key('role', 'name');
// Rename the built-in serial role IDs into the hardcoded machine names.
db_update('role')
->fields(array('rid' => DRUPAL_ANONYMOUS_RID))
->condition('rid', 1)
->execute();
db_update('role')
->fields(array('rid' => DRUPAL_AUTHENTICATED_RID))
->condition('rid', 2)
->execute();
db_update('role_permission')
->fields(array('rid' => DRUPAL_ANONYMOUS_RID))
->condition('rid', 1)
->execute();
db_update('role_permission')
->fields(array('rid' => DRUPAL_AUTHENTICATED_RID))
->condition('rid', 2)
->execute();
db_update('users_roles')
->fields(array('rid' => DRUPAL_ANONYMOUS_RID))
->condition('rid', 1)
->execute();
db_update('users_roles')
->fields(array('rid' => DRUPAL_AUTHENTICATED_RID))
->condition('rid', 2)
->execute();
foreach (array(1, 2) as $rid) {
db_update('role')
->fields(array('rid' => _user_update_map_rid($rid)))
->condition('rid', $rid)
->execute();
db_update('users_roles')
->fields(array('rid' => _user_update_map_rid($rid)))
->condition('rid', $rid)
->execute();
}
}
/**
@ -1087,6 +1033,47 @@ function user_update_8018() {
}
}
/**
* Maps a role id to the new string.
*
* @param int $rid
* A D7 numeric role ID.
*
* @return string
* A D8 string role ID.
*/
function _user_update_map_rid($rid) {
$rid_map = array(
1 => DRUPAL_ANONYMOUS_RID,
2 => DRUPAL_AUTHENTICATED_RID,
);
return isset($rid_map[$rid]) ? $rid_map[$rid] : $rid;
}
/**
* Migrate roles permissions into configuration.
*
* @ingroup config_upgrade
*/
function user_update_8019() {
$db_permissions = db_select('role_permission', 'p')
->fields('p')
->execute()
->fetchAll();
$new_permissions = array();
foreach ($db_permissions as $permission) {
$rid = _user_update_map_rid($permission->rid);
if (!isset($new_permissions[$rid]) || !in_array($permission->permission, $new_permissions[$rid])) {
$new_permissions[$rid][] = $permission->permission;
}
}
foreach ($new_permissions as $rid => $permissions) {
config("user.role.$rid")
->set('permissions', $permissions)
->save();
}
}
/**
* @} End of "addtogroup updates-7.x-to-8.x".
*/

View File

@ -4,12 +4,10 @@ use Drupal\Component\Utility\Crypt;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\comment\Plugin\Core\Entity\Comment;
use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
use Drupal\file\Plugin\Core\Entity\File;
use Drupal\user\Plugin\Core\Entity\User;
use Drupal\user\UserInterface;
use Drupal\user\UserRole;
use Drupal\user\RoleInterface;
use Drupal\Core\Template\Attribute;
use Symfony\Component\HttpFoundation\RedirectResponse;
@ -410,44 +408,44 @@ function user_password($length = 10) {
/**
* Determine the permissions for one or more roles.
*
* @param $roles
* An array whose values are the role IDs of interest, such as $user->roles.
* @param array $roles
* An array of role IDs.
*
* @return
* An array indexed by role ID. Each value is an array whose keys are the
* permission strings for the given role ID.
* @return array
* An array indexed by role ID. Each value is an array of permission strings
* for the given role.
*/
function user_role_permissions($roles) {
$cache = &drupal_static(__FUNCTION__, array());
$role_permissions = $fetch = array();
function user_role_permissions(array $roles) {
if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') {
return _user_role_permissions_update($roles);
}
$entities = entity_load_multiple('user_role', $roles);
$role_permissions = array();
foreach ($roles as $rid) {
if (isset($cache[$rid])) {
$role_permissions[$rid] = $cache[$rid];
}
else {
// Add this rid to the list of those needing to be fetched.
$fetch[] = $rid;
// Prepare in case no permissions are returned.
$cache[$rid] = array();
}
$role_permissions[$rid] = isset($entities[$rid]) ? $entities[$rid]->getPermissions() : array();
}
return $role_permissions;
}
if ($fetch) {
// Get from the database permissions that were not in the static variable.
// Only role IDs with at least one permission assigned will return rows.
$result = db_query("SELECT rid, permission FROM {role_permission} WHERE rid IN (:fetch)", array(':fetch' => $fetch));
foreach ($result as $row) {
$cache[$row->rid][$row->permission] = TRUE;
}
foreach ($fetch as $rid) {
// For every rid, we know we at least assigned an empty array.
$role_permissions[$rid] = $cache[$rid];
}
/**
* Determine the permissions for one or more roles during update.
*
* A separate version is needed because during update the entity system can't
* be used and in non-update situations the entity system is preferred because
* of the hook system.
*
* @param array $roles
* An array of role IDs.
*
* @return array
* An array indexed by role ID. Each value is an array of permission strings
* for the given role.
*/
function _user_role_permissions_update($roles) {
$role_permissions = array();
foreach ($roles as $rid) {
$role_permissions[$rid] = Drupal::config("user.role.$rid")->get('permissions') ?: array();
}
return $role_permissions;
}
@ -490,13 +488,10 @@ function user_access($string, AccountInterface $account = NULL) {
}
$perm = &$drupal_static_fast['perm'];
if (!isset($perm[$account->uid])) {
$role_permissions = user_role_permissions($account->getRoles());
$perms = array();
foreach ($role_permissions as $one_role) {
$perms += $one_role;
$perm[$account->uid] = array();
foreach (user_role_permissions($account->getRoles()) as $role_permissions) {
$perm[$account->uid] += array_fill_keys($role_permissions, TRUE);
}
$perm[$account->uid] = $perms;
}
return isset($perm[$account->uid][$string]);
@ -1759,7 +1754,7 @@ function user_mail_tokens(&$replacements, $data, $options) {
* value.
*/
function user_role_names($membersonly = FALSE, $permission = NULL) {
return array_map(function($item) {
return array_map(function ($item) {
return $item->label();
}, user_roles($membersonly, $permission));
}
@ -1844,12 +1839,9 @@ function user_roles($membersonly = FALSE, $permission = NULL) {
}
if (!empty($permission)) {
$result = db_select('role_permission', 'p')
->fields('p', array('rid'))
->condition('p.rid', array_keys($roles))
->condition('p.permission', $permission)
->execute()->fetchCol();
$roles = array_intersect_key($roles, array_flip($result));
$roles = array_filter($roles, function ($role) use ($permission) {
return $role->hasPermission($permission);
});
}
if (empty($permission)) {
@ -1944,23 +1936,14 @@ function user_role_change_permissions($rid, array $permissions = array()) {
* @see user_role_revoke_permissions()
*/
function user_role_grant_permissions($rid, array $permissions = array()) {
$modules = user_permission_get_modules();
// Grant new permissions for the role.
foreach ($permissions as $name) {
db_merge('role_permission')
->key(array(
'rid' => $rid,
'permission' => $name,
))
->fields(array(
'module' => $modules[$name],
))
->execute();
$role = entity_load('user_role', $rid);
foreach ($permissions as $permission) {
$role->grantPermission($permission);
}
$role->save();
// Clear the user access cache.
drupal_static_reset('user_access');
drupal_static_reset('user_role_permissions');
}
/**
@ -1976,14 +1959,13 @@ function user_role_grant_permissions($rid, array $permissions = array()) {
*/
function user_role_revoke_permissions($rid, array $permissions = array()) {
// Revoke permissions for the role.
db_delete('role_permission')
->condition('rid', $rid)
->condition('permission', $permissions, 'IN')
->execute();
$role = entity_load('user_role', $rid);
foreach ($permissions as $permission) {
$role->revokePermission($permission);
}
$role->save();
// Clear the user access cache.
drupal_static_reset('user_access');
drupal_static_reset('user_role_permissions');
}
function user_multiple_cancel_confirm($form, &$form_state) {
@ -2143,18 +2125,20 @@ function user_build_filter_query(SelectInterface $query) {
// the authenticated role. If so, then all users would be listed, and we can
// skip adding it to the filter query.
if ($key == 'permission') {
$account = entity_create('user', array(
'uid' => 'user_filter',
'roles' => array(DRUPAL_AUTHENTICATED_RID),
));
if (user_access($value, $account)) {
$roles = user_roles(FALSE, $value);
if (isset($roles[DRUPAL_AUTHENTICATED_RID])) {
continue;
}
$users_roles_alias = $query->join('users_roles', 'ur', '%alias.uid = u.uid');
$permission_alias = $query->join('role_permission', 'p', $users_roles_alias . '.rid = %alias.rid');
$query->condition($permission_alias . '.permission', $value);
if (!empty($roles)) {
$value = array_keys($roles);
}
else {
// There's no role that has this permission set value to an impossible
// rid so that no users are matched.
$value = array('');
}
}
elseif ($key == 'role') {
if ($key == 'permission' || $key == 'role') {
$users_roles_alias = $query->join('users_roles', 'ur', '%alias.uid = u.uid');
$query->condition($users_roles_alias . '.rid' , $value);
}
@ -2427,9 +2411,6 @@ function user_modules_installed($modules) {
* Implements hook_modules_uninstalled().
*/
function user_modules_uninstalled($modules) {
db_delete('role_permission')
->condition('module', $modules, 'IN')
->execute();
// Remove any potentially orphan module data stored for users.
drupal_container()->get('user.data')->delete($modules);
}

View File

@ -359,19 +359,7 @@ function user_views_data() {
),
);
// Define the base group of this table. Fields that don't have a group defined
// will go into this field by default.
$data['role_permission']['table']['group'] = t('User');
// Explain how this table joins to others.
$data['role_permission']['table']['join'] = array(
'users' => array(
'left_table' => 'users_roles',
'left_field' => 'rid',
'field' => 'rid',
),
);
$data['role_permission']['permission'] = array(
$data['users_roles']['permission'] = array(
'title' => t('Permission'),
'help' => t('The user permissions.'),
'field' => array(
@ -380,6 +368,7 @@ function user_views_data() {
),
'filter' => array(
'id' => 'user_permissions',
'real field' => 'rid',
),
);

View File

@ -309,7 +309,7 @@ class ManyToOneHelper {
else {
$placeholder = $this->placeholder();
if (count($this->handler->value) > 1) {
$this->query->addWhereExpression(0, "$field $operator($placeholder)", array($placeholder => $value));
$this->handler->query->addWhereExpression(0, "$field $operator($placeholder)", array($placeholder => $value));
}
else {
$this->handler->query->addWhereExpression(0, "$field $operator $placeholder", array($placeholder => $value));

View File

@ -0,0 +1,100 @@
<?php
/**
* @file
* Definition of Drupal\views\Tests\Handler\FieldCounterTest.
*/
namespace Drupal\views\Tests\Handler;
use Drupal\views\Tests\ViewUnitTestBase;
/**
* Tests the Drupal\views\Plugin\views\field\Counter handler.
*/
class FieldCounterTest extends ViewUnitTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('user');
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array('test_view');
public static function getInfo() {
return array(
'name' => 'Field: Counter',
'description' => 'Tests the Drupal\views\Plugin\views\field\Counter handler.',
'group' => 'Views Handlers',
);
}
function testSimple() {
$view = views_get_view('test_view');
$view->setDisplay();
$view->displayHandlers->get('default')->overrideOption('fields', array(
'counter' => array(
'id' => 'counter',
'table' => 'views',
'field' => 'counter',
'relationship' => 'none',
),
'name' => array(
'id' => 'name',
'table' => 'views_test_data',
'field' => 'name',
'relationship' => 'none',
),
));
$view->preview();
$counter = $view->style_plugin->getField(0, 'counter');
$this->assertEqual($counter, 1, format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', array('@expected' => 1, '@counter' => $counter)));
$counter = $view->style_plugin->getField(1, 'counter');
$this->assertEqual($counter, 2, format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', array('@expected' => 2, '@counter' => $counter)));
$counter = $view->style_plugin->getField(2, 'counter');
$this->assertEqual($counter, 3, format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', array('@expected' => 3, '@counter' => $counter)));
$view->destroy();
$view->setDisplay();
$rand_start = rand(5, 10);
$view->displayHandlers->get('default')->overrideOption('fields', array(
'counter' => array(
'id' => 'counter',
'table' => 'views',
'field' => 'counter',
'relationship' => 'none',
'counter_start' => $rand_start
),
'name' => array(
'id' => 'name',
'table' => 'views_test_data',
'field' => 'name',
'relationship' => 'none',
),
));
$view->preview();
$counter = $view->style_plugin->getField(0, 'counter');
$expected_number = 0 + $rand_start;
$this->assertEqual($counter, $expected_number, format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', array('@expected' => $expected_number, '@counter' => $counter)));
$counter = $view->style_plugin->getField(1, 'counter');
$expected_number = 1 + $rand_start;
$this->assertEqual($counter, $expected_number, format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', array('@expected' => $expected_number, '@counter' => $counter)));
$counter = $view->style_plugin->getField(2, 'counter');
$expected_number = 2 + $rand_start;
$this->assertEqual($counter, $expected_number, format_string('Make sure the expected number (@expected) patches with the rendered number (@counter)', array('@expected' => $expected_number, '@counter' => $counter)));
}
// @TODO: Write tests for pager.
function testPager() {
}
}

View File

@ -38,11 +38,6 @@ class FieldUnitTest extends ViewUnitTestBase {
);
}
public function setUp() {
parent::setUp();
$this->installSchema('user', 'role_permission');
}
/**
* Overrides Drupal\views\Tests\ViewTestBase::viewsData().
*/

View File

@ -60,7 +60,6 @@ class DisplayPageTest extends ViewUnitTestBase {
$this->installSchema('system', 'router');
$this->installSchema('system', 'url_alias');
$this->installSchema('system', 'menu_router');
$this->installSchema('user', 'role_permission');
}
/**

View File

@ -26,7 +26,7 @@ abstract class RelationshipJoinTestBase extends PluginUnitTestBase {
* Overrides \Drupal\views\Tests\ViewUnitTestBase::setUpFixtures().
*/
protected function setUpFixtures() {
$this->installSchema('user', array('users', 'users_roles', 'role_permission'));
$this->installSchema('user', array('users', 'users_roles'));
$this->installConfig(array('user'));
parent::setUpFixtures();

View File

@ -80,7 +80,7 @@ class ViewExecutableTest extends ViewUnitTestBase {
}
protected function setUpFixtures() {
$this->installSchema('user', array('users', 'role_permission'));
$this->installSchema('user', array('users'));
$this->installSchema('node', array('node_type', 'node', 'node_field_data'));
$this->installSchema('comment', array('comment', 'node_comment_statistics'));
parent::setUpFixtures();

View File

@ -56,7 +56,6 @@ class ViewPageControllerTest extends ViewUnitTestBase {
parent::setUp();
$this->installSchema('system', 'menu_router');
$this->installSchema('user', 'role_permission');
$this->pageController = new ViewPageController($this->container->get('plugin.manager.entity')->getStorageController('view'), new ViewExecutableFactory());
}