How to make sure WP-CRON job loops through all posts?

I am using WP-Crontrol and have some CRON jobs running daily to check the age of the posts. If the post is 2 days older, they will be deleted.

This works but for some reason, only some of the three days and older posts get deleted. There are still some that remain published.

It must be because there are a lot of posts on the site around 3000. Is there a way to make my CRON job more efficient?

Here is the current code that I have running:

class EventsWPCron {

    public function __construct() {

        if ( ! wp_next_scheduled( 'trash_old_events' ) ) {
            wp_schedule_event( time(), 'daily', 'trash_old_events' );
        }

        add_action( 'trash_old_events', array( $this, 'delete_events' ) ); 

    }

    public function delete_events() {
        $args = array(
            'post_type' = 'event',
            'post_status' = 'publish',
            'posts_per_page' = -1,
            'date_query' = array(
                array(
                    'before' = '2 days ago'
                )
            )
        ); 

        $query = new WP_Query( $args );
        $posts = $query-get_posts();

        foreach( $posts as $post ) { 
            wp_delete_post( $post-ID, true );
        }


    }     


}

new EventsWPCron();

Topic wp-cron cron Wordpress

Category Web


Almost always there is a time limit set for PHP scripts. If a script runs longer than the limit, it gets killed.

So if there are many posts to delete, then there is a chance that the script gets killed, so it deletes only part of them.

But doing it this way isn’t very efficient either - what if there will be many many posts, so they won’t fit in memory limit?

Much better approach would be to run your cron event more often and delete only part of old posts. It will be much nicer for server too...

So instead of running it daily, run it hourly and put an explicit limit in the query. Let’s say there are 1000 posts to delete on average. So your script should remove 42 hourly. Let’s set it to 100 - this way you’ll be sure all of them will be deleted.

And if they should be deleted faster, then set the cron event to run even more often - every 5 minutes?

PS. There is one more thing worth noticing. If old posts should not be shown on site, then I would modify queries in such way, that these posts will be ignored. Relying on cron in this case won’t be very good idea (deleting posts may take a while, cron may not get called and so on...). Of course you can still delete them after they are ignored by all site queries...


You're not specifying the number of posts you want back from the query, so it defaults to whatever you have set under Settings > Reading.

If you want all that match your criteria, then add 'posts_per_page' => -1 to your query arguments.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.