Index: cck_field_perms.module
===================================================================
--- cck_field_perms.module	(revision 825)
+++ cck_field_perms.module	(working copy)
@@ -1,13 +1,13 @@
 <?php
 
-// $Id: cck_field_perms.module,v 1.3.2.24 2007/05/10 21:14:03 arthuregg Exp $ 
+// $Id: cck_field_perms.module,v 1.3.2.24 2007/05/10 21:14:03 arthuregg Exp $
 
 /*
- * This module adds the ability to restrict some fields in a CCK node 
- * to certian user roles based on create, updated, and view. Note that 
- * when this module is enabled, you must positively grant view access 
+ * This module adds the ability to restrict some fields in a CCK node
+ * to certian user roles based on create, updated, and view. Note that
+ * when this module is enabled, you must positively grant view access
  * if you want users to have view access.
- * 
+ *
  */
 
 /* ********************************************* */
@@ -24,7 +24,7 @@
       return t('<p>Gives the option of limited access to CCK data for user roles.</p>');
       break;
   }
-} 
+}
 
 /**
  * Implentation of hook menu
@@ -49,7 +49,7 @@
 function cck_field_perms_perm(){
   $perm_list[] = "administer cck field permissions";
   $field_perms = unserialize(variable_get('cfp_values', null));
-  if ($field_perms) { 
+  if ($field_perms) {
     foreach ($field_perms as $type_name => $fields) {
       foreach ($fields as $field_name => $value) {
         if ($value) {
@@ -67,24 +67,24 @@
  * Implementation of hook_nodeapi
  * removes fields if a user does not have perms to view it
  */
-function cck_field_perms_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { 
+function cck_field_perms_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
   if ($op == 'view') {
     $type = $node->type;
     if ($types = variable_get('cfp_types', null)) {
       if ($types[$type]) {
         $disallowed_fields = unserialize(variable_get('cfp_values', null));
-        if ($disallowed_fields) { 
+        if ($disallowed_fields) {
           foreach ($disallowed_fields[$type] as $disallowed_field => $value ) {
             if ($value == 0) {continue; }
-              if (!(user_access(_cfp_content_to_readable($type, $disallowed_field, "view")))) {     
+              if (!(user_access(_cfp_content_to_readable($type, $disallowed_field, "view")))) {
                 $node->$disallowed_field['#access'] = false;
-                $node->content[$disallowed_field]['#access'] = false;                   
-            }   
+                $node->content[$disallowed_field]['#access'] = false;
+            }
           }
-        }   
+        }
       }
     }
-  }  
+  }
 }
 
 
@@ -96,11 +96,11 @@
   // detect if we're editing or creating
   if ($form['#node']->nid) {
     global $user;
-    $verb = $form['uid']['#value'] == $user->uid ?  "edit own" : "edit"; 
-  } 
-  else { 
-    $verb = "create"; 
+    $verb = $form['uid']['#value'] == $user->uid ?  "edit own" : "edit";
   }
+  else {
+    $verb = "create";
+  }
   $form =  _cfp_form_helper($form_id, $form, $verb);
 }
 
@@ -111,7 +111,7 @@
 
 /**
  * Defines the CRUD.
- */ 
+ */
 function cck_field_perms_verbs(){
   return array('create', 'edit', 'edit own', 'view',);
 }
@@ -122,13 +122,13 @@
  */
 function _cfp_content_to_readable ($content_type, $field_name, $verb){
   static $content_types;
-  if (! ($content_types)) {$content_types = content_types();} 
-  
+  if (! ($content_types)) {$content_types = content_types();}
+
   // support fieldgroup content
   if(strstr($field_name, "group_")){
     $output = $verb . " " . $content_types[$content_type]['name'] . " " . $field_name;
-  } 
-  else {  
+  }
+  else {
     $output = $verb . " " . $content_types[$content_type]['name'] . " " . $content_types[$content_type]['fields'][$field_name]['widget']['label'];
   }
   return $output;
@@ -138,61 +138,82 @@
  * gets list of form groups from a form and removes
  * field groups if the user does not have permission
  * helper function for the form alter
- * 
+ *
  */
 function _cfp_form_group_fieldset_helper(&$form, $disallowed, $type, $verb){
   if (module_exists("fieldgroup")){
     foreach($form as $name => $item){
       if($disallowed[$name]){
-        if (!(user_access(_cfp_content_to_readable($type, $name, $verb)))){        
-          unset($form[$name]);
+        if (!(user_access(_cfp_content_to_readable($type, $name, $verb)))){
+          // Do not unset the form, else any existing values will be
+          // overwritten with the field default values, instead, disable
+          // them in _cfp_form_helper()
+          //unset($form[$name]);
         }
       }
-      
+
       // check this item to see if it is a group
       // if group, recurse to check for sub groups and or fieldsets
       if (strstr($name, "group")){
-        if(is_array($form[$name])){    
+        if(is_array($form[$name])){
           _cfp_form_group_fieldset_helper($form[$name], $disallowed, $type, $verb);
-        }        
+        }
       }
     }
   }
-} 
+}
 
 
 /**
  * helper function to unset form values
- * 
+ *
  * @form is drupal form
  * @verb is create or update
  * @return is the modified drupal form
- * 
+ *
  */
-function _cfp_form_helper($form_id, $form, $verb){
+function _cfp_form_helper($form_id, &$form, $verb){
   //content_video_node_form
   $types = variable_get('cfp_types', null);
+
   if ($types) {
     foreach ($types as $type) {
-      if ($form_id == $type . "_node_form") {       
-        $disallowed_fields = unserialize(variable_get('cfp_values', null));                          
-        if ($disallowed_fields) {          
-          // removes fieldgroups
-          _cfp_form_group_fieldset_helper($form, $disallowed_fields[$type], $type, $verb);     
-          foreach ($disallowed_fields[$type] as $disallowed_field => $value){
-            if ($value == 0 ) {continue;}
-              if (! user_access(_cfp_content_to_readable($type, $disallowed_field, $verb))) { 
-               $form[$disallowed_field]['#access'] = false;          
+      if ($form_id == $type . "_node_form") {
+        $disallowed_fields = unserialize(variable_get('cfp_values', null));
+        if ($disallowed_fields) {
+          // disable fieldgroups
+          _cfp_form_group_fieldset_helper($form, $disallowed_fields[$type], $type, $verb);
+
+          foreach ($disallowed_fields[$type] as $disallowed_field => $disallowable) {
+            if ($disallowable) {
+              if (!user_access(_cfp_content_to_readable($type, $disallowed_field, $verb))) {
+                // This is a hack. With CCK we don't know where the actual form
+                // element may be stored, so we manually check all known loctions
+                // and set the #disabled flag when we find the location.
+                if ($form[$disallowed_field]['#type']) {
+                  $form[$disallowed_field]['#disabled'] = TRUE;
+                }
+                elseif ($form[$disallowed_field]['key']['#type']) {
+                  $form[$disallowed_field]['key']['#disabled'] = TRUE;
+                }
+                elseif ($form[$disallowed_field]['uids']['#type']) {
+                  $form[$disallowed_field]['uids']['#disabled'] = TRUE;
+                }
+                else {
+                  // potentially unhandled nested form here
+                }
+              }
+              // else access allowed, leave form unchanged
             }
           }
-        }   
-      }   
+        }
+      }
     }
   }
+
   return $form;
 }
 
-
 /* ************************ */
 /* ADMIN Functions */
 /* ************************ */
@@ -200,7 +221,7 @@
 
 /**
  * page for the admin settings form
- * use this instead of standard settings for b/c we 
+ * use this instead of standard settings for b/c we
  * serialize all the data into one variable
  */
 function cck_field_perms_admin_settings(){
@@ -221,11 +242,11 @@
                         "Please note: you must grant view access for a field once you enable this field to be permissions controlled. " .
                         "If you do not do this, no users will be able to view the field. "),
   );
-  
+
   $types = content_types();
 
   foreach ($types as $key => $value) {
-    $options[$key] = $value['name']; 
+    $options[$key] = $value['name'];
   }
   $enabled_types = variable_get('cfp_types', null);
   $form['field_perms']['cfp_types'] = array(
@@ -243,17 +264,17 @@
       if ($enabled_type) {
         $form['field_fields'][$enabled_type] = array(
           '#type' => 'fieldset',
-          '#title' => $types[$enabled_type]['name'] . " content fields",                           
+          '#title' => $types[$enabled_type]['name'] . " content fields",
         );
 
         if ($types[$enabled_type]['fields']) {
-          
+
           // deal with grouped content
           _cfp_group_form_fields($form, $types[$enabled_type]['fields'], $enabled_type, $the_settings);
-          
-          foreach ($types[$enabled_type]['fields'] as $field) {          
-            $field_perms[$field['field_name']] = $field['widget']['label'];                   
-          
+
+          foreach ($types[$enabled_type]['fields'] as $field) {
+            $field_perms[$field['field_name']] = $field['widget']['label'];
+
             $form['field_fields'][$enabled_type]["{$enabled_type}_{$field['field_name']}"]= array(
               '#type' => 'checkbox',
               '#title' => $field['widget']['label'],
@@ -264,11 +285,11 @@
           }
         }
       }
-    }       
+    }
   }
-  
+
   $form['submit'] = array(
-    '#type' => 'submit', 
+    '#type' => 'submit',
     '#value' => t('Save')
   );
   return $form;
@@ -299,9 +320,9 @@
           '#title' => $afield['label'] ." field",
           '#description' => t("Checking this box will hide this field "),
           '#default_value' => $values[$type][$afield['field_name']],
-          
+
         );
-        //remove this field from the list of fields that we have      
+        //remove this field from the list of fields that we have
         unset($fields[$afield['field_name']]);
       }
     }
@@ -317,21 +338,21 @@
   // @ TODO figure out why the hell it is neccessary to do this
   if ($form_values['cfp_types'][0]) { unset($form_values['cfp_types'][0]); }
   if ($form_values['cfp_types'][1]) { unset($form_values['cfp_types'][1]); }
-  
-  variable_set('cfp_types', $form_values['cfp_types']); 
-  
+
+  variable_set('cfp_types', $form_values['cfp_types']);
+
   foreach ($form_values as $key => $value) {
-    if (strstr($key, "_field_") ) { 
+    if (strstr($key, "_field_") ) {
       $type = substr($key, 0, strpos($key, "_field"));
       $field = substr($key, strpos($key, "field"));
       $stored_values[$type][$field] = $value;
     }
-    if (strstr($key, "_group_") ) { 
+    if (strstr($key, "_group_") ) {
       $type = substr($key, 0, strpos($key, "_group"));
       $field = substr($key, strpos($key, "group"));
       $stored_values[$type][$field] = $value;
     }
-  }  
+  }
   variable_set('cfp_values', serialize($stored_values));
   drupal_set_message("Remember to update ". l("admin/user/access", "admin/user/access") ." after you've changed permissions.");
-}
\ No newline at end of file
+}
