Taxonomy: Introduce more fine grained capabilities for managing taxonomy terms.

This introduces the singular `edit_term`, `delete_term`, and `assign_term` meta capabilities for terms, and switches the base capability name for tags from `manage_categories` to `manage_post_tags` and the corresponding `edit_post_tags`, `delete_post_tags`, and `assign_post_tags`.

All of these capabilities ultimately map to `manage_categories` so by default there is no change in the behaviour of the capabilities for categories, tags, or custom taxonomies. The `map_meta_cap` filter and the `capabilities` argument when registering a taxonomy now allow for control over editing, deleting, and assigning individual terms, as well as a separation of capabilities for tags from those of categories.

Fixes #35614
Props johnjamesjacoby for feedback


git-svn-id: https://develop.svn.wordpress.org/trunk@38698 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
John Blackbourn
2016-09-30 22:39:32 +00:00
parent ad6ef7c110
commit 17ef6d8cfa
14 changed files with 173 additions and 46 deletions
+78
View File
@@ -223,6 +223,15 @@ class Tests_User_Capabilities extends WP_UnitTestCase {
'customize' => array( 'administrator' ),
'delete_site' => array( 'administrator' ),
'add_users' => array( 'administrator' ),
'edit_categories' => array( 'administrator', 'editor' ),
'delete_categories' => array( 'administrator', 'editor' ),
'manage_post_tags' => array( 'administrator', 'editor' ),
'edit_post_tags' => array( 'administrator', 'editor' ),
'delete_post_tags' => array( 'administrator', 'editor' ),
'assign_categories' => array( 'administrator', 'editor', 'author', 'contributor' ),
'assign_post_tags' => array( 'administrator', 'editor', 'author', 'contributor' ),
);
}
@@ -242,6 +251,15 @@ class Tests_User_Capabilities extends WP_UnitTestCase {
'customize' => array( 'administrator' ),
'delete_site' => array( 'administrator' ),
'add_users' => array( 'administrator' ),
'edit_categories' => array( 'administrator', 'editor' ),
'delete_categories' => array( 'administrator', 'editor' ),
'manage_post_tags' => array( 'administrator', 'editor' ),
'edit_post_tags' => array( 'administrator', 'editor' ),
'delete_post_tags' => array( 'administrator', 'editor' ),
'assign_categories' => array( 'administrator', 'editor', 'author', 'contributor' ),
'assign_post_tags' => array( 'administrator', 'editor', 'author', 'contributor' ),
);
}
@@ -399,6 +417,9 @@ class Tests_User_Capabilities extends WP_UnitTestCase {
$expected['delete_post_meta'],
$expected['add_post_meta'],
$expected['edit_comment'],
$expected['edit_term'],
$expected['delete_term'],
$expected['assign_term'],
$expected['delete_user']
);
@@ -1078,6 +1099,63 @@ class Tests_User_Capabilities extends WP_UnitTestCase {
}
}
/**
* @dataProvider dataTaxonomies
*
* @ticket 35614
*/
public function test_default_taxonomy_term_cannot_be_deleted( $taxonomy ) {
if ( ! taxonomy_exists( $taxonomy ) ) {
register_taxonomy( $taxonomy, 'post' );
}
$tax = get_taxonomy( $taxonomy );
$user = self::$users['administrator'];
$term = self::factory()->term->create_and_get( array(
'taxonomy' => $taxonomy,
) );
update_option( "default_{$taxonomy}", $term->term_id );
$this->assertTrue( user_can( $user->ID, $tax->cap->delete_terms ) );
$this->assertFalse( user_can( $user->ID, 'delete_term', $term->term_id ) );
}
/**
* @dataProvider dataTaxonomies
*
* @ticket 35614
*/
public function test_taxonomy_caps_map_correctly_to_their_meta_cap( $taxonomy ) {
if ( ! taxonomy_exists( $taxonomy ) ) {
register_taxonomy( $taxonomy, 'post' );
}
$tax = get_taxonomy( $taxonomy );
$term = self::factory()->term->create_and_get( array(
'taxonomy' => $taxonomy,
) );
foreach ( self::$users as $role => $user ) {
$this->assertSame(
user_can( $user->ID, 'edit_term', $term->term_id ),
user_can( $user->ID, $tax->cap->edit_terms ),
"Role: {$role}"
);
$this->assertSame(
user_can( $user->ID, 'delete_term', $term->term_id ),
user_can( $user->ID, $tax->cap->delete_terms ),
"Role: {$role}"
);
$this->assertSame(
user_can( $user->ID, 'assign_term', $term->term_id ),
user_can( $user->ID, $tax->cap->assign_terms ),
"Role: {$role}"
);
}
}
public function dataTaxonomies() {
return array(
array(
+1 -1
View File
@@ -43,7 +43,7 @@ class Tests_XMLRPC_wp_deleteTerm extends WP_XMLRPC_UnitTestCase {
$result = $this->myxmlrpcserver->wp_deleteTerm( array( 1, 'subscriber', 'subscriber', 'category', $this->term['term_id'] ) );
$this->assertInstanceOf( 'IXR_Error', $result );
$this->assertEquals( 401, $result->code );
$this->assertEquals( __( 'Sorry, you are not allowed to delete terms in this taxonomy.' ), $result->message );
$this->assertEquals( __( 'Sorry, you are not allowed to delete this term.' ), $result->message );
}
function test_empty_term() {
+1 -1
View File
@@ -49,7 +49,7 @@ class Tests_XMLRPC_wp_editTerm extends WP_XMLRPC_UnitTestCase {
$result = $this->myxmlrpcserver->wp_editTerm( array( 1, 'subscriber', 'subscriber', $this->parent_term['term_id'], array( 'taxonomy' => 'category' ) ) );
$this->assertInstanceOf( 'IXR_Error', $result );
$this->assertEquals( 401, $result->code );
$this->assertEquals( __( 'Sorry, you are not allowed to edit terms in this taxonomy.' ), $result->message );
$this->assertEquals( __( 'Sorry, you are not allowed to edit this term.' ), $result->message );
}
function test_term_not_exists() {
+1 -1
View File
@@ -43,7 +43,7 @@ class Tests_XMLRPC_wp_getTerm extends WP_XMLRPC_UnitTestCase {
$result = $this->myxmlrpcserver->wp_getTerm( array( 1, 'subscriber', 'subscriber', 'category', $this->term['term_id'] ) );
$this->assertInstanceOf( 'IXR_Error', $result );
$this->assertEquals( 401, $result->code );
$this->assertEquals( __( 'Sorry, you are not allowed to assign terms in this taxonomy.' ), $result->message );
$this->assertEquals( __( 'Sorry, you are not allowed to assign this term.' ), $result->message );
}