Index: modules/taxonomy/taxonomy.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.admin.inc,v retrieving revision 1.49 diff -u -p -r1.49 taxonomy.admin.inc --- modules/taxonomy/taxonomy.admin.inc 15 Apr 2009 14:12:55 -0000 1.49 +++ modules/taxonomy/taxonomy.admin.inc 19 Apr 2009 21:33:28 -0000 @@ -155,15 +155,15 @@ function taxonomy_form_vocabulary(&$form ); $form['settings']['tags'] = array( '#type' => 'checkbox', - '#title' => t('Tags'), + '#title' => t('Autocomplete'), '#default_value' => $edit['tags'], - '#description' => t('Terms are created by users when submitting posts by typing a comma separated list.'), + '#description' => t('Use autocomplete selection when posting content. Users with the appropriate permission may create new terms.'), ); $form['settings']['multiple'] = array( '#type' => 'checkbox', '#title' => t('Multiple select'), '#default_value' => $edit['multiple'], - '#description' => t('Allows posts to have more than one term from this vocabulary (always true for tags).'), + '#description' => t('Allows posts to have more than one term from this vocabulary (always true for autocomplete).'), ); $form['settings']['required'] = array( '#type' => 'checkbox', @@ -715,12 +715,16 @@ function taxonomy_form_term(&$form_state '#value' => t('Save')); if ($edit['tid']) { - $form['delete'] = array( - '#type' => 'submit', - '#value' => t('Delete')); + if (user_access("delete terms in $vocabulary->vid") || user_access('administer taxonomy')) { + $form['delete'] = array( + '#type' => 'submit', + '#value' => t('Delete'), + ); + } $form['tid'] = array( '#type' => 'value', - '#value' => $edit['tid']); + '#value' => $edit['tid'], + ); } else { $form['destination'] = array('#type' => 'hidden', '#value' => $_GET['q']); Index: modules/taxonomy/taxonomy.module =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v retrieving revision 1.470 diff -u -p -r1.470 taxonomy.module --- modules/taxonomy/taxonomy.module 18 Apr 2009 06:32:24 -0000 1.470 +++ modules/taxonomy/taxonomy.module 19 Apr 2009 21:33:29 -0000 @@ -10,12 +10,33 @@ * Implementation of hook_perm(). */ function taxonomy_perm() { - return array( + $permissions = array( 'administer taxonomy' => array( 'title' => t('Administer taxonomy'), 'description' => t('Manage taxonomy vocabularies and terms.'), ), ); + foreach (taxonomy_get_vocabularies() as $vocabulary) { + $permissions += array( + 'create terms in ' . $vocabulary->vid => array( + 'title' => t('Create terms in %vocabulary', array('%vocabulary' => $vocabulary->name)), + 'description' => t('Create terms in the %vocabulary vocabulary.', array('%vocabulary' => $vocabulary->name)), + ), + ); + $permissions += array( + 'edit terms in ' . $vocabulary->vid => array( + 'title' => t('Edit terms in %vocabulary', array('%vocabulary' => $vocabulary->name)), + 'description' => t('Edit terms in the %vocabulary vocabulary.', array('%vocabulary' => $vocabulary->name)), + ), + ); + $permissions += array( + 'delete terms in ' . $vocabulary->vid => array( + 'title' => t('Delete terms in %vocabulary', array('%vocabulary' => $vocabulary->name)), + 'description' => t('Delete terms in the %vocabulary vocabulary.', array('%vocabulary' => $vocabulary->name)), + ), + ); + } + return $permissions; } /** @@ -138,7 +159,8 @@ function taxonomy_menu() { 'title' => 'Edit term', 'page callback' => 'taxonomy_term_edit', 'page arguments' => array(2), - 'access arguments' => array('administer taxonomy'), + 'access callback' => 'taxonomy_term_edit_access', + 'access arguments' => array(2), 'type' => MENU_LOCAL_TASK, 'weight' => 10, ); @@ -194,6 +216,13 @@ function taxonomy_admin_vocabulary_title } /** + * Return edit access for a given term. + */ +function taxonomy_term_edit_access($term) { + return user_access("edit terms in $term->vid") || user_access('administer taxonomy'); +} + +/** * Save a vocabulary given a vocabulary object. */ function taxonomy_vocabulary_save($vocabulary) { @@ -757,6 +786,7 @@ function taxonomy_node_save($node, $term foreach ($typed_input as $vid => $vid_value) { $typed_terms = drupal_explode_tags($vid_value); + $rejected_terms = array(); $inserted = array(); foreach ($typed_terms as $typed_term) { @@ -771,10 +801,15 @@ function taxonomy_node_save($node, $term } if (!$typed_term_tid) { + if (user_access("create terms in $vid") || user_access('administer taxonomy')) { $edit = array('vid' => $vid, 'name' => $typed_term); $term = (object)$edit; $status = taxonomy_term_save($term); $typed_term_tid = $term->tid; + } + else { + $rejected_terms[] = $typed_term; + } } // Defend against duplicate, differently cased tags @@ -789,6 +824,9 @@ function taxonomy_node_save($node, $term $inserted[$typed_term_tid] = TRUE; } } + if (!empty($rejected_terms)) { + drupal_set_message(t('You do not permissions to save the terms: %terms.', array('%terms' => implode(', ', $rejected_terms)))); + } } } @@ -1569,27 +1607,6 @@ function taxonomy_node_delete_revision($ } /** - * Implementation of hook_node_validate(). - * - * Make sure incoming vids are free tagging enabled. - */ -function taxonomy_node_validate($node, $form) { - if (!empty($node->taxonomy)) { - $terms = $node->taxonomy; - if (!empty($terms['tags'])) { - foreach ($terms['tags'] as $vid => $vid_value) { - $vocabulary = taxonomy_vocabulary_load($vid); - if (empty($vocabulary->tags)) { - // see form_get_error $key = implode('][', $element['#parents']); - // on why this is the key - form_set_error("taxonomy][tags][$vid", t('The %name vocabulary can not be modified in this way.', array('%name' => $vocabulary->name))); - } - } - } - } -} - -/** * Implementation of hook_node_rss_item(). * * Provides category information for RSS feeds. Index: modules/taxonomy/taxonomy.test =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.test,v retrieving revision 1.30 diff -u -p -r1.30 taxonomy.test --- modules/taxonomy/taxonomy.test 13 Apr 2009 18:52:38 -0000 1.30 +++ modules/taxonomy/taxonomy.test 19 Apr 2009 21:33:30 -0000 @@ -372,9 +372,10 @@ class TaxonomyTermTestCase extends Taxon function setUp() { parent::setUp('taxonomy'); + $this->vocabulary = $this->createVocabulary(); $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'bypass node access')); + $this->normal_user = $this->drupalCreateUser(array('create article content')); $this->drupalLogin($this->admin_user); - $this->vocabulary = $this->createVocabulary(); } /** @@ -504,10 +505,20 @@ class TaxonomyTermTestCase extends Taxon $edit['taxonomy[tags][' . $this->vocabulary->vid .']'] = implode(', ', $terms); $edit['body'] = $this->randomName(); $this->drupalPost('node/add/article', $edit, t('Save')); - $this->assertRaw(t('@type %title has been created.', array('@type' => t('Article'), '%title' => $edit['title'])), t('The node was created successfully')); + $this->assertRaw(t('@type %title has been created.', array('@type' => t('Article'), '%title' => $edit['title'])), t('The node was created successfully.')); foreach ($terms as $term) { $this->assertText($term, t('The term was saved and appears on the node page')); } + + // Test attempted creation of tags by a user without sufficient permissions. + $this->drupalLogout(); + $this->drupalLogin($this->normal_user); + $extra_term = $this->randomName(); + $terms[] = $extra_term; + $edit['taxonomy[tags][' . $this->vocabulary->vid .']'] = implode(', ', $terms); + $this->drupalPost('node/add/article', $edit, t('Save')); + $this->assertRaw(t('You do not permissions to save the terms: %term.', array('%term' => $extra_term)), t('Term was rejected.')); + $this->assertFalse(taxonomy_get_term_by_name($extra_term), t('Term was not saved in the database.')); } /**