I have created a plugin that adds products programatically to WooCommerce. The plugin is working great, but now I need to make a cron job that runs every 5 minutes to update the inventory.
I have the script all written but I need to include calls to get_option() in this php file to get certain plugin values that the user has entered. However, I can't just include get_option()
in this file because it is outside of the Wordpress core. So my thought would be to put in require( 'path/to/wp-load.php' );
which I know you aren't really supposed to do. Anyway it fixes the issue if you hit the page via a web browser request. However the cron job fails the moment that this file is included because somewhere with wp-load.php it is sending HTTP_Header requests.
Any thoughts or solutions? I tried to add define('WP_USE_THEMES', false);
right above the requiring of wp-load.php but it is still causing the cron job to fail.
Long winded I know, but how do you include get_option()
requests inside of a external PHP script that will be accessed via a PHP cron job.
Thanks much.
WordPress supports many versions of PHP, some even obsolete, we recommend running PHP version 7.4 or higher: PHP 7.4. PHP 8.0*
To find the right file, navigate to wp-content/themes/[the name of your theme]. When you open this folder, you'll see the functions. php file. All you have to do now is to edit it using your preferred text editing software.
The problem is probably that you try to include wp-load.php from a wrong path. In a CLI environment, the path would not be the same as when you do an HTTP request to the file. So with this you should fixed your issue:
require(dirname(__FILE__) . '/../../../wp-config.php');
Based on cale_b comments and this article he linked, there is a much proper way to go by doing a Wordpress Cron job.
First in your plugin add a function that will contain the code needed to be executed, let's call it my_cron_job()
. You can eventually just include the script you already wrote in this function. Then add the following to schedule the execution of this every 5min:
// Define a new interval (5 minutes)
add_filter('cron_schedules', 'fively_interval');
function fively_interval($interval) {
$interval['fively'] = array('interval' => 5*60, 'display' => 'Once 5 minutes');
return $interval;
}
// Register the hook on plugin activation
register_activation_hook(__FILE__, 'my_cron_job_activation');
add_action('my_cron_event', 'my_cron_job');
function my_cron_job_activation() {
wp_schedule_event(time(), 'fively', 'my_cron_event');
}
// Unregister the hook on plugin deactivation
register_deactivation_hook( __FILE__, 'my_cron_job_deactivation' );
function my_cron_job_deactivation(){
wp_clear_scheduled_hook( 'my_cron_event' );
}
Then set up your cron to execute wp-cron.php every 5 minutes:
*/5 * * * * php-cli -f [path to your WP]/wp-cron.php
First when choosing the option of executing wp-cron.php with a server cron you should disable the default WP Cron behaviour (execution of cron through web visits):
define('DISABLE_WP_CRON', true);
Secondly, as for your question about WP Cron reliability I see a potential flaw indeed. I'm not 100% sure of that, but I think it is possible that wp_schedule_event
get desynchronized with the server cron, as the job get executed only if the interval is past. As it will be re-scheduled depending of the execution time of the script which is slightly different with the server cron time.
For example:
00:00:00:000 Server cron execute wp-cron.php
00:00:00:100 The job can be executed, so let it run
00:00:00:200 Wordpress finished to execute the job - it schedule the event in 5min
00:05:00:000 Server cron execute wp-cron.php
00:05:00:100 The job is planned for 00:05:00:200, no execution !
00:10:00:000 Server cron execute wp-cron.php
00:10:00:100 The job is executed
That's theory of course, maybe this is not accurate. I suggest doing some test and see how it behave. If it indeed behave like I think it did, I suggest as easy workaround to change the wp_schedule_event
to a lower interval - 4min for example.
add_filter('cron_schedules', 'fourly_interval');
function fourly_interval($interval) {
$interval['fourly'] = array('interval' => 4*60, 'display' => 'Once 4 minutes');
return $interval;
}
So we'll have the following:
00:00:00:000 Server cron execute wp-cron.php
00:00:00:100 The job can be executed, so let it run
00:00:00:200 Wordpress finished to execute the job - it schedule the event in 4min
00:05:00:000 Server cron execute wp-cron.php
00:05:00:100 The job is planned for 00:04:00:200, so let it run!
00:10:00:000 Server cron execute wp-cron.php
00:00:00:200 Wordpress finished to execute the job - it schedule the event in 4min
00:10:00:100 The job is executed (planned for 00:09:00:200)
With the default WP Cron behaviour disabled it should work flawlessly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With