Support » Plugins » Hacks » pending topics must be viewable to the author only – bbpress moderation plugin

  • Hi,

    I hope someone here can help me clarify my codes.
    You see I have modified the bbpress moderation plugin since I am not getting any response from it’s author.

    Okay, here’s the problem. I am making the pending post view-able only to the author, admin and moderators. Right now the bbpress moderation pending posts “always display option” is view-able to all. I have added some codes to it to achieve my goal. And when I added the global $post and call the post_author, I can’t make it work.

    Below is my code:

    function query($bbp) {
    
    		global $current_user, $post;
    
    		if (get_option(self::TD . 'always_display')) {
    			$post_author = wp_get_current_user();
    
    			if ( (current_user_can('moderate')) || (current_user_can('level_0') && $post_author->ID == $post->post_author) ) {
    
    					add_filter('posts_where', array($this, 'posts_where'));
    
    			} else{
    
    			}
    		}
    			else
    			{
    
    				// remove_filter('posts_where', array($this, 'posts_where'));
    			}
    
    		return $bbp;
    	}

    I am hoping for your kind response. Thanks.

    Best regards,
    Mariz

Viewing 4 replies - 1 through 4 (of 4 total)
  • Moderator bcworkz

    (@bcworkz)

    Hello again!

    You’ve got the right idea to alter the query with ‘posts_where’, but things start to unravel after that. If I’m not mistaken, the general concept is to display all posts as usual, except in the case of contributors that cannot publish posts, their posts that are pending show up as though they have been published, though no one else can see their posts yet. Is that the general idea? You realize that if the user is not logged in, it would be difficult to show them their own posts? It will be somewhat obvious their posts are not published immediately.

    The first task is to decide if the current user can contribute posts but cannot publish them. We use the current_user_can() function for this. We are looking for the condition where the user can ‘edit_posts’ and cannot ‘publish_posts’. Do not use numeric roles to check capabilities, the numeric roles were deprecated some time ago. You do not need to focus on roles at all for this sort of thing, focus solely on capabilities.

    You also will not need to worry about removing this filter. It would apply to the main query for the current request if the capabilities conditions apply. It will not impact other queries run during the same request, and everything is reset for the next request. We should also check that the query is not a single request. It would be silly to add another post to the single requested post.

    We can assume the current query is returning all the correct posts when it reaches our filter callback. We merely need to get the query to find the current user’s pending posts as well as all the usual posts. So we need to add on to the existing WHERE clause something along the lines of OR (post_status=pending AND post_author=$user_id AND post_type=post) This is in no way intended to be proper syntax, it’s merely illustrating the concept. You can get $user_id from get_current_user_id() No need to get the entire user object, all we need is the ID.

    There’s also no need for the global $post object. In fact, it hasn’t been defined yet. We are constructing a query that will find all the posts that will eventually be assigned to $post.

    I’m not sure what impact the ‘always_display’ option has, if any. There’s several similar complicating factors that will need to be addressed, like time restricted queries. The time restriction by default will only apply to the main query results, not the pending posts. We need to determine if there are such restrictions and ensure they are also applied to the pending posts as well.

    This might be done by either copying from the existing WHERE clause or by parsing the query vars for applicable restrictions. I suggest you first focus on getting the basic query correctly returning pending posts and worry about these sorts of details later.

    In summary, here’s a list of what needs to happen to show pending posts to the author along with normal content.

    1. add a filter callback to ‘posts_where’
    2. define the callback which will:
    3. confirm it is_main() query and ! is_single()
    4. confirm current user can ‘edit_posts’ and ! ‘publish_posts’
    5. append our OR clause to the existing clause and return the modified version
    Thread Starter marizpapas

    (@mariz_p)

    Hi Bcworkz,

    Good day!

    I have made it! I just got your idea above about the query. Please see my code below:

    function posts_where($where = '') {
    		$user_ID = get_current_user_id();
    		/*
    		 * Typical $where is:
    		 *
    		 * " AND wp_posts.post_parent = 490 AND wp_posts.post_type IN ('topic', 'reply') AND
    		 * (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'closed' OR wp_posts.post_author = 1
    		 * AND wp_posts.post_status = 'private' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'hidden')
    		 *
    		 */
    
    		// Real UGLY hack to add 'pending' post statuses to the
    		// list of returned posts. Changes to whitespace are gonna shoot us
    		// in the foot - regex anyone ?
    		//
    		// Might possibly mess up the query for posts without publish status !!!!
    		//
    		// fix to allow DB prefixes
    		global $wpdb;
    		$where = str_ireplace($wpdb->prefix."posts.post_status = 'publish'", "(".$wpdb->prefix."posts.post_status = 'publish' OR ".$wpdb->prefix."posts.post_status = 'pending' AND ".$wpdb->prefix."posts.post_author = ".$user_ID.")", $where);				
    
    		return $where;
    	}

    thank you so much for the idea.. πŸ™‚
    Anyways I have found an awkward situation, I just want to make the pending post be viewable to the user profile only not in the topics area of a certain category/forum. I’m debugging it now. I’ll post my code if I got it. I hope you can enlighten me once again.

    Thank you so much! πŸ™‚

    Moderator bcworkz

    (@bcworkz)

    You’re most welcome πŸ™‚

    Some nice work there! Complex SQL queries make my head spin.

    In order to not show the pending posts in a particular category the $where modification needs to be inside of an if() conditional that detects that state and only executes the modification if it is not that state.

    How to detect that state? I’m not sure TBH. Try using get_queried_object(). You’ll need to var_dump the result from various queries in order to determine just which value you need to check that is unique to that one category. If that one array key does not exist in other queries, you can’t simply check the value without some preliminary testing to verify the array key exists first. Otherwise you’ll get an error when you do the comparison in the case where there is no key to check.

    It’s too bad the modification of $where required string replacement. I see you understand the issues with this approach. I had envisioned a simple concatenation, but like so many things in hacking, it’s never as simple as you think initially.

    Another approach, not as efficient but surely more robust would be to do two separate queries and then insert the pending posts into the main query results in such a way the sort order is maintained.

    Since you’ve pretty much gotten the current approach working, it probably doesn’t make sense right now to abandon it for another. Perhaps establish some kind of working version right now and slate the other approach as a possible improvement for the near future.

    Thread Starter marizpapas

    (@mariz_p)

    I didn’t get the answer yet but I’ll post it here if ever I got it.
    Thank you so much for the help bcworkz. πŸ™‚

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘pending topics must be viewable to the author only – bbpress moderation plugin’ is closed to new replies.