6

I'm trying to implement what seemed like a relatively straight forward idea, basically I am building an access control plugin to control viewing and editing of a custom post type (in this case 'Projects').

How I intend for it to work is that there are multiple users who either have read-only access or read/write access to specific 'Projects'.

There are multiple Projects in the system and read access is controlled by enabling checkboxes for the specific Projects within the User Profile settings on the site (shown below):

Additional edit options added to User Options

So you assign access to these Projects via this interface then code on the actual Projects page restricts the content from being viewed if the ID of the Project does not match any of the IDs of the checked Projects.

That is all working fine, however, I need to also allow edit capabilities in the same way. So I could enable a user to read a specific page but also to edit that specific page. The problem I am having is that what I'm after doesn't seem to fit into the regular Roles and Capabilities as basically I just want all users to have the same Role (basically just the Subscriber Role). But I want to add edit capability to a specific user for a specific page, whereas Roles are generally about adding Capabilities to a 'type' of user.

Hopefully I've managed to explain what I'm trying to here, I'm struggling to find the correct code / function for doing this although I'm sure it must be possible as there are Plugins out there that can enable access to specific pages etc, but obviously in this case I don't want to rely on a plugin as what I'm building is a plugin itself!

Update: I've persevered further trying to resolve this, but so far I still can't see how to enable access to specific posts / pages etc without resorting to creating a custom-role / capability for each specific page, but this seems a bit overkill and I'm not even sure that would work.

Update 2: I've added a bounty to this question now to hopefully inspire someone! ;) I've looked further into this but even though I've found other plugins that seem to be capable of what I need (along with loads of other features I don't need!) I just haven't managed to figure out what code is required to restrict specific instances of a post type to a specific user.

Update 31st Oct: I've been able to get something running thanks to the code that @alexey posted. I now have two lists of IDs, one of which controls Read access and one for Edit access. I'm using current_user_can('read_projects') to limit viewing of the page content, however, I've got a problem in it takes two page loads before it actually restricts the content. The first time I click on a page the content shows, but if I reload the page then the content is hidden correctly. It seems to be something to do with the timing of when user_has_cap is being triggered but I can't seem to track anything down, as far as I can tell this should be triggered before the page content is rendered. I'm not going to post any further code here in this update as if there's no simple reason why this isn't working then I'd be better posting a new question rather than continuing this one.

7
  • Do you want to add capabilities for pages and posts as well or just projects? Commented Sep 20, 2011 at 20:13
  • In this particular case I want to add it for the custom post type 'Projects', however, the access restriction could apply to any WordPress post type: posts, pages, attachments etc. Commented Sep 20, 2011 at 23:42
  • Where does user edit projects? template or admin area?
    – Alexey
    Commented Sep 30, 2011 at 16:41
  • @Alexey - Projects are a custom post type and are edited within the Admin area. However, the restriction of access to the Projects in this case is managed within the User profile page, a list of all projects is shown there (as per the image in my question) and you check the required projects. What I'm really trying to figure out is how to actually restrict access to any kind of post type, but specifically restricting access to a specific post by a specific user rather than broader roles which are hierarchical. I hope this is clear in my question! Commented Oct 1, 2011 at 1:06
  • I know what custom post type is :). But i have a theme that allows users to edit custom post types. That's why i asked you.
    – Alexey
    Commented Oct 1, 2011 at 8:15

1 Answer 1

5
+50

I can suggest another method.

First of all: grant full access to projects post type (Example).

At the user profile add allowed posts' id.

Then use below filter to restrict access if post id isn't allowed.

function allow_user_to_edit_cpt_filter( $capauser, $capask, $param){

    global $wpdb;

    $allowed_posts_id_for_current_user = array( '29', '30' ); // you need to get these ids yourself
    $post = get_post( $param[2] );

    // If current post isn't allowed then delete edit and delete capabilities
    if( !in_array( $post->ID, $allowed_post_type_ids ) ){
        if( ( $param[0] == "edit_projects") || ( $param[0] == "delete_projects" ) ) { // Change to yours capabilities
            foreach( (array) $capask as $capasuppr) {
               if ( array_key_exists($capasuppr, $capauser) ) {
                  $capauser[$capasuppr] = 0;
               }
            }
        }
    }

    return $capauser;
}
add_filter('user_has_cap', 'allow_user_to_edit_cpt_filter', 100, 3 );
8
  • @Rick, was it useful?
    – Alexey
    Commented Oct 3, 2011 at 11:40
  • Thanks for that, apologies for slow response but I couldn't back online to check until just now. I haven't tried it out yet, is this going to enable / disable access on individual posts? Basically if the ID is in the allowed array then edit capability remains for that user for the allowed post id's but edit capability is removed for all other posts? And this disabling happens as the user views the posts? (Viewed in the site or viewed in the Admin?) – Thanks again! Commented Oct 3, 2011 at 13:31
  • Welcome back online, @Rick ) Basically if the ID is in the allowed array then edit capability remains for that user for the allowed post id's but edit capability is removed for all other posts? Yes. And this disabling happens as the user views the posts? (Viewed in the site or viewed in the Admin? in the Admin.
    – Alexey
    Commented Oct 3, 2011 at 21:10
  • Thanks, this looks like this should get me to where I'm trying to get! I will update with full details once I get it working. I'm planning on making the plugin available once I've got it functional. Thanks again for your help! Commented Oct 6, 2011 at 16:56
  • 1
    change $allowed_post_type_ids to $allowed_posts_id_for_current_user =)
    – fdrv
    Commented Apr 8, 2016 at 6:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.