? .project ? sites/all/themes/.DS_Store ? sites/default/.DS_Store ? sites/default/files ? sites/default/settings.php Index: modules/comment/comment.test =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.test,v retrieving revision 1.35 diff -u -p -r1.35 comment.test --- modules/comment/comment.test 1 Jul 2009 12:06:21 -0000 1.35 +++ modules/comment/comment.test 12 Jul 2009 10:21:59 -0000 @@ -173,9 +173,9 @@ class CommentHelperCase extends DrupalWe */ function setAnonymousUserComment($access_comments, $post_comments, $without_approval) { $edit = array(); - $edit['1[access comments]'] = $access_comments; - $edit['1[post comments]'] = $post_comments; - $edit['1[post comments without approval]'] = $without_approval; + $edit['access__comments[1]'] = $access_comments; + $edit['post__comments[1]'] = $post_comments; + $edit['post__comments__without__approval[1]'] = $without_approval; $this->drupalPost('admin/user/permissions', $edit, t('Save permissions')); $this->assertText(t('The changes have been saved.'), t('Anonymous user comments ' . ($access_comments ? 'access comments' : 'not access comments'). '.')); } Index: modules/contact/contact.test =================================================================== RCS file: /cvs/drupal/drupal/modules/contact/contact.test,v retrieving revision 1.25 diff -u -p -r1.25 contact.test --- modules/contact/contact.test 13 Jun 2009 20:40:07 -0000 1.25 +++ modules/contact/contact.test 12 Jul 2009 10:22:00 -0000 @@ -286,7 +286,7 @@ class ContactSitewideTestCase extends Dr // Create edit array from permission. $edit = array(); foreach ($permissions as $name => $value) { - $edit[$rid . '[' . $name . ']'] = $value; + $edit[str_replace(' ', '__', $name) . '[' . $rid . ']'] = $value; } $this->drupalPost('admin/user/permissions', $edit, t('Save permissions')); Index: modules/search/search.test =================================================================== RCS file: /cvs/drupal/drupal/modules/search/search.test,v retrieving revision 1.24 diff -u -p -r1.24 search.test --- modules/search/search.test 3 Jul 2009 19:21:54 -0000 1.24 +++ modules/search/search.test 12 Jul 2009 10:22:00 -0000 @@ -466,14 +466,14 @@ class SearchCommentTestCase extends Drup $this->drupalPost('admin/settings/formats/1', $edit, t('Save configuration')); // Allow anonymous users to search content. $edit = array( - DRUPAL_ANONYMOUS_RID . '[search content]' => 1, + 'search__content[' . DRUPAL_ANONYMOUS_RID . ']' => 1, // @todo Comments are added to search index without checking first whether // anonymous users are allowed to access comments. - DRUPAL_ANONYMOUS_RID . '[access comments]' => 1, + 'access__comments[' . DRUPAL_ANONYMOUS_RID . ']' => 1, // @todo Without this permission, "Login or register to post comments" is // added to the search index. Comment.module is not guilty; that text // seems to be added via node links. - DRUPAL_ANONYMOUS_RID . '[post comments]' => 1, + 'post__comments[' . DRUPAL_ANONYMOUS_RID . ']' => 1, ); $this->drupalPost('admin/user/permissions', $edit, t('Save permissions')); Index: modules/user/user.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.admin.inc,v retrieving revision 1.64 diff -u -p -r1.64 user.admin.inc --- modules/user/user.admin.inc 12 Jul 2009 08:36:35 -0000 1.64 +++ modules/user/user.admin.inc 12 Jul 2009 10:22:02 -0000 @@ -597,52 +597,60 @@ function user_admin_settings() { * @see theme_user_admin_permissions() */ function user_admin_permissions($form_state, $rid = NULL) { + drupal_add_js(drupal_get_path('module', 'user') . '/user.js'); - // Retrieve role names for columns. - $role_names = user_roles(); - if (is_numeric($rid)) { - $role_names = array($rid => $role_names[$rid]); - } - // Fetch permissions for all roles or the one selected role. - $role_permissions = user_role_permissions($role_names); + // Fieldset to search the permissions form. + $form['search'] = array( + '#type' => 'fieldset', + '#weight' => -5, + '#collapsible' => FALSE, + '#title' => t('Search permissions'), + ); + + $form['search']['search_string'] = array( + '#type' => 'textfield', + ); - // Store $role_names for use when saving the data. - $form['role_names'] = array( - '#type' => 'value', - '#value' => $role_names, + $form['search']['search_submit'] = array( + '#type' => 'submit', + '#value' => t('Search'), + '#submit' => array('user_admin_permissions_search_submit'), + // This uses a custom JS function to insert the new content into the page. + // See Drupal.behaviors.permissionsFormAhahSettings in user.js for details. + '#ahah' => array( + 'callback' => 'user_admin_permissions_search_js', + 'keypress' => TRUE, + 'event' => 'click', + ), ); + // Render role/permission overview: - $options = array(); $hide_descriptions = !system_admin_compact_mode(); + $form['permissions'] = array( + '#type' => 'vertical_tabs', + ); + + if (!empty($form_state['storage']['search_string'])) { + $form['permissions']['search_pane'] = _user_admin_permissions_search_form($rid, $form_state['storage']['search_string']); + } foreach (module_implements('permission') as $module) { if ($permissions = module_invoke($module, 'permission')) { + $status = array(); $info = drupal_parse_info_file(drupal_get_path('module', $module) . "/$module.info"); - $form['permission'][] = array( - '#markup' => $info['name'], - '#id' => $module, - ); + $form['permissions'][$module] = array( + '#type' => 'fieldset', + '#title' => $info['name'], + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#description' => '', + ); foreach ($permissions as $perm => $perm_item) { - $options[$perm] = ''; - $form['permission'][$perm] = array( - '#type' => 'item', - '#markup' => $perm_item['title'], - '#description' => $hide_descriptions ? $perm_item['description'] : NULL, - ); - foreach ($role_names as $rid => $name) { - // Builds arrays for checked boxes for each role - if (isset($role_permissions[$rid][$perm])) { - $status[$rid][] = $perm; - } - } + $permission = str_replace(' ', '__', $perm); + $form['permissions'][$module][$permission] = _user_admin_permissions_build_row($perm, $perm_item, $rid); } } } - // Have to build checkboxes here after checkbox arrays are built - foreach ($role_names as $rid => $name) { - $form['checkboxes'][$rid] = array('#type' => 'checkboxes', '#options' => $options, '#default_value' => isset($status[$rid]) ? $status[$rid] : array()); - $form['role_names'][$rid] = array('#markup' => $name, '#tree' => TRUE); - } $form['submit'] = array('#type' => 'submit', '#value' => t('Save permissions')); $form['#attached_js'] = array(drupal_get_path('module', 'user') . '/user.permissions.js'); @@ -651,25 +659,136 @@ function user_admin_permissions($form_st } /** + * Build a row for the user permissions page. + */ +function _user_admin_permissions_build_row($perm, $perm_item, $rid) { + // Retrieve role names. + $role_names = user_roles(); + if (is_numeric($rid)) { + $role_names = array($rid => $role_names[$rid]); + } + // Fetch permissions for all roles or the one selected role. + $role_permissions = user_role_permissions($role_names); + + $hide_descriptions = !system_admin_compact_mode(); + $form = array( + '#tree' => TRUE, + '#theme' => 'user_admin_permissions_fieldset', + '#header' => array(), + ); + $form['name'] = array( + '#markup' => $perm_item['title'], + ); + $form['description'] = array( + '#markup' => $hide_descriptions ? $perm_item['description'] : NULL, + ); + foreach ($role_names as $rid => $name) { + $granted = FALSE; + // Builds arrays for checked boxes for each role + if (isset($role_permissions[$rid][$perm])) { + $granted = TRUE; + } + $form[$rid] = array( + '#type' => 'checkbox', + '#title' => $name, + '#default_value' => $granted, + ); + } + return $form; +} + +/** + * Submit callback for the search button on the modules form. + * + * If a search string is present, store it in $form_state['storage']. + */ +function user_admin_permissions_search_submit($form, &$form_state) { + if (isset($form_state['values']['search_string'])) { + $form_state['storage']['search_string'] = $form_state['values']['search_string']; + } + else { + unset($form_state['storage']['search_string']); + } +} + +/** + * AHAH callback for the search button on the modules form. + */ +function user_admin_permissions_search_js($form, &$form_state) { + if (isset($form['permissions']['search_pane'])) { + $search_form = $form['permissions']['search_pane']; + drupal_json(array('status' => TRUE, 'data' => drupal_render($search_form))); + } +} + +/** + * Creates the search result fieldset for the permissions form. + * + * This returns a fieldset similar to the normal permissions category fieldsets, + * but containing permissions whose names or descriptions match $search_string. + */ +function _user_admin_permissions_search_form($rid, $search_string) { + $permissions = array(); + // Get all available permissions. + foreach (module_implements('permission') as $module) { + if ($module_permissions = module_invoke($module, 'permission')) { + $permissions += $module_permissions; + } + } + + $search_form = array( + '#type' => 'fieldset', + '#weight' => 9999, + '#title' => t('Search results'), + ); + + if (!empty($search_string)) { + // Iterate over the permissions, and add rows for matching names or + // descriptions. + foreach ($permissions as $perm => $perm_item) { + if (stripos($perm_item['title'], $search_string) !== FALSE || + stripos($perm_item['description'], $search_string) !== FALSE) { + $permission = str_replace(' ', '__', $perm); + $search_form[$permission] = _user_admin_permissions_build_row($perm, $perm_item, $rid); + $search_form[$permission] += array( + '#theme' => 'user_admin_permissions_fieldset', + '#header' => array(), + ); + } + } + } + + if (!element_children($search_form)) { + $search_form['info']['#markup'] = t('Your search did not return any results.'); + } + + return $search_form; +} + +/** * Save permissions selected on the administer permissions page. * * @see user_admin_permissions() */ 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(); + foreach ($form_state['values'] as $perm => $values) { + if (is_array($form_state['values'][$perm])) { + $permission_real_name = str_replace('__', ' ', $perm); + $checked = array_filter($form_state['values'][$perm]); + // Delete existing grants for this permission. This handles "unchecking" checkboxes. + db_delete('role_permission') + ->condition('permission', $permission_real_name) + ->execute(); + // Insert new grants. + $query = db_insert('role_permission')->fields(array('rid', 'permission')); + foreach ($checked as $rid => $value) { + $query->values(array( + 'rid' => $rid, + 'permission' => $permission_real_name, + )); + } + $query->execute(); + } } drupal_set_message(t('The changes have been saved.')); @@ -679,36 +798,40 @@ function user_admin_permissions_submit($ } /** + * Theme callback for the admin permissions form. + * + * @param $form + * An associative array containing the structure of the form. + * @ingroup themeable + */ +function theme_user_admin_permissions_fieldset($form) { + $rows = array(); + $output = ''; + $output .= '' . drupal_render($form['name']) . ''; + $output .= '
'; + return $output; +} + +/** * Theme the administer permissions page. * * @ingroup themeable */ function theme_user_admin_permissions($form) { - $roles = user_roles(); - foreach (element_children($form['permission']) as $key) { - $row = array(); - // Module name - if (is_numeric($key)) { - $row[] = array('data' => drupal_render($form['permission'][$key]), 'class' => 'module', 'id' => 'module-' . $form['permission'][$key]['#id'], 'colspan' => count($form['role_names']['#value']) + 1); - } - else { - // Permission row. - $row[] = array( - 'data' => drupal_render($form['permission'][$key]), - 'class' => 'permission', - ); - foreach (element_children($form['checkboxes']) as $rid) { - $row[] = array('data' => drupal_render($form['checkboxes'][$rid][$key]), 'class' => 'checkbox', 'title' => $roles[$rid] . ' : ' . t($key)); - } - } - $rows[] = $row; - } - $header[] = (t('Permission')); - foreach (element_children($form['role_names']) as $rid) { - $header[] = array('data' => drupal_render($form['role_names'][$rid]), 'class' => 'checkbox'); - } $output = theme('system_compact_link'); - $output .= theme('table', $header, $rows, array('id' => 'permissions')); + $output .= drupal_render($form['search']); + $output .= drupal_render($form['permissions']); $output .= drupal_render_children($form); return $output; } Index: modules/user/user.css =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.css,v retrieving revision 1.11 diff -u -p -r1.11 user.css --- modules/user/user.css 14 Jun 2009 08:04:25 -0000 1.11 +++ modules/user/user.css 12 Jul 2009 10:22:02 -0000 @@ -50,3 +50,24 @@ .profile dd { margin: 0 0 1em 0; } + +/** + * Formatting of the user permissions form. + */ +#user-admin-permissions #edit-search { + margin-bottom: 0; + margin-right: 5%; + border-bottom: none; +} + +#user-admin-permissions #edit-search .search-string-wrapper, #user-admin-permissions #edit-search #edit-search-submit { + float: left; +} + +#user-admin-permissions #edit-search .search-string-wrapper { + margin: 0 1em 0 0; +} + +#user-admin-permissions div.vertical-tabs { + margin-top: 0; +} Index: modules/user/user.js =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.js,v retrieving revision 1.15 diff -u -p -r1.15 user.js --- modules/user/user.js 13 Jun 2009 20:40:09 -0000 1.15 +++ modules/user/user.js 12 Jul 2009 10:22:03 -0000 @@ -1,6 +1,8 @@ // $Id: user.js,v 1.15 2009/06/13 20:40:09 dries Exp $ (function ($) { +Drupal.ahah = Drupal.ahah || {}; + /** * Attach handlers to evaluate the strength of any password fields and to check * that its confirmation is correct. @@ -172,4 +174,72 @@ Drupal.behaviors.userSettings = { } }; +/** + * AHAH insertNewContent callback for the search button on the user permissions form. + * + * If no search fieldset is present, this inserts the search fieldset into + * the form and adds a vertical tab for it. If there is already a search fieldset, + * it is replaced by the new one. + */ +Drupal.behaviors.permissionsFormAhahSettings = { + attach: function(context, settings) { + if (Drupal.ahah['edit-search-submit']) { + Drupal.ahah['edit-search-submit'].insertNewContent = function(response, status) { + new_content = $(response.data); + + // Check if there is already a search tab present, and if so, replace it with + // the new one. + // We copy over the existing verticalTab data property to reduce flickering. + if ($('#user-admin-permissions #edit-search-pane').size()) { + var tab = $('#edit-search-pane').data('verticalTab') + tab.fieldset = $(new_content); + $('#user-admin-permissions #edit-search-pane').replaceWith(new_content); + } + // Otherwise, append the search fieldset to the wrapper and add a vertical tab for it. + else { + $('#user-admin-permissions .vertical-tabs-panes').append(new_content); + var tab = new Drupal.verticalTab({ title: $('> legend', new_content).text(), fieldset: $(new_content) }); + var list = new_content.parents().find('.vertical-tabs-panes').siblings('ul.vertical-tabs-list'); + list.append(tab.item); + } + + // Add the tab behavior and styling to the new fieldset. + $(new_content) + .addClass('vertical-tabs-pane') + .data('verticalTab', tab); + + // Give the search tab the focus and update the description. + tab.focus(); + Drupal.permissionsFormSetFieldsetSummary(tab.fieldset); + tab.updateSummary(); + + // Attach behaviors to the new content. + Drupal.attachBehaviors(new_content); + } + } + } +}; + +/** + * Assing the vertical tab callback to update the description to all fieldsets + * on the user permissions form. + */ +Drupal.behaviors.permissionsFormFieldsetSummaries = { + attach: function(context) { + $('#user-admin-permissions .vertical-tabs-panes > fieldset', context).each( function() { + Drupal.permissionsFormSetFieldsetSummary(this); + }); + } +}; + +/** + * Set the summary for a fieldset on the user permissions form. + */ +Drupal.permissionsFormSetFieldsetSummary = function(fieldset) { + $(fieldset).setSummary(function(context) { + permissions = $('.permission-wrapper', context).size(); + return Drupal.formatPlural(permissions, '1 permission.', '!permissions permissions.', { '!permissions': permissions }); + }); +}; + })(jQuery); Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.1011 diff -u -p -r1.1011 user.module --- modules/user/user.module 12 Jul 2009 08:36:35 -0000 1.1011 +++ modules/user/user.module 12 Jul 2009 10:22:07 -0000 @@ -61,6 +61,10 @@ function user_theme() { 'arguments' => array('form' => NULL), 'file' => 'user.admin.inc', ), + 'user_admin_permissions_fieldset' => array( + 'arguments' => array('form' => NULL), + 'file' => 'user.admin.inc', + ), 'user_admin_new_role' => array( 'arguments' => array('form' => NULL), 'file' => 'user.admin.inc', Index: modules/user/user.test =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.test,v retrieving revision 1.45 diff -u -p -r1.45 user.test --- modules/user/user.test 12 Jul 2009 08:36:35 -0000 1.45 +++ modules/user/user.test 12 Jul 2009 10:22:09 -0000 @@ -752,7 +752,7 @@ class UserPermissionsTestCase extends Dr // Add a permission. $this->assertFalse(user_access('administer nodes', $account, TRUE), t('User does not have "administer nodes" permission.')); $edit = array(); - $edit[$rid . '[administer nodes]'] = TRUE; + $edit['administer__nodes[' . $rid . ']'] = TRUE; $this->drupalPost('admin/user/permissions', $edit, t('Save permissions')); $this->assertText(t('The changes have been saved.'), t('Successful save message displayed.')); $this->assertTrue(user_access('administer nodes', $account, TRUE), t('User now has "administer nodes" permission.')); @@ -760,7 +760,7 @@ class UserPermissionsTestCase extends Dr // Remove a permission. $this->assertTrue(user_access('access user profiles', $account, TRUE), t('User has "access user profiles" permission.')); $edit = array(); - $edit[$rid . '[access user profiles]'] = FALSE; + $edit['access__user__profiles[' . $rid . ']'] = FALSE; $this->drupalPost('admin/user/permissions', $edit, t('Save permissions')); $this->assertText(t('The changes have been saved.'), t('Successful save message displayed.')); $this->assertFalse(user_access('access user profiles', $account, TRUE), t('User no longer has "access user profiles" permission.'));