In WordPress v5.5.1, I have used below function to restrict authors to publish the posts:
function set_capabilities() { $author = get_role('author'); $caps = array( 'edit_others_posts', 'edit_others_pages', 'publish_posts', 'delete_posts', 'delete_published_posts', ); foreach ($caps as $cap) { $author->remove_cap($cap); } } add_action('init', 'set_capabilities');
It resulted in complete removal of posts page and adding new posts at wp-admin/post-new.php
.
I have removed the set_capabilities()
function, still getting the error “Sorry, you are not allowed to access this page.”.
I have tried resetting the wp-capabilities
, still it did not worked for me.
I have tried adding a new user with author
role, the new user have the same issue as well.
How can I have the authors create a post accessing wp-admin/post-new.php
again?
Advertisement
Answer
Problem
After calling $author->remove_cap($cap)
the capability was removed from the author role, not only in memory but also in the database (see reference section below for implementation and links). As a result, removing the call to set_capabilities()
or adding a new user to the role would not reset the role capabilities.
Solutions
Approach 1 – Using WordPress
You could do the opposite of set_capabilities()
eg add_capabilities()
as shown below to re-assign these privileges both in memory and database using the official WordPress API
function add_capabilities() { $author = get_role('author'); $caps = array( 'edit_others_posts', 'edit_others_pages', 'publish_posts', 'delete_posts', 'delete_published_posts', ); foreach ($caps as $cap) { $author->add_cap($cap); } } add_action('init', 'add_capabilities');
From your users
administration page you could then ensure the user is assigned the desired role of author.
Approach 2 – Manually accessing and updating your database
Assuming wp_
as your database prefix, you could ensure that the user is indeed assigned the role of author
and if not manually assign this. This is in your wp_usermeta
table, you should see a record with the user_id
in question and the name wp_capabilities
. The value stores a php serialized array of roles for example if the user was just an author the value would be a:1:{s:6:"author";b:1;}
.
Now that you have ensured the user is indeed in the role, all role capabilities are stored in wp_options
table within option_name wp_user_roles
. Again, this is a long serialized php associative array that is structed as such (assume $roleName
to be any role eg. ‘author’)
["$roleName"=>[ 'name'=>"$roleName", 'capabilities'=>[ 'edit_others_posts', 'edit_others_pages', 'publish_posts', 'delete_posts', 'delete_published_posts', ] ] ]
If you had a backup or another working location you could restore it. If you desire to manually modify these values, due to the need for php serialization, I would recommend writing custom code in php to achieve such as a last resort if using Solution 1
is not helpful or the WordPress methods are not available eg. working from a different client/server/location.
Additional Resources and References
See implementation from official WordPress Documenation
$author = get_role(‘author’); –> returns a WP_Role in $author
And an implementation of the remove_cap
called and the add_cap
I will make reference to retrieved from https://developer.wordpress.org/reference/classes/wp_roles/ is included below:
/** * Add capability to role. * * @since 2.0.0 * * @param string $role Role name. * @param string $cap Capability name. * @param bool $grant Optional. Whether role is capable of performing capability. * Default true. */ public function add_cap( $role, $cap, $grant = true ) { if ( ! isset( $this->roles[ $role ] ) ) { return; } $this->roles[ $role ]['capabilities'][ $cap ] = $grant; if ( $this->use_db ) { update_option( $this->role_key, $this->roles ); } } /** * Remove capability from role. * * @since 2.0.0 * * @param string $role Role name. * @param string $cap Capability name. */ public function remove_cap( $role, $cap ) { if ( ! isset( $this->roles[ $role ] ) ) { return; } unset( $this->roles[ $role ]['capabilities'][ $cap ] ); if ( $this->use_db ) { update_option( $this->role_key, $this->roles ); } }