-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom capability types for custom post types doesn't automatically give administrator capabilities #79
Comments
Well since I wrote this issue yesterday I learned a few things (I'm a newbie at wordpress development so please forgive my ignorance :). First I learned that the reason I hadn't seen this come up before was because I was using a multi-site installation and I was on a super admin account which automatically has all capabilities and I hadn't yet tested with any other accounts. Second, I learned that since assigning capabilities to roles is persistent it's better to do it during plugin activation and remove them during deactivation. So I'm modifying my suggestion with the following: In the Helper class add a remove_caps method: /**
* Removes all capabilities for a capability type to a role
*
* @param string|array $cap_type the capability array allows for specifying
* singular and plural, otherwise plural is constructed by adding an 's'
* to the string
* @param string $role_name the role name (default: administrator)
* @return WP_Role
*/
static function remove_caps( $cap_type, $role_name = 'administrator' ) {
$role = get_role( $role_name );
if ( is_array( $cap_type ) ) {
$singular = $cap_type[0];
$plural = $cap_type[1];
} else {
$singular = $cap_type;
$plural = $cap_type . 's';
}
$role->remove_cap( 'edit_' . $singular );
$role->remove_cap( 'edit_' . $plural );
$role->remove_cap( 'edit_other_' . $plural );
$role->remove_cap( 'publish_' . $plural );
$role->remove_cap( 'read_' . $singular );
$role->remove_cap( 'read_private_' . $plural );
$role->remove_cap( 'delete_' . $singular );
return $role;
} In the main plugin class _activate function add: <Custom post type class name>::activate(); In the _deactivate function: <Custom post type class name>::deactivate(); In the custom post type class: /**
* Capability type
*
* @var string
* @since 0.0.0
*/
const CAPABILITY_TYPE = '<capability type specified>';
/**
* Things to do on plugin activation
*
* @since 0.0.0
* @return void
*/
static function activate() {
self::add_caps();
}
/**
* Things to do on plugin deactivation
*
* @since 0.0.0
* @return void
*/
static function deactivate() {
self::remove_caps();
}
/**
* Add capabilities for our custom capability type
*
* @since 0.0.0
* @return void
*/
static function add_caps() {
Helper::add_caps( self::CAPABILITY_TYPE );
}
/**
* Remove capabilities for our custom capability type
*
* @since 0.0.0
* @return void
*/
static function remove_caps() {
Helper::remove_caps( self::CAPABILITY_TYPE );
} And finally, to fill out the testing in tests/test-helper.php class <prefix>_Helper_Test extends WP_UnitTestCase {
function test_sample() {
// replace this with some actual testing code
$this->assertTrue( true );
}
function test_class_exists() {
$this->assertTrue( class_exists( 'Helper') );
}
/**
* Test Helper::add_caps
*/
function test_add_caps() {
Helper::add_caps('test');
$role = get_role('administrator');
$this->assertTrue( $role->has_cap('edit_test') );
$this->assertTrue( $role->has_cap('edit_tests') );
$this->assertTrue( $role->has_cap('edit_other_tests') );
$this->assertTrue( $role->has_cap('publish_tests') );
$this->assertTrue( $role->has_cap('read_test') );
$this->assertTrue( $role->has_cap('read_private_tests') );
$this->assertTrue( $role->has_cap('delete_test') );
}
function test_add_caps_role() {
Helper::add_caps('test', 'author');
$role = get_role('author');
$this->assertTrue( $role->has_cap('edit_test') );
$this->assertTrue( $role->has_cap('edit_tests') );
$this->assertTrue( $role->has_cap('edit_other_tests') );
$this->assertTrue( $role->has_cap('publish_tests') );
$this->assertTrue( $role->has_cap('read_test') );
$this->assertTrue( $role->has_cap('read_private_tests') );
$this->assertTrue( $role->has_cap('delete_test') );
}
function test_add_caps_plural() {
Helper::add_caps( array('test', 'testies') );
$role = get_role('administrator');
$this->assertTrue( $role->has_cap('edit_test') );
$this->assertTrue( $role->has_cap('edit_testies') );
$this->assertTrue( $role->has_cap('edit_other_testies') );
$this->assertTrue( $role->has_cap('publish_testies') );
$this->assertTrue( $role->has_cap('read_test') );
$this->assertTrue( $role->has_cap('read_private_testies') );
$this->assertTrue( $role->has_cap('delete_test') );
}
/**
* Test Helper::remove_caps
*/
function test_remove_caps() {
Helper::add_caps('test');
Helper::remove_caps('test');
$role = get_role('administrator');
$this->assertFalse( $role->has_cap('edit_test') );
$this->assertFalse( $role->has_cap('edit_tests') );
$this->assertFalse( $role->has_cap('edit_other_tests') );
$this->assertFalse( $role->has_cap('publish_tests') );
$this->assertFalse( $role->has_cap('read_test') );
$this->assertFalse( $role->has_cap('read_private_tests') );
$this->assertFalse( $role->has_cap('delete_test') );
}
function test_remove_caps_role() {
Helper::add_caps('test', 'author' );
Helper::remove_caps('test', 'author');
$role = get_role('author');
$this->assertFalse( $role->has_cap('edit_test') );
$this->assertFalse( $role->has_cap('edit_tests') );
$this->assertFalse( $role->has_cap('edit_other_tests') );
$this->assertFalse( $role->has_cap('publish_tests') );
$this->assertFalse( $role->has_cap('read_test') );
$this->assertFalse( $role->has_cap('read_private_tests') );
$this->assertFalse( $role->has_cap('delete_test') );
}
function test_remove_caps_plural() {
Helper::add_caps( array('test', 'testies') );
Helper::remove_caps( array('test', 'testies') );
$role = get_role('administrator');
$this->assertFalse( $role->has_cap('edit_test') );
$this->assertFalse( $role->has_cap('edit_testies') );
$this->assertFalse( $role->has_cap('edit_other_testies') );
$this->assertFalse( $role->has_cap('publish_testies') );
$this->assertFalse( $role->has_cap('read_test') );
$this->assertFalse( $role->has_cap('read_private_testies') );
$this->assertFalse( $role->has_cap('delete_test') );
}
} There are, of course, other possible implementations such as just putting the add_caps and remove_caps calls directly in the _activate/_deactivate plugin functions, but this is the one I chose to keep the capabilities with the post type that was the reason for adding them. |
If a custom capability type is defined for a custom post type the administrator role doesn't automatically get capabilities for that capability type. I discovered this when I did a fresh install of wordpress that has only my plugin in it, so I must have some plugin that changes that behavior in my old installation.
So I propose adding to the CPT sub generator the following:
A helper class (mine has some other stuff in it too, but this is what's pertinent to this issue):
In the generated post type class:
Define the capability type:
In the constructor - parent::__construct args array:
In the hooks method:
And the add_caps method:
I don't remember if the generator has an option for adding a custom capability_type in the args for the CPT, but if not that could be added and this code generated if a custom capability_type is selected.
This would give the user a starting point for their custom capabilities.
The text was updated successfully, but these errors were encountered: