From 62b3b880c14267708cc8b018c5e8f4926e868766 Mon Sep 17 00:00:00 2001 From: ale <ale@incal.net> Date: Thu, 24 Nov 2022 22:16:31 +0000 Subject: [PATCH] Handle unsafe (plugin) cron events by spawning wp-cli --- lib/cron.php | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/cron.php b/lib/cron.php index 5981b79..55630ee 100644 --- a/lib/cron.php +++ b/lib/cron.php @@ -1,12 +1,34 @@ <?php +function is_hook_safe($hook) { + if (strlen($hook) > 2 && substr($hook, 0, 3) == "wp_") { + return true; + } + if ($hook == "delete_expired_transients") { + return true; + } + return false; +} + // Run cron jobs for the current blog. -// (Use switch_to_blog() before calling this). +// (Use switch_to_blog() before calling this). +// +// We can deal with core Wordpress events inline, but not with events +// associated with plugins, as they aren't properly loaded when +// switch_to_blog() is called. So we detect when "unsafe" events +// should be scheduled, and only for those blogs we spawn a wp-cli +// process (much slower) to run them in the specific context of the +// blog. function noblogs_run_cron_for_current_blog() { $crons = wp_get_ready_cron_jobs(); + $has_unsafe_hooks = false; foreach ($crons as $timestamp => $cronhooks) { foreach ($cronhooks as $hook => $keys) { + if (!is_hook_safe($hook)) { + $has_unsafe_hooks = true; + continue; + } foreach ($keys as $k => $v) { echo " {$k} -> {$hook}()\n"; $schedule = $v['schedule']; @@ -28,4 +50,10 @@ function noblogs_run_cron_for_current_blog() { } } } + + if ($has_unsafe_hooks) { + $domain = get_option('domain'); + echo " executing wp-cli for unsafe hooks ({$domain})"; + system("wp cron event run --due-now --url={$domain}"); + } } -- GitLab