s_name = substr( $class_name, 0, 140 );
return 'wc_batch_' . $class_name . '_' . $class_md5;
}
/**
* Update the state for a processor after a batch has completed processing.
*
* @param BatchProcessorInterface $batch_processor Batch processor instance.
* @param float $time_taken Time take by the batch to complete processing.
* @param \Exception|null $last_error Exception object in processing the batch, if there was one.
*/
private function update_processor_state( BatchProcessorInterface $batch_processor, float $time_taken, \Exception $last_error = null ): void {
$current_status = $this->get_process_details( $batch_processor );
$current_status['total_time_spent'] += $time_taken;
$current_status['last_error'] = null !== $last_error ? $last_error->getMessage() : null;
update_option( $this->get_processor_state_option_name( $batch_processor ), $current_status, false );
}
/**
* Schedule a processing action for a single processor.
*
* @param string $processor_class_name Fully qualified class name of the processor.
* @param bool $with_delay Whether to schedule the action for immediate execution or for later.
*/
private function schedule_batch_processing( string $processor_class_name, bool $with_delay = false ) : void {
$time = $with_delay ? time() + MINUTE_IN_SECONDS : time();
as_schedule_single_action( $time, self::PROCESS_SINGLE_BATCH_ACTION_NAME, array( $processor_class_name ) );
}
/**
* Check if a batch processing action is already scheduled for a given processor.
* Differs from `as_has_scheduled_action` in that this excludes actions in progress.
*
* @param string $processor_class_name Fully qualified class name of the batch processor.
*
* @return bool True if a batch processing action is already scheduled for the processor.
*/
public function is_scheduled( string $processor_class_name ): bool {
return as_has_scheduled_action( self::PROCESS_SINGLE_BATCH_ACTION_NAME, array( $processor_class_name ) );
}
/**
* Get an instance of a processor given its class name.
*
* @param string $processor_class_name Full class name of the batch processor.
*
* @return BatchProcessorInterface Instance of batch processor for the given class.
* @throws \Exception If it's not possible to get an instance of the class.
*/
private function get_processor_instance( string $processor_class_name ) : BatchProcessorInterface {
$processor = wc_get_container()->get( $processor_class_name );
/**
* Filters the instance of a processor for a given class name.
*
* @param object|null $processor The processor instance given by the dependency injection container, or null if none was obtained.
* @param string $processor_class_name The full class name of the processor.
* @return BatchProcessorInterface|null The actual processor instance to use, or null if none could be retrieved.
*
* @since 6.8.0.
*/
$processor = apply_filters( 'woocommerce_get_batch_processor', $processor, $processor_class_name );
if ( ! isset( $processor ) && class_exists( $processor_class_name ) ) {
// This is a fallback for when the batch processor is not registered in the container.
$processor = new $processor_class_name();
}
if ( ! is_a( $processor, BatchProcessorInterface::class ) ) {
throw new \Exception( "Unable to initialize batch processor instance for $processor_class_name" );
}
return $processor;
}
/**
* Helper method to get list of all the enqueued processors.
*
* @return array List (of string) of the class names of the enqueued processors.
*/
public function get_enqueued_processors() : array {
return get_option( self::ENQUEUED_PROCESSORS_OPTION_NAME, array() );
}
/**
* Dequeue a processor once it has no more items pending processing.
*
* @param string $processor_class_name Full processor class name.
*/
private function dequeue_processor( string $processor_class_name ): void {
$pending_processes = $this->get_enqueued_processors();
if ( in_array( $processor_class_name, $pending_processes, true ) ) {
$pending_processes = array_diff( $pending_processes, array( $processor_class_name ) );
$this->set_enqueued_processors( $pending_processes );
}
}
/**
* Helper method to set the enqueued processor class names.
*
* @param array $processors List of full processor class names.
*/
private function set_enqueued_processors( array $processors ): void {
update_option( self::ENQUEUED_PROCESSORS_OPTION_NAME, $processors, false );
}
/**
* Check if a particular processor is enqueued.
*
* @param string $processor_class_name Fully qualified class name of the processor.
*
* @return bool True if the processor is enqueued.
*/
public function is_enqueued( string $processor_class_name ) : bool {
return in_array( $processor_class_name, $this->get_enqueued_processors(), true );
}
/**
* Dequeue and de-schedule a processor instance so that it won't be processed anymore.
*
* @param string $processor_class_name Fully qualified class name of the processor.
* @return bool True if the processor has been dequeued, false if the processor wasn't enqueued (so nothing has been done).
*/
public function remove_processor( string $processor_class_name ): bool {
$enqueued_processors = $this->get_enqueued_processors();
if ( ! in_array( $processor_class_name, $enqueued_processors, true ) ) {
return false;
}
$enqueued_processors = array_diff( $enqueued_processors, array( $processor_class_name ) );
if ( empty( $enqueued_processors ) ) {
$this->force_clear_all_processes();
} else {
update_option( self::ENQUEUED_PROCESSORS_OPTION_NAME, $enqueued_processors, false );
as_unschedule_all_actions( self::PROCESS_SINGLE_BATCH_ACTION_NAME, array( $processor_class_name ) );
}
return true;
}
/**
* Dequeues and de-schedules all the processors.
*/
public function force_clear_all_processes(): void {
as_unschedule_all_actions( self::PROCESS_SINGLE_BATCH_ACTION_NAME );
as_unschedule_all_actions( self::WATCHDOG_ACTION_NAME );
update_option( self::ENQUEUED_PROCESSORS_OPTION_NAME, array(), false );
}
/**
* Log an error that happened while processing a batch.
*
* @param \Exception $error Exception object to log.
* @param BatchProcessorInterface $batch_processor Batch processor instance.
* @param array $batch Batch that was being processed.
*/
protected function log_error( \Exception $error, BatchProcessorInterface $batch_processor, array $batch ) : void {
$batch_detail_string = '';
// Log only first and last, as the entire batch may be too big.
if ( count( $batch ) > 0 ) {
$batch_detail_string = "\n" . wp_json_encode(
array(
'batch_start' => $batch[0],
'batch_end' => end( $batch ),
),
JSON_PRETTY_PRINT
);
}
$error_message = "Error processing batch for {$batch_processor->get_name()}: {$error->getMessage()}" . $batch_detail_string;
/**
* Filters the error message for a batch processing.
*
* @param string $error_message The error message that will be logged.
* @param \Exception $error The exception that was thrown by the processor.
* @param BatchProcessorInterface $batch_processor The processor that threw the exception.
* @param array $batch The batch that was being processed.
* @return string The actual error message that will be logged.
*
* @since 6.8.0
*/
$error_message = apply_filters( 'wc_batch_processing_log_message', $error_message, $error, $batch_processor, $batch );
$this->logger->error( $error_message, array( 'exception' => $error ) );
}
}
Fatal error: Uncaught Error: Class 'Automattic\WooCommerce\Internal\BatchProcessing\BatchProcessingController' not found in /home/arasetne/public_html/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ServiceProviders/BatchProcessingServiceProvider.php:35
Stack trace:
#0 /home/arasetne/public_html/wp-content/plugins/woocommerce/lib/packages/League/Container/ServiceProvider/ServiceProviderAggregate.php(102): Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders\BatchProcessingServiceProvider->register()
#1 /home/arasetne/public_html/wp-content/plugins/woocommerce/lib/packages/League/Container/Container.php(172): Automattic\WooCommerce\Vendor\League\Container\ServiceProvider\ServiceProviderAggregate->register('Automattic\\WooC...')
#2 /home/arasetne/public_html/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ExtendedContainer.php(158): Automattic\WooCommerce\Vendor\League\Container\Container->get('Automattic\\WooC...', false)
#3 /home/arasetne/public_html/wp-content/plugins/wo in /home/arasetne/public_html/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ServiceProviders/BatchProcessingServiceProvider.php on line 35
Fatal error: Uncaught Automattic\WooCommerce\Vendor\League\Container\Exception\ContainerException: Service provider lied about providing (Automattic\WooCommerce\Internal\BatchProcessing\BatchProcessingController) service in /home/arasetne/public_html/wp-content/plugins/woocommerce/lib/packages/League/Container/Container.php:175
Stack trace:
#0 /home/arasetne/public_html/wp-content/plugins/woocommerce/src/Internal/DependencyManagement/ExtendedContainer.php(158): Automattic\WooCommerce\Vendor\League\Container\Container->get('Automattic\\WooC...', false)
#1 /home/arasetne/public_html/wp-content/plugins/woocommerce/lib/packages/League/Container/Argument/ArgumentResolverTrait.php(45): Automattic\WooCommerce\Internal\DependencyManagement\ExtendedContainer->get('Automattic\\WooC...')
#2 [internal function]: Automattic\WooCommerce\Vendor\League\Container\Definition\Definition->Automattic\WooCommerce\Vendor\League\Container\Argument\{closure}('Automattic\\WooC...')
#3 /home/arasetne/public_html/wp-content/plugins/woocommerce/lib/p in /home/arasetne/public_html/wp-content/plugins/woocommerce/lib/packages/League/Container/Container.php on line 175