--- term_permissions.module	2010-05-28 10:17:38.000000000 -0400
+++ term_permissions.new	2010-06-04 11:30:00.000000000 -0400
@@ -5,6 +5,13 @@
  * @file
  * Allows access to terms in a vocabulary to be limited by user or role.
  */
+ 
+ function term_permissions_views_api() {
+  $return = array(
+    'api' => 2
+  );
+  return $return;
+ }
 
 /**
  * Implementation of hook_help().
@@ -13,23 +20,25 @@ function term_permissions_help($path, $a
   switch ($path) {
     case 'admin/help#term_permissions':
       $output = '<p>' . t('This module allows taxonomy administrators the ability to restrict setting individual terms on nodes by user or role. If a user is unable to set any terms for a required vocabulary, they are blocked from adding or editing content with that vocabulary.') . '</p>';
-      $output .= '<p>' . t('To add permissions for a term, go to Administer >> Content Management >> Taxonomy, and add or edit a term. If the permissions are left blank, the term is available to all users.') . '</p>';
+      $output .= '<p>' . t('To add permissions for a term, go to Administer >> Users, and view the individual users profile. In the edit tab will be a new field set for taxonomy permissions.') . '</p>';
       return $output;
   }
 }
 
 /**
- * Implementation of hook_menu().
+ * Implementation of hook_perm()
+ * Note, this generates a dynamic set of permissions
  */
-function term_permissions_menu() {
-  $items = array();
-  $items['term-permissions/autocomplete'] = array(
-    'title' => '',
-    'page callback' => 'term_permissions_autocomplete_multiple',
-    'access arguments' => array('access user profiles'),
-    'type' => MENU_CALLBACK,
-  );
-  return $items;
+  function term_permissions_perm() {
+    $result = db_query("SELECT vid, name FROM {vocabulary}");
+    $perms = array('use all taxonomy terms');
+    while($vid = db_fetch_array($result)) {
+      $terms = taxonomy_get_tree($vid['vid']);
+      foreach ($terms as $term) {
+        $perms[] = 'use taxonomy term '. $term->name;
+      }
+    }
+    return $perms;
 }
 
 /**
@@ -44,122 +53,148 @@ function term_permissions_menu() {
  */
 function term_permissions_form_alter(&$form, $form_state, $form_id) {
   // This is the add / edit term form from the taxonomy page.
-  if ($form_id == 'taxonomy_form_term') {
-    // Ensure that the Identification fieldset is at the top, as by default it
-    // has no weight specified.
-    $form['identification']['#weight'] = -15;
-    $form['advanced']['#weight'] = -10;
-
-    $form['access'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Permissions'),
-      '#description' => t('To limit selection of this term by user or roles, add users or roles to the following lists. Leave empty to allow selection by all users.'),
-      '#collapsible' => TRUE,
-      '#collapsed' => TRUE,
-      '#attributes' => array('id' => 'fieldset_term_access'),
-      '#weight' => -5,
-      '#tree' => TRUE,
-    );
-    // Pull in any stored users in the database.
-    $allowed_users = array();
-    if (!empty($form['tid']['#value'])) {
-      $result = db_query("SELECT uid FROM {term_permissions_user} WHERE tid = %d", $form['#term']['tid']);
-      while($uid = db_result($result)) {
-        $u = user_load($uid);
-        $allowed_users[] = $u->name;
+  if ($form_id == 'user_profile_form') {
+    // we need currently logged in user for later
+    global $user;
+    
+    // get user account we are editing
+    $account = user_load(arg(1));
+    $term_perms = term_permissions_get_term_perms($account);
+    $terms = term_permissions_get_terms();
+    $ops = array();
+    $current_perms = array();
+    
+    foreach ($terms as $term) {
+      $ops[$term['tid']] = $term['name'];
+      foreach ($term_perms as $term_perm){
+      
+        if ($term['tid'] == $term_perm['tid']) {
+          $current_perms[] = $term['tid'];
+        }
       }
     }
-    $allowed_users = drupal_implode_tags($allowed_users);
-    // Note that the autocomplete widget will only enable for users with the
-    // 'access profiles' permission. Other users will have to specify the name
-    // manually.
-    $form['access']['user'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Allowed users'),
-      '#description' => t('Enter a comma-seperated list of user names to give them permission to use this term.'),
-      '#default_value' => $allowed_users,
-      '#size' => 40,
-      '#autocomplete_path' => 'term-permissions/autocomplete',
-      '#weight' => -10,
+    
+    $form['uid'] = array(
+      '#type' => 'hidden',
+      '#value' => $account->uid
     );
-
-    $allowed_roles = array();
-    if (!empty($form['tid']['#value'])) {
-      $result = db_query("SELECT rid FROM {term_permissions_role} WHERE tid = %d", array($form['tid']['#value']));
-      while($rid = db_result($result)) {
-        $allowed_roles[] = $rid;
-      }
-    }
-
-    // Now, lets do the Roles table.
-    $form['access']['role'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Allowed roles'),
-      '#description' => t('Select a role to allow all members of that role access to this term.'),
-      '#default_value' => $allowed_roles,
-      '#options' => user_roles(),
-      '#multiple' => FALSE,
-      '#weight' => 5,
+    
+    $form['term_permissions'] = array(
+     '#title' => 'Term Permissions',
+     '#type' => 'fieldset',
+     
+     // make sure currently logged in user has correct perms
+     '#access' => user_access('administer users', $user),
+     '#collapsible' => TRUE
+    );    
+    
+    $form['term_permissions']['terms'] = array(
+      '#title' => 'Taxonomy Terms '. $account->name .' Can Use',
+      '#type' => 'select',
+      '#options' => $ops,
+      '#multiple' => TRUE,
+      '#default_value' => $current_perms      
     );
-
     $form['#validate'][] = 'term_permissions_validate';
     $form['#submit'][] = 'term_permissions_submit';
+    
   }
-
+  
   // This is the node add / edit form. If a different selector is used from
   // another contributed module, we do nothing so as to not break the form.
   if (isset($form['type']) && isset($form['#node']) && isset($form['taxonomy']) && (!variable_get('taxonomy_override_selector', FALSE)) && $form['type']['#value'] .'_node_form' == $form_id) {
+    
+    // first get the users term perms
+    global $user;
+    $term_perms = term_permissions_get_term_perms($user);
+   
     foreach($form['taxonomy'] as $vid => $vocabulary) {
       if (!is_array($vocabulary) || !isset($vocabulary['#options'])) {
         continue;
       }
-      $total_terms = count($vocabulary['#options']) - 1;
+      
+      if (count($term_perms) == 0) {
+        if ($vocabulary['#required']) {
+          drupal_set_message(t("Your account doesn't have permission to use any of the terms in the %vocabulary vocabulary. Your account must be given permission to use at least one term in the %vocabulary vocabulary to be able to add or edit the %content-type content type.", array('%vocabulary' => $vocabulary['#title'], '%content-type' => node_get_types('name', $form['type']['#value']))), 'warning');
+          watchdog('term_permissions', '%user was blocked from accessing the %content-type form as they do not have permission to use any terms in the <a href="@vocabulary-url">%vocabulary</a> vocabulary.', array('%user' => isset($user->name) ? $user->name : variable_get('anonymous', 'Anonymous'), '%content-type' => node_get_types('name', $form['type']['#value']), '@vocabulary-url' => url('admin/content/taxonomy/' . $vid), '%vocabulary' => $vocabulary['#title']), WATCHDOG_WARNING, l(t('edit vocabulary'), 'admin/content/taxonomy/' . $vid));
+          drupal_access_denied();
+          exit();
+        }
+      }   
+        
+      $total_terms = count($vocabulary['#options']);
       foreach($vocabulary['#options'] as $terms) {
         if (!isset($terms->option)) {
           continue;
         }
+        
+        // check if user has access to this term  
         foreach($terms->option as $tid => $term) {
-          // Now we have the term ID, check to see if the current user has
-          // access to the term.
-          global $user;
-          if (!term_permissions_allowed($tid, $user)) {
-            $total_terms--;
-            unset($terms->option[$tid]);
-          }
-          // If the user doesn't have access to any of the terms in the
-          // vocabulary, remove the form item entirely.
-          if ($total_terms <= 0) {
-            if ($vocabulary['#required']) {
-              drupal_set_message(t("Your account doesn't have permission to use any of the terms in the %vocabulary vocabulary. Your account must be given permission to use at least one term in the %vocabulary vocabulary to be able to add or edit the %content-type content type.", array('%vocabulary' => $vocabulary['#title'], '%content-type' => node_get_types('name', $form['type']['#value']))), 'warning');
-              watchdog('term_permissions', '%user was blocked from accessing the %content-type form as they do not have permission to use any terms in the <a href="@vocabulary-url">%vocabulary</a> vocabulary.', array('%user' => isset($user->name) ? $user->name : variable_get('anonymous', 'Anonymous'), '%content-type' => node_get_types('name', $form['type']['#value']), '@vocabulary-url' => url('admin/content/taxonomy/' . $vid), '%vocabulary' => $vocabulary['#title']), WATCHDOG_WARNING, l(t('edit vocabulary'), 'admin/content/taxonomy/' . $vid));
-              drupal_access_denied();
-              exit();
+            
+          // to unset or not to unset, that is the question.
+          $unset = TRUE;
+          foreach($term_perms as $item) {
+            if($item['tid'] == $tid) {
+              $unset = FALSE;
             }
-            unset($form['taxonomy'][$vid]);
           }
-        }
+            
+          if ($unset) {
+            // there has to be a better way...
+            // ...but we loop through each option of each vocabulary
+              
+            foreach ($form['taxonomy'][$vid]['#options'] as $op_key=>$op_val) {   
+                
+              // next, we check against every term perm
+              foreach($op_val->option as $key=>$val) {
+                  
+                // check for match to unset
+                if ($key == $tid) {
+                  $tname = db_result(db_query("SELECT name FROM {term_data} WHERE tid = %d", $tid));
+                  
+                    // and finally, check to see if the users role has access
+                    if (!user_access('use taxonomy term '. $tname)) {
+                      if (!user_access('use all taxonomy terms')) {
+                        unset($form['taxonomy'][$vid]['#options'][$op_key]);
+                      }
+                    }
+                }
+              }
+            }
+          } 
+        }  
+      }
+      
+      // check for newly emptied vocabularies
+      if (count($form['taxonomy'][$vid]['#options']) == 0) {
+        unset($form['taxonomy'][$vid]);
       }
     }
   }
 }
-
-/**
- * Validation function to ensure that the selected user exists.
- *
- * @param $form
- *   The current form array.
- * @param $form_state
- *   The state of the current form.
+ 
+/*
+ * Gets a users term perms
+ * 
+ * @param $user
+ *   The user account
  */
-function term_permissions_validate($form, &$form_state) {
-  if (!empty($form_state['values']['access']['user'])) {
-    $allowed_users = drupal_explode_tags($form_state['values']['access']['user']);
-    foreach ($allowed_users as $name) {
-      if (!(user_load(array('name' => $name)))) {
-        form_set_error('search_user', t('The user %name does not exist.', array('%user' => $name)));
-      }
-    }
+
+function term_permissions_get_term_perms($user) {
+  $results = db_query("SELECT * FROM {term_permissions_user} WHERE uid = %d", $user->uid);
+  $terms = array();
+  while($term = db_fetch_array($results)) {
+    $terms[] = $term;
+  }
+  return $terms;
+}
+
+function term_permissions_get_terms() {
+  $results = db_query("SELECT tid, vid, name FROM term_data");
+  while($row = db_fetch_array($results)){
+    $return[] = $row;
   }
+  return $return;
 }
 
 /**
@@ -172,74 +207,21 @@ function term_permissions_validate($form
  *   The state of the current form.
  */
 function term_permissions_submit($form, &$form_state) {
-  // For each user, save the term ID and the user ID.
-  db_query("DELETE FROM {term_permissions_user} WHERE tid = %d", $form_state['values']['tid']);
-  if (!empty($form_state['values']['access']['user'])) {
-    $allowed_users = drupal_explode_tags($form_state['values']['access']['user']);
-    foreach($allowed_users as $name) {
-      $u = user_load(array('name' => $name));
-      db_query("INSERT INTO {term_permissions_user} (tid, uid) VALUES (%d, %d)", $form_state['values']['tid'], $u->uid);
-    }
-  }
-
-  // For each role, save the term ID and the role ID.
-  db_query("DELETE FROM {term_permissions_role} WHERE tid = %d", $form_state['values']['tid']);
-  if (!empty($form_state['values']['access']['role'])) {
-    foreach(array_keys(array_filter($form_state['values']['access']['role'])) as $rid) {
-      db_query("INSERT INTO {term_permissions_role} (tid, rid) VALUES (%d, %d)", $form_state['values']['tid'], $rid);
-    }
-  }
-}
-
-/**
- * Given a term ID, determine if a user has access to that term. UID 1 is
- * always allowed access. If no permissions are set on the term, allow
- * access by default.
- *
- * @param $tid
- *   The term ID to look up.
- * @param $user
- *   The user to determine if it has access to the term ID.
- * @return bool
- *   TRUE if the user has access to the term, otherwise FALSE.
- */
-function term_permissions_allowed($tid, $user) {
-  if ($user->uid == 1) {
-    return TRUE;
-  }
-  // Are permissions enabled on this term?
-  if (!(db_result(db_query("SELECT COUNT(1) FROM {term_permissions_user} WHERE tid = %d", $tid)) || db_result(db_query("SELECT COUNT(1) FROM {term_permissions_role} WHERE tid = %d", $tid)))) {
-    return TRUE;
-  }
-  // Permissions are enabled, check to see if this user or one of their roles
-  // is allowed.
-  if (db_result(db_query("SELECT uid FROM {term_permissions_user} WHERE tid = %d AND uid = %d", $tid, $user->uid)) || db_result(db_query("SELECT rid FROM {term_permissions_role} WHERE tid = %d AND rid IN (" . implode(', ', array_keys($user->roles)) . ")", $tid))) {
-    return TRUE;
-  }
-  return FALSE;
-}
 
-/**
- * Returns JS array for Taxonomy Term Permissions autocomplete fields. Supports
- * multiple entries separated by a comma.
- */
-function term_permissions_autocomplete_multiple($string) {
-  // The user enters a comma-separated list of users. We only autocomplete the last user.
-  $array = drupal_explode_tags($string);
-
-  // Fetch last tag
-  $last_string = trim(array_pop($array));
-
-  $matches = array();
-  $result = db_query_range("SELECT u.name FROM {users} u WHERE LOWER(u.name) LIKE LOWE                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                