diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
index 9bd703b..6896c80 100644
--- a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
+++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php
@@ -76,6 +76,7 @@ function setUp() {
// Create users.
$this->admin_user = $this->drupalCreateUser(array(
'access administration pages',
+ 'access taxonomy overview',
'administer modules',
'administer blocks',
'administer forums',
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php
index 6b7d00d..8f2a3be 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessBaseTableTest.php
@@ -66,7 +66,7 @@ function testNodeAccessBasic() {
$titles = array(); // Titles keyed by nid
$private_nodes = array(); // Array of nids marked private.
for ($i = 0; $i < $num_simple_users; $i++) {
- $simple_users[$i] = $this->drupalCreateUser(array('access content', 'create article content'));
+ $simple_users[$i] = $this->drupalCreateUser(array('access content', 'create article content', 'create terms in 1'));
}
foreach ($simple_users as $this->webUser) {
$this->drupalLogin($this->webUser);
diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php
index 00e4259..109d570 100644
--- a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php
+++ b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php
@@ -99,7 +99,7 @@ function testDrupalRdfaAttributes() {
*/
function testAttributesInMarkupFile() {
// Create a user to post the image.
- $admin_user = $this->drupalCreateUser(array('edit own article content', 'revert revisions', 'administer content types'));
+ $admin_user = $this->drupalCreateUser(array('edit own article content', 'revert revisions', 'administer content types', 'create terms in 1'));
$this->drupalLogin($admin_user);
$langcode = LANGUAGE_NOT_SPECIFIED;
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php
index d00f373..7c74713 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/LegacyTest.php
@@ -24,7 +24,7 @@ public static function getInfo() {
function setUp() {
parent::setUp();
- $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'administer nodes', 'bypass node access'));
+ $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'administer nodes', 'bypass node access', 'create terms in 1'));
$this->drupalLogin($this->admin_user);
}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
index b2603d6..8ff4ee2 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTest.php
@@ -22,8 +22,6 @@ public static function getInfo() {
function setUp() {
parent::setUp();
- $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'bypass node access'));
- $this->drupalLogin($this->admin_user);
$this->vocabulary = $this->createVocabulary();
$field = array(
@@ -55,6 +53,10 @@ function setUp() {
),
);
field_create_instance($this->instance);
+
+ drupal_static_reset();
+ $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'access taxonomy overview', 'bypass node access', 'create terms in ' . $this->vocabulary->vid));
+ $this->drupalLogin($this->admin_user);
}
/**
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php
index 043defc..0897439 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php
@@ -117,7 +117,7 @@ public function testTranslationUI() {
* Tests translate link on vocabulary term list.
*/
function testTranslateLinkVocabularyAdminPage() {
- $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer taxonomy', 'translate any entity'));
+ $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer taxonomy', 'translate any entity', 'access taxonomy overview'));
$this->drupalLogin($this->admin_user);
$translatable_vocabulary_name = $this->vocabulary->name;
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyTest.php
index 6197fdb..9b38782 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/VocabularyTest.php
@@ -22,7 +22,7 @@ public static function getInfo() {
function setUp() {
parent::setUp();
- $this->admin_user = $this->drupalCreateUser(array('administer taxonomy'));
+ $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'access taxonomy overview'));
$this->drupalLogin($this->admin_user);
$this->vocabulary = $this->createVocabulary();
}
diff --git a/core/modules/taxonomy/taxonomy.admin.inc b/core/modules/taxonomy/taxonomy.admin.inc
index 6a14e3c..12d362a 100644
--- a/core/modules/taxonomy/taxonomy.admin.inc
+++ b/core/modules/taxonomy/taxonomy.admin.inc
@@ -29,18 +29,24 @@ function taxonomy_overview_vocabularies($form) {
'#default_value' => $vocabulary->weight,
);
$links = array();
- $links['edit'] = array(
- 'title' => t('edit vocabulary'),
- 'href' => "admin/structure/taxonomy/$vocabulary->machine_name/edit",
- );
+
+ if (user_access('administer taxonomy')) {
+ $links['edit'] = array(
+ 'title' => t('edit vocabulary'),
+ 'href' => "admin/structure/taxonomy/$vocabulary->machine_name/edit",
+ );
+ }
$links['list'] = array(
'title' => t('list terms'),
'href' => "admin/structure/taxonomy/$vocabulary->machine_name",
);
- $links['add'] = array(
- 'title' => t('add terms'),
- 'href' => "admin/structure/taxonomy/$vocabulary->machine_name/add",
- );
+
+ if (user_access('create terms in ' . $vocabulary->vid)) {
+ $links['add'] = array(
+ 'title' => t('add terms'),
+ 'href' => "admin/structure/taxonomy/$vocabulary->machine_name/add",
+ );
+ }
$form[$vocabulary->vid]['operations'] = array(
'#type' => 'operations',
'#links' => $links,
@@ -284,10 +290,15 @@ function taxonomy_overview_terms($form, &$form_state, Vocabulary $vocabulary) {
'#default_value' => $term->weight,
);
}
- $operations = array(
- 'edit' => array('title' => t('edit'), 'href' => 'taxonomy/term/' . $term->tid . '/edit', 'query' => $destination),
- 'delete' => array('title' => t('delete'), 'href' => 'taxonomy/term/' . $term->tid . '/delete', 'query' => $destination),
- );
+
+ $operations = array();
+ if (taxonomy_term_access('edit', $term)) {
+ $operations['edit'] = array('title' => t('edit'), 'href' => 'taxonomy/term/' . $term->tid . '/edit', 'query' => $destination);
+ }
+ if (taxonomy_term_access('delete', $term)) {
+ $operations['delete'] = array('title' => t('delete'), 'href' => 'taxonomy/term/' . $term->tid . '/delete', 'query' => $destination);
+ }
+
if (module_invoke('translation_entity', 'translate_access', $term)) {
$operations['translate'] = array(
'title' => t('translate'),
@@ -306,7 +317,11 @@ function taxonomy_overview_terms($form, &$form_state, Vocabulary $vocabulary) {
$form['#page_entries'] = $page_entries;
$form['#back_step'] = $back_step;
$form['#forward_step'] = $forward_step;
- $form['#empty_text'] = t('No terms available. Add term.', array('@link' => url('admin/structure/taxonomy/' . $vocabulary->machine_name . '/add')));
+
+ $form['#empty_text'] = t('No terms available.');
+ if (user_access('create terms in ' . $vocabulary->vid)) {
+ $form['#empty_text'] .= ' ' . l(t('Add term'), 'admin/structure/taxonomy/' . $vocabulary->machine_name . '/add');
+ }
if ($vocabulary->hierarchy != TAXONOMY_HIERARCHY_MULTIPLE && count($tree) > 1) {
$form['actions'] = array('#type' => 'actions', '#tree' => FALSE);
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 0158e7e..29cb5b6 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -87,11 +87,22 @@ function taxonomy_help($path, $arg) {
function taxonomy_permission() {
$permissions = array(
'administer taxonomy' => array(
- 'title' => t('Administer vocabularies and terms'),
+ 'title' => t('Administer vocabularies'),
+ ),
+ 'access taxonomy overview' => array(
+ 'title' => t('Access the taxonomy overview page'),
+ 'description' => t('Access the taxonomy overview page at admin/structure/taxonomy.', array(
+ '@url' => url('admin/structure/taxonomy'),
+ )),
),
);
foreach (taxonomy_vocabulary_load_multiple() as $vocabulary) {
$permissions += array(
+ 'create terms in ' . $vocabulary->vid => array(
+ 'title' => t('Add terms in %vocabulary', array('%vocabulary' => $vocabulary->name)),
+ ),
+ );
+ $permissions += array(
'edit terms in ' . $vocabulary->vid => array(
'title' => t('Edit terms in %vocabulary', array('%vocabulary' => $vocabulary->name)),
),
@@ -246,7 +257,7 @@ function taxonomy_menu() {
'description' => 'Manage tagging, categorization, and classification of your content.',
'page callback' => 'drupal_get_form',
'page arguments' => array('taxonomy_overview_vocabularies'),
- 'access arguments' => array('administer taxonomy'),
+ 'access arguments' => array('access taxonomy overview'),
'file' => 'taxonomy.admin.inc',
);
$items['admin/structure/taxonomy/list'] = array(
@@ -320,7 +331,7 @@ function taxonomy_menu() {
'title arguments' => array(3),
'page callback' => 'drupal_get_form',
'page arguments' => array('taxonomy_overview_terms', 3),
- 'access arguments' => array('administer taxonomy'),
+ 'access arguments' => array('access taxonomy overview'),
'file' => 'taxonomy.admin.inc',
);
$items['admin/structure/taxonomy/%taxonomy_vocabulary_machine_name/list'] = array(
@@ -342,7 +353,8 @@ function taxonomy_menu() {
'title' => 'Add term',
'page callback' => 'taxonomy_term_add',
'page arguments' => array(3),
- 'access arguments' => array('administer taxonomy'),
+ 'access callback' => 'taxonomy_term_access',
+ 'access arguments' => array('create', 3),
'type' => MENU_LOCAL_ACTION,
'file' => 'taxonomy.admin.inc',
);
@@ -368,25 +380,27 @@ function taxonomy_admin_paths() {
* operation.
*
* @param $op
- * The operation to be performed on the taxonomy term. Possible values are:
+ * The operation to be performed with a taxonomy term. Possible values are:
+ * - "create"
* - "edit"
* - "delete"
- * @param $term
- * The $term object on which the operation is to be performed.
+ * @param $obj
+ * If op is either edit or delete then $obj should be a $term object on which
+ * the operation is to be performed. If $op is create then this argument
+ * should be a vocabulary in which a term can be created.
*
* @return
* TRUE if the operation may be performed, FALSE otherwise.
*
* @see taxonomy_menu()
*/
-function taxonomy_term_access($op, $term) {
- if (!$term || !in_array($op, array('edit', 'delete'), TRUE)) {
- // If there was no term to check against, or the $op was not one of the
+function taxonomy_term_access($op, $obj) {
+ if (!$obj || !in_array($op, array('create', 'edit', 'delete'), TRUE)) {
+ // If there was no object to check against, or the $op was not one of the
// supported ones, we return access denied.
return FALSE;
}
-
- return user_access("$op terms in $term->vid") || user_access('administer taxonomy');
+ return user_access("$op terms in $obj->vid") || user_access('administer taxonomy');
}
/**
@@ -1062,6 +1076,13 @@ function taxonomy_field_validate($entity_type, $entity, $field, $instance, $lang
if (!empty($item['tid']) && $item['tid'] != 'autocreate') {
$tids[] = $item['tid'];
}
+ // Check if the current user has permissions to create new terms.
+ if (!empty($item['tid']) && $item['tid'] == 'autocreate' && !user_access('create terms in ' . $item['vid'])) {
+ $errors[$field['field_name']][$langcode][$delta][] = array(
+ 'error' => 'taxonomy_term_reference_illegal_value',
+ 'message' => t('You do not have permission to create new term: %term in field %name.', array('%term' => $item['name'], '%name' => $instance['label'])),
+ );
+ }
}
if (!empty($tids)) {
$terms = taxonomy_term_load_multiple($tids);
diff --git a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
index cf3d19e..772b955 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/TaggedWithTest.php
@@ -89,6 +89,10 @@ function setUp() {
),
);
field_create_instance($this->tag_instance);
+
+ drupal_static_reset();
+ $views_admin = $this->drupalCreateUser(array('administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view revisions', 'create terms in ' . $this->tag_vocabulary->vid));
+ $this->drupalLogin($views_admin);
}
/**