# Content Audit Summary (WP-CLI)

> Adds a "wp content-audit" command that shows, per post type, how many items are published, drafts, missing a featured image, missing an excerpt and not updated for two years.

- Type: PHP
- Runs: Run everywhere
- Category: [Developer](https://wpide.com/library/category/developer/)
- Tags: wp-cli, content, audit
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/cli-content-audit/

## Code

```php
if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
    return;
}

WP_CLI::add_command( 'content-audit', function ( $args, $assoc_args ) {
    global $wpdb;

    $stale_days = max( 1, (int) ( $assoc_args['stale-days'] ?? 730 ) );
    $cutoff     = gmdate( 'Y-m-d H:i:s', time() - $stale_days * DAY_IN_SECONDS );
    $items      = array();

    foreach ( get_post_types( array( 'public' => true ), 'objects' ) as $type ) {
        if ( 'attachment' === $type->name ) {
            continue;
        }
        $counts = wp_count_posts( $type->name );
        $row    = $wpdb->get_row( $wpdb->prepare(
            "SELECT
                SUM( t.meta_id IS NULL ) AS no_image,
                SUM( p.post_excerpt = '' ) AS no_excerpt,
                SUM( p.post_modified_gmt < %s ) AS stale
            FROM {$wpdb->posts} p
            LEFT JOIN {$wpdb->postmeta} t ON t.post_id = p.ID AND t.meta_key = '_thumbnail_id'
            WHERE p.post_type = %s AND p.post_status = 'publish'",
            $cutoff,
            $type->name
        ) );

        $items[] = array(
            'post_type'  => $type->name,
            'published'  => (int) $counts->publish,
            'drafts'     => (int) $counts->draft,
            'no_image'   => post_type_supports( $type->name, 'thumbnail' ) ? (int) $row->no_image : '-',
            'no_excerpt' => (int) $row->no_excerpt,
            'stale'      => (int) $row->stale,
        );
    }

    WP_CLI\Utils\format_items( $assoc_args['format'] ?? 'table', $items, array( 'post_type', 'published', 'drafts', 'no_image', 'no_excerpt', 'stale' ) );
}, array(
    'shortdesc' => 'Summarizes content health per post type.',
    'synopsis'  => array(
        array( 'type' => 'assoc', 'name' => 'stale-days', 'optional' => true, 'default' => 730 ),
        array( 'type' => 'assoc', 'name' => 'format', 'optional' => true, 'default' => 'table', 'options' => array( 'table', 'csv', 'json' ) ),
    ),
) );
```

## Notes

Change the stale threshold with --stale-days=365.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Content Audit Summary (WP-CLI)" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
