--- node_privacy_byrole.orig	2005-06-30 04:00:40.000000000 +0200
+++ node_privacy_byrole.module	2005-07-07 16:32:28.000000000 +0200
@@ -179,6 +179,7 @@
       }
       break;
     case 'validate':
+      $edit = $_POST['edit'];
       if (variable_get('node_privacy_byrole_enabled', FALSE)) {
         _node_privacy_byrole_set_defaults($node, !$user_has_meta_perm);
       }
@@ -188,6 +189,10 @@
           $node->uid = $row->uid;
         }
       }
+      // user selected 'custom', but did not choose permissions yet
+      if ($edit['node_privacy_byrole_rule'] == 'custom' && !$edit['node_privacy_byrole_custom']) {
+        form_set_error('node_privacy_byrole_rule', t('Please now choose custom permissions'));
+      }
       break;
     case 'settings':
       return array('Node privacy by role' => node_privacy_byrole_workflow_settings($node));
@@ -204,7 +209,7 @@
       break;
     case 'update':
       if ($user_has_meta_perm) {
-        node_privacy_byrole_update_permissions($node);
+        node_privacy_byrole_save_permissions($node);
       }
       break;
   }
@@ -307,15 +312,30 @@
 function node_privacy_byrole_save_permissions(&$node) {
   global $user;
 
+  // delete permissions
+  db_query('DELETE FROM {node_access} WHERE nid = %d AND realm = \'node_privacy_byrole_role\'', $node->nid); 
+
+  $privacy_rules = variable_get('privacy_roles');
   $roleids_array = array_keys(user_roles());
-  $results = db_query('SELECT * FROM {role}');
+
+  // user selected a permission
+  if (array_key_exists($node->node_privacy_byrole_rule, $privacy_rules)) {
+    $privacy_rule = $privacy_rules[$node->node_privacy_byrole_rule];
+    foreach($roleids_array as $roleid) {
+      $edit_field = 'node_privacy_byrole_foredit_'.$roleid;
+      $view_field = 'node_privacy_byrole_forview_'.$roleid;
+      $node->$edit_field = $privacy_rule[$roleid]['edit'];
+      $node->$view_field = $privacy_rule[$roleid]['view'];
+    }
+  }
+  
+  // now save the permissions
   foreach($roleids_array as $roleid) {
     $edit_perm_field = 'node_privacy_byrole_foredit_'. $roleid;
     $view_perm_field = 'node_privacy_byrole_forview_'. $roleid; 
-    $edit_perm = isset($node->$edit_perm_field) ? $node->$edit_perm_field : 0;
-    $view_perm = $edit_perm ? 1 : $node->$view_perm_field;
+    $edit_perm = (bool)$node->$edit_perm_field;
+    $view_perm = $edit_perm ? 1 : (bool)$node->$view_perm_field;
     db_query('INSERT INTO {node_access} (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (%d, %d, \'node_privacy_byrole_role\', %d, %d, %d)', $node->nid, $roleid, $view_perm, $edit_perm, 0);
-    
   }
   
   // Regardless of what permissions the user assigns, make sure s/he has view access to his/her own node
@@ -332,20 +352,6 @@
   }
 }
 
-function node_privacy_byrole_update_permissions(&$node) {
-  global $user;
-  db_query('DELETE FROM {node_access} WHERE nid = %d AND realm = \'node_privacy_byrole_role\'', $node->nid); 
-  $edit = $_POST['edit'];
-  $roleids_array = array_keys(user_roles());
-  foreach ($roleids_array as $roleid) {
-    $edit_perm_field = 'node_privacy_byrole_foredit_'. $roleid;
-    $view_perm_field = 'node_privacy_byrole_forview_'. $roleid;
-    $edit_perm = isset($node->$edit_perm_field) ? $node->$edit_perm_field : 0;
-    $view_perm = $edit_perm ? 1 : $node->$view_perm_field;    
-    db_query('INSERT INTO {node_access} (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (%d, %d, \'node_privacy_byrole_role\', %d, %d, %d)', $node->nid, $roleid, $view_perm, $edit_perm, 0);
-  }
-}
-
 function node_privacy_byrole_delete_permissions(&$node) {
        db_query('DELETE FROM {node_access} WHERE nid = %d AND (realm = \'node_privacy_byrole_user\' OR realm = \'node_privacy_byrole_role\')', $node->nid);
 }
@@ -360,39 +366,60 @@
       return '';
     }
   }
+  
+  $output = "";
 
   $op = $_POST['op'];
-  $formitems_view = '';
-  $formitems_edit = '';
-  
-  $rows = array();
-  $header = array(t('Role'), t('View'), t('Edit'));
+  $edit = $_POST['edit'];
   
   $roles_array = user_roles();
   $roleids_array = array_keys($roles_array);
-  // if the node already exists, return a form where the permissions already granted are already marked in checkboxes,
-  // else, return a form where all the checkboxes are marked.
-  if ($node->nid  && $op != t('Preview')) {
+
+  if ($node->nid  && $op != t('Preview')) { // case where the node already exists
     $current_perms_results = db_query('SELECT gid, grant_view, grant_update FROM {node_access} WHERE nid = %d AND (grant_view = 1 OR grant_update = 1) AND realm = \'node_privacy_byrole_role\'', $node->nid);
-    $already_permitted_forview_rids = array();
-    $already_permitted_foredit_rids = array();
     while($permitted_role = db_fetch_object($current_perms_results)) {
-      $already_permitted_forview_rids[$permitted_role->gid] = $permitted_role->grant_view;
-      $already_permitted_foredit_rids[$permitted_role->gid] = $permitted_role->grant_update;
+      $edit['node_privacy_byrole_forview_'.$permitted_role->gid] = $permitted_role->grant_view;
+      $edit['node_privacy_byrole_foredit_'.$permitted_role->gid] = $permitted_role->grant_update;
     }
-
+  }
+  else if ($op != t('Preview')) { // case where the node is being created
     foreach ($roleids_array as $roleid) {
-      $row = array(
-               t($roles_array[$roleid]),
-               form_checkbox(NULL, 'node_privacy_byrole_forview_'. $roleid, 1, $already_permitted_forview_rids[$roleid]),
-               form_checkbox(NULL, 'node_privacy_byrole_foredit_'. $roleid, 1, $already_permitted_foredit_rids[$roleid])
-             );
-      $rows[] = $row;
+      $edit['node_privacy_byrole_forview_'.$roleid] = variable_get('npbr_forview_'. $node->type .'_default_'. $roleid);
+      $edit['node_privacy_byrole_foredit_'.$roleid] = variable_get('npbr_foredit_'. $node->type .'_default_'. $roleid);
     }
   }
-  else { // the following generates the form based on the assumption that the node is being created or previewed
-    if ($op == t('Preview')) { // case where node is being previewed
-      $edit = $_POST['edit'];
+  
+  $privacy_roles = variable_get('privacy_roles', array());
+
+  // try to find the privacy rule that match the permissions
+  // return 'custom' if there is no match  
+  if (!$node->node_privacy_byrole_rule) {
+    $found_rule = 'custom';
+    foreach($privacy_roles as $privacy_name => $privacy) {
+      foreach($roleids_array as $roleid) {
+        if ($edit['node_privacy_byrole_forview_'.$roleid] XOR $privacy[$roleid]['view'])
+         continue 2;
+        if ($edit['node_privacy_byrole_foredit_'.$roleid] XOR $privacy[$roleid]['edit'])
+         continue 2;
+      }
+      $found_rule = $privacy_name;
+      break;
+    }
+  } else {
+    $found_rule = $node->node_privacy_byrole_rule;
+  }
+  
+  // build the privacy rules array for form_select
+  $privacy_select_options = array();
+  foreach(array_keys($privacy_roles) as $privacy_name) $privacy_select_options[$privacy_name] = t($privacy_name);
+  $privacy_select_options['custom'] = t('Custom');
+
+  // output a select box
+  $output .= form_select(t('Permission type'), 'node_privacy_byrole_rule', $found_rule, $privacy_select_options, t('Select which users can view/edit your post based on their role.'));
+  
+  if ($found_rule == 'custom') {
+      $rows = array();
+      $header = array(t('Role'), t('View'), t('Edit'));
       foreach ($roleids_array as $roleid) {
         $rows[] = array(
                     t($roles_array[$roleid]),
@@ -400,19 +427,11 @@
                     form_checkbox(NULL, 'node_privacy_byrole_foredit_'. $roleid, 1, $edit['node_privacy_byrole_foredit_'. $roleid])
                   );    
       }
-    }
-    else { // case where node is being created
-      foreach ($roleids_array as $roleid) {
-        $rows[] = array(
-                    t($roles_array[$roleid]),
-                    form_checkbox(NULL, 'node_privacy_byrole_forview_'. $roleid, 1, variable_get('npbr_forview_'. $node->type .'_default_'. $roleid, 0)),
-                    form_checkbox(NULL, 'node_privacy_byrole_foredit_'. $roleid, 1, variable_get('npbr_foredit_'. $node->type .'_default_'. $roleid, 0))
-                  );
-      }
-    }
+      $output .= theme('table', $header, $rows);
+      $output .= form_hidden('node_privacy_byrole_custom', 1);
   }
   
-  return form_item(t('View/Edit Permissions'), theme('table', $header, $rows), t('Select which users can view/edit your post based on their role.'));
+  return $output;
 }
 
 function node_privacy_byrole_settings() {
@@ -484,4 +503,72 @@
   }
 }
 
-?>
\ No newline at end of file
+function node_privacy_byrole_menu($may_cache) {
+  $items = array();
+  
+  if ($may_cache) {
+     $items[] = array('path' => 'admin/access/privacy', 'title' => t('privacy settings'), 'access' => user_access('administer site configuration'), 'type' => MENU_LOCAL_TASK, 'callback' => 'node_privacy_byrole_admin_page');
+  }     
+  
+  return $items;
+}
+
+function node_privacy_byrole_admin_page() {
+
+  $op = $_POST['op'];
+  $edit = $_POST['edit'];
+  
+  $roles = user_roles();
+
+  if ($op == 'Add a permission' || $op == t('Add a permission')
+       || $op == 'Save permissions' || $op == t('Save permissions')) {
+     $privacy_roles = array();
+     $max = intval($edit['node_privacy_byrole_max']);
+     for ($i = 0; $i<$max; $i++) {
+       $name = $edit['node_privacy_byrole_'.$i.'_name'];
+       if ($name) {
+         $thatprivacy = array();
+         foreach($roles as $roleid => $role_name) {
+           if ($edit['node_privacy_byrole_'.$i.'_forview_'.$roleid])
+             $thatprivacy[$roleid]['view'] = true;
+           if ($edit['node_privacy_byrole_'.$i.'_foredit_'.$roleid])
+             $thatprivacy[$roleid]['edit'] = true;
+         }
+         $privacy_roles[$name] = $thatprivacy;
+       }
+    }
+    variable_set('privacy_roles', $privacy_roles);
+  } else {
+    $privacy_roles = variable_get('privacy_roles', array());
+  }
+  
+  if ($op == 'Save permissions' || $op == t('Save permissions')) {
+    drupal_set_message('Permission saved');
+    drupal_goto('admin/access/privacy');
+    die();
+  } else if ($op == 'Add a permission' || $op == t('Add a permission')) {
+    $privacy_roles[''] = array();
+  }
+    
+  $i = 0;
+  foreach($privacy_roles as $privacy_name => $privacy) {
+        $output .= form_textfield(t('Name of the privacy setting'), 'node_privacy_byrole_'.$i.'_name', $privacy_name);
+        $header = array(t('Role'), t('View'), t('Edit'));
+        $rows = array();
+        foreach($roles as $roleid => $role_name) {
+            $rows[] = array(
+               t($role_name),
+               form_checkbox(NULL, 'node_privacy_byrole_'.$i.'_forview_'. $roleid, 1, $privacy[$roleid]['view']),
+               form_checkbox(NULL, 'node_privacy_byrole_'.$i.'_foredit_'. $roleid, 1, $privacy[$roleid]['edit'])
+            );
+        }
+        $output .= theme_table($header, $rows);
+        $i++;
+  }
+  $output .= form_hidden('node_privacy_byrole_max', $i);
+  
+  $output .= form_button(t('Save permissions'));  
+  $output .= form_button(t('Add a permission'));
+
+  echo theme('page', form($output));
+}
\ No newline at end of file
