Index: modules/role_weights/README.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/role_weights/README.txt,v
retrieving revision 1.4
diff -u -r1.4 README.txt
--- modules/role_weights/README.txt	6 Jun 2006 17:40:33 -0000	1.4
+++ modules/role_weights/README.txt	26 Jun 2006 18:00:26 -0000
@@ -4,7 +4,7 @@
   Last updated 06/06/2006
 ========================================
 
-A small utility module to allow site admins to specify certain weights for user roles. Its
+A small utility module to allow site admins to specify certain weights for user roles. It's
 not much use on its own, more of a helper module for other modules which require this
 functionality.
 
@@ -23,8 +23,7 @@
 ========================================
 1. Upload the role_weights directory to your modules directory.
 2. Enable the module under admin -> modules.
-3. Visit admin -> access control to allow certain roles to set role weights (see notes below).
-4. Visit admin -> access control and choose the 'role weights' tab to change role weights
+3. Visit admin -> access control and choose a role to change role weights
 
 
 Usage (with Views)
@@ -56,7 +55,6 @@
 
 To do
 ========================================
-* Form alter - get the weights into the roles table/form somehow?
 * Tidy up the role weights form, add help text - see http://drupal.org/node/61669
 * Harder testing - can anyone break it?
 * Improve views support - look at fields, filters and arguments
Index: modules/role_weights/role_weights.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/role_weights/role_weights.module,v
retrieving revision 1.7
diff -u -r1.7 role_weights.module
--- modules/role_weights/role_weights.module	6 Jun 2006 17:40:33 -0000	1.7
+++ modules/role_weights/role_weights.module	26 Jun 2006 17:57:47 -0000
@@ -17,54 +17,119 @@
 }
 
 /**
- * Implementation of hook_menu().
- */
-function role_weights_menu($may_cache) {
-  global $user;
-  $items = array();
-
-  if ($may_cache) {
-    $items[] = array(
-      'path' => 'admin/access/roleweights',
-      'title' => t('role weights'),
-      'access' => user_access('administer access control'),
-      'callback' => 'role_weights_admin',
-      'type' => MENU_LOCAL_TASK,
-    );
+ * 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_id, &$form) {
+  // Alter the 'user_admin_new_role' form to retheme.
+  if ($form_id == 'user_admin_new_role') {
+    $form['#pre_render'][] = 'role_weights_admin_new_role_set_theme';
   }
+  else if ($form_id == 'user_admin_role') {
+    $rid = arg(4);
+    // Lock the anonymous and authenticated roles.
+    if (in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
+      $form['name'] = array(
+        '#type' => 'markup',
+        '#value' => t('<strong>%name</strong> (locked)', array('%name' => $form['name']['#default_value'])),
+        '#weight' => -1
+      );
+    }
 
-  return $items;
+    $weight = role_weights_get_weight($rid);
+    $form['weight'] = array(
+      '#type' => 'weight',
+      '#title' => t('Weight'),
+      '#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'] = 10;
+    $form['delete']['#weight'] = 10;
+    $form['#submit']['role_weights_admin_role_submit'] = array();
+  }
 }
 
 /**
- * Admin page for setting role weights.
+ * Set the theme function before rendering. Called by a #pre_render item.
+ *
+ * This needs to be done in pre_render because drupal_get_form uses a
+ * $form_id .'_theme' function if present for the #theme value.
  */
-function role_weights_admin() {
-
-  $user_roles = user_roles();
+function role_weights_admin_new_role_set_theme($form_id, &$form) {
+  $form['#theme'] = 'role_weights_admin_new_role';
+}
 
-  // for each role, output a dropdown select with weights
-  foreach ($user_roles as $rid => $role_name) {
-    $weight = role_weights_get_weight($rid);
-    $form['roles'][$rid] = array(
-      '#type' => 'weight',
-      '#title' => t('Weight for %role', array('%role' => $role_name)),
-      '#default_value' => $weight,
-      '#weight' => $weight,
-    );
+/**
+ * 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 then in the role
+ * admin form instead.
+ */
+function theme_role_weights_admin_new_role($form) {
+  $header = array(t('Name'), t('Operations'));
+  foreach (user_roles() as $rid => $name) {
+    $rows[] = array($name, l(t('edit'), 'admin/access/roles/edit/'. $rid));
   }
+  $rows[] = array(form_render($form['name']), form_render($form['submit']));
 
-  $form['submit'] = array('#type' => 'submit', '#value' => t('Save weights'));
-  return drupal_get_form('role_weights_admin', $form);
+  return theme('table', $header, $rows);
 }
 
 /**
  * Submission from role_weights_admin form.
  */
-function role_weights_admin_submit($form_id, $form_values) {
-  _role_weights_set_weights($form_values);
-  drupal_set_message(t('The role weights were saved.'));
-  return 'admin/access/roleweights';
+function role_weights_admin_role_submit($form_id, $form_values) {
+  $id = arg(4);
+  switch ($_POST['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_values['name'], $id);
+
+      // Now set weights.
+      _role_weights_set_weight($id, $form_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:
+      $result = db_query('SELECT DISTINCT(ur1.uid) FROM {users_roles} ur1 LEFT JOIN {users_roles} ur2 ON ur2.uid = ur1.uid WHERE ur1.rid = %d AND ur2.rid != ur1.rid', $id);
+      $uid = array();
+  
+      while ($u = db_fetch_object($result)) {
+        $uid[] = $u->uid;
+      }
+  
+      if ($uid) {
+        db_query('DELETE FROM {users_roles} WHERE rid = %d AND uid IN (%s)', $id, implode(', ', $uid));
+      }
+  
+      // Now delete weight data.
+      db_query('DELETE FROM {role_weights} WHERE rid = %d', $id);
+
+      drupal_set_message(t('The role has been deleted.'));
+      break;
+  }
+  return 'admin/access/roles';
 }
 
 /**
@@ -94,7 +159,7 @@
   $role_weights = _role_weights_get_weights();
   arsort($role_weights);
 
-  // run through $roles, returning FIRST role matched
+  // Run through $roles, returning FIRST role matched
   foreach ($role_weights as $rid => $weight) {
     if (array_key_exists($rid, $roles)) {
       return array('rid' => $rid, 'name' => $roles[$rid]);
@@ -105,21 +170,16 @@
 }
 
 /**
- * Sets role weights
+ * Sets role weight for a role based on form input.
  */
-function _role_weights_set_weights($weights) {
-  foreach ($weights as $rid => $weight) {
-    $result = db_query('SELECT count(rid) AS count FROM role_weights WHERE rid=%d', $rid);
-    $row = db_fetch_object($result);
-    if ($row->count == 0) {
-      db_query('INSERT INTO role_weights (rid, weight) VALUES (%d, %d)', $rid, $weight);
-    }
-    else {
-      db_query('UPDATE role_weights SET weight=%d WHERE rid=%d', $weight, $rid);
-    }
+function _role_weights_set_weight($rid, $weight) {
+  $exists = db_num_rows(db_query('SELECT * FROM {role_weights} WHERE rid = %d', $rid));
+  if ($exists) {
+    db_query('UPDATE {role_weights} SET weight=%d WHERE rid=%d', $weight, $rid);
+  }
+  else {
+    db_query('INSERT INTO {role_weights} (rid, weight) VALUES (%d, %d)', $rid, $weight);
   }
-
-  // TODO: tidy up 'old' rows - ie where role does not exist, or weight is not set?
 }
 
 /**
@@ -127,7 +187,7 @@
  */
 function _role_weights_get_weights() {
   $weights = array();
-  $result = db_query('SELECT * FROM role_weights');
+  $result = db_query('SELECT * FROM {role_weights}');
   while ($row = db_fetch_object($result)) {
     $weights[$row->rid] = $row->weight;
   }
