I've tried to make a script that only allows a specific user to edit a specific page but without any success.
The idea behind, is that if a users username contains a specific word, they are allowed to edit a special page.
I've tried to do this, by granting the specific users a special capability, and then checking that capability when opening the special page.
Here's my code:
add_action( 'admin_init', function() {
$current_user = wp_get_current_user();
$user_login = $current_user->data->user_login;
if( strpos($user_login, '@special-domain') !== false ) {
$user = new WP_User($current_user->ID);
$user->add_cap('edit_special_page');
}
});
add_filter( 'map_meta_cap', function( $caps, $cap, $user_id, $args ) {
if ( 'edit_page' == $cap && user_can( $user_id, 'edit_special_page' ) )
{
$post_id = $args[0];
$special_page_id = get_page_by_path('special-page') ? get_page_by_path('special-page')->ID : null;
if ( special_page_id == $post_id ) {
$caps = [];
$caps[] = 'edit_special_page';
}
}
return $caps;
}, 10, 4 );
But all users can still edit to the special page, which should only be possible for users with @special-domain in their usernames.
I've also tried to use the post-id directly instead of $special_page_id
, but with the same result.
Any idea why this is not working and how to do it?
PS: I am NOT interested in any kind of plugins.
I've tried to make a script that only allows a specific user to edit a specific page but without any success.
The idea behind, is that if a users username contains a specific word, they are allowed to edit a special page.
I've tried to do this, by granting the specific users a special capability, and then checking that capability when opening the special page.
Here's my code:
add_action( 'admin_init', function() {
$current_user = wp_get_current_user();
$user_login = $current_user->data->user_login;
if( strpos($user_login, '@special-domain') !== false ) {
$user = new WP_User($current_user->ID);
$user->add_cap('edit_special_page');
}
});
add_filter( 'map_meta_cap', function( $caps, $cap, $user_id, $args ) {
if ( 'edit_page' == $cap && user_can( $user_id, 'edit_special_page' ) )
{
$post_id = $args[0];
$special_page_id = get_page_by_path('special-page') ? get_page_by_path('special-page')->ID : null;
if ( special_page_id == $post_id ) {
$caps = [];
$caps[] = 'edit_special_page';
}
}
return $caps;
}, 10, 4 );
But all users can still edit to the special page, which should only be possible for users with @special-domain in their usernames.
I've also tried to use the post-id directly instead of $special_page_id
, but with the same result.
Any idea why this is not working and how to do it?
PS: I am NOT interested in any kind of plugins.
Share Improve this question asked Jul 15, 2019 at 11:34 JesperJesper 32 bronze badges1 Answer
Reset to default 0The issue is that an empty return value from map_meta_cap
will grant all users permission to do that thing, because that's essentially the same thing as saying "no capabilities are required to do this". What you really want to do is just add edit_special_page
to the existing list of required capabilities:
add_filter( 'map_meta_cap', function( $caps, $cap, $user_id, $args ) {
if ( 'edit_post' === $cap || 'edit_page' === $cap ) {
$current_page_id = $args[0];
$special_page_id = get_page_by_path( 'special-page' ) ? get_page_by_path( 'special-page' )->ID : null;
// If the page being edited is the special page...
if ( $special_page_id === $current_page_id ) {
// ... the user must have the edit_special_page capability.
$caps[] = 'edit_special_page';
}
}
return $caps;
}, 10, 4 );
An unrelated issue, but something that you'll need to address, is that you shouldn't add capabilities on admin_init
or init
. Adding capabilities writes to the database, so its only something that should be done once of plugin/theme activation or when the user is registered:
add_action( 'user_register', function( $user_id ) {
$user = get_userdata( $user_id );
if ( strpos( $user->user_login, '@special-domain' ) !== false ) {
$user->add_cap( 'edit_special_page' );
}
} );