I’m writing a plugin that uses WordPress Cron.
Here the code I am using to add and remove the cron event. On plugin activation it creates the cron event, and on plugin de-activation it removes the event:
//On plugin activation schedule the cron event
register_activation_hook( __FILE__, 'bg_create_pods_midnight_cron' );
function bg_create_pods_midnight_cron(){
//Use wp_next_scheduled to check if the event is already scheduled
$timestamp = wp_next_scheduled( 'bg_pods_midnight_cron' );
//If $timestamp == false schedule event since it hasn't been done previously
if( $timestamp == false ){
//Schedule the event for today at midnight, then to repeat daily using the hook 'bg_pods_midnight_cron'
wp_schedule_event( strtotime('today midnight'), 'daily', 'bg_pods_midnight_cron' );
}
}
//On plugin de-activation de-schedule the cron event
register_deactivation_hook( __FILE__, 'bg_remove_pods_midnight_cron' );
function bg_remove_pods_midnight_cron(){
wp_clear_scheduled_hook( 'bg_pods_midnight_cron' );
}
I then created a function that hooks into the cron event I just created. The function is supposed to update some custom fields.
It works fine when hooked into a post save hook, but it doesn’t do anything (custom fields are not updated) when it’s hooked into my bg_pods_midnight_cron
which I created above.
add_action( 'bg_pods_midnight_cron', 'bg_update_country_speed_averages');
function bg_update_country_speed_averages() {
$vpn_args = array(
'posts_per_page' => -1,
'post_type' => 'vpn',
);
$vpns = get_posts( $vpn_args );
foreach ($vpns as $vpn) {
$vpn_id = $vpn->ID;
// Country IDs and the starting string of their matching "avg" meta key on VPN posts
$country_keys = array(
292 => 'avg_australia',
529 => 'avg_united_states',
357 => 'avg_france',
443 => 'avg_new_zealand',
326 => 'avg_china',
517 => 'avg_turkey',
393 => 'avg_japan',
528 => 'avg_united_kingdom',
439 => 'avg_netherlands',
319 => 'avg_canada',
);
foreach ($country_keys as $country_id => $meta_key_start) {
$speed_args = array(
'posts_per_page' => 30,
'post_type' => 'speed_test',
'meta_query' => array(
array(
'key' => 'vpn',
'value' => $vpn_id,
),
array(
'key' => 'server_country',
'value' => $country_id,
),
)
);
$speed_tests = get_posts( $speed_args );
$download_meta_key = $meta_key_start . "_download_speed_30_days_input";
$upload_meta_key = $meta_key_start . "_upload_speed_30_days_input";
$latency_meta_key = $meta_key_start . "_latency_30_days_input";
if (!empty($speed_tests)) {
// Get all the comparions
$download_speed_array = array();
$upload_speed_array = array();
$latency_array = array();
foreach ($speed_tests as $speed_test) {
if (!empty(get_post_meta( $speed_test->ID, 'download_speed_comparison', true ))) {
$download_speed_array[] = get_post_meta( $speed_test->ID, 'download_speed_comparison', true );
}
if (!empty(get_post_meta( $speed_test->ID, 'upload_speed_comparison', true ))) {
$upload_speed_array[] = get_post_meta( $speed_test->ID, 'upload_speed_comparison', true );
}
if (!empty(get_post_meta( $speed_test->ID, 'latency_comparison', true ))) {
$latency_array[] = get_post_meta( $speed_test->ID, 'latency_comparison', true );
}
}
// Calculate an average
if ( !empty($download_speed_array) ) {
$download_speed_avg_last_30_days = array_sum($download_speed_array) / count($download_speed_array);
}
if ( !empty($upload_speed_array) ) {
$upload_speed_avg_last_30_days = array_sum($upload_speed_array) / count($upload_speed_array);
}
if ( !empty($latency_array) ) {
$latency_avg_last_30_days = array_sum($latency_array) / count($latency_array);
}
// Update the vpn custom field with the country average speed
if (metadata_exists( 'post', $vpn_id, $download_meta_key)) {
update_post_meta( $vpn_id, $download_meta_key, $download_speed_avg_last_30_days);
}
if (metadata_exists( 'post', $vpn_id, $upload_meta_key)) {
update_post_meta( $vpn_id, $upload_meta_key, $upload_speed_avg_last_30_days);
}
if (metadata_exists( 'post', $vpn_id, $latency_meta_key)) {
update_post_meta( $vpn_id, $latency_meta_key, $latency_avg_last_30_days);
}
} else {
// Update the vpn custom field with 0
if (metadata_exists( 'post', $vpn_id, $download_meta_key)) {
update_post_meta( $vpn_id, $download_meta_key, 0);
}
if (metadata_exists( 'post', $vpn_id, $upload_meta_key)) {
update_post_meta( $vpn_id, $upload_meta_key, 0);
}
if (metadata_exists( 'post', $vpn_id, $latency_meta_key)) {
update_post_meta( $vpn_id, $latency_meta_key, 0);
}
}
}
}
}
I know that WordPress Cron only fires when someone visits your website, so that is why I installed WP Control to run the cron on demand for debugging. You can see a screenshot of WP Control below.
The cron hook is registered correctly. And my function is hooked into that correctly. But when I click the “run now” button the custom fields are not updating.
I can’t figure out why it works when hooked into the post save, but does not work when hooked into my custom cron.