1

I have a custom post status and the issue I have is that the filter option for it that automatically appears above the post listings on the edit.php page of the WP admin shows a total count of all the posts with this status. I want it to show a count that is specific to the user in question.

So for example

All (1) | Published (0) | Draft (0) | Pending (0) | | Trash (0) | Awaiting (8)

That figure of 8 for awaiting is all the posts in the system with the status, yet the user I'm logged in at, if they had no posts set to that status I would want that to appear with zero or to not be visible at all (the default functionality in WP I believe).

I can't see if this is functionality supported by WP but I assume there must be a way as the other totals listed in the filter links ARE user specific.

This is all setup via the simple register_post_status function....

function awaiting_custom_post_status(){
    register_post_status( 'awaiting', array(
        'label'                     => _x( 'Changes Awaiting Approval', 'apartments' ),
        'public'                    => true,
        'exclude_from_search'       => false,
        'show_in_admin_all_list'    => true,
        'show_in_admin_status_list' => true,
        'label_count'               => _n_noop( 'Changes Awaiting Approval <span class="count">(%s)</span>', 'Changes Awaiting Approval <span class="count">(%s)</span>' ),
    ) );
}
add_action( 'init', 'awaiting_custom_post_status' );

Anyone got any ideas how to modify this count value to be user specific such as the other values are?

2
  • So all the users see every post on the "all" portion of the admin, but specifically on this status you want them to only see their own posts? Or do they only see their own posts throughout the admin?
    – jimihenrik
    Jun 22, 2017 at 11:16
  • By "all" portion of the admin, if you mean the all filter, no, they see just their posts there. Correct when this filter on the status is listed the count should be for just their posts of that status. When you click the filter the correct number of filtered posts does appear, so theres nothing wrong with the filter itself, just the count that appears on its link.
    – AdamJones
    Jun 22, 2017 at 12:14

2 Answers 2

4
+50

Edit: Just to credit the original, I'm fairly sure [this] is where I grabbed it from. Seems a quick search shows stackexchange is full of modifications of the same/ish code. But as the comments are spot on, I'd say all the credit goes to @W van Dam

I had a similar setup with multiple users who only saw their own posts but I have not worked with custom post statuses at all.

This is an old code snippet from an old project, but maybe it's of some use

add_filter('wp_count_posts', function($counts, $type, $perm) {
    global $wpdb;

    // We only want to modify the counts shown in admin and depending on $perm being 'readable' 
    if (!is_admin() || 'readable' !== $perm) return $counts;

    // Only modify the counts if the user is not allowed to edit the posts of others
    $post_type_object = get_post_type_object($type);
    if (current_user_can( $post_type_object->cap->edit_others_posts ) ) {   return $counts; }

    $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s AND (post_author = %d) GROUP BY post_status";
    $results = (array) $wpdb->get_results($wpdb->prepare( $query, $type, get_current_user_id() ), ARRAY_A);
    $counts = array_fill_keys(get_post_stati(), 0);

    foreach ($results as $row) { $counts[ $row['post_status'] ] = $row['num_posts']; }
    return (object) $counts;
}, 10, 3);

And the reason I asked about the posts they were seeing because I'm fairly sure this'll edit the counts to show only their own posts.

6
  • This should work. ps: I'm just wondering what effects it could have to have different wp_count_posts() results depending if we are on the front-end and backend and for object caching? Did you experience anything related to that for your project?
    – birgire
    Jun 22, 2017 at 13:52
  • To be fair, the project died before I get to make anything big on the front end wise :D I just happened to remember dabbling with something similar, and it had the get_post_stati() which made me think that it would work for any number of statuses. But yeah, back when I was on this performance was the least on my mind. So no idea, it could probably bring up some interesting behavior in tricky situations for sure.
    – jimihenrik
    Jun 22, 2017 at 14:23
  • And btw, I find that your solution to this problem is way more refined. The one I was using feels like a hack even if it does do the same thing :)
    – jimihenrik
    Jun 22, 2017 at 14:28
  • Thanks for elaborating on your old project. ps: my current snippet only filters the query posts, but doesn't modify the label status counting, but your snippet does the exact opposite ;-) So maybe OP could just combine both into one, if I understand the original problem correctly ;-)
    – birgire
    Jun 22, 2017 at 14:35
  • Fantastic @jimihenrik this worked straight away with no modifications!
    – AdamJones
    Jun 22, 2017 at 19:12
3

Here's a way to additionally filter the Awating status view by the current user:

add_action( 'pre_get_posts', function( \WP_Query $q )
{
    // Only target the edit.php admin page
    if( ! did_action( 'load-edit.php' ) )
        return;

    // Only target the main query
    if ( ! $q->is_main_query() )
        return;

    // Only target the 'post' post type
    if ( 'post' !== $q->get( 'post_type' ) )
        return;

    // Only target the 'awaiting' post status
    if ( 'awaiting' !== $q->get( 'post_status' ) )
        return;

    // Only fetch posts created by the current user     
    $q->set( 'author', get_current_user_id() );

} );

PS: I removed the views_edit-{$post_type} filtering part as it had problems, as it only counted correctly when the Awaiting link was clicked on. I just noticed it when I tested it ;-) But the idea was to avoid having an extra counting query and reuse the main query for counting. As a workaround we could of course only display the modified counting when the Awaiting status is filtered, otherwise remove it for that status , but it's probably better to keep the current UX. So for that part you could instead check out the alternative approach suggested by @imihenrik.

Hope it helps!

3
  • Hi @birgire thanks for your input. This code doesn't work out of the box and I've changed the post type as I need to but not sure what else I need to do.. ?
    – AdamJones
    Jun 22, 2017 at 12:13
  • Please check the updated answer ;-)
    – birgire
    Jun 22, 2017 at 13:43
  • Sorry I still can't get it working. I've stripped it down piece by piece removing some of the escaping return clauses and it still doesn't work. I now have a solution in the other answer posted. Thanks for your time though!
    – AdamJones
    Jun 22, 2017 at 19:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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