From c33f619496faec360a1750ae1d855967dd6241ee Mon Sep 17 00:00:00 2001 From: Andrew Berry Date: Fri, 3 Feb 2012 12:57:50 -0500 Subject: [PATCH 1/4] Issue #908434 by witchcraft, MiSC: Port Term Permissions to Drupal 7. --- README.txt | 2 +- term_permissions.info | 2 +- term_permissions.install | 42 ++++++++-- term_permissions.module | 198 ++++++++++++++++++++++++++++++---------------- 4 files changed, 164 insertions(+), 80 deletions(-) diff --git a/README.txt b/README.txt index 65a7446..8bbee03 100755 --- a/README.txt +++ b/README.txt @@ -13,7 +13,7 @@ to be "privileged" terms, such as marking a wiki page as stable or verified. To install the Taxonomy Term Permissions module, extract the module to your modules folder, such as sites/all/modules. After enabling the module, each term can be assigned permissions when adding or editing a term at Administer > -Content Management > Taxonomy. If no permissions are assigned, all users may +Structure > Taxonomy. If no permissions are assigned, all users may access the term. If a user may not access any terms in a required vocabulary, they will be denied access to the node form entirely. diff --git a/term_permissions.info b/term_permissions.info index 7f8ca95..88edcd1 100644 --- a/term_permissions.info +++ b/term_permissions.info @@ -1,4 +1,4 @@ name = Taxonomy Term Permissions description = Allows limiting the selection of specific taxonomy terms by user or role. -core=6.x +core = 7.x dependencies[] = taxonomy diff --git a/term_permissions.install b/term_permissions.install index 1e1b991..dc63804 100644 --- a/term_permissions.install +++ b/term_permissions.install @@ -1,12 +1,19 @@ array( - 'tid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE), - 'uid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE), + 'tid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'uid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), ), 'primary key' => array( 'tid', @@ -37,8 +52,16 @@ function term_permissions_schema() { $schema['term_permissions_role'] = array( 'fields' => array( - 'tid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE), - 'rid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE), + 'tid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'rid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), ), 'primary key' => array( 'tid', @@ -50,8 +73,9 @@ function term_permissions_schema() { } /** - * Implementation of hook_uninstall(). + * Implements hook_uninstall(). */ function term_permissions_uninstall() { - drupal_uninstall_schema('term_permissions'); + // TODO The drupal_(un)install_schema functions are called automatically in D7. + // drupal_uninstall_schema('term_permissions') } diff --git a/term_permissions.module b/term_permissions.module index e6550b6..a4eb82c 100644 --- a/term_permissions.module +++ b/term_permissions.module @@ -1,24 +1,28 @@ ' . 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.') . '

'; - $output .= '

' . 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.') . '

'; + $output = '

' . 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.') . '

'; + $output .= '

' . 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.') . '

'; return $output; } } /** - * Implementation of hook_menu(). + * Implements hook_menu(). */ function term_permissions_menu() { $items = array(); @@ -32,18 +36,19 @@ function term_permissions_menu() { } /** - * Implementation of hook_form_alter() + * Implements hook_form_alter(). * - * @param $form + * @param array $form * The form to alter. - * @param $form_state + * @param array $form_state * The form state of the current form. - * @param $form_id + * @param array $form_id * The form id of the current form. */ 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; @@ -52,7 +57,9 @@ function term_permissions_form_alter(&$form, $form_state, $form_id) { $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.'), + '#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'), @@ -62,9 +69,13 @@ function term_permissions_form_alter(&$form, $form_state, $form_id) { // 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); + $result = db_select('term_permissions_user') + ->fields('term_permissions_user') + ->condition('tid', $form['#term']['tid']) + ->execute(); + + foreach ($result as $row) { + $u = user_load($row->uid); $allowed_users[] = $u->name; } } @@ -75,18 +86,23 @@ function term_permissions_form_alter(&$form, $form_state, $form_id) { $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.'), + '#description' => t('Enter a comma-seperated list of user names to give + them permission to use this term.'), '#default_value' => $allowed_users, - '#size' => 40, + '#size' => 60, '#autocomplete_path' => 'term-permissions/autocomplete', '#weight' => -10, ); $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; + $result = db_select('term_permissions_role') + ->fields('term_permissions_role') + ->condition('tid', $form['#term']['tid']) + ->execute(); + + foreach ($result as $row) { + $allowed_roles[] = $row->rid; } } @@ -105,37 +121,57 @@ function term_permissions_form_alter(&$form, $form_state, $form_id) { $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) { - foreach($form['taxonomy'] as $vid => $vocabulary) { - if (!is_array($vocabulary) || !isset($vocabulary['#options'])) { - continue; - } - $total_terms = count($vocabulary['#options']); - foreach($vocabulary['#options'] as $terms) { - if (!isset($terms->option)) { - continue; - } - 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]); + // 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']) && + (!variable_get('taxonomy_override_selector', FALSE)) && + $form['type']['#value'] .'_node_form' == $form_id) { + $types = array('taxonomy_term_reference'); // Field types we are looking for + + foreach($form as $field_name => $field) { + if(!$field_info = field_info_field($field_name)) + continue; + + $options = &$form[$field_name][$form[$field_name]['#language']]['#options']; + if (!in_array($field_info['type'], $types) || !isset($options)) { + continue; } - // 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 %vocabulary 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(); - } - unset($form['taxonomy'][$vid]); + + foreach($options as $tid => $name) { + if($tid == "_none") + continue; + + // 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)) { + unset($options[$tid]); + } + // If the user doesn't have access to any of the terms in the + // vocabulary, remove the form item entirely. + if (count($options) <= 1) { + 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 %vocabulary + 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(); } + unset($form[$field_name]); } } } @@ -154,8 +190,9 @@ 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))); + if (!(array_shift(user_load_multiple(array(), array('name' => $name))))) { + form_set_error('search_user', t('The user %name does not exist.', + array('%user' => $name))); } } } @@ -172,20 +209,34 @@ function term_permissions_validate($form, &$form_state) { */ 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']); + db_delete('term_permissions_user') + ->condition('tid', $form_state['values']['tid']) + ->execute(); 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); + foreach ($allowed_users as $name) { + $u = array_shift(user_load_multiple(array(), array('name' => $name))); + $id = db_insert('term_permissions_user') + ->fields(array( + 'tid' => $form_state['values']['tid'], + 'uid' => $u->uid, + )) + ->execute(); } } // 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']); + db_delete('term_permissions_role') + ->condition('tid', $form_state['values']['tid']) + ->execute(); 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); + foreach (array_keys(array_filter($form_state['values']['access']['role'])) as $rid) { + $id = db_insert('term_permissions_role') + ->fields(array( + 'tid' => $form_state['values']['tid'], + 'rid' => $rid, + )) + ->execute(); } } } @@ -206,39 +257,48 @@ 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; + if (!(db_query("SELECT COUNT(1) FROM {term_permissions_user} WHERE tid = :tid", + array(':tid' => $tid))->fetchField() || + db_query("SELECT COUNT(1) FROM {term_permissions_role} WHERE tid = :tid", + array(':tid' => $tid))->fetchField())) { + return TRUE; } + // We need to convert user->roles to be useful for us. + $users_uid = implode(', ', array_keys($user->roles)); // 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))) { + + if (db_query("SELECT uid FROM {term_permissions_user} WHERE tid = :tid AND uid = :uid", + array(':tid' => $tid, ':uid' => $user->uid))->fetchField() || + db_query("SELECT rid FROM {term_permissions_role} WHERE tid = :tid AND rid IN (:user_roles)", + array(':tid' => $tid, ':user_roles'=> $users_uid))->fetchField()) { return TRUE; } return FALSE; } /** - * Returns JS array for Taxonomy Term Permissions autocomplete fields. Supports + * Returns Json 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. + // The user enters a comma-separated list of users. + // We only autocomplete the last user. $array = drupal_explode_tags($string); - // Fetch last tag + // Fetch last user. $last_string = trim(array_pop($array)); $matches = array(); - $result = db_query_range("SELECT u.name FROM {users} u WHERE LOWER(u.name) LIKE LOWER('%s%%')", $last_string, 0, 10); + $result = db_select('users')->fields('users', array('name'))->condition('name', + db_like($last_string) . '%', 'LIKE')->range(0, 10)->execute(); - $prefix = count($array) ? implode(', ', $array) .', ' : ''; + $prefix = count($array) ? implode(', ', $array) . ', ' : ''; - while ($user = db_fetch_object($result)) { + foreach ($result as $user) { $matches[$prefix . $user->name] = check_plain($user->name); } - if (module_exists('devel')) { - $GLOBALS['devel_shutdown'] = FALSE; - } - exit(drupal_json($matches)); + exit(drupal_json_output($matches)); } -- 1.7.7.4 From 9ee033cf4169357c0cc30ae883c47aa34a57827a Mon Sep 17 00:00:00 2001 From: Andrew Berry Date: Fri, 3 Feb 2012 13:01:12 -0500 Subject: [PATCH 2/4] Issue #908434: Remove old hook_install / hook_uninstall functions. --- term_permissions.install | 27 --------------------------- 1 files changed, 0 insertions(+), 27 deletions(-) diff --git a/term_permissions.install b/term_permissions.install index dc63804..57ae761 100644 --- a/term_permissions.install +++ b/term_permissions.install @@ -5,26 +5,6 @@ * */ - - -/** - * Implements hook_install(). - */ -function term_permissions_install() { - $ret = array(); - // TODO The drupal_(un)install_schema functions are called automatically in D7. - $results = array()/*drupal_install_schema('term_permissions')*/; - $install_pass = TRUE; - foreach ($results as $result) { - if (!$result['success']) { - $install_pass = FALSE; - } - } - if (!$install_pass) { - drupal_set_message(t('There was an error installing the Taxonomy Term Permissions module. The error log may have more information about the error.', array('@watchdog-url' => url('admin/reports/dblog'))), 'error'); - } -} - /** * Implements hook_schema(). */ @@ -72,10 +52,3 @@ function term_permissions_schema() { return $schema; } -/** - * Implements hook_uninstall(). - */ -function term_permissions_uninstall() { - // TODO The drupal_(un)install_schema functions are called automatically in D7. - // drupal_uninstall_schema('term_permissions') -} -- 1.7.7.4 From 1f301c038832d5bbd0abe967ce0527ab7426509f Mon Sep 17 00:00:00 2001 From: Andrew Berry Date: Fri, 3 Feb 2012 13:06:54 -0500 Subject: [PATCH 3/4] Issue #908434: Implement coder style reviews. --- term_permissions.module | 91 ++++++++++++++++++++++++----------------------- 1 files changed, 46 insertions(+), 45 deletions(-) diff --git a/term_permissions.module b/term_permissions.module index a4eb82c..6674ee1 100644 --- a/term_permissions.module +++ b/term_permissions.module @@ -121,54 +121,55 @@ function term_permissions_form_alter(&$form, $form_state, $form_id) { $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']) && - (!variable_get('taxonomy_override_selector', FALSE)) && - $form['type']['#value'] .'_node_form' == $form_id) { - $types = array('taxonomy_term_reference'); // Field types we are looking for + // 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']) && + (!variable_get('taxonomy_override_selector', FALSE)) && + $form['type']['#value'] . '_node_form' == $form_id) { + $types = array('taxonomy_term_reference'); // Field types we are looking for - foreach($form as $field_name => $field) { - if(!$field_info = field_info_field($field_name)) - continue; + foreach ($form as $field_name => $field) { + if (!$field_info = field_info_field($field_name)) + continue; - $options = &$form[$field_name][$form[$field_name]['#language']]['#options']; - if (!in_array($field_info['type'], $types) || !isset($options)) { - continue; - } + $options = &$form[$field_name][$form[$field_name]['#language']]['#options']; + if (!in_array($field_info['type'], $types) || !isset($options)) { + continue; + } - foreach($options as $tid => $name) { - if($tid == "_none") - continue; + foreach ($options as $tid => $name) { + if ($tid == "_none") { + continue; + } - // 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)) { - unset($options[$tid]); - } - // If the user doesn't have access to any of the terms in the - // vocabulary, remove the form item entirely. - if (count($options) <= 1) { - 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 %vocabulary - 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(); + // 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)) { + unset($options[$tid]); + } + // If the user doesn't have access to any of the terms in the + // vocabulary, remove the form item entirely. + if (count($options) <= 1) { + 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 %vocabulary + 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(); } unset($form[$field_name]); @@ -273,7 +274,7 @@ function term_permissions_allowed($tid, $user) { if (db_query("SELECT uid FROM {term_permissions_user} WHERE tid = :tid AND uid = :uid", array(':tid' => $tid, ':uid' => $user->uid))->fetchField() || db_query("SELECT rid FROM {term_permissions_role} WHERE tid = :tid AND rid IN (:user_roles)", - array(':tid' => $tid, ':user_roles'=> $users_uid))->fetchField()) { + array(':tid' => $tid, ':user_roles' => $users_uid))->fetchField()) { return TRUE; } return FALSE; -- 1.7.7.4 From fe0f1802a02f71b179533fc06c189b5074685652 Mon Sep 17 00:00:00 2001 From: Andrew Berry Date: Fri, 3 Feb 2012 13:58:24 -0500 Subject: [PATCH 4/4] Issue #908434: Always cast terms to an object. --- term_permissions.module | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/term_permissions.module b/term_permissions.module index 6674ee1..ec4b49f 100644 --- a/term_permissions.module +++ b/term_permissions.module @@ -48,6 +48,9 @@ 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') { + // Normally the term is an array, but when deleting terms it becomes an + // object. So, we cast it to an object so we can consistently reference it. + $term = (object)$form['#term']; // Ensure that the Identification fieldset is at the top, as by default it // has no weight specified. @@ -68,10 +71,11 @@ function term_permissions_form_alter(&$form, $form_state, $form_id) { ); // Pull in any stored users in the database. $allowed_users = array(); + error_log(print_r($term, TRUE)); if (!empty($form['tid']['#value'])) { $result = db_select('term_permissions_user') ->fields('term_permissions_user') - ->condition('tid', $form['#term']['tid']) + ->condition('tid', $term->tid) ->execute(); foreach ($result as $row) { @@ -98,7 +102,7 @@ function term_permissions_form_alter(&$form, $form_state, $form_id) { if (!empty($form['tid']['#value'])) { $result = db_select('term_permissions_role') ->fields('term_permissions_role') - ->condition('tid', $form['#term']['tid']) + ->condition('tid', $term->tid) ->execute(); foreach ($result as $row) { -- 1.7.7.4