From 97baa5b5e8703b9c918e70f4a5eca9b1bfdee080 Mon Sep 17 00:00:00 2001 From: Erick Hitter <git-contrib@ethitter.com> Date: Fri, 8 Sep 2017 14:58:17 -0700 Subject: [PATCH] CLI command to offload a CLI command --- includes/functions.php | 20 ++++++++++++----- includes/schedule.php | 38 ++++++++++++++++++++++++++++++++- wp-cli-cron-control-offload.php | 1 + 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/includes/functions.php b/includes/functions.php index 94c175b..68a96c0 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -1,13 +1,14 @@ <?php namespace Automattic\WP\WP_CLI_Cron_Control_Offload; +use WP_Error; /** * Create cron event for a given WP-CLI command * * @param string $command * @param int $timestamp Optional. - * @return bool|\WP_Error + * @return int|WP_Error */ function schedule_cli_command( $command, $timestamp = null ) { $command = validate_command( $command ); @@ -20,18 +21,26 @@ function schedule_cli_command( $command, $timestamp = null ) { $timestamp = strtotime( '+30 seconds' ); } + if ( $timestamp <= time() ) { + return new WP_Error( 'invalid-timestamp', __( 'Timestamp is in the past.', 'wp-cli-cron-control-offload' ) ); + } + $event_args = array( 'command' => $command, ); $scheduled = wp_schedule_single_event( $timestamp, ACTION, $event_args ); - return false !== $scheduled; + if ( false === $scheduled ) { + return new WP_Error( 'not-scheduled', __( 'Command may already be scheduled, or it was blocked via the `schedule_event` filter.', 'wp-cli-cron-control-offload' ) ); + } + + return $timestamp; } /** * Validate WP-CLI command to be scheduled * * @param string $command - * @return array|\WP_Error + * @return array|WP_Error */ function validate_command( $command ) { $command = trim( $command ); @@ -45,7 +54,7 @@ function validate_command( $command ) { $first_command = explode( ' ', $command ); $first_command = array_shift( $first_command ); if ( ! is_command_allowed( $first_command ) ) { - return new \WP_Error( sprintf( __( '%1$s: `%2$s` not allowed', 'wp-cli-cron-control-offload' ), MESSAGE_PREFIX, $first_command ) ); + return new WP_Error( 'blocked-command', sprintf( __( '`%1$s` not allowed', 'wp-cli-cron-control-offload' ), $first_command ) ); } // Don't worry about the user WP-CLI runs as @@ -57,7 +66,7 @@ function validate_command( $command ) { // Nothing to run if ( empty( $command ) ) { - return new \WP_Error( 'Invalid command provided' ); + return new WP_Error( 'invalid-command', 'Invalid command provided' ); } return $command; @@ -118,6 +127,7 @@ function get_command_whitelist() { function get_command_blacklist() { // TODO: constant! return array( + CLI_NAMESPACE, // Don't support scheduling loops 'cli', 'config', 'core', diff --git a/includes/schedule.php b/includes/schedule.php index de83129..18df07a 100644 --- a/includes/schedule.php +++ b/includes/schedule.php @@ -6,4 +6,40 @@ if ( ! defined( 'WP_CLI' ) || ! \WP_CLI ) { return false; } -// TODO: WP-CLI command to schedule an event +use WP_CLI; +use WP_CLI_Command; + +/** + * Offload WP-CLI commands to cron + */ +class CLI extends WP_CLI_Command { + /** + * Create an event to run a given WP-CLI command + * + * @subcommand create + * @synopsis --command=<command> [--timestamp=<timestamp>] + */ + public function create( $args, $assoc_args ) { + $command = WP_CLI\Utils\get_flag_value( $assoc_args, 'command', '' ); + $command = validate_command( $command ); + + if ( is_wp_error( $command ) ) { + WP_CLI::error( $command->get_error_message() ); + } + + $timestamp = WP_CLI\Utils\get_flag_value( $assoc_args, 'timestamp', null ); + if ( is_numeric( $timestamp ) ) { + $timestamp = absint( $timestamp ); + } + + $scheduled = schedule_cli_command( $command, $timestamp ); + + if ( is_wp_error( $scheduled ) ) { + WP_CLI::error( $scheduled->get_error_message() ); + } + + WP_CLI::success( __( 'Command scheduled!', 'wp-cli-cron-control-offload' ) ); + } +} + +WP_CLI::add_command( CLI_NAMESPACE, __NAMESPACE__ . '\CLI' ); diff --git a/wp-cli-cron-control-offload.php b/wp-cli-cron-control-offload.php index 40d30f9..9cdae62 100644 --- a/wp-cli-cron-control-offload.php +++ b/wp-cli-cron-control-offload.php @@ -15,6 +15,7 @@ namespace Automattic\WP\WP_CLI_Cron_Control_Offload; const ACTION = 'wp_cli_cron_control_offload'; +const CLI_NAMESPACE = 'cli-cron-offload'; const MESSAGE_PREFIX = 'WP-CLI via Cron'; require_once __DIR__ . '/includes/functions.php'; -- GitLab