User_FTW
User_FTW

Reputation: 524

wp_cron() not updating time from options page

I'm working in a simple plugin that initiates a wp_cron job.

I have an options page with a field (daily_message_time) where I enter my desired time to schedule the cron, say 17:30:00 for example, and it gets stored in the _options table as expected. I can then get that value and use it in my plugin script like this:

register_activation_hook(__FILE__, 'send_message');
function send_message() {
    if (! wp_next_scheduled ( 'daily_email_event' )) {
        $options        = get_option( 'my_settings' );
        $daily_time     = $options['daily_message_time'];

        // Honour WordPress timezone setting
        $date = new DateTime( $daily_time, new DateTimeZone( get_option( 'timezone_string' ) ) );
        $timestamp = $date->getTimestamp();

        // Shedule the event
        wp_schedule_event($timestamp, 'daily', 'daily_email_event');
    }
}

add_action('daily_email_event', 'send_email');
function send_email() {
    // Do stuff
}

This works and I can see my cron has been scheduled for the correct time:

enter image description here

But the problem is this: If I change the time in my options page, the new time does get stored in the database but the cron job does not show the new time (it keeps the original time). The only way I can get it to work is by deactivating and reactivating the plugin again, after which it then shows the new time.

How can I get around this?

Upvotes: 1

Views: 510

Answers (1)

CodeMascot
CodeMascot

Reputation: 855

Well, this register_activation_hook only fires on activating the plugin. This will not fire on saving the options. So for firing the function on saving options you need to hook that to update_option_{$option} or a more generic hook update_option.

Now your code will be like below-

// This hook fires only on activating the plugin
register_activation_hook(__FILE__, 'send_message');
// This will fire when you update my_settings option.
add_action( 'update_option_my_settings', 'send_message' );
// or if the above hook doesn't work then use this below. It's for global options update.
// add_action( 'update_option', 'send_message' );
function send_message() {
    if (! wp_next_scheduled ( 'daily_email_event' )) {
        // May be you should use the below function to clear any previous schedule.
        // wp_clear_scheduled_hook( 'daily_email_event' );
        $options        = get_option( 'my_settings' );
        $daily_time     = $options['daily_message_time'];

        // Honour WordPress timezone setting
        $date = new DateTime( $daily_time, new DateTimeZone( get_option( 'timezone_string' ) ) );
        $timestamp = $date->getTimestamp();

        // Shedule the event
        wp_schedule_event($timestamp, 'daily', 'daily_email_event');
    }
}

add_action('daily_email_event', 'send_email');
function send_email() {
    // Do stuff
}

Look may be you should also use wp_clear_scheduled_hook to clear any previous schedule. Please research on that before use.

Hope that helps.

Upvotes: 1

Related Questions