Auto Draft Specific Categories Posts after a certain number of Days

Two most important notes to your code. It’s not working, because always will be retrieved only 5 (the default value of 'post_per_page' parameter) recent posts. If you want to add a task to the cron, you do not specify the function name as the parameter, but the name of the action hook. And you attach a function to this action hook.

add_action( 'se354599_old_posts_to_draft', '{function-name}' );
wp_schedule_event( time(), 'daily', 'se354599_old_posts_to_draft' );

The task should be added to the schedule only once, preferably when activating the plugin or theme.
But you can also:

Now the parameters of the get_posts() function.

To update the status of the post there is no need to retrieve all the data of the post, just its ID.

'fields' => 'ids'

You want to get all posts that meet the conditions, so you need to set the post_per_page parameter to -1.
To limit results to posts published more than 90 days ago use 'date_query' parameter.
To limit results to specific custom categories use 'tax_query' parameter.

Having posts IDs, all you have to do is update their status. Use wp_update_post() function
or divide results array into smaller pieces (e.g. 30 items each) and update posts in batches ($wpdb->query(())

add_action( 'init', 'se354599_add_cronjob' );
add_action( 'se354599_old_posts_to_draft', 'se354599_update_post' );

function se354599_add_cronjob()
{
    if ( !wp_next_scheduled( 'se354599_old_posts_to_draft' ) ) {
        wp_schedule_event(time(), 'daily', 'se354599_old_posts_to_draft');
    }
    // DISABLE
    //if ( wp_next_scheduled( 'se354599_old_posts_to_draft' ) ) {
    //    wp_clear_scheduled_hook( 'se354599_old_posts_to_draft' );
    //}
}

function se354599_update_post()
{
    $args = [
        'post_type'     => 'property',
        'fields'        => 'ids',
        'post_per_page' => -1,
        'date_query'    => [
            'before' => '-90 day',
        ],
        'tax_query' => [
            [
                'taxonomy'  => 'property-ad-type',
                'include_children' => false,
                'field'     => 'term_id',
                'terms'     => [107, 108],
                // --- or by slug: ---
                // 'field'     => 'slug',   // ‘term_id’, ‘name’, ‘slug’ or ‘term_taxonomy_id’
                // 'terms'     => ['free-text-only-ad', 'photo-ad'],
            ],
        ],
    ];
    $to_update = get_posts( $args );
    if ( !is_array($to_update) || empty($to_update) )
        return;

    $arg = [ 'ID' => 0, 'post_status' => 'draft' ];
    foreach ( $to_update as $pID ) 
    {
        $arg['ID'] = (int)$pID;
        wp_update_post( $arg );
    }
}

Leave a Comment