Last active
March 16, 2023 19:00
-
-
Save kasparsd/10b9a8b1217b26992a30 to your computer and use it in GitHub Desktop.
Cron for WordPress Multisite
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 | |
// Author: Kaspars Dambis <hi@kaspars.net> | |
// Usage: php ms-cron-runner.php --domain=example.com [--path=/path/to/wordpress] | |
// We can't run this reliably from CLI because of how WordPress | |
// relies on $_SERVER for loading functions.php | |
if ( php_sapi_name() !== 'cli' ) | |
die; | |
define( 'WP_USE_THEMES', false ); | |
$_SERVER = array(); | |
$opts = getopt( null, array( | |
'domain::', | |
'path:', | |
) ); | |
// WordPress uses the domain name to resolve DB settings, etc. | |
if ( isset( $opts['domain'] ) ) | |
$_SERVER['HTTP_HOST'] = $opts['domain']; | |
else | |
die( 'Please specify the --domain option.' . PHP_EOL ); | |
// Resolve WordPress core | |
if ( isset( $opts['path'] ) ) | |
$path = $opts['path'] . '/wp-load.php'; | |
else | |
$path = dirname( __FILE__ ) . '/wp-load.php'; | |
if ( ! file_exists( $path ) || ! is_file( $path ) ) | |
die( sprintf( 'Can not find %s.' . PHP_EOL, $path ) ); | |
// Load WordPress core | |
require_once( $path ); | |
if ( ! defined( 'ABSPATH' ) ) | |
die( sprintf( 'Can not find WordPress at %s.' . PHP_EOL, $path ) ); | |
$sites = get_sites( array( | |
'deleted' => 0, | |
'archived' => 0, | |
) ); | |
foreach ( $sites as $site ) { | |
$site_url = get_site_url( $site->blog_id, 'wp-cron.php' ); | |
$run = wp_remote_get( | |
$site_url, | |
array( | |
'blocking' => true, | |
'sslverify' => false, | |
) | |
); | |
if ( is_wp_error( $run ) ) | |
printf( 'Failed WordPress cron for %s.' . PHP_EOL, $site_url ); | |
else | |
printf( 'Completed WordPress cron for %s.' . PHP_EOL, $site_url ); | |
} | |
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 | |
// Author: Kaspars Dambis <hi@kaspars.net> | |
if ( php_sapi_name() == 'cli' ) | |
die( 'WordPress cron does not support CLI.' . PHP_EOL ); | |
ignore_user_abort(true); | |
define( 'DOING_CRON', true ); | |
define( 'WP_USE_THEMES', false ); | |
$stats = array(); | |
// Location of WordPress core | |
$path = realpath( './wp-load.php' ); | |
if ( ! file_exists( $path ) || ! is_file( $path ) ) | |
die( sprintf( 'Can not find %s.' . PHP_EOL, $path ) ); | |
// Load WordPress core | |
require_once( $path ); | |
// Ensure that WordPress core was loaded | |
if ( ! defined( 'ABSPATH' ) ) | |
die( sprintf( 'Can not find WordPress at %s.' . PHP_EOL, $path ) ); | |
printf( 'Running cron jobs on %s.' . PHP_EOL, site_url() ); | |
// Check if there is a cron job in progress | |
$lock = get_transient('doing_cron'); | |
if ( $lock ) { | |
printf( 'Another cron job is already running for %d seconds on %s.' . PHP_EOL, ( time() - $lock ), site_url() ); | |
continue; | |
} | |
// Get all cron tasks from the 'cron' option | |
$crons = _get_cron_array(); | |
$time = time(); | |
// Lock this cron job | |
$lock = sprintf( '%.22F', microtime( true ) ); | |
set_transient( 'doing_cron', $lock ); | |
foreach ( $crons as $timestamp => $hooks ) { | |
// Skip tasks in future | |
if ( $timestamp > $time ) | |
continue; | |
foreach ( $hooks as $hook => $events ) { | |
foreach ( $events as $id => $event ) { | |
// This is a reapeating event, register another one in future | |
if ( $event['schedule'] ) { | |
wp_reschedule_event( $timestamp, $event['schedule'], $hook, $event['args'] ); | |
} | |
// Remove this current job | |
wp_unschedule_event( $timestamp, $hook, $event['args'] ); | |
printf( 'Running "%s" cron job on %s.' . PHP_EOL, $hook, site_url() ); | |
// Run the cron hook | |
do_action_ref_array( $hook, $event['args'] ); | |
$stats[] = $hook; | |
// Ensure that cron lock is still the same | |
if ( get_transient('doing_cron') !== $lock ) { | |
printf( 'Another process stole the cron lock on %s.' . PHP_EOL, site_url() ); | |
die; | |
} | |
} | |
} | |
} | |
// Remove the lock | |
delete_transient( 'doing_cron' ); | |
print_r($stats); |
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 | |
// Author: Kaspars Dambis <hi@kaspars.net> | |
// Usage: php wp-cron-cli.php --domain=example.com [--path=/path/to/wordpress] | |
if ( php_sapi_name() !== 'cli' ) | |
die; | |
$_SERVER = array_merge( | |
$_SERVER, | |
array( | |
'SERVER_PROTOCOL' => 'HTTP/1.0', | |
'REQUEST_METHOD' => 'GET', | |
'REMOTE_ADDR' => '127.0.0.1', | |
) | |
); | |
$opts = getopt( null, array( | |
'domain::', | |
'path:', | |
) ); | |
// WordPress uses the domain name to resolve DB settings, etc. | |
if ( isset( $opts['domain'] ) ) | |
$_SERVER['HTTP_HOST'] = $opts['domain']; | |
else | |
die( 'Please specify the --domain option.' . PHP_EOL ); | |
// Resolve WordPress cron | |
if ( isset( $opts['path'] ) ) | |
$path = $opts['path'] . '/wp-cron.php'; | |
else | |
$path = dirname( __FILE__ ) . '/wp-cron.php'; | |
if ( ! file_exists( $path ) || ! is_file( $path ) ) | |
die( sprintf( 'Can not find %s.' . PHP_EOL, $path ) ); | |
// Run WordPress cron | |
require_once( $path ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment