WordPress Version: 6.3
/**
* Counts number of posts of a post type and if user has permissions to view.
*
* This function provides an efficient method of finding the amount of post's
* type a blog has. Another method is to count the amount of items in
* get_posts(), but that method has a lot of overhead with doing so. Therefore,
* when developing for 2.5+, use this function instead.
*
* The $perm parameter checks for 'readable' value and if the user can read
* private posts, it will display that for the user that is signed in.
*
* @since 2.5.0
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param string $type Optional. Post type to retrieve count. Default 'post'.
* @param string $perm Optional. 'readable' or empty. Default empty.
* @return stdClass An object containing the number of posts for each status,
* or an empty object if the post type does not exist.
*/
function wp_count_posts($type = 'post', $perm = '')
{
global $wpdb;
if (!post_type_exists($type)) {
return new stdClass();
}
$cache_key = _count_posts_cache_key($type, $perm);
$counts = wp_cache_get($cache_key, 'counts');
if (false !== $counts) {
// We may have cached this before every status was registered.
foreach (get_post_stati() as $status) {
if (!isset($counts->{$status})) {
$counts->{$status} = 0;
}
}
/** This filter is documented in wp-includes/post.php */
return apply_filters('wp_count_posts', $counts, $type, $perm);
}
$query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s";
if ('readable' === $perm && is_user_logged_in()) {
$post_type_object = get_post_type_object($type);
if (!current_user_can($post_type_object->cap->read_private_posts)) {
$query .= $wpdb->prepare(" AND (post_status != 'private' OR ( post_author = %d AND post_status = 'private' ))", get_current_user_id());
}
}
$query .= ' GROUP BY post_status';
$results = (array) $wpdb->get_results($wpdb->prepare($query, $type), ARRAY_A);
$counts = array_fill_keys(get_post_stati(), 0);
foreach ($results as $row) {
$counts[$row['post_status']] = $row['num_posts'];
}
$counts = (object) $counts;
wp_cache_set($cache_key, $counts, 'counts');
/**
* Filters the post counts by status for the current post type.
*
* @since 3.7.0
*
* @param stdClass $counts An object containing the current post_type's post
* counts by status.
* @param string $type Post type.
* @param string $perm The permission to determine if the posts are 'readable'
* by the current user.
*/
return apply_filters('wp_count_posts', $counts, $type, $perm);
}