Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding crons in wordpress & a snippet of code

Tags:

php

wordpress

I'm looking for some help understanding this code with some comments if possible, I'm trying to figure out how it works exactly.

It's located in a plugin and I have had a look at Wordpress's codex but it hasn't really helped me much.

The pages I looked at are/were:

https://codex.wordpress.org/Function_Reference/wp_schedule_event https://codex.wordpress.org/Function_Reference/wp_next_scheduled

And also: http://codex.wordpress.org/Plugin_API/Action_Reference/wp

Code Snippet:

add_action('wp','prefix_setup_schedule');
function prefix_setup_schedule() {
    if (!wp_next_scheduled('prefix_hourly_event')){
        wp_schedule_event(time(), 'hourly', 'prefix_hourly_event');
    }
    if (!wp_next_scheduled('daily_prefix_hourly_event')){
        //wp_schedule_event(time(), 'daily', 'daily_prefix_hourly_event');
        wp_schedule_event(time(), 'wpo_daily', 'daily_prefix_hourly_event');
    }
}

add_action('prefix_hourly_event','filter_mem');

$t = time();
$hour = date('G');
if(get_option('cronhour') != null){
    $hcron = (int)get_option('cronhour');
    if($hcron > 0 && $hcron <= 23){
        if($hour < $hcron){
            $on = mktime($hcron, 0, 0, date('m'), date('d'), date('Y'));
        }else{
            $on = mktime($hcron, 0, 0, date('m'), date('d')+1, date('Y'));
        }
    }else{
        $hcron = 0;
        if($hour < $hcron){
            $on = mktime($hcron, 0, 0, date('m'), date('d'), date('Y'));
        }else{
            $on = mktime($hcron, 0, 0, date('m'), date('d')+1, date('Y'));
        }
    }
} else {
    $hcron = 0;
    if($hour < $hcron){
        $on = mktime($hcron, 0, 0, date('m'), date('d'), date('Y'));
    }else{
        $on = mktime($hcron, 0, 0, date('m'), date('d')+1, date('Y'));
    }
}

if ($t>=$on){
    add_action('daily_prefix_hourly_event', 'filter_temp');
}

As far as I can tell, it seems to be comparing the current time to the "cronhour" and somehow adding the cron.

I also noticed the plugin has no unschedule / clear schedule hook so surely it would keep firing even when plugin is disabled?

I looked at the following

https://codex.wordpress.org/Function_Reference/wp_unschedule_event https://codex.wordpress.org/Function_Reference/wp_clear_scheduled_hook

Not sure what one I should be using, it isn't very clear. I'd greatly appreciate some help understanding what this is doing, with some comments and explaining the differences.

like image 624
Ryflex Avatar asked Oct 20 '22 01:10

Ryflex


1 Answers

Before going in to the code, I am wondering something regarding the option cronhour referenced in the code. I'm not sure what it represents or how it is used (i.e. does the plugin change/update it [perhaps in some of these events that get triggered] or is it set somewhere in the options by the site admin and stays fixed)?

That variable affects part of this code which is why I mention it. That said, I have to guess a little bit on the second part which is probably causing most of your confusion.

Also, as you'll see, some of the logic in this code is poor. There is repeated code that doesn't need to be and one statement that will never execute because the condition will never be met.

Here is how I interpret some of the code to work:

<?php

// this causes the 'prefix_setup_schedule' function to run on all WP requests
add_action('wp','prefix_setup_schedule');

// the function referenced above - essentially gets run on every request
function prefix_setup_schedule() {
    // checks to see if WP's scheduler has an hourly event for
    // prefix_hourly_event set to run, if not, schedules it to run "now"
    // and then every hour going forward
    if (!wp_next_scheduled('prefix_hourly_event')){
        wp_schedule_event(time(), 'hourly', 'prefix_hourly_event');
    }
    // same as above, except for the daily event, and every day at this
    // time going forward
    if (!wp_next_scheduled('daily_prefix_hourly_event')){
        //wp_schedule_event(time(), 'daily', 'daily_prefix_hourly_event');
        wp_schedule_event(time(), 'wpo_daily', 'daily_prefix_hourly_event');
    }
}

// tells WP to run the filter_mem function when the prefix_hourly_event
// hook runs if that hook is called based on the schedule
add_action('prefix_hourly_event','filter_mem');

$t = time(); // current time
$hour = date('G'); // current hour in 24h format

// again, not sure about this variable, but it represents an hour of the day
// for this example, pretend it equals 5 (5 AM)
if(get_option('cronhour') != null) {
    $hcron = (int)get_option('cronhour');
    if($hcron > 0 && $hcron <= 23){ // range check
        if($hour < $hcron){
            // if current hour is less than 5, set timestamp to 5 AM today
            $on = mktime($hcron, 0, 0, date('m'), date('d'), date('Y'));
        }else{
            // else timestamp is 5 am tomorrow
            $on = mktime($hcron, 0, 0, date('m'), date('d')+1, date('Y'));
        }
    }else{
        // invalid range, they just set hour to midnight
        $hcron = 0;
        if($hour < $hcron){
            // NOOP: not possible, date('G') cannot be less than 0
            $on = mktime($hcron, 0, 0, date('m'), date('d'), date('Y'));
        }else{
            // set time to midnight tomorrow (hcron was set to 0)
            $on = mktime($hcron, 0, 0, date('m'), date('d')+1, date('Y'));
        }
    }
} else {
    // cronhour option not set, set to midnight
    // this is essentially duplicate to code above.
    // written properly, this block could have been avoided

    // option was not set, so set hour to midnight
    $hcron = 0;
    if($hour < $hcron){
        // again, $hour cannot be less than 0
        $on = mktime($hcron, 0, 0, date('m'), date('d'), date('Y'));
    }else{
        // midnight tomorrow
        $on = mktime($hcron, 0, 0, date('m'), date('d')+1, date('Y'));
    }
}

if ($t>=$on){
    // if current time is later than $on calculated above, runs the daily action
    add_action('daily_prefix_hourly_event', 'filter_temp');
}

It would seem to me after looking at it (unless the option cronhour changes frequently like I mentioned earlier), that once cronhour passes, this code will essentially run the "daily" hook on every request after the cronhour passes (someone correct me if I'm reading this wrong).

All the code after add_action('prefix_hourly_event','filter_mem'); seems to be unnecessary (intended as a failsafe if WP scheduler fails to run those hooks which it should not).

Given some of the redundant code, and the two if statements than can never run because date('G') will never be less than 0, my opinion is the person who wrote it didn't fully understand what they were doing.

And to comment on what you said regarding the "plugin [having] no unschedule / clear schedule hook so surely it would keep firing even when plugin is disabled"; when a plugin is disabled, WordPress doesn't call any of its code so none of this should run when the plugin is disabled.

Even if WP's event scheduler has daily and hourly events, since those functions it would be calling are defined by this plugin, and therefore not available when the plugin is disabled so they would just be ignored (and yes, it is sloppy to leave those values in the scheduler when the plugin is disabled/deleted because it just results in extra unnecessary processing that will be done by WP that has no result).

I hope what I said makes sense - please feel free to comment if you want clarification on anything or have further questions.

like image 177
drew010 Avatar answered Oct 29 '22 17:10

drew010