Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm using WordPress as a directory site, where a user can submit a post, which becomes their ad/listing. The users are assigned a custom wordpress role.

Posts need to need to be approved and published by the admin once, and then they can freely update their post as they see fit. It work's fine like this at the moment because I haven't given the custom role any publishing capabilities.

However, I also need the ability for the user to take their post offline (draft perhaps) temporary whenever they want, and make it published again whenever they want. Currently, when they make their post a "draft", they need to submit it for a review to make it published again - this isn't ideal.

Is there a way around this so they can change their post from published to draft, and then back again from draft to published, without needing it to be approved?

Or maybe I give them publish capabilities to start off with, but there's a plugin that requires their first post to be approved? (they are only permitted 1 post anyway).

What about a custom metabox with a checkbox that controls whether or not the post is published? Unfortunately I would have no idea where to begin with this kind if functionality. I am using WPALchemy for other metaboxes though.

share|improve this question

2 Answers 2

I recently was dealing with the exact same problem. I didn't solve it, and we decided that since people had to pay a relatively large sum for their listings that they would be sufficiently incented not to post bad stuff. Plus it would be a pain to manually approve each one -- people don't like waiting a day to get results.

So we gave our directory_member user level the publish_posts and edit_published_posts capabilities from the start. They have to go through the payment process before the post is published; once they've paid they can do anything they want with their post.

But I had a brainwave (rare) looking at your question. I think where I went wrong is only have one directory_member level, rather than directory_member and directory_member_approved. The latter would have the edit_published_posts capability; the former would not. It would be relatively simple to bump the user up when an admin publishes the post for the first time.

The other possibility is assigning the edit_published_posts capability on the fly based on a user meta field, in admin_init or somewhere. But somehow I suspect the idea of having two explicit levels is better.

Let me know what you end up doing.

share|improve this answer
    
thanks for your helpful answer. That's exactly my scenario. They also go through payment beforehand, although there's going to be a "free" period, thus someone could still post something bad. Approving the first post seems like the way to approach this, with the idea of approving their post as soon as we can, because you're right - If they are paying, it would be annoying to have to wait too long. I like both your ideas so will investigate them further. I do however have quite a few custom WP roles, so having 2 for each may be a bit much but I'll just have to see how it goes. –  Andrew Aug 8 '11 at 4:58
    
Thanks for your tip on adding the capability on the fly. Please see my answer which may help if you ever decide to bring back an approval system. –  Andrew Aug 22 '11 at 0:38
up vote 0 down vote accepted

Thanks to Chris's suggestion of assigning a capability on the fly I was able to get something working that might help someone else. There may be a better method, but this one works well for my situation.

Because I'm working with a custom post type of listing I needed to assign the mapped capability publish_listings to the user, but only after they are approved. The best way I could think of doing this was to include an "admin only" metabox on the custom post screens that only admins could see. This was done with the help of WPAlchemy and it's output_filter.

With a metabox that only an admin could now see, I added a simple checkbox. When checked, and the post is updated, it adds the publish_listings capability to the author of the current post. being a type of directory site, I'm only allowing 1 post per author in my case so this works quite well. If unchecked and updated, the capability is removed. So the use case would look like this:

  1. User submits post for approval
  2. Admin reviews post, ticks the checkbox, and publishes the post for the first time
  3. User is now free to update their post at will, including making it a draft and publishing it again.

As I mentioned, I'm using WPAlchemy for the heavy lifting of metaboxes, so I was able to utilise save_filter to add the capability when the post is updated.

function save_admin_only( $meta, $post_id ) {
global $post;

//get the author ID of the post we're on
$author_id = $post->post_author;
$id = get_the_author_meta( 'ID' , $author_id );
$user = new WP_User( $id ); //retrieves the user, based on their ID specified above for user with WP_User class

    if($meta['_can_publish'] == 'yes') {    
        $user->add_cap( 'publish_listings' ); //assign capability to this user if checkbox is ticked
    }
    else { $user->remove_cap( 'publish_listings' ); } //otherwise remove the capability so they can not publish

return $meta;
}

If you need to check for a custom post type (say you had more than one), you can wrap it with:

if ( 'other_post_type' == get_post_type() ) {
    ...
}

This looks like it could be extremely helpful for other scenarios where you don't want to create a whole new role, just to give a user some capabilities. If anyone can improve on the above, then please do.

share|improve this answer
    
Very cool. I didn't think of the fact that caps are stored per user in the database. –  Chris Carson Aug 22 '11 at 13:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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