Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Is it possible to display the total post count for all blogs in a Network? get_blog_count and get_user_count do so for blogs and users, but I can't find any methods to do so for post count.

share|improve this question

2 Answers 2

In form of a Network Dashboard Widget:

network dashboard widget

That <h2> for the widget title is a bit overkill, but was just testing some styling :)

add_action( 'wp_network_dashboard_setup', 'wpse_66963_network_dashboard_setup' );

function wpse_66963_network_dashboard_setup() 
{
    wp_add_dashboard_widget( 
        'wpse_66963_posts_count_widget', 
        '<div id="icon-edit" class="icon32"></div><h2>Network Posts Count</h2>', 
        'wpse_66963_posts_count' );
}

function wpse_66963_posts_count() 
{
    global $wpdb;
    $blogs = $wpdb->get_results( $wpdb->prepare( 
            "SELECT * FROM {$wpdb->blogs} WHERE  spam = '0' 
            AND deleted = '0' AND archived = '0' 
            ORDER BY registered DESC, 5", ARRAY_A ) );

    $original_blog_id = get_current_blog_id();

    if ( empty( $blogs ) ) 
    {
        echo '<p>No blogs!</p>';
        break;
    }
    ?>          
    <table class="widefat">
        <thead>
            <tr>
                <th>Site</th>
                <th>Total posts</th>       
                <th>Draft posts</th>
            </tr>
        </thead>
        <tfoot>
            <tr>
            <th>Site</th>
            <th>Total posts</th>
            <th>Draft posts</th>
            </tr>
        </tfoot>
        <tbody>
        <?php
    $args = array(
        'numberposts'     => -1,
        'post_type'       => 'post',
        'post_status'     => 'publish' );
    $total_network = $draft_network = 0;

    foreach ($blogs as $blog) 
    {
        switch_to_blog( $blog->blog_id );

        $args['post_status'] = 'publish';
        $total_posts = count( get_posts( $args ) );
        $total_network += $total_posts;

        $args['post_status'] = 'draft';
        $draft_posts = count( get_posts( $args ) );
        $draft_network += $draft_posts;
        ?>
           <tr>
             <td><?php echo $blog->domain; ?></td>
             <td><?php echo $total_posts; ?></td>
             <td><?php echo $draft_posts; ?></td>
           </tr>
        <?php
    }
    ?>
           <tr>
             <td><b>Total count</b></td>
             <td><?php echo $total_network; ?></td>
             <td><?php echo $draft_network; ?></td>
           </tr>
        </tbody>
    </table>
    <?php
    switch_to_blog( $original_blog_id );
}
share|improve this answer

Made a couple of tweaks to brasofilo's example as we were getting hit with memory execution issues; one of which may be related to a possible switch_to_blog memory leak that has been impacting sites doing a lot of switch_to_blog calls (we would typically run around ~1000 or so when loading this dashboard widget.) Even with memory limits of 256MB+; still getting execution errors. The fix was adding wp_cache_flush();

Crude perhaps, but cleans up the memory enough to allow it to execute. Additional changes also include some logic to avoid displaying sites with only 1 post (presumably the default) and show the total number of "active" sites with 2+ posts with the summary at the bottom of the table.

    add_action( 'wp_network_dashboard_setup', 'wpse_66963_network_dashboard_setup' );

function wpse_66963_network_dashboard_setup()
{
    wp_add_dashboard_widget(
        'wpse_66963_posts_count_widget',
        '<div id="icon-edit" class="icon32"></div><h2>Network Posts Count</h2>',
        'wpse_66963_posts_count' );
}

function wpse_66963_posts_count()
{
    global $wpdb;
    $blogs = $wpdb->get_results( $wpdb->prepare(
            "SELECT * FROM {$wpdb->blogs} WHERE  spam = '0' 
            AND deleted = '0' AND archived = '0' 
            ORDER BY registered DESC, 2", ARRAY_A ) );

    $original_blog_id = get_current_blog_id();

    if ( empty( $blogs ) )
    {
        echo '<p>No blogs!</p>';
        break;
    }
    ?>
    <table class="widefat">
        <thead>
            <tr>
                <th>Site</th>
                <th>Total posts</th>
                <th>Draft posts</th>
            </tr>
        </thead>
        <tfoot>
            <tr>
            <th>Site</th>
            <th>Total posts</th>
            <th>Draft posts</th>
            </tr>
        </tfoot>
        <tbody>
        <?php
    $args = array(
        'numberposts'     => -1,
        'post_type'       => 'post',
        'post_status'     => 'publish' );
    $total_network = $draft_network = 0;
    $total_sites = 0;

    foreach ($blogs as $blog)
    {
        wp_cache_flush();
        switch_to_blog( $blog->blog_id );
        $args['post_status'] = 'publish';
        if (count(get_posts($args))<2) { continue; }
        $total_posts = count( get_posts( $args ) );
        $total_network += $total_posts;
        $total_sites += 1;

        $args['post_status'] = 'draft';
        $draft_posts = count( get_posts( $args ) );
        $draft_network += $draft_posts;
        ?>
           <tr>
             <td><a href="<?php echo site_url(); ?>"><?php echo site_url(); ?></a></td>
             <td><?php echo $total_posts; ?></td>
             <td><?php echo $draft_posts; ?></td>
           </tr>
        <?php
    }
    ?>
           <tr>
             <td><b>Total count (<?php echo $total_sites;?> sites with content)</b></td>
             <td><?php echo $total_network; ?></td>
             <td><?php echo $draft_network; ?></td>
           </tr>
        </tbody>
    </table>
<?php echo memory_get_usage(); ?>
<br/>
<?php echo memory_get_peak_usage(); ?>
    <?php
    switch_to_blog( $original_blog_id );
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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