--- /Users/dblake/tmp/nodeaccess_autoreference/nodeaccess_autoreference.inc	2009-10-07 12:27:19.000000000 -0500
+++ /Users/dblake/Sites/winstage/sites/all/modules/nodeaccess_autoreference/nodeaccess_autoreference.inc	2010-03-26 11:29:34.000000000 -0500
@@ -24,7 +24,7 @@
  *   optional parameter for depth checking
  * @return matches
  *   returns all matches where connection has been found
- * 
+ *
  */
 function nodeaccess_autoreference_find_connection($node, $obj = NULL) {
   static $naar_counter_nocache = 0, $naar_counter_cache = 0;
@@ -39,9 +39,9 @@ function nodeaccess_autoreference_find_c
   $obj_id = ($obj->nid ? $obj->nid : $obj->uid);
   $nid = is_object($node) ? $node->nid : $node;
   $cid = "nodeaccess_autoreference_$obj_type:$obj_id:nid:$nid";
-  if (!variable_get('nodeaccess_autoreference_disable_cache', FALSE) 
-     && ($cache_data = cache_get($cid)->data)
-     && $naar_counter_cache++ < variable_get('nodeaccess_autoreference_max_node_render_cache', 20)) {
+  if (!variable_get('nodeaccess_autoreference_disable_cache', FALSE)
+  && ($cache_data = cache_get($cid)->data)
+  && $naar_counter_cache++ < variable_get('nodeaccess_autoreference_max_node_render_cache', 20)) {
     $cached = TRUE;
     $res = $path = $cache_data;
     $connected = (bool)!empty($cache_data);
@@ -59,8 +59,8 @@ function nodeaccess_autoreference_find_c
   }
   if ($res && variable_get('nodeaccess_autoreference_debug', FALSE)) {
     drupal_set_message(($cached ? t('Cached: ') : '')
-      . t('Connected: %connected; Path between user %uid and node %nid (%type): %path',
-        array('%nid' => $node->nid, '%uid' => $obj->uid, '%type' => $node->type, '%path' => !empty($path) ? print_r($path,true) : t('n/a'), '%connected' => ($path ? 'YES' : 'NO'))), 'status');
+    . t('Connected: %connected; Path between user %uid and node %nid (%type): %path',
+    array('%nid' => $node->nid, '%uid' => $obj->uid, '%type' => $node->type, '%path' => !empty($path) ? print_r($path,true) : t('n/a'), '%connected' => ($path ? 'YES' : 'NO'))), 'status');
   }
   return $res;
 }
@@ -78,63 +78,63 @@ function nodeaccess_autoreference_find_c
  *   optional parameter for depth checking
  * @return matches
  *   returns all matches where connection has been found
- * 
+ *
  */
 function nodeaccess_autoreference_obj_connected($obj, $user, &$path = array(), &$ignore_list = array(), $depth = 0) {
-    if ($depth == 0) {
-      $obj_id = ($obj->nid ? $obj->nid : $obj->uid);
-      $path[] = "$obj->type|$type|" . $obj_id; // init path
-      $path = array();
-    } else if ($depth > variable_get('nodeaccess_autoreference_max_depth', 5)) {
-      return FALSE;
+  if ($depth == 0) {
+    $obj_id = ($obj->nid ? $obj->nid : $obj->uid);
+    $path[] = "$obj->type|$type|" . $obj_id; // init path
+    $path = array();
+  } else if ($depth > variable_get('nodeaccess_autoreference_max_depth', 5)) {
+    return FALSE;
+  }
+  $type = $obj->nid ? 'nid' : 'uid';
+  if (nodeaccess_autoreference_same_objs($user, $obj)) { // if objects are the same, then mark as found
+    $path[] = $user->uid.'_is_owner_of_' . $obj->nid;
+    return TRUE;
+  }
+
+  $refs = nodeaccess_autoreference_obj_references($obj, variable_get('nodeaccess_autoreference_reverse_reference', FALSE));
+  foreach ($refs as $field_name => $ref) {
+    global $na_skip_next_load;
+    $na_skip_next_load = TRUE;
+
+    $n_obj = NULL;
+    if (isset($ref['nid'])) {
+      $n_obj = node_load(array('nid' => $ref['nid']));
+      $n_obj_id = $ref['nid'];
+      $n_obj_type = 'nid';
+    } else if (isset($ref['uid'])) {
+      $n_obj = user_load(array('uid' => $ref['uid']));
+      $n_obj_id = $ref['uid'];
+      $n_obj_type = 'uid';
     }
-    $type = $obj->nid ? 'nid' : 'uid';
-    if (nodeaccess_autoreference_same_objs($user, $obj)) { // if objects are the same, then mark as found
-      $path[] = $user->uid.'_is_owner_of_' . $obj->nid;
+    if (nodeaccess_autoreference_same_objs($user, $n_obj)) {
+      $path[] = $field_name;
       return TRUE;
-    }
-
-    $refs = nodeaccess_autoreference_obj_references($obj, variable_get('nodeaccess_autoreference_reverse_reference', FALSE));
-    foreach ($refs as $field_name => $ref) {
-      global $na_skip_next_load;
-      $na_skip_next_load = TRUE;
-
-      $n_obj = NULL;
-      if (isset($ref['nid'])) {
-        $n_obj = node_load(array('nid' => $ref['nid']));
-        $n_obj_id = $ref['nid'];
-        $n_obj_type = 'nid';
-      } else if (isset($ref['uid'])) {
-        $n_obj = user_load(array('uid' => $ref['uid']));
-        $n_obj_id = $ref['uid'];
-        $n_obj_type = 'uid';
+    } else if (!array_key_exists($ref['nid'], $ignore_list)) {
+      if (variable_get('nodeaccess_autoreference_debug_more', FALSE)) {
+        $path[] = $field_name; // considered paths - use for testing purposes
+        drupal_set_message(print_r($path, true)); // for debug purposes
       }
-      if (nodeaccess_autoreference_same_objs($user, $n_obj)) {
-        $path[] = $field_name;
-        return TRUE; 
-      } else if (!array_key_exists($ref['nid'], $ignore_list)) {
-        if (variable_get('nodeaccess_autoreference_debug_more', FALSE)) {
-          $path[] = $field_name; // considered paths - use for testing purposes
-          drupal_set_message(print_r($path, true)); // for debug purposes
-        }
-        $ignore_list[$ref['nid']] = TRUE;
-        $cid = "nodeaccess_autoreference_uid:$user->uid:$n_obj_type:$n_obj_id";
-        if (variable_get('nodeaccess_autoreference_disable_cache', FALSE) && ($data = cache_get($cid)->data)) {
-          foreach ($data as $key => $n_path) {
-            $path[] = $n_path;
-          }
-          $ret = $data;
-        } else {
-          $ret = nodeaccess_autoreference_obj_connected($n_obj, $user, $path, $ignore_list, $depth+1);
+      $ignore_list[$ref['nid']] = TRUE;
+      $cid = "nodeaccess_autoreference_uid:$user->uid:$n_obj_type:$n_obj_id";
+      if (variable_get('nodeaccess_autoreference_disable_cache', FALSE) && ($data = cache_get($cid)->data)) {
+        foreach ($data as $key => $n_path) {
+          $path[] = $n_path;
         }
-      }
-      if ($ret) {
-        $path[] = $field_name;
-        return $ret;
+        $ret = $data;
       } else {
+        $ret = nodeaccess_autoreference_obj_connected($n_obj, $user, $path, $ignore_list, $depth+1);
       }
     }
-    return FALSE;
+    if ($ret) {
+      $path[] = $field_name;
+      return $ret;
+    } else {
+    }
+  }
+  return FALSE;
 }
 
 /**
@@ -146,7 +146,7 @@ function nodeaccess_autoreference_obj_co
  *   could be user or node object
  * @return bool
  *   returns TRUE if objects are the same, otherwise FALSE
- * 
+ *
  */
 function nodeaccess_autoreference_same_objs($a, $b) {
   return ($a->uid == $b->uid && $a->type == $b->type);
@@ -159,7 +159,7 @@ function nodeaccess_autoreference_same_o
  *   could be user or node object
  * @return matches
  *   returns all matches where connection has been found
- * 
+ *
  */
 function nodeaccess_autoreference_obj_references($obj, $reverse = FALSE) { // data = user/node
   $matches = array();
@@ -231,7 +231,7 @@ function nodeaccess_autoreference_obj_re
           }
         } // end: while
       }
-      
+
       if (!empty($referenced_roles)) {
         $uid = $id; // current user id
         $ref_types = implode(", ", array_keys($referenced_roles));
@@ -263,10 +263,10 @@ function nodeaccess_autoreference_obj_re
  *   could be user or node object
  * @return array
  *   returns array of grants for current user, otherwise NULL
- * 
+ *
  */
 function nodeaccess_autoreference_node_get_grants($node, $user = NULL) {
-  module_load_include('inc', 'nodeaccess_autoreference'); // load additional function from included file
+  //module_load_include('inc', 'nodeaccess_autoreference'); // load additional function from included file
   if (empty($user)) {
     global $user;
   }
@@ -275,15 +275,57 @@ function nodeaccess_autoreference_node_g
   }
   $connected = nodeaccess_autoreference_find_connection($node, $user);
   if ($connected) {
+    //lets check our grants update and delete, separate to the field
     $grants = array();
-    $grants[] = array(
-      'nid' => $node->nid,
-      'gid' => $user->uid,
-      'realm' => 'nodeaccess_autoreference_owner',
-      'grant_view' => '1',
-      'grant_update' => user_access("edit referenced $node->type content"),
-      'grant_delete' => user_access("delete referenced $node->type content"),
-    );
+    //find all our cck fields for the node that are userref?  Maybe just check each object and if the variable is set then set our grants?
+    foreach($node as $field => $value) {
+      $perms = variable_get($node->type.'_'.$field.'_permissions', FALSE);
+      //if we find permissions then this field is a user reference field so lets build our uid list so we can determine what permissions to grant to this user.
+      if($perms) {
+        $uids = array();
+        foreach($node->$field as $uid) {
+          $uids[] = $uid['uid'];
+        }
+        if(in_array($user->uid, $uids)) {
+          $grants[] = array(
+            'nid' => $node->nid,
+            'gid' => $user->uid,
+            'realm' => 'nodeaccess_autoreference_owner',
+            'grant_view' => '1',
+            'grant_update' => isset($perms['update']) ? '1' : user_access("edit referenced $node->type content"),
+            'grant_delete' => isset($perms['delete']) ? '1' : user_access("delete referenced $node->type content"),
+          );
+        }
+      }
+    }
+    //no grants have been assigned then assume we are in a sub level item.  We need to get the nid of the top level connection where our permissions are assigned.
+    if(empty($grants)) {
+      $path = explode("|", $connected[0]);
+      $nid = $path[0];
+      //load up our main node and get our permissions
+      $parent = node_load($nid);
+      foreach($parent as $field => $value) {
+        $perms = variable_get($parent->type.'_'.$field.'_permissions', FALSE);
+        //if we find permissions then this field is a user reference field so lets build our uid list so we can determine what permissions to grant to this user.
+        if($perms) {
+          $uids = array();
+          foreach($parent->$field as $uid) {
+            $uids[] = $uid['uid'];
+          }
+          if(in_array($user->uid, $uids)) {
+            $grants[] = array(
+              'nid' => $parent->nid,
+              'gid' => $user->uid,
+              'realm' => 'nodeaccess_autoreference_owner',
+              'grant_view' => '1',
+              'grant_update' => isset($perms['update']) ? '1' : user_access("edit referenced $parent->type content"),
+              'grant_delete' => isset($perms['delete']) ? '1' : user_access("delete referenced $parent->type content"),
+            );
+          }
+        }
+      }
+    }
+    //if grants are still empty, we did something wrong...
     return $grants;
   } else {
     return NULL;
@@ -297,13 +339,13 @@ function nodeaccess_autoreference_node_g
  *   node object
  * @param object $grants
  *   grants object (can be retrieved from nodeaccess_autoreference_node_get_grants())
- * 
+ *
  */
 function nodeaccess_autoreference_node_write_grants($node, $grants) {
-    node_access_write_grants($node, $grants, NULL, FALSE);
-    if (variable_get('nodeaccess_autoreference_log', FALSE)) {
-      $args = array('%nid' => $node->nid, '%permission' => print_r($grants, TRUE));
-      $msg = 'Added permissions to node %nid. (permission: %permission)';
-    }
+  node_access_write_grants($node, $grants, NULL, FALSE);
+  if (variable_get('nodeaccess_autoreference_log', FALSE)) {
+    $args = array('%nid' => $node->nid, '%permission' => print_r($grants, TRUE));
+    $msg = 'Added permissions to node %nid. (permission: %permission)';
+  }
 }
 
