Wordpress - Update post counts (published, draft, unattached) in admin interface
I got this almost working, but refinements are needed to fit the specifics of the question and to deal with Attachments and Post-Types differently (see comments in code)...
First, I think it's worth noting how I found the filter:
apply_filters( 'views_' . $screen->id, $views )
inspect element
do a global search in
/wp-admin
and/wp-includes
for subsubsub (funny class name, btw)...- and here it is:
/wp-admin/includes/class-wp-list-table.php
foreach( array( 'edit-post', 'edit-page', 'edit-movie', 'upload' ) as $hook )
add_filter( "views_$hook" , 'wpse_30331_custom_view_count', 10, 1);
function wpse_30331_custom_view_count( $views )
{
global $current_screen;
switch( $current_screen->id )
{
case 'edit-post':
$views = wpse_30331_manipulate_views( 'post', $views );
break;
case 'edit-page':
$views = wpse_30331_manipulate_views( 'page', $views );
break;
case 'edit-movie':
$views = wpse_30331_manipulate_views( 'movie', $views );
break;
case 'upload':
$views = wpse_30331_manipulate_views( 'attachment', $views );
break;
}
return $views;
}
function wpse_30331_manipulate_views( $what, $views )
{
global $user_ID, $wpdb;
/*
* This is not working for me, 'artist' and 'administrator' are passing this condition (?)
*/
if ( !current_user_can('artist') )
return $views;
/*
* This needs refining, and maybe a better method
* e.g. Attachments have completely different counts
*/
$total = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE (post_status = 'publish' OR post_status = 'draft' OR post_status = 'pending') AND (post_author = '$user_ID' AND post_type = '$what' ) ");
$publish = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_status = 'publish' AND post_author = '$user_ID' AND post_type = '$what' ");
$draft = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_status = 'draft' AND post_author = '$user_ID' AND post_type = '$what' ");
$pending = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_status = 'pending' AND post_author = '$user_ID' AND post_type = '$what' ");
/*
* Only tested with Posts/Pages
* - there are moments where Draft and Pending shouldn't return any value
*/
$views['all'] = preg_replace( '/\(.+\)/U', '('.$total.')', $views['all'] );
$views['publish'] = preg_replace( '/\(.+\)/U', '('.$publish.')', $views['publish'] );
$views['draft'] = preg_replace( '/\(.+\)/U', '('.$draft.')', $views['draft'] );
$views['pending'] = preg_replace( '/\(.+\)/U', '('.$pending.')', $views['pending'] );
// Debug info
//echo 'Default counts: <pre>'.print_r($views,true).'</pre>';
//echo '<hr><hr>';
//echo 'Query for this screen of this post_type: <b>'.$what.'</b><pre>'.print_r($wp_query,true).'</pre>';
return $views;
}
As of writing, this functionality now resides in the class WP_List_Table, in the method "views()".
The filter now looks like this:
$views = apply_filters( "views_{$this->screen->id}", $views );
$views will contain an array of each list element:
[19-Feb-2016 11:43:44 UTC] Array
(
[all] => <a href="link_to_view" class="current">Alle <span class="count">(1)</span></a>
[trash] => <a href="link_to_view">Trash <span class="count">(94)</span></a>
[confirmed] => <a href="link_to_view">Confirmed <span class="count">(1)</span></a>
)
You can hook it up at the current_screen hook with a priority >10:
add_action( 'current_screen', function ( $current_screen ) {
if ($current_screen->id === 'edit-my_page')
add_filter( "views_{$current_screen->id}", 'list_table_views_filter' );
}, 20);
function list_table_views_filter( array $view ) {
error_log(print_r($view, true));
return $view;
}
You can then add/change/remove upon elements in the list.