0

I try to create a scheduled cron job which runs every hour, Its my first time working with wp-cron.

In the cron function, I want to update post meta values, if some conditions are met.

I also tested the code of the cron function outside of the cron to see/print the results. The results looked ok, but when the cronjob runs no post gets updated.

Iam using WP Crontrol to see the all available cronjobs.

First I schedule an event (this seems to works):

function prfx_hourly_status_update_cron_job() {
    if ( ! wp_next_scheduled( 'prfx_run_hourly_status_update_cron_job' ) ) {
        wp_schedule_event( current_time( 'timestamp' ), 'hourly', 'prfx_run_hourly_status_update_cron_job' );
    }
}
add_action( 'wp', 'prfx_hourly_status_update_cron_job' );

After creating this event I than try to run this function.

I get all posts which have a meta field where the value is not empty.
This field is an date. (Y-m-d)
For each post/product I than get two meta values.
The deadline-date and a sooner deadline-soon-date.
I than compare the todays date with these saved dates and want to update another meta value based on this.

function prfx_run_hourly_status_update_cron_job( ) {

    // create meta query to get all posts which have a deadline date (field not empty)
    $args = array(
        'posts_per_page'   => -1,
        'meta_query' => array(
            array(
                'key' => '_prfx_custom_product_deadline',
                'value'   => '',
                'compare' => '!='
            ),
        ),
        'post_type' => 'product',
        'no_found_rows' => true, //speeds up a query significantly and can be set to 'true' if we don't use pagination
        'fields' => 'ids', //again, for performance
    );
    $posts_array = get_posts( $args );

    // start if we have posts
    if ($posts_array) {

        // get todays date in Y-m-d format
        $today = date('Y-m-d');

        //now check conditions and update the code
        foreach( $posts_array as $post_id ){

            $saved_deadline = get_post_meta( $post_id, '_prfx_custom_product_deadline', true ); // get deadline-date
            $soon_deadline = get_post_meta( $post_id, '_prfx_custom_product_deadline_soon', true );// get deadline-soon-date

            if ($today > $saved_deadline) { // if today is after deadline
                update_post_meta( $post_id, '_prfx_custom_product_status', 'deadline-met' );
            } elseif ($today < $saved_deadline && $today > $soon_deadline) { // if today is before deadline but after soon-deadline
                update_post_meta( $post_id, '_prfx_custom_product_status', 'deadline-soon' );
            }

        }
    }
}

As said above I tried to dry run this function, instead of update_post_meta I just printed the data out. This seems to work. Iam also using a similar function to echo out some strings on the frontend, so the date compare also works.


Update: So, I cant get this to work with the cronjobs. I just tested the following code inside an plugin, as I activate the plugin, the code runs. The query is working fine, I printed/checked the results, and it is working as simple plugin code.

But the same code is not running in the cronjob. When I look at the cron output with Wp Crontrol, I can see the hourly event "prfx_run_hourly_status_update_cron_job", but without any action assigned. However, for example "woocommerce_geoip_updater" has also no action listed.
Maybe someone has an idea why?

Here is the tested code:

add_action('init','prfx_resave_posts');
function prfx_resave_posts(){

    $args = array(
        'posts_per_page'   => -1,
        'post_type'        => 'product',
        'meta_query' => array(
            array(
                'key' => '_prfx_custom_product_deadline_soon',
                'value'   => '',
                'compare' => '!='
            ),
        ),
        'no_found_rows' => true, //speeds up a query significantly and can be set to 'true' if we don't use pagination
        'fields' => 'ids', //again, for performance
    );
    $posts_array = get_posts( $args );

    if ($posts_array) { //output: Array ( [0] => 120399 [1] => 120431 [2] => 120469 [3] => 120401 [4] => 120433 )

        // get todays date in Y-m-d format
        $today = date('Y-m-d');

        foreach ($posts_array as $my_post) {

            #print_r($my_post);
            //output example: 120399

            $saved_soon_deadline = get_post_meta( $my_post, '_prfx_custom_product_deadline_soon', true );

            #print_r($saved_soon_deadline);
            //output: 2018-11-30

            if ($today > $saved_soon_deadline) {
                update_post_meta( $my_post, '_prfx_custom_product_status', 'my-new-val-here' );
            }

        }
    }

}
2
  • If you get the return value of the calls to update_post_meta and log them what do you see? E.g. you could do something like $return = update_post_meta(...); var_dump( $return ); or use error_log(var_export( $return, 1 ) ); to see it in the debug.log if you have that enabled.
    – phatskat
    Commented Oct 19, 2018 at 13:47
  • Thanks for your input, I tried to return the output via error_log, but no new logs in the debug.log
    – LWS-Mo
    Commented Oct 19, 2018 at 14:12

2 Answers 2

0

What your are doing is that you are looping over an array of post objects.

The get_posts() function returns objects, not ID's.

So what you will have to do is either use

$post_id->ID

or

setup_postdata( $post_id ) and then use get_the_ID().

Might wanna rename $post_id to $post_object to avoid confusion.

5
  • Ah, interesting. I just quickly tried to use $post_object->ID (renamed $post_id before), but this was not working. In the get_posts args I have set 'fields' => 'ids' to only get the ids. Maybe this does something here?!
    – LWS-Mo
    Commented Oct 19, 2018 at 14:16
  • I just removed 'fields' => 'ids' and also 'no_found_rows' from the args to see if something changes, but no, still not working.
    – LWS-Mo
    Commented Oct 19, 2018 at 14:36
  • maybe do a var_dump on $posts_array? I don't directly see what's wrong, $post_object->ID should be working
    – Pim
    Commented Oct 19, 2018 at 14:55
  • Do the classical debugging steps, echo the post ID to see if it's being returned properly, then you can isolate the error.
    – Pim
    Commented Oct 19, 2018 at 14:57
  • Yes, I was debugging more today. Just now I set up a separate plugin for this cronjob, and it works. So I think maybe there was something wrong with creating the events, because the get_posts code I use is the same as before.
    – LWS-Mo
    Commented Oct 22, 2018 at 13:01
0

I dont know exactly what happened here, but I found a solution.
The code I posted in the initial question, was sitting inside an plugin with several other functions and code.
Just now, I created a separate plugin only for the hourly cronjob I would like to use.
On plugin activation I add the new cronjob, and on deactivation the job gets deleted.
But regardless, the code to update the post meta is still the same as I posted. So I have no idea why it is working in a separate plugin file. Maybe there was something wrong in setting up the events?

register_activation_hook( __FILE__, 'prfx_add_cronjob_on_activation' );
function prfx_add_cronjob_on_activation() {
    wp_schedule_event( time(), 'hourly', 'prfx_update_status_job' );
}

register_deactivation_hook( __FILE__, 'prfx_delete_cronjob_on_deactivation' );
function prfx_delete_cronjob_on_deactivation() {
    wp_clear_scheduled_hook( 'prfx_update_status_job' );
}

add_action( 'prfx_update_status_job', 'prfx_update_status_code' );
function prfx_update_status_code(){

    $args = array(
        'posts_per_page'   => -1,
        'post_type'        => 'product',
        'meta_query' => array(
            array(
                'key' => '_prfx_custom_product_deadline',
                'value'   => '',
                'compare' => '!='
            ),
        ),
        'no_found_rows' => true, //speeds up a query significantly and can be set to 'true' if we don't use pagination
        'fields' => 'ids', //again, for performance
    );
    $posts_array = get_posts( $args );

    if ($posts_array) {

        // get todays date in Y-m-d format
        $today = date('Y-m-d');

        foreach ($posts_array as $single) {

            $saved_deadline = get_post_meta( $single, '_prfx_custom_product_deadline', true );
            $soon_deadline = get_post_meta( $single, '_prfx_custom_product_deadline_soon', true );

            if ($today > $saved_deadline) {
                update_post_meta( $single, '_prfx_custom_product_status', 'deadline-met' );
            } else {
                if ($soon_deadline && $today > $soon_deadline) {
                    update_post_meta( $single, '_prfx_custom_product_status', 'deadline-soon' );
                }
            }
        }
    }
}

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.