User Role Generator
Generate a custom WordPress user role: cloned capabilities, the ones you add or take away, a version guard so changes re-apply, and the cleanup on deactivation.
<?php
/**
* The "my_plugin_manager" role.
*/
/**
* Registers the role, and re-applies it whenever the version changes.
*
* Roles are stored in the database, not in code, so editing this file does
* nothing on a site that already has the role. The version option is what
* makes a change take effect.
*/
function my_plugin_register_role() {
$version = '1.0.0';
if ( get_option( 'my_plugin_role_version' ) === $version ) {
return;
}
remove_role( 'my_plugin_manager' );
$source = get_role( 'editor' );
$caps = $source ? $source->capabilities : array( 'read' => true );
$grant = array(
'edit_theme_options',
);
foreach ( $grant as $cap ) {
$caps[ $cap ] = true;
}
add_role( 'my_plugin_manager', 'Content Manager', $caps );
// Administrators do not inherit custom capabilities. Without this they
// cannot reach anything your own checks guard.
$administrator = get_role( 'administrator' );
if ( $administrator ) {
foreach ( $grant as $cap ) {
$administrator->add_cap( $cap );
}
}
update_option( 'my_plugin_role_version', $version );
}
add_action( 'init', 'my_plugin_register_role' );
Output is valid and updates as you type.
Fix the highlighted fields to update the output.
Pick a role to copy, add the capabilities you need and take off the ones you do not, and the generator writes the registration, the version guard that makes later edits take effect, and the cleanup.
How to use
- Choose the role key first. It is stored against every user who gets the role, so renaming it later strands all of them.
- Start from the closest core role. Editor minus a few capabilities is almost always less work than building a set from scratch.
- Add your own capabilities with a prefix, such as
acme_approve_copy. That is what yourcurrent_user_can()checks should test, not the role name. - Leave the administrator grant on when you add custom capabilities. Administrators do not inherit them, which is how people lock themselves out of their own settings page.
- Bump the role version whenever you change the capability list. Nothing else makes an existing site pick the change up.
Example
A role copied from Editor that can approve copy but cannot delete anything published:
function acme_copy_register_role() {
$version = '1.2.0';
if ( get_option( 'acme_copy_role_version' ) === $version ) {
return;
}
remove_role( 'acme_copy_editor' );
$source = get_role( 'editor' );
$caps = $source ? $source->capabilities : array( 'read' => true );
$caps['acme_approve_copy'] = true;
unset( $caps['delete_published_posts'] );
add_role( 'acme_copy_editor', 'Copy Editor', $caps );
update_option( 'acme_copy_role_version', $version );
}
add_action( 'init', 'acme_copy_register_role' );
The option read is the whole cost on a normal request, which is why init is the safer hook here even though activation looks tidier.
Pitfalls
- Roles live in the
wp_user_rolesoption, not in your code. Editing the capability list and uploading it changes nothing on a site that already registered the role. add_role()returns null and does nothing when the role already exists. Without the remove-then-add above, your second version never applies.- Administrators do not get custom capabilities for free. A screen guarded by
acme_approve_copyis invisible to the site owner until you grant it. - Capabilities are not roles. Check
current_user_can( 'edit_shop_orders' ), nevercurrent_user_can( 'acme_shop_helper' ), or a site that renames roles breaks. remove_role()does not touch users. They keep the role name and simply have no capabilities until something registers it again.- Registering on activation only means an update that changes the list is never applied, because activation does not run again.
- Multisite super admins pass every capability check, so a broken capability set can look fine to you and be broken for everyone else.
- Copying Administrator hands out
manage_options,edit_usersand plugin installation. It is rarely the role you meant to build.
Compatibility
add_role(), remove_role(), get_role() and WP_Role::add_cap() have been stable since WordPress 3.0, and the capability names used here are core ones. The generated code targets PHP 7.0 and up, and the tool runs entirely in your browser.
Frequently asked questions
Why did my capability change not apply?
Should I register on init or activation?
init with the version guard, unless the role is trivial. It costs one option read and survives updates, which activation does not.What happens to users when I remove the role?
Do I need to grant custom capabilities to administrators?
manage_options. Core only gives administrators the capabilities core knows about.How do I map capabilities to a custom post type?
capability_type and map_meta_cap on the post type, then add the resulting names here. Those names are what core will check.