-
-
Save Grezvany13/35384a7855d544c7fed7 to your computer and use it in GitHub Desktop.
WordPress Cron handler with multisite support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* WP Cron Multi | |
* | |
* A simple script which can be executed through the command line (or crontab) | |
* to run wp_cron for multisite (or not) without the use of wget, wp_remote or cURL. | |
* | |
* It has a 'copy' of wp-cron.php to run the transients. | |
* | |
* @author Johan de Jong <johan@notitia.nl> | |
* @version 1.0 | |
* @package WordPress | |
*/ | |
ignore_user_abort(true); | |
$opts = getopt('', [ | |
"url::", | |
"wp::", | |
"help" | |
]); | |
// display help settings | |
if (isset($opts['help']) || empty($opts)) { | |
echo "\n"; | |
echo "\033[0;33mUsage:\033[0m\n"; | |
echo " php wp-cron-multi.php <options>\n"; | |
echo "\n"; | |
echo "\033[0;33mOptions:\033[0m\n"; | |
echo " \033[0;32m--help\033[0m This help\n"; | |
echo " \033[0;32m--url=<base_url>\033[0m Network domain\n"; | |
echo " The base URL is required to run the cronjob.\n"; | |
echo " It MUST match the domain of the website, or\n"; | |
echo " the network domain of a multisite.\n"; | |
echo " \033[0;32m--wp=<wp_path>\033[0m Path to WP directory\n"; | |
echo " If the location of wp-load.php is different\n"; | |
echo " from the current location, set the relative\n"; | |
echo " path with a trailing slash.\n"; | |
echo "\n"; | |
exit; | |
} | |
// set URL argument | |
// useful if wp-config.php uses $_SERVER['HTTP_HOST'] | |
// required for sunrise.php by wordpress-mu-domain-mapping plugin | |
if (isset($opts['url']) && !empty($opts['url'])) { | |
$_SERVER['HTTP_HOST'] = trim($opts['url']); | |
} else { | |
echo "\033[0;31mERROR:\033[0m This script requires the --url argument\n"; | |
echo " Please check --help for more information\n"; | |
exit; | |
} | |
/** | |
* Tell WordPress we are doing the CRON task. | |
* | |
* @var bool | |
*/ | |
define('DOING_CRON', true); | |
if (!defined('ABSPATH')) { | |
$wp_loaded = false; | |
/** | |
* if the --wp argument is set, try to load wp-load.php through this path | |
*/ | |
if (isset($opts['wp']) && !empty($opts['wp'])) { | |
$path = dirname(__FILE__).DIRECTORY_SEPARATOR.$opts['wp']; | |
if (false !== $path && file_exists($path . '/wp-load.php')) { | |
require_once($path . '/wp-load.php'); | |
$wp_loaded = true; | |
} | |
} | |
if (!$wp_loaded) { | |
if (file_exists(dirname(__FILE__) . '/wp-load.php')) { | |
require_once(dirname(__FILE__) . '/wp-load.php'); | |
} else { | |
echo "\033[0;31mERROR:\033[0m Can't find wp-load.php\n"; | |
echo " Please check --help for more information\n"; | |
exit; | |
} | |
} | |
} | |
// check if multisite | |
if (defined('MULTISITE') && true === MULTISITE) { | |
global $wpdb; | |
$blogs = $wpdb->get_results($wpdb->prepare("SELECT blog_id FROM $wpdb->blogs WHERE archived='%d' AND deleted ='%d' LIMIT 0,300", 0, 0)); | |
foreach ($blogs as $blog) { | |
switch_to_blog($blog->blog_id); | |
run_cron(); | |
} | |
} else { | |
run_cron(); | |
} | |
/** | |
* The actual code to run WP-Cron (code from wp-cron.php) | |
*/ | |
function run_cron() | |
{ | |
if (false === $crons = _get_cron_array()) { | |
die(); | |
} | |
$keys = array_keys($crons); | |
$gmt_time = microtime(true); | |
if (isset($keys[0]) && $keys[0] > $gmt_time) { | |
die(); | |
} | |
// The cron lock: a unix timestamp from when the cron was spawned. | |
$doing_cron_transient = get_transient('doing_cron'); | |
// Use global $doing_wp_cron lock otherwise use the GET lock. If no lock, trying grabbing a new lock. | |
if (empty($doing_wp_cron)) { | |
if (empty($_GET['doing_wp_cron'])) { | |
// Called from external script/job. Try setting a lock. | |
if ($doing_cron_transient && ($doing_cron_transient + WP_CRON_LOCK_TIMEOUT > $gmt_time)) { | |
return; | |
} | |
$doing_cron_transient = $doing_wp_cron = sprintf('%.22F', microtime(true)); | |
set_transient('doing_cron', $doing_wp_cron); | |
} else { | |
$doing_wp_cron = $_GET['doing_wp_cron']; | |
} | |
} | |
/* | |
* The cron lock (a unix timestamp set when the cron was spawned), | |
* must match $doing_wp_cron (the "key"). | |
*/ | |
if ($doing_cron_transient != $doing_wp_cron) { | |
return; | |
} | |
foreach ($crons as $timestamp => $cronhooks) { | |
if ($timestamp > $gmt_time) { | |
break; | |
} | |
foreach ($cronhooks as $hook => $keys) { | |
foreach ($keys as $k => $v) { | |
$schedule = $v['schedule']; | |
if ($schedule != false) { | |
$new_args = array($timestamp, $schedule, $hook, $v['args']); | |
call_user_func_array('wp_reschedule_event', $new_args); | |
} | |
wp_unschedule_event($timestamp, $hook, $v['args']); | |
/** | |
* Fires scheduled events. | |
* | |
* @ignore | |
* @since 2.1.0 | |
* | |
* @param string $hook Name of the hook that was scheduled to be fired. | |
* @param array $args The arguments to be passed to the hook. | |
*/ | |
do_action_ref_array($hook, $v['args']); | |
// If the hook ran too long and another cron process stole the lock, quit. | |
if (_get_cron_lock() != $doing_wp_cron) { | |
return; | |
} | |
} | |
} | |
} | |
if (_get_cron_lock() == $doing_wp_cron) { | |
delete_transient('doing_cron'); | |
} | |
} | |
/** | |
* Retrieves the cron lock. | |
* | |
* Returns the uncached `doing_cron` transient. | |
* | |
* @ignore | |
* @since 3.3.0 | |
* | |
* @return string|false Value of the `doing_cron` transient, 0|false otherwise. | |
*/ | |
function _get_cron_lock() | |
{ | |
global $wpdb; | |
$value = 0; | |
if (wp_using_ext_object_cache()) { | |
/* | |
* Skip local cache and force re-fetch of doing_cron transient | |
* in case another process updated the cache. | |
*/ | |
$value = wp_cache_get('doing_cron', 'transient', true); | |
} else { | |
$row = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", '_transient_doing_cron')); | |
if (is_object($row)) { | |
$value = $row->option_value; | |
} | |
} | |
return $value; | |
} | |
die(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment