Change the Status of Many Posts at Once (WP-CLI)
Adds a "wp change-status" command that moves posts from one status to another, for example every draft older than a date back to pending, with a preview count before anything changes.
Opens WPIDE on
Code
if ( ! defined( 'WP_CLI' ) || ! WP_CLI ) {
return;
}
WP_CLI::add_command( 'change-status', function ( $args, $assoc_args ) {
$from = sanitize_key( $assoc_args['from'] );
$to = sanitize_key( $assoc_args['to'] );
$statuses = get_post_stati();
if ( ! isset( $statuses[ $from ], $statuses[ $to ] ) ) {
WP_CLI::error( 'Unknown post status.' );
}
$query_args = array(
'post_type' => sanitize_key( $assoc_args['post_type'] ?? 'post' ),
'post_status' => $from,
'posts_per_page' => -1,
'fields' => 'ids',
'no_found_rows' => true,
);
if ( ! empty( $assoc_args['before'] ) ) {
$query_args['date_query'] = array( array( 'before' => sanitize_text_field( $assoc_args['before'] ) ) );
}
$ids = get_posts( $query_args );
if ( empty( $assoc_args['yes'] ) ) {
WP_CLI::log( sprintf( '%d posts would change from %s to %s. Add --yes to apply.', count( $ids ), $from, $to ) );
return;
}
foreach ( $ids as $id ) {
wp_update_post( array( 'ID' => $id, 'post_status' => $to ) );
}
WP_CLI::success( sprintf( 'Changed %d posts from %s to %s.', count( $ids ), $from, $to ) );
}, array(
'shortdesc' => 'Moves posts from one status to another.',
'synopsis' => array(
array( 'type' => 'assoc', 'name' => 'from', 'description' => 'Current status, for example draft.' ),
array( 'type' => 'assoc', 'name' => 'to', 'description' => 'New status, for example pending.' ),
array( 'type' => 'assoc', 'name' => 'post_type', 'optional' => true, 'default' => 'post' ),
array( 'type' => 'assoc', 'name' => 'before', 'optional' => true, 'description' => 'Only posts dated before this date (Y-m-d).' ),
array( 'type' => 'flag', 'name' => 'yes', 'optional' => true ),
),
) );
Notes
Example "wp change-status --from=draft --to=pending --before=2024-01-01 --yes"; without --yes it only counts.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.