• Resolved farhan25

    (@farhan25)


    Hello there,
    I’m creating a plugin in which I use crons.
    When I register a new task using wp_schedule_event with a future timestamp, the task registered successfully but it executes immediately after activating the plugin.

    Here is my code sample:

    <?php
    
    /**
     * Plugin Name: Email Check
     */
    
    if ( ! defined( 'ABSPATH' ) ) {
    	exit; // Exit if accessed directly
    }
    
    add_action( 'mc_cron_hook', 'mc_cron_exec' );
    if ( ! function_exists( 'mc_cron_exec' ) ) {
    	function mc_cron_exec() {
    		// send mail ..
    		// insert query ..
    	}
    }
    
    register_activation_hook( __FILE__, 'mc_activated' );
    if ( ! function_exists( 'mc_activated' ) ) {
    	function mc_activated() {
    		// create log table
    		// if mc_cron_hook is not scheduled before, schedule it
    		if ( ! wp_next_scheduled( 'mc_cron_hook' ) ) {
    			date_default_timezone_set( "Europe/Helsinki" );
    			$time = strtotime( '12:00' );
    			wp_schedule_event( $time, 'daily', 'mc_cron_hook' );
    		}
    	}
    }
    
    register_deactivation_hook( __FILE__, 'mc_deactivated' );
    if ( ! function_exists( 'mc_deactivated' ) ) {
    	function mc_deactivated() {
    		$timestamp = wp_next_scheduled( 'mc_cron_hook' );
    		wp_unschedule_event( $timestamp, 'mc_cron_hook' );
    	}
    }
Viewing 9 replies - 1 through 9 (of 9 total)
  • Moderator bcworkz

    (@bcworkz)

    Try removing date_default_timezone_set(). It’s use is discouraged (under “Not Recommended” here). All time should be based on the timezone set in WP settings. I think date_default_timezone_set() causes a double timezone correction in WP.

    Thread Starter farhan25

    (@farhan25)

    @bcworkz I removed date_default_timezone_set() as you suggested but the problem still exist, the task of sending the mail and inserting into the DB is still executing after activating the plug-in.
    Thank you very much for your reply.

    Moderator bcworkz

    (@bcworkz)

    I can replicate the same behavior, you may have stumbled upon a bug. Allow me some time to investigate and try to find the root cause. I’ll report back with what I’ve discovered.

    Thread Starter farhan25

    (@farhan25)

    @bcworkz Ok I’m not in a hurry, thank you for your hard work an precious time!

    • This reply was modified 5 years, 5 months ago by farhan25.
    Moderator bcworkz

    (@bcworkz)

    Sorry, it seems I’ve misspoken. I’m actually unable to replicate the behavior. There was a stray cron event from an earlier test confusing what I was observing. Now I’m wondering if you also have stray cron events. Deactivate your plugin, there should in theory then be no related cron events for this. Double check the “cron” option and ensure that “mc_cron_exec” does not exist anywhere in the serialized array data. If you find any, execute the deactivation code to unschedule the event without the plugin being active.

    Now that we’re sure there are no stray events, activate your plugin without the timezone set call. Note that the time returned by strtotime without that call is at UTC, so adjust the ’12:00′ accordingly. Under these conditions, no email is sent for me when the plugin is activated. I actually used error_log() to test if the event fired, I didn’t send an email, not that it matters.

    If you still have trouble, I suspect the event callback is being called from somewhere besides wp-cron. Have the callback trigger a user error and get the backtrace to learn where the function was called from.

    Thread Starter farhan25

    (@farhan25)

    @bcworkz Thank you for your reply.
    I’m using the latest WP version 5.6, when I deactivate all plugins including mine, then apply the same test mentioned here I get these tasks (with various intervals of course):

    1. wp_scheduled_delete
    2. delete_expired_transients
    3. wp_scheduled_auto_draft_delete
    4. wp_privacy_delete_old_export_files
    5. wp_version_check
    6. wp_update_plugins
    7. wp_update_themes
    8. recovery_mode_clean_expired_keys
    9. wp_site_health_scheduled_check

    As you can see, my task is not there since I call wp_unschedule_event on deactivating.
    So I think there is no stray events.
    The time as defined in $timestamp is appearing in UTC as expected and it executes at the specific time in future, the problem is the execution immediately after activating the plug-in which I don’t want it to.
    Thanks again for your time and Merry Christmas 🙂

    Thread Starter farhan25

    (@farhan25)

    @bcworkz
    I found out what is causing this problem.
    it’s the misuse of strtotime function, strtotime('12:00'); is returning the 12:00 PM of the current day so:

    • if it runs after 12:00 PM, it consider the task schedule as elapsed time and thus the task will execute.
    • if it runs before 12:00 PM, everything works as expected and it runs in the future this day.

    using strtotime('tomorrow 12:00'); solve the problem as it assures the task will always run for the first time at the next 12:00 PM.
    Thank you and happy holidays!

    Moderator bcworkz

    (@bcworkz)

    Ah! Good catch! I was useless to track that down as it was working as expected for me. Might have something to do with which side of UTC one is on. And/or the ambiguity of whether 12:00 is midnight or noon on a 12 hour clock.

    Thread Starter farhan25

    (@farhan25)

    Yeah for sure, but thanks anyway for your help and putting attention for UTC and telling me that using date_default_timezone_set is a bad idea. It was my fault that I didn’t notice strtotime() at the first place ..

Viewing 9 replies - 1 through 9 (of 9 total)

The topic ‘problem with scheduled crons’ is closed to new replies.