Issue
I am trying to set up a scheduled cron event through cPanel that will trigger a PHP function in a specific PHP script file on a Wordpress site. For the sake of testing, I want the function to run every minute so it checks the database for new orders within a table with a specific status. If the rows exist, then use another method (Woocommerce) to update the order status to "completed".
The cron job is running without issue but the result--which is to update the status--is not working.
When triggered and tested with shortcode and var_dump(), the called function getPend() works fine and produces the desired change in status to all results without error. However, when run through the cPanel cron scheduler, I get this error:
PHP Fatal error: Uncaught Exception: Invalid order. in /home/path_to/public_html/site_folder/wp-content/plugins/woocommerce/includes/data-stores/abstract-wc-order-data-store-cpt.php:104
This is the cron line I have (which runs without error but does not produce the result):
* * * * * /usr/local/bin/php /home/path_to/public_html/site_folder/wp-content/themes/theme-child/pending.php >/dev/null 2>&1
So the cron runs without error and the getPend() function runs without error when I test both of these independently, but when I try to combine them, I get the aforementioned invalid order error.
Here is my script (pending.php):
<?php
getPend(); //call function
function getPend() {
global $wpdb;
$getPending = $wpdb->get_results( " SELECT order_id,status
FROM wp_wc_order_stats
WHERE status = 'wc-processing'"
);
if (!empty($getPending)) {
$pending_group = array();
foreach ($getPending as $pkey => $pitem) {
$pending_meta = get_object_vars($pitem);
foreach ($pending_meta as $meta_in => $pendingdetails) {
$pending_group[$pitem->order_id]['oid'] = $pending_meta['order_id'];
$pending_group[$pitem->order_id]['stat'] = $pending_meta['status'];
}
}
$o_id = '';
$o_stat = '';
foreach($pending_group as $pend) {
$o_id .= $pend['oid'];
$o_stat .= $pend['stat'];
$order = new WC_Order($o_id);
if (!empty($order)) {
$order->update_status( 'completed' );
}
}
//var_dump($pending_group); //used with shortcode for testing
}
}
//add_shortcode('order-pending','getPend'); //used with var_dump() for testing
//$triedthisdidntwork = getPend();
//return $triedthisdidntwork;
?>
Ultimately, I need the getPend() script to run on a schedule so order statuses can be updated based on whether they exist in the wp_wc_order_stats table. I thought a cron set up through cPanel would be the best way to go about it. But could this issue be solved by setting it up to run as a wordpress scheduled event instead? If so, how could that be done? There is no hook I could use to implicitly trigger the function; it needs to be triggered explicitly...if that makes sense.
Solution
Okay...I ended up solving this using the Wordpress scheduler as follows:
- Setup a cron schedule on the server to run the WP_Cron every five minutes.
*/5 * * * * /usr/local/bin/php /home/path_to/public_html/site_folder/wp-cron.php >/dev/null 2>&1
- Add custom schedule to functions.php for Wordpress Cron:
$schedules['every_five_minutes'] = array(
'interval' => 5 * MINUTE_IN_SECONDS,
'display' => __('Every 5 Minutes')
);
return $schedules;
}
add_filter( 'cron_schedules', 'addfive_cron_schedule' );
- Renamed getPend() to pendord_getPend() and created a custom hook in Wordpress functions.php:
add_action( 'pendord_cronhook', 'pendord_getPend' );
if (!wp_next_scheduled('pendord_cronhook')) {
wp_schedule_event(time(), 'every_five_minutes', 'pendord_cronhook');
}
WP_Cron will run the pendord_getPend function every five minutes, and the server cron scheduler will run WP_Cron every five minutes.
Answered By - Shay Answer Checked By - David Goodson (WPSolving Volunteer)