--- role_weights.module +++ role_weights.module @@ -34,6 +34,16 @@ 'access arguments' => array('administer users'), 'type' => MENU_NORMAL_ITEM, ); + + $items['admin/user/roles/weights'] = array( + 'title' => 'Role Weights', + 'description' => "Enable sorting roles by weight on the Roles and Permissions configuration pages.", + 'page callback' => 'drupal_get_form', + 'page arguments' => array('role_weights_sort'), + 'access arguments' => array('administer users'), + 'type' => MENU_NORMAL_ITEM, + ); + return $items; } @@ -42,8 +52,8 @@ */ function role_weights_theme($existing, $type, $theme, $path) { return array( - 'role_weights_admin_new_role' => array( - 'arguments' => array('form' => NULL), + 'role_weights_sort' => array( + 'arguments' => array('form' => array()), ), ); } @@ -65,151 +75,6 @@ } /** - * Implementation of hook_form_alter(). - * - * User.module's role handling is not fully Forms API - * compliant, in that it doesn't trigger drupal_submit_form, - * instead directly reading in the $_POST['edit'] - * array. Here we 'fix' this problem by altering the - * submit behavior. This way, we can add to existing - * role forms, and also act on role deletion (deleting - * role_weights). - */ -function role_weights_form_alter(&$form, &$form_state, $form_id) { - - // Alter the 'user_admin_new_role' form to retheme. - if ($form_id == 'user_admin_new_role') { - $form['#theme'] = 'role_weights_admin_new_role'; - } - elseif ($form_id == 'user_admin_role') { - $rid = arg(4); - _role_weights_shift_rid($rid, FALSE); - - // Lock the anonymous and authenticated roles. - if (in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) { - switch ($rid) { - case DRUPAL_ANONYMOUS_RID: - $name = 'anonymous user'; - break; - case DRUPAL_AUTHENTICATED_RID: - $name = 'authenticated user'; - break; - } - - $form['#prefix'] = t('@name (locked)', array('@name' => $name)); - - // Pass the name and rid as values, so that they will register properly on submit. - $form['name'] = array( - '#type' => 'value', - '#value' => $name, - ); - $form['rid'] = array( - '#type' => 'value', - '#value' => $rid, - ); - } - - $weight = role_weights_get_weight($rid); - $form['weight'] = array( - '#type' => 'weight', - '#title' => t('Weight'), - '#description' => t('Set a lower number to have this role take precedence over other roles.'), - '#default_value' => $weight, - ); - // By changing the values of the buttons, we force - // user_admin_role() to bypass its custom handling of - // form submission and instead use the regular Forms API - // method of building and submitting the form. - $form['submit']['#value'] = t('Save'); - $form['delete']['#value'] = t('Delete'); - // Reset weights so that the 'weight' field doesn't - // appear below the buttons. - $form['submit']['#weight'] = 9; - $form['delete']['#weight'] = 10; - $form['#submit'][] = 'role_weights_admin_role_submit'; - } - elseif ($form_id == 'user_admin_perm' && variable_get('role_weights_reorder_forms', FALSE)) { - // For each role, fetch the weight, and add as a #weight on the row names and checkboxes - foreach ($form['checkboxes'] as $key => $value) { - if (is_numeric($key)) { - $weight = role_weights_get_weight($key); - $form['checkboxes'][$key]['#weight'] = $weight; - $form['role_names'][$key]['#weight'] = $weight; - } - } - // Resort according to the adjusted weights - uasort($form['checkboxes'], 'element_sort'); - uasort($form['role_names'], 'element_sort'); - } -} - -/** - * Theme the 'user_admin_new_role' form. - * - * Based on theme_user_admin_new_role(), this version - * doesn't lock anonymous and authenticated user - * links, as we need to be able to navigate to them - * to provide weights. We will lock them in the role - * admin form instead. - * - */ -function theme_role_weights_admin_new_role($form) { - $header = array(t('Name'), array('data' => t('Operations'), 'colspan' => 2)); - - $user_roles = user_roles(); - if (variable_get('role_weights_reorder_forms', FALSE)) { - uksort($user_roles, '_role_weights_rid_compare'); - } - - foreach ($user_roles as $rid => $name) { - $edit_permissions = l(t('edit permissions'), 'admin/user/permissions/'. $rid); - - // Drupal core redirects if the rid is DRUPAL_ANONYMOUS_RID or DRUPAL_AUTHENTICATED_RID. - // We prevent this by shifting the rid. - _role_weights_shift_rid($rid); - $rows[] = array($name, l(t('edit role'), 'admin/user/roles/edit/'. $rid), $edit_permissions); - } - $rows[] = array(drupal_render($form['name']), array('data' => drupal_render($form['submit']), colspan => 2)); - - return drupal_render($form) . theme('table', $header, $rows); -} - -/** - * Submission from role_weights_admin form. - */ -function role_weights_admin_role_submit($form, &$form_state) { - $id = arg(4); - _role_weights_shift_rid($id, FALSE); - - switch ($form_state['values']['op']) { - case t('Save'): - // Handle the role name update previously done in user_admin_role(). - db_query("UPDATE {role} SET name = '%s' WHERE rid = %d", $form_state['values']['name'], $id); - - // Now set weights. - _role_weights_set_weight($id, $form_state['values']['weight']); - drupal_set_message(t('The changes have been saved.')); - break; - case t('Delete'): - // Handle the role deletion previously done in user_admin_role(). - db_query('DELETE FROM {role} WHERE rid = %d', $id); - db_query('DELETE FROM {permission} WHERE rid = %d', $id); - - // Update the users who have this role set: - db_query('DELETE FROM {users_roles} WHERE rid = %d', $id); - - // Now delete weight data. - db_query('DELETE FROM {role_weights} WHERE rid = %d', $id); - - drupal_set_message(t('The role has been deleted.')); - break; - } - - $form_state['redirect'] = 'admin/user/roles'; - $form_state['rid'] = $id; -} - -/** * Get roles list with specified weights. * * @param $refresh @@ -386,3 +251,96 @@ return $tokens; } } + +/** + * Form builder to list and manage role weights. + * + * @ingroup forms + * @see role_weights_sort_submit() + * @see theme_role_weights_sort() + */ +function role_weights_sort() { + $form = array(); + + $weights = array(); + $result = db_query('SELECT rw.weight, r.* FROM {role} AS r LEFT JOIN {role_weights} AS rw ON rw.rid=r.rid ORDER BY rw.weight'); + while ($row = db_fetch_object($result)) { + if(!isset($row->weight)) { + $row->weight = 0; + } + $weights[] = $row; + } + + $form = array('#tree' => TRUE); + + foreach ($weights as $role) { + $form[$role->rid]['#role'] = (array)$role; + $form[$role->rid]['name'] = array('#value' => check_plain($role->name)); + $form[$role->rid]['weight'] = array('#type' => 'weight', '#delta' => 10, '#default_value' => $role->weight); + if ($role->rid != DRUPAL_ANONYMOUS_RID && $role->rid != DRUPAL_AUTHENTICATED_RID) { + $form[$role->rid]['edit'] = array('#value' => l(t('edit role'), "admin/user/roles/edit/$role->rid")); + } + else { + $form[$role->rid]['edit'] = array('#value' => t('locked')); + } + + } + + // Only make this form include a submit button and weight if more than one + // role exists. + if (count($weights) > 1) { + $form['submit'] = array('#type' => 'submit', '#value' => t('Save')); + } + + return $form; +} + +/** + * Submit handler for role weights. Updates changed role weights. + * + * @see role_weights_sort() + */ +function role_weights_sort_submit($form, &$form_state) { + foreach ($form_state['values'] as $rid => $role) { + if (is_numeric($rid) && $form[$rid]['#role']['weight'] != $form_state['values'][$rid]['weight']) { + $form[$rid]['#role']['weight'] = $form_state['values'][$rid]['weight']; + _role_weights_set_weight($rid, $form[$rid]['#role']['weight']); + } + } +} + +/** + * Theme the role weights as a sortable list of roles. + * + * @ingroup themeable + * @see role_weights_sort() + */ +function theme_role_weights_sort($form) { + $rows = array(); + foreach (element_children($form) as $key) { + if (isset($form[$key]['name'])) { + $role = &$form[$key]; + + $row = array(); + $row[] = drupal_render($role['name']); + if (isset($role['weight'])) { + $role['weight']['#attributes']['class'] = 'role-weight'; + $row[] = drupal_render($role['weight']); + } + $row[] = drupal_render($role['edit']); + $rows[] = array('data' => $row, 'class' => 'draggable'); + } + } + if (empty($rows)) { + $rows[] = array(array('data' => t('No role available.'), 'colspan' => '5')); + } + + $header = array(t('Name')); + if (isset($form['submit'])) { + $header[] = t('Weight'); + drupal_add_tabledrag('role', 'order', 'sibling', 'role-weight'); + } + $header[] = array('data' => t('Operations'), 'colspan' => '3'); + return theme('table', $header, $rows, array('id' => 'role')) . drupal_render($form); +} +