Allowing user to edit only certain pages

The first thing to do to implements such task is to be able to recognise which page an user can edit.

There are different ways to do it. It could be a user meta, some configuration value… For the sake of this answer, I will assume that a function lile this exists:

function wpse_user_can_edit( $user_id, $page_id ) {

   $page = get_post( $page_id );

   // let's find the topmost page in the hierarchy
   while( $page && (int) $page->parent ) {
     $page = get_post( $page->parent );
   }

   if ( ! $page ) {
     return false;
   }

   // now $page is the top page in the hierarchy
   // how to know if an user can edit it, it's up to you...

}

Now that we have a way to determine if an user can edit a page we just need to tell WordPress to use this function to check useer capability to edit a page.

That can be done via 'map_meta_cap' filter.

Something like:

add_filter( 'map_meta_cap', function ( $caps, $cap, $user_id, $args ) {

    $to_filter = [ 'edit_post', 'delete_post', 'edit_page', 'delete_page' ];

    // If the capability being filtered isn't of our interest, just return current value
    if ( ! in_array( $cap, $to_filter, true ) ) {
        return $caps;
    }

    // First item in $args array should be page ID
    if ( ! $args || empty( $args[0] ) || ! wpse_user_can_edit( $user_id, $args[0] ) ) {
        // User is not allowed, let's tell that to WP
        return [ 'do_not_allow' ];
    }
    // Otherwise just return current value
    return $caps;

}, 10, 4 );

At this point, we need only a way to connect an user to one or more pages.

There might be different solutions depending on use case.

A flexible solution could be to add a dropdown of “root” pages (see wp_dropdown_pages) to the edit user admin screen, and save selected page(s) as user meta.

We could leverage 'edit_user_profile' to add the pages dropdown field and 'edit_user_profile_update' to store the selected value as user meta.

I am sure that in this website there’s enough guidance on how to that in detail.

When page(s) are stored as user meta, the wpse_user_can_edit() function from above can be finished by checking if the page id is part of the user meta value.

Removing capability to edit the page, WordPress will do the rest: will remove any edit link from backend and frontend, will prevent direct access… and so on.

Leave a Comment