Put update-like notification bubble on multiple CPTs menus for pending items

Much like how the Plugins or Comments menu items have these number notifications in a bubble for updates and unmoderated comments respectively, I’d like to use that bubble to display the number of CPTs which have a “Pending review” status. How to go about doing that?

I have found this thread, but not quite sure where to go from there.

Read More

That would be neat to have; as I need this feature on a site that uses user-generated content (custom post types). Whenever users submit a new CPT, its status is set to “Pending review”, and I want the site admins to quickly glance at the menu to see how many items need their attention.

EDIT: I now have this code:

// buuble notifications for custom posts with status pending
add_action( 'admin_menu', 'add_pending_bubble' );

function add_pending_bubble() {
    global $menu;

    $custom_post_count = wp_count_posts('custom-post-name');
    $custom_post_pending_count = $custom_post_count->pending;

    if ( $custom_post_pending_count ) {
        foreach ( $menu as $key => $value ) {
            if ( $menu[$key][2] == 'edit.php?post_type=custom-post-name' ) {
                $menu[$key][0] .= ' <span class="update-plugins count-' . $custom_post_pending_count . '"><span class="plugin-count">' . $custom_post_pending_count . '</span></span>';
                return;
            }
        }
    }
}

…which does work, albeit a bit inconsistent. Sometimes displaying, sometimes not. Also, if I have multiple CPTs, how do I apply this code for each and every menu item of those CPTs? The above code will work with only one CPT.

Related posts

Leave a Reply

1 comment

  1. I made this work iterating through a post types list, and pinpointing the correct $menu key for the post type using a secondary function (instead of manually iterating through the $menu object).

    pending posts bubbles

    Function reference: get_post_types and wp_count_posts.

    add_action( 'admin_menu', 'pending_posts_bubble_wpse_89028', 999 );
    
    function pending_posts_bubble_wpse_89028() 
    {
        global $menu;
    
        // Get all post types and remove Attachments from the list
        // Add '_builtin' => false to exclude Posts and Pages
        $args = array( 'public' => true ); 
        $post_types = get_post_types( $args );
        unset( $post_types['attachment'] );
    
        foreach( $post_types as $pt )
        {
            // Count posts
            $cpt_count = wp_count_posts( $pt );
    
            if ( $cpt_count->pending ) 
            {
                // Menu link suffix, Post is different from the rest
                $suffix = ( 'post' == $pt ) ? '' : "?post_type=$pt";
    
                // Locate the key of 
                $key = recursive_array_search_php_91365( "edit.php$suffix", $menu );
    
                // Not found, just in case 
                if( !$key )
                    return;
    
                // Modify menu item
                $menu[$key][0] .= sprintf(
                    '<span class="update-plugins count-%1$s" style="background-color:white;color:black"><span class="plugin-count">%1$s</span></span>',
                    $cpt_count->pending 
                );
            }
        }
    }
    
    // http://www.php.net/manual/en/function.array-search.php#91365
    function recursive_array_search_php_91365( $needle, $haystack ) 
    {
        foreach( $haystack as $key => $value ) 
        {
            $current_key = $key;
            if( 
                $needle === $value 
                OR ( 
                    is_array( $value )
                    && recursive_array_search_php_91365( $needle, $value ) !== false 
                )
            ) 
            {
                return $current_key;
            }
        }
        return false;
    }