diff --git a/modules/block/block.module b/modules/block/block.module index cc1e63ba4c2283475a2a287ba762401e50ed1f5e..630555ba4c5353facdcfd6505502553f34bf7191 100644 --- a/modules/block/block.module +++ b/modules/block/block.module @@ -853,6 +853,17 @@ function template_preprocess_block(&$variables) { $variables['template_files'][] = 'block-' . $variables['block']->module . '-' . $variables['block']->delta; } +/** + * Implement hook_user_role_delete(). + * + * Remove deleted role from blocks that use it. + */ +function block_user_role_delete($role) { + db_delete('block_role') + ->condition('rid', $role->rid) + ->execute(); +} + /** * Implement hook_filter_format_delete(). */ diff --git a/modules/filter/filter.module b/modules/filter/filter.module index ccc7bb101daed06eccb7a98c90e3afb64b1ca3ab..71df8fcaa16497e87d56fd787838eec871650805 100644 --- a/modules/filter/filter.module +++ b/modules/filter/filter.module @@ -963,3 +963,15 @@ function _filter_autop($text) { /** * @} End of "Standard filters". */ + +/** + * Implement hook_user_role_delete(). + * + * Remove deleted role from formats that use it. + */ +function filter_user_role_delete($role) { + db_update('filter_format') + ->expression('roles', 'REPLACE(roles, :rid, :replacement)', array(':rid' => ',' . $role->rid, ':replacement' => '')) + ->condition('roles', '%,' . $role->rid . '%', 'LIKE') + ->execute(); +} diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php index 8ef61367aa4120ae1a3320a5a90ab6b8414386d6..822a92a15500b8d6bf41a048d5d125067b2de041 100644 --- a/modules/simpletest/drupal_web_test_case.php +++ b/modules/simpletest/drupal_web_test_case.php @@ -892,26 +892,19 @@ protected function drupalCreateRole(array $permissions, $name = NULL) { $name = $this->randomName(); } + // Check the all the permissions strings are valid. if (!$this->checkPermissions($permissions)) { return FALSE; } // Create new role. - db_insert('role') - ->fields(array('name' => $name)) - ->execute(); - $role = db_query('SELECT * FROM {role} WHERE name = :name', array(':name' => $name))->fetchObject(); - $this->assertTrue($role, t('Created role of name: @name, id: @rid', array('@name' => $name, '@rid' => (isset($role->rid) ? $role->rid : t('-n/a-')))), t('Role')); + $role = new stdClass(); + $role->name = $name; + user_role_save($role); + user_role_set_permissions($role->name, $permissions); + + $this->assertTrue(isset($role->rid), t('Created role of name: @name, id: @rid', array('@name' => $name, '@rid' => (isset($role->rid) ? $role->rid : t('-n/a-')))), t('Role')); if ($role && !empty($role->rid)) { - // Assign permissions to role and mark it for clean-up. - $query = db_insert('role_permission')->fields(array('rid', 'permission')); - foreach ($permissions as $permission_string) { - $query->values(array( - 'rid' => $role->rid, - 'permission' => $permission_string, - )); - } - $query->execute(); $count = db_query('SELECT COUNT(*) FROM {role_permission} WHERE rid = :rid', array(':rid' => $role->rid))->fetchField(); $this->assertTrue($count == count($permissions), t('Created permissions: @perms', array('@perms' => implode(', ', $permissions))), t('Role')); return $role->rid; diff --git a/modules/system/system.install b/modules/system/system.install index df678015aed23ccb4ef74af64addd0051a05c168..613f029be56835677e9e3622023f4057cb71e9aa 100644 --- a/modules/system/system.install +++ b/modules/system/system.install @@ -385,21 +385,6 @@ function system_install() { ->execute(); } - $query = db_insert('role_permission')->fields(array('rid', 'permission')); - // Anonymous role permissions. - $query->values(array( - 'rid' => DRUPAL_ANONYMOUS_RID, - 'permission' => 'access content', - )); - - // Authenticated role permissions. - foreach (array('access comments', 'access content', 'post comments', 'post comments without approval', 'view own unpublished content') as $permission) { - $query->values(array( - 'rid' => DRUPAL_AUTHENTICATED_RID, - 'permission' => $permission, - )); - } - $query->execute(); variable_set('theme_default', 'garland'); diff --git a/modules/user/user.admin.inc b/modules/user/user.admin.inc index b7f3ff4a1a7febfae831add0f0424e990a778793..99948a3579e10706e054709e2e54797e03804645 100644 --- a/modules/user/user.admin.inc +++ b/modules/user/user.admin.inc @@ -663,19 +663,8 @@ function user_admin_permissions($form_state, $rid = NULL) { */ function user_admin_permissions_submit($form, &$form_state) { foreach ($form_state['values']['role_names'] as $rid => $name) { - $checked = array_filter($form_state['values'][$rid]); - // Delete existing permissions for the role. This handles "unchecking" checkboxes. - db_delete('role_permission') - ->condition('rid', $rid) - ->execute(); - $query = db_insert('role_permission')->fields(array('rid', 'permission')); - foreach ($checked as $permission) { - $query->values(array( - 'rid' => $rid, - 'permission' => $permission, - )); - } - $query->execute(); + $permissions = array_filter($form_state['values'][$rid]); + user_role_set_permissions($rid, $permissions); } drupal_set_message(t('The changes have been saved.')); @@ -776,13 +765,13 @@ function user_admin_role() { function user_admin_role_validate($form, &$form_state) { if ($form_state['values']['name']) { if ($form_state['values']['op'] == t('Save role')) { - $existing_role = (bool) db_query_range("SELECT 1 FROM {role} WHERE name = :name AND rid <> :rid", array(':name' => $form_state['values']['name'], ':rid' => $form_state['values']['rid']), 0, 1)->fetchField(); - if ($existing_role) { + $role = user_role_load($form_state['values']['name']); + if ($role && $role->rid != $form_state['values']['rid']) { form_set_error('name', t('The role name %name already exists. Please choose another role name.', array('%name' => $form_state['values']['name']))); } } elseif ($form_state['values']['op'] == t('Add role')) { - if ((bool) db_query_range('SELECT 1 FROM {role} WHERE name = :name', array(':name' => $form_state['values']['name']), 0, 1)->fetchField()) { + if (user_role_load($form_state['values']['name'])) { form_set_error('name', t('The role name %name already exists. Please choose another role name.', array('%name' => $form_state['values']['name']))); } } @@ -793,31 +782,17 @@ function user_admin_role_validate($form, &$form_state) { } function user_admin_role_submit($form, &$form_state) { + $role = (object)$form_state['values']; if ($form_state['values']['op'] == t('Save role')) { - db_update('role') - ->fields(array('name' => $form_state['values']['name'])) - ->condition('rid', $form_state['values']['rid']) - ->execute(); + user_role_save($role); drupal_set_message(t('The role has been renamed.')); } elseif ($form_state['values']['op'] == t('Delete role')) { - db_delete('role') - ->condition('rid', $form_state['values']['rid']) - ->execute(); - db_delete('role_permission') - ->condition('rid', $form_state['values']['rid']) - ->execute(); - // Update the users who have this role set: - db_delete('users_roles') - ->condition('rid', $form_state['values']['rid']) - ->execute(); - + user_role_delete($form_state['values']['rid']); drupal_set_message(t('The role has been deleted.')); } elseif ($form_state['values']['op'] == t('Add role')) { - db_insert('role') - ->fields(array('name' => $form_state['values']['name'])) - ->execute(); + user_role_save($role); drupal_set_message(t('The role has been added.')); } $form_state['redirect'] = 'admin/config/people/roles'; diff --git a/modules/user/user.api.php b/modules/user/user.api.php index e3c706555f67ab8fc32433af6b1c13be8ddb9a81..88d4c0fa1016b2040c4571edf1c0a844f336a180 100644 --- a/modules/user/user.api.php +++ b/modules/user/user.api.php @@ -422,6 +422,66 @@ function hook_user_view($account) { } } +/** + * Inform other modules that a user role has been added. + * + * Modules implementing this hook can act on the user role object when saved to + * the database. It's recommended that you implement this hook if your module + * adds additional data to user roles object. The module should save its custom + * additions to the database. + * + * @param $role + * A user role object. + */ +function hook_user_role_insert($role) { + // Save extra fields provided by the module to user roles. + db_insert('my_module_table') + ->fields(array( + 'rid' => $role->rid, + 'role_description' => $role->description, + )) + ->execute(); +} + +/** + * Inform other modules that a user role has been updated. + * + * Modules implementing this hook can act on the user role object when updated. + * It's recommended that you implement this hook if your module adds additional + * data to user roles object. The module should save its custom additions to + * the database. + * + * @param $role + * A user role object. + */ +function hook_user_role_update($role) { + // Save extra fields provided by the module to user roles. + db_merge('my_module_table') + ->key(array('rid' => $role->rid)) + ->fields(array( + 'role_description' => $role->description + )) + ->execute(); +} + +/** + * Inform other modules that a user role has been deleted. + * + * This hook allows you act when a user role has been deleted. + * If your module stores references to roles, it's recommended that you + * implement this hook and delete existing instances of the deleted role + * in your module database tables. + * + * @param $role + * The $role object being deleted. + */ +function hook_user_role_delete($role) { + // Delete existing instances of the deleted role. + db_delete('my_module_table') + ->condition('rid', $role->rid) + ->execute(); +} + /** * @} End of "addtogroup hooks". */ diff --git a/modules/user/user.module b/modules/user/user.module index 0b25f3e44962835cab5d64145e61e3f0660a3607..cc7c83d99bdd2e2cd904997dc3c0a0c69e44c801 100644 --- a/modules/user/user.module +++ b/modules/user/user.module @@ -2206,6 +2206,114 @@ function user_roles($membersonly = FALSE, $permission = NULL) { return array_filter($roles); } +/** + * Fetch a user role from database. + * + * @param $role + * A string with the role name, or an integer with the role ID. + * @return + * A fully-loaded role object if a role with the given name or ID + * exists, FALSE otherwise. + */ +function user_role_load($role) { + $field = is_int($role) ? 'rid' : 'name'; + return db_select('role', 'r') + ->fields('r') + ->condition($field, $role) + ->execute() + ->fetchObject(); +} +/** + * Save a user role to the database. + * + * @param $role + * A role object to modify or add. If $role->rid is not specified, a new + * role will be created. + * @return + * Status constant indicating if role was created or updated. + * Failure to write the user role record will return FALSE. Otherwise. + * SAVED_NEW or SAVED_UPDATED is returned depending on the operation + * performed. + */ +function user_role_save($role) { + if ($role->name) { + // Prevent leading and trailing spaces in role names. + $role->name = trim($role->name); + } + if (!empty($role->rid) && $role->name) { + $status = drupal_write_record('role', $role, 'rid'); + module_invoke_all('user_role_update', $role); + } + else { + $status = drupal_write_record('role', $role); + module_invoke_all('user_role_insert', $role); + } + + return $status; +} + +/** + * Delete a user role from database. + * + * @param $role + * A string with the role name, or an integer with the role ID. + */ +function user_role_delete($role) { + $role = user_role_load($role); + + db_delete('role') + ->condition('rid', $role->rid) + ->execute(); + db_delete('role_permission') + ->condition('rid', $role->rid) + ->execute(); + // Update the users who have this role set: + db_delete('users_roles') + ->condition('rid', $role->rid) + ->execute(); + + // Clear the user access cache. + user_access(NULL, NULL, TRUE); + + module_invoke_all('user_role_delete', $role); +} + +/** + * Assign permissions to a user role. + * + * @param $role + * A string with the role name, or an integer with the role ID. + * @param $permissions + * An array of permissions strings. + * @param $merge + * A boolean indicating whether to add permissions or to merge + * with all existing permissions. + */ +function user_role_set_permissions($role, array $permissions = array(), $merge = FALSE) { + $role = user_role_load($role); + if (!$merge) { + // Delete existing permissions for the role. + db_delete('role_permission') + ->condition('rid', $role->rid) + ->execute(); + } + + // Assign the new permissions for the role. + foreach ($permissions as $permission_string) { + db_merge('role_permission') + ->key(array( + 'rid' => $role->rid, + 'permission' => $permission_string, + )) + ->execute(); + } + + // Clear the user access cache. + user_access(NULL, NULL, TRUE); + + return TRUE; +} + /** * Implement hook_user_operations(). */ diff --git a/profiles/default/default.install b/profiles/default/default.install index 7a81aecd52349797a8c6a8eed5a15b0af086fce7..60e5d012e0ed12d09d52938a41fd8640a7229288 100644 --- a/profiles/default/default.install +++ b/profiles/default/default.install @@ -183,20 +183,18 @@ function default_install() { ))->execute(); db_insert('taxonomy_vocabulary_node_type')->fields(array('vid' => $vid, 'type' => 'article'))->execute(); - // Create a default role for site administrators. - $rid = db_insert('role')->fields(array('name' => 'administrator'))->execute(); + // Enable default permissions for system roles. + user_role_set_permissions(DRUPAL_ANONYMOUS_RID, array('access content')); + user_role_set_permissions(DRUPAL_AUTHENTICATED_RID, array('access content', 'access comments', 'post comments', 'post comments without approval')); + + // Create a default role for site administrators, with all available permissions assigned. + $admin_role = new stdClass(); + $admin_role->name = 'administrator'; + user_role_save($admin_role); + user_role_set_permissions($admin_role->name, array_keys(module_invoke_all('permission'))); // Set this as the administrator role. - variable_set('user_admin_role', $rid); - - // Assign all available permissions to this role. - foreach (module_invoke_all('permission') as $key => $value) { - db_insert('role_permission') - ->fields(array( - 'rid' => $rid, - 'permission' => $key, - ))->execute(); - } + variable_set('user_admin_role', $admin_role->rid); // Update the menu router information. menu_rebuild(); diff --git a/profiles/expert/expert.install b/profiles/expert/expert.install index bcb6cfff8d7eadb398086bf40c274e2cc347721d..4693b84b4814c073dfad1097f3295cd235f69289 100644 --- a/profiles/expert/expert.install +++ b/profiles/expert/expert.install @@ -66,6 +66,10 @@ function expert_install() { $query->values($record); } $query->execute(); + + // Enable default permissions for system roles. + user_role_set_permissions(DRUPAL_ANONYMOUS_RID, array('access content')); + user_role_set_permissions(DRUPAL_AUTHENTICATED_RID, array('access content', 'access comments', 'post comments', 'post comments without approval')); }