From f5eeb244aadcb79817f7bc498f1366f0aa2ad859 Mon Sep 17 00:00:00 2001 From: Bram Driesen Date: Thu, 21 Aug 2025 19:18:30 +0200 Subject: [PATCH 1/7] feat: Add WP CLI logic --- wp-batch-processing.php | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/wp-batch-processing.php b/wp-batch-processing.php index d96d188..48b446e 100644 --- a/wp-batch-processing.php +++ b/wp-batch-processing.php @@ -14,6 +14,22 @@ die; } +require_once 'includes/class-bp-helper.php'; +require_once 'includes/class-bp-singleton.php'; +require_once 'includes/class-batch-item.php'; +require_once 'includes/class-batch.php'; +require_once 'includes/class-batch-processor.php'; +require_once 'includes/class-batch-ajax-handler.php'; +require_once 'includes/class-batch-list-table.php'; +require_once 'includes/class-batch-processor-admin.php'; + +if ( defined( 'WP_CLI' ) && WP_CLI ) { + require_once 'includes/class-wp-cli.php'; + + $wp_cli_command = new Batch_Processor_CLI_Command(); + WP_CLI::add_command( 'batch_process', $wp_cli_command ); +} + if ( ! is_admin() ) { return; } @@ -26,15 +42,6 @@ define( 'WP_BP_URL', plugin_dir_url( __FILE__ ) ); } -require_once 'includes/class-bp-helper.php'; -require_once 'includes/class-bp-singleton.php'; -require_once 'includes/class-batch-item.php'; -require_once 'includes/class-batch.php'; -require_once 'includes/class-batch-processor.php'; -require_once 'includes/class-batch-ajax-handler.php'; -require_once 'includes/class-batch-list-table.php'; -require_once 'includes/class-batch-processor-admin.php'; - WP_Batch_Processor::boot(); // Examples From 8147a9f15b08330a3166d109e82302a7e7e4670c Mon Sep 17 00:00:00 2001 From: Bram Driesen Date: Thu, 21 Aug 2025 19:20:19 +0200 Subject: [PATCH 2/7] feat: Added CLI command --- includes/class-wp-cli.php | 55 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 includes/class-wp-cli.php diff --git a/includes/class-wp-cli.php b/includes/class-wp-cli.php new file mode 100644 index 0000000..56cd846 --- /dev/null +++ b/includes/class-wp-cli.php @@ -0,0 +1,55 @@ + + * : The unique ID of the batch to run. + * + * ## EXAMPLES + * + * wp batch_process email_post_authors + */ + public function __invoke( $args, $assoc_args ) { + list( $batch_id ) = $args; + do_action( 'wp_batch_processing_init' ); + + $batch = WP_Batch_Processor::get_instance()->get_batch($batch_id); + if ( !$batch ) { + WP_CLI::error( "Batch with ID '{$batch_id}' not found." ); + return; + } + + WP_CLI::log( "Starting processing batch: {$batch_id} with {$batch->get_items_count()} items" ); + + $batch_items = $batch->get_all_items(); + $progress = WP_CLI\Utils\make_progress_bar( "Processing batch items", $batch->get_items_count() ); + + /** @var WP_Batch_Item $item */ + foreach ( $batch_items as $item ) { + // Process each item in the batch. + try { + if ( !$batch->is_processed( $item ) ) { + $batch->process( $item ); + $batch->mark_as_processed( $item->id ); + } + } catch ( Exception $e ) { + WP_CLI::warning( "Error processing item ID {$item->id}: " . $e->getMessage() ); + } + $progress->tick(); + } + + WP_CLI::success( "Batch '{$batch_id}' processing complete." ); + } +} From addb91d4e7ac5bf15287abef631caa9d4cbb700e Mon Sep 17 00:00:00 2001 From: Bram Driesen Date: Thu, 21 Aug 2025 22:49:40 +0200 Subject: [PATCH 3/7] fix: rename --- includes/class-wp-cli.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wp-cli.php b/includes/class-wp-cli.php index 56cd846..3306859 100644 --- a/includes/class-wp-cli.php +++ b/includes/class-wp-cli.php @@ -7,7 +7,7 @@ /** * Class Batch_Processor_CLI_Command(). */ -class Batch_Processor_CLI_Command extends WP_CLI_Command { +class WP_Batch_Processor_CLI_Command extends WP_CLI_Command { /** * Process a registered batch by ID. From f8c68995b593211425687136f0d5a7b506d5cdcd Mon Sep 17 00:00:00 2001 From: Bram Driesen Date: Thu, 21 Aug 2025 22:50:08 +0200 Subject: [PATCH 4/7] fix: rename --- wp-batch-processing.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wp-batch-processing.php b/wp-batch-processing.php index 48b446e..83e0530 100644 --- a/wp-batch-processing.php +++ b/wp-batch-processing.php @@ -26,7 +26,7 @@ if ( defined( 'WP_CLI' ) && WP_CLI ) { require_once 'includes/class-wp-cli.php'; - $wp_cli_command = new Batch_Processor_CLI_Command(); + $wp_cli_command = new WP_Batch_Processor_CLI_Command(); WP_CLI::add_command( 'batch_process', $wp_cli_command ); } @@ -46,3 +46,4 @@ // Examples // require_once 'examples/class-example-batch.php'; + From 699be973d4c10e125d0f1ed5fdebf4abeeef5ab9 Mon Sep 17 00:00:00 2001 From: Graham May Date: Wed, 28 Jan 2026 11:40:55 +0000 Subject: [PATCH 5/7] Rename batch_process to batch-process to match other WP CLI commands (e.g. if you run `wp help`). --- wp-batch-processing.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wp-batch-processing.php b/wp-batch-processing.php index 83e0530..841d2c7 100644 --- a/wp-batch-processing.php +++ b/wp-batch-processing.php @@ -27,7 +27,7 @@ require_once 'includes/class-wp-cli.php'; $wp_cli_command = new WP_Batch_Processor_CLI_Command(); - WP_CLI::add_command( 'batch_process', $wp_cli_command ); + WP_CLI::add_command( 'batch-process', $wp_cli_command ); } if ( ! is_admin() ) { @@ -46,4 +46,3 @@ // Examples // require_once 'examples/class-example-batch.php'; - From bf5b1ae317a5c83dc871c29276f6e95692c6d286 Mon Sep 17 00:00:00 2001 From: Graham May Date: Wed, 28 Jan 2026 11:42:46 +0000 Subject: [PATCH 6/7] Function `get_all_items()` doesn't seem to exist in `/includes/class-batch.php`. Have made `$items` public and adjusted `class-wp-cli.php` accordingly. --- includes/class-batch.php | 2 +- includes/class-wp-cli.php | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/includes/class-batch.php b/includes/class-batch.php index ef1c7b0..2e21258 100644 --- a/includes/class-batch.php +++ b/includes/class-batch.php @@ -50,7 +50,7 @@ abstract class WP_Batch { * Data store of batch items * @var WP_Batch_Item[] */ - protected $items = array(); + public $items = array(); /** * Initialize diff --git a/includes/class-wp-cli.php b/includes/class-wp-cli.php index 3306859..0b3fa4c 100644 --- a/includes/class-wp-cli.php +++ b/includes/class-wp-cli.php @@ -1,7 +1,7 @@ get_batch($batch_id); - if ( !$batch ) { + $batch = WP_Batch_Processor::get_instance()->get_batch( $batch_id ); + if ( ! $batch ) { WP_CLI::error( "Batch with ID '{$batch_id}' not found." ); return; } WP_CLI::log( "Starting processing batch: {$batch_id} with {$batch->get_items_count()} items" ); - $batch_items = $batch->get_all_items(); - $progress = WP_CLI\Utils\make_progress_bar( "Processing batch items", $batch->get_items_count() ); + $progress = WP_CLI\Utils\make_progress_bar( 'Processing batch items', $batch->get_items_count() ); /** @var WP_Batch_Item $item */ - foreach ( $batch_items as $item ) { + foreach ( $batch->items as $item ) { // Process each item in the batch. try { - if ( !$batch->is_processed( $item ) ) { + if ( ! $batch->is_processed( $item ) ) { $batch->process( $item ); $batch->mark_as_processed( $item->id ); } From fc8ddf4da47fbd7116baf0c07ee262beb0f9fd16 Mon Sep 17 00:00:00 2001 From: Graham May Date: Wed, 28 Jan 2026 12:14:10 +0000 Subject: [PATCH 7/7] Adding subcommands for wp batch-process list and wp batch-process restart --- includes/class-wp-cli.php | 68 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/includes/class-wp-cli.php b/includes/class-wp-cli.php index 0b3fa4c..38824dd 100644 --- a/includes/class-wp-cli.php +++ b/includes/class-wp-cli.php @@ -9,6 +9,39 @@ */ class WP_Batch_Processor_CLI_Command extends WP_CLI_Command { + /** + * List all registered batches. + * + * ## EXAMPLES + * + * wp batch-process list + * + * @subcommand list + */ + public function list_batches( $args, $assoc_args ) { + do_action( 'wp_batch_processing_init' ); + + $batches = WP_Batch_Processor::get_instance()->get_batches(); + + if ( empty( $batches ) ) { + WP_CLI::error( 'No batches registered.' ); + return; + } + + $items = array(); + foreach ( $batches as $batch ) { + $items[] = array( + 'ID' => $batch->id, + 'Total' => $batch->get_items_count(), + 'Processed' => $batch->get_processed_count(), + 'Percentage' => $batch->get_percentage() . '%', + 'Finished' => $batch->is_finished() ? 'Yes' : 'No', + ); + } + + WP_CLI\Utils\format_items( 'table', $items, array( 'ID', 'Total', 'Processed', 'Percentage', 'Finished' ) ); + } + /** * Process a registered batch by ID. * @@ -19,9 +52,11 @@ class WP_Batch_Processor_CLI_Command extends WP_CLI_Command { * * ## EXAMPLES * - * wp batch_process email_post_authors + * wp batch-process process email_post_authors + * + * @subcommand process */ - public function __invoke( $args, $assoc_args ) { + public function process( $args, $assoc_args ) { list( $batch_id ) = $args; do_action( 'wp_batch_processing_init' ); @@ -51,4 +86,33 @@ public function __invoke( $args, $assoc_args ) { WP_CLI::success( "Batch '{$batch_id}' processing complete." ); } + + /** + * Restart a registered batch by ID. + * + * ## OPTIONS + * + * + * : The unique ID of the batch to restart. + * + * ## EXAMPLES + * + * wp batch-process restart email_post_authors + * + * @subcommand restart + */ + public function restart( $args, $assoc_args ) { + list( $batch_id ) = $args; + do_action( 'wp_batch_processing_init' ); + + $batch = WP_Batch_Processor::get_instance()->get_batch( $batch_id ); + if ( ! $batch ) { + WP_CLI::error( "Batch with ID '{$batch_id}' not found." ); + return; + } + + $batch->restart(); + + WP_CLI::success( "Batch '{$batch_id}' restarted." ); + } }