6

I'm looking add-in a bit more speficity to the WP Cron intervals. To add a "weekly" interval, I've done the following:

function re_not_add_weekly( $schedules ) {
    $schedules['weekly'] = array(
        'interval' => 604800, //that's how many seconds in a week, for the unix timestamp
        'display' => __('weekly')
    );
    return $schedules;
}
add_filter('cron_schedules', 're_not_add_weekly');

Which works great, but - the extra sauce here is getting that cron to run on a specific day:

if( !wp_next_scheduled( 're_not_mail' ) ) {
    wp_schedule_event( time(), 'weekly', 're_not_mail' );
}

Anyone have any thoughts on the best way to accomplish this using WP Cron (assuming this isn't per a specific site that we'll have control over their cPanel/CRON area). Thanks!

Update

Going at this full-force and found an article that may have clarified things a bit more, but doesn't exactly answer my question. The basic gist of that article states that the WP Cron isn't as flexible (past the "hourly, daily, weekly" params), so extending it to something like weekly on a certain day seems a bit farfetched.

The issue (calling it an issue out of confusion/frustration) I have with that is -> sure, I could disable WP CRON and have WP CRON run once a week using the server CRON, BUT, that also means that the items that are normally run, like plugin/theme updates, post deletions/publishes based on CRON are put on a backlog for an entire week (if I wanted CRON to run once a week every Monday for example).

I'd have to assume others have come across this, so anymore insight on this would be a huge help. Thanks!

2
  • What exactly is a certain day? Does it start in Greenwich UNIX time at 00:00:00? Or somewhere else?
    – kaiser
    Commented Sep 10, 2012 at 18:17
  • Hi @kaiser - let's go with the assumption that this should be run weekly, each Monday at 7:00am EDT. Does that clarify things a bit better? Thanks!
    – Zach
    Commented Sep 10, 2012 at 18:36

5 Answers 5

2

WP-Cron is not intended to be that precise, and should not be used if you have to have things scheduled at specific times. WP-Cron is a "best effort" scheduling mechanism, and it cannot guarantee run timing like a real cron system can.

If you need precision of this nature, the only real answer is to not use WP-Cron for it. It's not designed for that, and it cannot do it. Any hacky code you attempt to add to it to make it capable of this won't fix that underlying problem.

Use a real cron system.

6
  • Hey Otto - appreciate the response. So - it sounds like, you really can't have "the best of both worlds here". If I disable CRON as mentioned in that article and have it run weekly, either scheduled posts throughout WP will not be published until that day and the other items will run as needed, or CRON will run as normal (weekly), but I can't specify a specific day (as it will execute each week since the plugin was activated), right? Thanks again.
    – Zach
    Commented Sep 12, 2012 at 16:08
  • Or are you possibly saying, don't disable Cron, just don't put that function into it - meaning I'd create a standalone PHP file (then "including" WordPress files to recognize WP logic/functions) and only run that specific PHP file with cron?
    – Zach
    Commented Sep 12, 2012 at 19:29
  • You don't have to disable the wp-cron. Just don't use it for events that require specific timing like that. Scheduled posts will continue to work fine.
    – Otto
    Commented Sep 12, 2012 at 22:47
  • This is actually very easy to do. Just setup a daily schedule event, then in the hook, check for the day you want to run using the DateTime object. Sure, it's not as accurate as a real cron but this is absolutely doable. Not everyone has access to a "real cron system". One issue that may rise, is if you are using the poor man's cron and no one visits your site that day. To fix this, you can check the last run time and adjust as you need.
    – Jeremy
    Commented Oct 21, 2014 at 19:02
  • 1
    You can do things like that, but it's still a best effort system. "Monday at 7am" is a bit precise. What if nobody visits the site on Monday? Your job will run on Tuesday instead. This may be undesirable if you need that sort of precision in the first place. In which case, you should use a real cron for things that need to run at specific times. WP_Cron isn't meant for timing-specific tasks like this, and can cause you unexpected grief if you try to use it for such.
    – Otto
    Commented Oct 21, 2014 at 20:35
1

If you have important WP cron jobs on a schedule you should of course have a system cron job running that regularly calls WP cron to make things are always fired when you need them.

If you need a specific time/date for your WP cron runs you can always schedule a single event and have the called method schedule the next event.

Simple example:

function some_awesome_hook() {
    // Do stuff here

    // Run next Monday
    $next_run = strtotime('next monday');

    // Clear hook, just in case
    wp_clear_scheduled_hook('some_awesome_hook');

    // Add our event
    wp_schedule_single_event($next_run, 'some_awesome_hook');
}

// Run next Monday
$first_run = strtotime('next monday');

// Add our event
wp_schedule_single_event($first_run, 'some_awesome_hook');

OOP style:

class My_Sweet_Plugin {

    public $cron_hook;

    public function __construct() {
        // Store our cron hook name
        $this->cron_hook = 'my_awesome_cron_hook';

        // Install cron!
        $this->setup_cron();

        // Add action that points to class method
        add_action($this->cron_hook, array($this, 'my_awesome_function'));
    }

    public function setup_cron() {
        // Clear existing hooks
        wp_clear_scheduled_hook($this->cron_hook);

        // Next run time
        $next_run = strtotime('next monday');

        // Add single event
        wp_schedule_single_event($first_run, $this->cron_hook);
    }

    public function my_awesome_function() {
        // Do stuff!

        // Setup our next run
        $this->setup_cron();
    }
}
1

Even though this is quite an old post, accurate scheduling problem remains, so I thought it worthwhile to add a solution that I use to work around this. Hopefully it helps get a bit more resolution on scheduling (i.e. more specificity).

While the WordPress Cron is not designed to execute on a particular day or time every week, there is a way to work around this and get reasonably good results.

My example will be to schedule the Cron to run on a particular day of the week (Sunday) at a particular time (02:00), but you can modify this to make it run on any particular day in the month, day in the year, whatever.

First set the custom recurrence period in the usual way (if you need a custom schedule):

function my_add_custom_time( $schedules ) {
  $schedules['weekly'] = array(
    'interval' => 604800,
    'display' => __('Every Week')
  );
  return $schedules;
}
add_filter('cron_schedules', 'my_add_custom_time');

Next, assign the schedule to your Cron hook.

The logic is as follows... When setting up the schedule, check if the event has already been scheduled, if not, schedule to the next possible Sunday at 2:00. If it is already scheduled, check that the day is a Sunday. If the day was wrong then re-schedule the Cron to run on the next Sunday at 2:00.

function my_custom_cron_settings() {
  $next_stamp = strtotime('next sunday + 2 hour');
  $timestamp = wp_next_scheduled('my_cron_hook');
  if ( !$timestamp ) {
    wp_schedule_event( $next_stamp, 'weekly', 'my_cron_hook' );
  } else {
    $day = date("D", $timestamp);
    if ( $day != 'Sun' ){
        wp_clear_scheduled_hook('my_cron_hook');
        wp_schedule_event( $next_stamp, 'weekly', 'my_cron_hook' );
    }
  }
}
add_action( 'wp', 'my_custom_cron_settings' );

Finally, set up the Cron hook action to do whatever actions you want to perform.

function my_cron_do_whatever(){
  //do whatever you want the Cron to do here
}
add_action( 'my_cron_hook', 'my_cron_do_whatever' );

This code can easily be modified to handle other scenarios, and while not a perfect solution, it may help if you want a bit more control over your Cron Job.

2
  • 1
    Thanks man. It's working on my custom plugin. Commented Jun 25 at 3:08
  • Glad to hear this code helped you. Thanks for the feedback.
    – Clinton
    Commented Jun 28 at 8:48
0

According to Codex you can use wp_get_schedules to add in an option like Weekly (which you've already done).

WP-Cron was not intended to have all the Cron functions so why not just login to the server and create a cron job to call your PHP file only on Monday and add something like this to your crontab

* 07 * * Mon root cmd

3
  • Hi - can't do this on the server level as I mentioned in my question (as we will not always have access to the cron tab if we distribute this)
    – Zach
    Commented Sep 10, 2012 at 20:02
  • @zach how will you mange things if no one visits on a Monday therefore wp-cron won't run? Just wondering ..l
    – Damien
    Commented Sep 10, 2012 at 21:44
  • This is going to be used on intranets, so people will be accessing it almost every day, but I do see your point. I did see this article that says you'd need to completely disable cron which I'd prefer not to do. If I did and had it run once a week on Monday, then nothing else (like plugin updates) would run either, correct? Thanks.
    – Zach
    Commented Sep 11, 2012 at 0:29
0

You can use this approach

//Your cron function which you want to execute any specific day, e.g. Monday
function daily_cron_callback() {
    $timestamp = time();    
    
    if(date('D', $timestamp) !== 'Mon') { //do nothing, if not Monday
        return;
    }
    
    //Process your logic here
}

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.