I'm trying to create a cron job that will compare a date set as product metadata to the current date, then update the product stock if the date set as product metadata has passed.
Here's what I have so far, but it doesn't work:
// Custom CRON Function
function update_pre_order_stock_status($post_id){
$current_date = date( 'YYYY-mm-dd' );
$expiryDate = $product->get_meta('woo_expiry_date');
$woo_expiry_action = $product->get_meta('woo_expiry_action');
$product_category = array( 'comic-book-pre-orders', 'dc-comics-pre-orders', 'image-comics-pre-orders', 'manga-pre-orders', 'marvel-comics-pre-orders', 'other-publisher-pre-orders');
if(( is_product_category( $product_category )) && ( $expiryDate <= $current_date ) && ( $woo_expiry_action == 'out' )) {
// 1. Updating the stock quantity
update_post_meta( $post_id, '_stock', 0);
// 2. Updating the stock quantity
update_post_meta( $post_id, '_stock_status', wc_clean( 'outofstock' ) );
// 3. Updating post term relationship
wp_set_post_terms( $post_id, 'outofstock', 'product_visibility', true );
}
}
if ( ! wp_next_scheduled( 'my_pre_order_stock_update' ) ) {
wp_schedule_event( time(), 'hourly', 'my_pre_order_stock_update' );
}
add_action( 'my_pre_order_stock_update', 'update_pre_order_stock_status' );
The Cron event 'my_pre_order_stock_update' shows up in the cron list, but running it isn't doing anything.
Any recommendations would be very much appreciated!
There are many mistakes in your code:
$post_id
is not defined as you are not passing any post ID argument to wp_next_scheduled
and wp_schedule_event
functions.$product
is not defined either (and can't be defined actually).I assume that you are trying to update some specific products based on:
woo_expiry_date
woo_expiry_action
So you need to get those products IDs via a WP_Query
which will be the simplest way.
Now as WooCommerce is migrating to custom tables since version 3, and as some product data is cached, you should not use WordPress post meta functions anymore.
Try the following instead (untested):
// Custom Cron hooked Function called by wp_schedule_event
add_action( 'jape_pre_order_stock_update', 'update_pre_order_stock_status' );
function update_pre_order_stock_status(){
// Get all related product IDs to update via a WP_Query
$products_ids = get_posts( [
'post_type' => 'product',
'post_status' => 'publish',
'numberposts' => -1, // <= the number of products to process (-1 is all)
'fields' => 'ids',
'tax_query' => array( array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array(
'comic-book-pre-orders',
'dc-comics-pre-orders',
'image-comics-pre-orders',
'manga-pre-orders',
'marvel-comics-pre-orders',
'other-publisher-pre-orders',
),
) ),
'meta_query' => array(
'relation' => 'AND',
array(
'key' => '_stock_status',
'value' => 'instock',
'compare' => '=',
),
array(
'key' => 'woo_expiry_date',
'value' => date_i18n('Y-m-d'),
'compare' => '<=',
'type' => 'DATE',
),
array(
'key' => 'woo_expiry_action',
'value' => 'out',
'compare' => '=',
),
),
] );
foreach( $products_ids as $product_id ) {
$product = wc_get_product($product_id);
$product->set_stock_quantity(0); // Set stock quantity
$product->set_stock_status('outofstock'); // Set stock status
$product->save(); // Save updated product data
}
}
// Cron schedule event function
function cron_starter_hourly_products_update() {
if ( ! wp_next_scheduled( 'jape_pre_order_stock_update' ) ) {
wp_schedule_event( time(), 'hourly', 'jape_pre_order_stock_update' );
}
}
cron_starter_hourly_products_update(); // Initiate cron schedule event
Code goes in functions.php file of your child theme (or in a plugin). It could work.
Caution: The number of product to process should be fine-tuned in 'numberposts'
argument, as if there are too many products to process, it may crash the scheduled event or even the website.
Related: