--- taxonomy_access.module	Sun Nov 28 10:50:56 2004
+++ new_taxonomy_access.module	Sun Nov 28 12:43:35 2004
@@ -1,4 +1,47 @@
-<?  
+<?php  
+
+function taxonomy_access_help($section) {
+  switch ($section) {
+    
+    // Brief message for administrators to explain what this module does
+    case 'admin/user/configure/category':
+      return t('In this area you will define the permissions that each <a href="%role">user role</a> has for each category.  Each category can have view, update and delete permissions set for each user role.  /*The "Default Permissions" are the permissions applied to all categories for this role.  The <a href="%default">Default</a> role allows you to set the default category permissions for all roles.', array('%role' => url('admin/user/configure/role'), '%default' => url('admin/user/configure/category/0*/')));
+      
+    case 'admin/modules#description': 
+      return t('Allows users to specify which categories and viewed by various roles.');
+      
+    // Creates the header content for the taxonomy_access settings page dependent upon
+    // whether the node is enabled or disabled.
+    // Note: the form that appears on this page is not generated by this fucntion.
+    case 'admin/settings/taxonomy_access':                                              
+    
+      $taxonomy_access_enabled = variable_get('taxonomy_access_enabled', FALSE);
+      $message = '';
+      
+      // header message if module is enabled
+      if ($taxonomy_access_enabled) { 
+        $message .= 'The module is currently enabled properly.<br/>';
+        $message .= 'To disable the module properly, select \'disable\' here and save the configuration before disabling it in the modules page.<br/>';
+      }
+      
+      // header message if module is not enabled
+      else {
+      $message .= 'The module is currently disabled, but must also be disabled in the %module_page_link in order for it to be properly disabled.<br/>To properly enable this module, select \'enable\' here and save the configuration.<br/>';
+      $message = t($message, array('%module_page_link' => l(t('modules admin page'), 'admin/modules', array('title' => t('View more.')))   ));
+      }
+      return $message;
+  }
+}
+
+/**
+ * Implementation of hook_node_grants()
+ * Gives access to taxonomies based on the taxonomy_access table
+ */
+function taxonomy_access_node_grants($user, $op)  {
+	global $user;
+  return array('term_access' => array_keys(is_array($user->roles) ? $user->roles : array()));
+}
+
 function taxonomy_access_menu()  {
   $access = user_access('administer users');
 
@@ -12,33 +55,68 @@
   $tids = $_POST['tids'];
   $rid = arg(4);
   $output = '';
+  $grant_types = array('view', 'update', 'delete');
+  
+  // Code to handle user supplied changes to permission configuration
   if (isset($edit)) {
-    if (!isset($rid)) return t('Please select a role to update');
-    // Save permissions:
-    foreach ($tids as $tid)  {
-	if (isset($edit[$tid]))
-          foreach($edit[$tid] as $key => $val)  {
-            ($val == 'on') ? $edit[$tid][$key]=1 : $edit[$tid][$key]=0;
-	   }
-      taxonomy_access_grant_update($tid,$rid,$edit[$tid]);
+    if (!isset($rid)) {
+      return t('Please select a role to update');
     }
+    
+    // Process input data and use it to make changes to the database.
+    foreach($tids as $tid) {
+      // The $edit array is filled out with zeroes here to
+    	// reduce code complexity when we update the term_access table.
+      if(!array_key_exists($tid, $edit)) {
+        foreach($grant_types as $grant) {
+        	$edit[$tid][$grant] = 0;
+				}
+      }
+      // Enter a '0' for any permission that has been left unchecked by the user
+      // For any permission checked by user, set it to a value of '1'
+      else {
+      	foreach($grant_types as $grant) {
+        	if(!isset($edit[$tid][$grant])) {
+          	$edit[$tid][$grant] = 0;
+          }
+          else {
+          	$edit[$tid][$grant] = 1;
+        	}
+				}
+      }
+      
+      // Make the changes to the term_access table
+      foreach($edit[$tid] as $key => $val)  {
+      	taxonomy_access_grant_update($tid, $rid, $edit[$tid]);
+      }
+    }
+    // Reflect changes made to term_access table in node_access table
+    _refresh_node_access_table();
 
     // Clear the cache, as we might have changed the anonymous user's
     // permissions.
     cache_clear_all();
   }
+  
+  // Output the permission matrix user form
   if (isset($rid))  {
     // Get name of role
-    if ($rid == 0) $role_name = t('Default');
-    else $role_name = db_result(db_query('select name from {role} where rid='.$rid));
+    if ($rid == 0) {
+      $role_name = t('no role');
+    }
+    else {
+      $role_name = db_result(db_query('select name from {role} where rid='.$rid));
+    }
+    
     $output = '<h2>Permissions for \''.$role_name.'\'</h2><p>';
     // Get all category permissions
     $perm = taxonomy_access_get_grants($rid);
     // Compile category permission overview
     $term_list = array();
     $header = array('Category','View','Update','Delete');
-    // Do the default row
-    $rows[] = array('Default Permissions',
+    
+    // Do the row for uncategorized nodes
+    $rows[] = array('uncategorized nodes',
            '<input type="hidden" name="tids[]" value="0">'.
            '<input type="checkbox" name="edit[0][view]" '. (($perm[0]['view']) ? 'checked>' : '>'),
            '<input type="checkbox" name="edit[0][update]" '. (($perm[0]['update']) ? 'checked>' : '>'),
@@ -51,7 +129,7 @@
       foreach($terms as $term)  {
         $rows[] = array(str_repeat('-',$term->depth).$term->name,
            '<input type="hidden" name="tids[]" value="'.$term->tid.'">'.
-	   '<input type="checkbox" name="edit['.$term->tid.'][view]" '. (($perm[$term->tid]['view']) ? 'checked>' : '>'),
+     '<input type="checkbox" name="edit['.$term->tid.'][view]" '. (($perm[$term->tid]['view']) ? 'checked>' : '>'),
            '<input type="checkbox" name="edit['.$term->tid.'][update]" '. (($perm[$term->tid]['update']) ? 'checked>' : '>'),
            '<input type="checkbox" name="edit['.$term->tid.'][delete]" '. (($perm[$term->tid]['delete']) ? 'checked>' : '>'));
       }
@@ -74,7 +152,7 @@
     // Render role/permission overview:
     $header = array("Role","Category Permissions");
     // Default settings for categories
-    $rows[] = array(t('Default'),array('data'=>l(t("edit"),"admin/user/configure/category/0"),'align'=>'right'));
+    //$rows[] = array(t('no role'), array('data'=>l(t("edit"),"admin/user/configure/category/0"),'align'=>'right'));
     foreach ($role_names as $rid => $name) {
      $rows[] = array($name,array('data'=>l(t("edit"),"admin/user/configure/category/$rid"), 'align'=>'right'));
     }
@@ -105,54 +183,27 @@
   print theme('page', $output);
 
 }
-function taxonomy_access_help($section)  {
-  switch($section)  {
-    case 'admin/user/configure/category':
-      return t('In this area you will define the permissions that each <a href="%role">user role</a> has for each category.  Each category can have view, update and delete permissions set for each user role.  The "Default Permissions" are the permissions applied to all categories for this role.  The <a href="%default">Default</a> role allows you to set the default category permissions for all roles.', array('%role' => url('admin/user/configure/role'), '%default' => url('admin/user/configure/category/0')));
-    case 'admin/modules#description':
-      return t('Allows the user administrator to control access to categories based on user role.');
-  }
-}
-/**
- * Implementation of hook_node_grants()
- * Gives access to taxonomies based on the taxonomy_access table
- */
-function taxonomy_access_node_grants($user, $op)  {
-//    if (user_access('administer nodes'))
-//      return array('taxonomy'=>'0');
-
-    $sql = "SELECT tid from {term_access} where (rid=0 ";
-    if (isset($user) && is_array($user->roles)) $sql .= "OR rid in ('". implode("','",array_keys($user->roles)) . "')";
-    $sql .= ") and grant_". $op . "=1";
-    $result = db_query($sql);
-    $nids = array();
-    $i=0;
-    while (($nid = db_result($result,$i)) != null)  {
-      $nids[] = $nid;
-      $i++;
-    }
-    $nids[] = 0; // catchall
-    return array('taxonomy'=>$nids);
-
-}
 
-/** 
- * Inserts a permission for a role to a term
+/**
+ * Updates permissions for a role from a term
  * @param $tid
- *   The term to add the permission for. 
- * @param $role 
+ *   The term to add the permission for.
+ * @param $role
  *   The role to add the permission to.
- *   Can be the name or the role id or blank for all term permissions
+ *   Can be the name or the role id or blank for all term permissions.
  * @param $grants
  *   A hash of the grants in the form of $grants['perm'] = boolean
- *   A value of true will grant the permission for this user and term.
- *   If omitted, only the permission for 'view' will be granted.
+ *   A value of 1 will grant the permission for this user and term.
 **/
-function taxonomy_access_grant_add($tid,$role = null,$grants = null)  {
-  if (!isset($tid)) return false;
-  if (isset($role) && !is_numeric($role))
+function taxonomy_access_grant_update($tid, $role = null, $grants = null)  {
+  if (!isset($tid)) {
+    return FALSE;
+  }
+  if (isset($role) && !is_numeric($role)) {
     $role = db_result(db_query("SELECT rid from {role} where name='$role'"));
-  $ta_sql = "INSERT INTO {term_access} (tid";
+  }
+  
+  $ta_sql = "REPLACE INTO {term_access} (tid";
   $ta_sql_values = " VALUES ($tid";
   if (isset($role)) {
     $ta_sql .= ",rid";
@@ -174,56 +225,6 @@
   $ta_sql .= $sql . $ta_sql_values;
 
   db_query($ta_sql);  // insert into term_access
-
-  // take care of node_access
-  $result = db_query("SELECT DISTINCT(n.nid) from {node} as n INNER JOIN {term_node} as tn 
-			on n.nid=tn.nid where tn.tid=$tid");
-  while ($node = db_fetch_array($result))  {
-    $nid = $node['nid'];
-    db_query("INSERT INTO {node_access} (nid,gid,realm,grant_view,grant_update,grant_delete)
-		VALUES ($nid,$tid,'taxonomy',1,1,1)");
-  }
-
-}
-
-/**
- * Deletes permissions for a role from a term
- * @param $tid
- *   The term to add the permission for.
- * @param $role
- *   The role to add the permission to. 
- *   Can be the name or the role id or blank for all term permissions.
-**/
-function taxonomy_access_grant_del($tid,$role = null)  {
-  if (!isset($tid)) return false;
-  if (isset($role) && !is_numeric($role))
-    $role = db_result(db_query("SELECT rid from {role} where name='$role'"));
-  $ta_sql = "DELETE FROM {term_access} where tid=$tid";
-  $na_sql = "DELETE FROM {node_access} where gid=$tid and realm='taxonomy'";
-  if (isset($role))
-    $ta_sql .= " and rid=$role";
-  db_query($ta_sql);
-  db_query($na_sql);
-}
-/**
- * Updates permissions for a role from a term
- * @param $tid
- *   The term to add the permission for.
- * @param $role
- *   The role to add the permission to.
- *   Can be the name or the role id or blank for all term permissions.
- * @param $grants
- *   A hash of the grants in the form of $grants['perm'] = boolean
- *   A value of true will grant the permission for this user and term.
- *   If omitted, only the permission for 'view' will be granted.
-**/
-function taxonomy_access_grant_update($tid,$role = null, $grants = null)  {
-  if (!isset($tid)) return false;
-  if (isset($role) && !is_numeric($role))
-    $role = db_result(db_query("SELECT rid from {role} where name='$role'"));
-  taxonomy_access_grant_del($tid,$role);
-  if (isset($grants))
-    taxonomy_access_grant_add($tid,$role,$grants);
 }
 
 /**
@@ -239,9 +240,10 @@
 **/
 function taxonomy_access_get_grants($role)  {
   if (!isset($role)) return false;
-  if (isset($role) && !is_numeric($role))
+  if (isset($role) && !is_numeric($role)) {
     $role = db_result(db_query("SELECT rid from {role} where name='$role'"));
-  $result = db_query("SELECT * from {term_access} where rid='$role' OR rid=0");
+  }
+  $result = db_query("SELECT * from {term_access} where rid='$role'");
   $grants = array();
   while ($grant = db_fetch_array($result))  {
     $tid = $grant['tid'];
@@ -264,20 +266,35 @@
   switch ($op) {
     case 'delete':
       // When a node is deleted, delete any relevant permissions.
-      db_query('DELETE FROM {node_access} WHERE nid = %d AND realm = \'taxonomy\'', $node->nid);
+      db_query('DELETE FROM {node_access} WHERE nid = %d AND realm = \'term_access\'', $node->nid);
       break;
 
-    case 'insert':
+    // Enter new data into node_access to set permissions for the new node
     case 'update':
-      // Clear out any existing permissions for the node, and set new ones.
-      db_query('DELETE FROM {node_access} WHERE nid = %d AND realm = \'taxonomy\'', $node->nid);
-      if ($node->taxonomy) {
-        foreach ($node->taxonomy as $term) {
-          db_query('INSERT IGNORE INTO {node_access} (nid,gid,realm,grant_view,grant_update,grant_delete) 
-			VALUES (%d, %d, \'taxonomy\', %d, %d, %d)', $node->nid, $term,1, 1, 1);
-        }
+      db_query('DELETE FROM {node_access} WHERE nid = %d AND realm = \'term_access\'', $node->nid);
+      // intentional fall through to insert
+    
+    case 'insert':
+      // Determine the category/categories the new node was assigned to
+      $tids = $node->taxonomy;
+       
+      // For nodes not assigned to a category
+      if(!$tids) {
+      	$query = db_query('SELECT * FROM term_access where tid = 0');
+      	while($result = db_fetch_array($query)) {
+      		db_query('REPLACE INTO node_access (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (%d, %d, \'term_access\', %d, %d, %d)', $node->nid, $result->rid, $result->grant_view, $result->grant_update, $result->grant_delete);
+      	}
       }
-      break;
+      // For nodes assigned to a category
+      else {      
+	      // Query the term_access table to get the permissions for the new node's assigned category/categories
+	      // then make appropriate changes to the node_access table.
+	      $result = db_query("SELECT * from term_access where tid in ('" . implode("','",array_values($tids)) . "')");
+	      while($row = db_fetch_object($result)) {
+	      	db_query('REPLACE INTO node_access (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (%d, %d, \'term_access\', %d, %d, %d)', $node->nid, $row->rid, $row->grant_view, $row->grant_update, $row->grant_delete);
+	      }
+	    }	    
+	    break;
   }
 }
 
@@ -285,8 +302,9 @@
  * Allows you to determine if the current user or $uid can access this taxonomy for the given perm
 **/
 function taxonomy_access($op, $taxonomy = NULL, $uid = NULL) {
-  if (!isset($uid) && user_access('administer taxonomy'))
+  if (!isset($uid) && user_access('administer taxonomy')) {
     return TRUE;
+  }
 
   $taxonomy = array2object($taxonomy);
 
@@ -308,12 +326,12 @@
   }
 
   $sql = "SELECT count(*) from {term_access} where (rid=0";
-      if (isset($user) && is_array($user->roles)) $sql .=" OR rid in ('". implode("','",array_keys($user_object->roles)) . "')";
-      $sql .= ") and (tid='$tid' OR tid=0) and grant_". $op . "=1";
+  if (isset($user) && is_array($user->roles)) {
+    $sql .=" OR rid in ('". implode("','",array_keys($user_object->roles)) . "')";
+  }
+  $sql .= ") and (tid='$tid' OR tid=0) and grant_". $op . "=1";
 
-  if (db_result(db_query($sql)))
-    return TRUE;
-  else return FALSE;
+  return db_result(db_query($sql)) ? TRUE : FALSE;
 }
 
 function taxonomy_access_settings() {
@@ -330,23 +348,216 @@
   return $formitems;
 }
 
-function _taxonomy_access_update_db() {
-  variable_set('taxonomy_access_settings_changed', FALSE);
+/**
+ * _taxonomy hook called when changes are made to the taxonomy structure
+**/
+function taxonomy_access_taxonomy($op, $type, $edit)  {
+	if($type = 'term') {
+		// Using this function is a lazy, expensive way of taking care of changes to the taxonomy data.
+    // More efficient code could be written to handle specific kinds of changes to the taxonomy.
+		_taxonomy_access_update_db();
+	}
+}
 
+/**
+ * _user hook called when a user event occurs to check for new roles.  It would make sense to have a _role hook
+ * instead.  However, that hook doesn't exist so we rely on the _user hook to determine if new roles have been added.
+ *
+**/
+function taxonomy_access_user($op, &$edit, &$user, $category) {
+  if($op == 'update' || $op == 'insert') {
+    // Get list of existing roles
+    $query = db_query('SELECT rid FROM role');
+		while($result = db_fetch_array($query)) {
+    	$current_rids[] = $result['rid'];
+    }
+    if(!in_array(0, $current_rids)) {
+      $current_rids[] = 0;
+    }
+    
+    // Get list of roles known to exist from term_access
+    $query = db_query('SELECT DISTINCT rid FROM term_access');
+  	while($result = db_fetch_array($query)) {
+     	$known_rids[] = $result['rid'];
+    }
+    if(!in_array(0, $known_rids)) {
+      $known_rids[] = 0;
+    }
+    
+    if(array_diff($current_rids, $known_rids)) {
+      _taxonomy_access_update_db($current_rids, $known_rids);
+    } 
+  }
+}  
+  
+function _taxonomy_access_update_db($current_rids = NULL, $old_rids = NULL) {
+  variable_set('taxonomy_access_settings_changed', FALSE);
+  
   if (!variable_get('taxonomy_access_enabled', FALSE)) {
-    db_query('REPLACE INTO {node_access} VALUES (0, 0, \'all\', 1, 0, 0)');
-    db_query('DELETE FROM {node_access} WHERE realm=\'taxonomy\'');
-    db_query('DELETE FROM {term_access}');
+    // We use the replace statement to avoid inserting a duplicate entry into the database.
+    // Without the DELETE query, this can happen when a site admin has already enabled the modules
+    // from the settings page and goes back to it and resaves the enabled setting.
+    db_query('REPLACE INTO node_access VALUES (0, 0, \'all\', 1, 0, 0)');
   }
-  else { // the module was just enabled; provide default view access to everyone for nodes that were created
-         // between the previous disabling of the module and the current enabling of the module;
-         // nodes that were created during a previous enabled period are left-alone.
-         // Permissions for those nodes will be the same as when the module was previously enabled.
-    db_query('DELETE from {node_access} where nid=0 AND gid=0 AND realm=\'all\' AND grant_view=1 AND grant_update=0 AND grant_delete=0');
-    db_query('INSERT INTO {term_access} VALUES (0, 0, 1, 0, 0)');
-    db_query('REPLACE INTO {node_access} VALUES (0, 0,\'taxonomy\', 1, 0, 0)');
+  else { // the module was just enabled; node_access table must initialized or updated to reflect the changes since it was disabled:
+         // Check for new nodes and assign them permissions in node_access table;
+         // Check for deleted nodes and delelte them from node_access;
+         // Check for new taxonomies and make appropriate entries into node_access table;
+         // Check for new roles and make approprate entries into node_access and term_access table;
+         // Check for deleted roles and make appropriate entries into node_access and term_access table;
+         // Permissions for nodes will be the same as when the module was previously enabled.
+    db_query('DELETE from node_access where nid=0 AND gid=0 AND realm=\'all\' AND grant_view=1 AND grant_update=0 AND grant_delete=0');
+    
+    // BEGIN: term_access table housekeeping
+    // Update the term_access table to reflect any changes that may have occured since module was disabled.
+    $tids = array();
+    $rids = array();
+    
+    // Create list of all term and role ids
+    $query = db_query('SELECT tid from term_data');
+    while($result = db_fetch_array($query)) {
+    	$current_tids[] = $result['tid'];
+    }
+    $current_tids[] = 0;
+		
+		if(!$current_rids) {
+		  $query = db_query('SELECT rid FROM role');
+		  while($result = db_fetch_array($query)) {
+    	  $current_rids[] = $result['rid'];
+      }
+      $current_rids[] = 0;
+    }
+    
+    // Get old list of term and role ids from when term_access was disabled
+    $query = db_query('SELECT tid FROM term_access');
+    while($result = db_fetch_array($query)) {
+    	$old_tids[] = $result['tid'];
+    }
+    $old_tids[] = 0;
+    $old_tids = array_unique($old_tids);
+    
+    if(!$old_rids) {
+      $query = db_query('SELECT rid FROM term_access');
+  		while($result = db_fetch_array($query)) {
+      	$old_rids[] = $result['rid'];
+      }
+      $old_rids[] = 0;
+      $old_rids = array_unique($old_rids);
+    }
+    
+    // Get the difference between old and current
+    $delete_tids = array_diff($old_tids, $current_tids);
+    $delete_rids = array_diff($old_rids, $current_rids);
+    
+    // Delete all rows with role and term ids that no longer exist from the term_access table
+    foreach($delete_rids as $rid) {
+    	db_query('DELETE from term_access where rid = %d', $rid);
+    }
+    foreach($delete_tids as $tid) {
+    	db_query('DELETE from term_access where tid = %d', $tid);
+    }
+    
+    // Set permissions for nodes without categories if they aren't already set
+    $query = db_query('SELECT tid FROM term_access where tid = 0');
+    if(!db_fetch_array($query)) {
+    	foreach($current_rids as $rid) {
+    		db_query('INSERT INTO term_access VALUES (0, %d, 1, 0, 0)', $rid);
+    	}
+    } 
 
+    // Add new role and term ids to term_access table since module was last disabled and assign them default permissions
+    $add_tids = array_diff($current_tids, $old_tids);
+    $add_rids = array_diff($current_rids, $old_rids);
+    $all_rids = array_merge($add_rids, $current_rids);
+    
+    // Add role permissions for each new taxonomy terms.
+    // Default permissions assume all users can not read content in the new taxonomy
+    foreach($add_tids as $tid) {
+      foreach($all_rids as $rid) {
+        db_query('INSERT INTO term_access VALUES (%d, %d, 0, 0, 0)', $tid, $rid);
+      }
+    }
+    
+    // Add role permissions for all old taxonomy terms.
+    // Default permissions assume new role does not have access to content in any category
+    foreach($current_tids as $tid) {
+      foreach($add_rids as $rid) {
+        db_query('INSERT INTO term_access VALUES (%d, %d, 0, 0, 0)', $tid, $rid);
       }
+    } 
+    // END: term_access table housekeeping
+    
+    // BEGIN: node_access table housekeeping
+    // Update the node_access table to reflect any changes that may have occured since module was disabled.
+    
+    // Get current list of all nodes
+    $current_nids = array();
+    $query = db_query('SELECT nid from node');
+    while($result = db_fetch_array($query)) {
+    	$current_nids[] = $result['nid'];
+  	}
+    
+    // Get list of node ids in the node_access table when module was disabled
+    $query = db_query('SELECT nid from node_access WHERE realm = \'term_access\'');
+    $old_nids = array();
+    while($result = db_fetch_array($query)) {
+    	$old_nids[] = $result['nid'];
+    }
+    $old_nids = array_unique($old_nids);
+    
+    // Get the difference between old and current
+    $delete_nids = array_diff($old_nids, $current_nids);
+    
+    // Delete all node ids that no longer exist from the term_access table
+    foreach($delete_nids as $nid) {
+    	db_query('DELETE from node_access where nid = %d AND realm = \'term_access\'', $nid);
+    }
+    
+    // Update node_access_table to reflect the changes made to term_access table
+    _refresh_node_access_table();
+  }
+}
+
+// Update the node_access table to reflect any changes made to the term_access table
+function _refresh_node_access_table() {
+	// Load term_access table data into memory and put it into an array structure for easy use by second half of function
+	$result = db_query("SELECT * FROM term_access WHERE 1");
+	while($term_access_row = db_fetch_array($result)) {
+		$term_access[] = $term_access_row;
+	}
+	foreach($term_access as $key => $value) {
+		$permissions[$value['tid']][$value['rid']] = array('grant_view' => $value['grant_view'], 'grant_update' => $value['grant_update'], 'grant_delete' => $value['grant_delete']);
+	}
+	
+	// Use the array structure of permissions we just created to make the updates to the node_access table
+	// for nodes that are in a category.
+	$result = db_query("SELECT term_node.nid, term_node.tid FROM term_node, term_data WHERE term_data.tid = term_node.tid");
+	$category_nids = array();
+	while($row = db_fetch_object($result)) {
+ 		$nid = $row->nid;
+ 		$tid = $row->tid;
+ 		$category_nids[] = $nid; // created now for use later on in code handling nodes without categories
+ 		if(array_key_exists($tid, $permissions)) {
+ 			foreach($permissions[$tid] as $key => $value) {
+			  db_query('REPLACE node_access (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (%d, %d, \'term_access\', %d, %d, %d)', $nid, $key, $value['grant_view'], $value['grant_update'], $value['grant_delete']);
+ 			}
+ 		}
+	}
+	
+	// Determine which nodes don't belong to a category
+	$query = db_query("SELECT nid FROM node where 1");
+	while($result = db_fetch_array($query)) {
+	  $all_nids[] = $result['nid'];
+	}
+	$category_nids = array_unique($category_nids);
+	$no_cat = array_diff($all_nids, $category_nids);
+
+	// Update or insert permission data for nodes without categories
+	foreach($no_cat as $nid) {
+	  foreach($permissions[0] as $key => $value) {
+		  db_query('REPLACE node_access (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (%d, %d, \'term_access\', %d, %d, %d)', $nid, $key, $value['grant_view'], $value['grant_update'], $value['grant_delete']);
+		}
+	}
 }
 
 
