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 new file mode 100644 index 0000000..38824dd --- /dev/null +++ b/includes/class-wp-cli.php @@ -0,0 +1,118 @@ +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. + * + * ## OPTIONS + * + * + * : The unique ID of the batch to run. + * + * ## EXAMPLES + * + * wp batch-process process email_post_authors + * + * @subcommand process + */ + public function process( $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" ); + + $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." ); + } + + /** + * 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." ); + } +} diff --git a/wp-batch-processing.php b/wp-batch-processing.php index d96d188..841d2c7 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 WP_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