Here is another flexible way to count posts:
Idea:
First I was going to write the SQL query directly, but then I thought it would be more flexible if we could instead just modify the SQL query generated by WP_Query()
so it would only return the results count instead of post objects.
Example:
I’ve been playing with these things today and this is what came out of it:
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'category_name' => 'reykjavik',
);
$q = new WPSE_121749_Query_Count( $args );
echo $q->count();
where you can change $args
to your likings and WPSE_121749_Query_Count
is an extension of WP_Query
.
Output:
In the above example the output of echo $q->count();
is 95
since
the output of print_r( $q->posts );
is:
Array ( [0] => 95 )
and it doesn’t contain any post objects, since we only want the count.
The Class:
There are many hooks available to modify the WP_Query
and I use three filters and one action but there might be better ways to do this using other hooks.
Here is the first version of the class:
/**
* Class WPSE_121749_Query_Count
*
*/
class WPSE_121749_Query_Count extends WP_Query
{
public function __construct( $args = array() )
{
add_filter( 'posts_request', array( $this, 'posts_request' ) );
add_filter( 'posts_orderby', array( $this, 'posts_orderby' ) );
add_filter( 'post_limits', array( $this, 'post_limits' ) );
add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
parent::__construct( $args );
}
public function count()
{
if( isset( $this->posts[0] ) )
return $this->posts[0];
return '';
}
public function posts_request( $request )
{
remove_filter( current_filter(), array( $this, __FUNCTION__ ) );
return sprintf( 'SELECT COUNT(*) FROM ( %s ) as t', $request );
}
public function pre_get_posts( $q )
{
$q->query_vars['fields'] = 'ids';
remove_action( current_filter(), array( $this, __FUNCTION__ ) );
}
public function post_limits( $limits )
{
remove_filter( current_filter(), array( $this, __FUNCTION__ ) );
return '';
}
public function posts_orderby( $orderby )
{
remove_filter( current_filter(), array( $this, __FUNCTION__ ) );
return '';
}
}