6

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.

2 Answers 2

5

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 );
}
1
  • 1
    wp_cache_flush() causes the cache for all sites to be flushed on a multisite so this is a bad solution in that case.
    – svandragt
    Commented Feb 24, 2017 at 10:59
4

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 );
}
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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