Automattic\WooCommerce\Internal\ProductFeed\Feed

ProductWalker::walk_batchespublicWC 11.0.0

Walks through products, optionally limited to a bounded number of batches.

The walker does not own the feed lifecycle: the caller is responsible for starting, flushing and ending the feed. This lets a feed be written across several processes by resuming the same feed between calls.

Called with the defaults it walks every remaining page in one go; pass $start_page and $max_batches to process a bounded slice and resume later from processed_batches.

Method of the class: ProductWalker{}

No Hooks.

Returns

WalkerProgress. Items/batches processed here, plus the overall total_count and total_batch_count so the caller knows whether the feed is complete.

Usage

$ProductWalker = new ProductWalker();
$ProductWalker->walk_batches( ?callable $callback, $start_page, $max_batches ): WalkerProgress;
?callable $callback
.
Default: null
$start_page(int)
The 1-based page (batch) to start at.
Default: 1
$max_batches(int)
The maximum number of batches to process in this call.
Default: PHP_INT_MAX

Changelog

Since 11.0.0 Introduced.

ProductWalker::walk_batches() code WC 11.0.0

public function walk_batches( ?callable $callback = null, int $start_page = 1, int $max_batches = PHP_INT_MAX ): WalkerProgress {
	if ( $start_page < 1 ) {
		$start_page = 1;
	}
	if ( $max_batches < 1 ) {
		$max_batches = 1;
	}

	$progress = null;
	$page     = $start_page;

	// Check how much memory is available at first.
	$initial_available_memory = $this->memory_manager->get_available_memory();

	$batches_processed = 0;
	do {
		$result   = $this->iterate( $this->query_args, $page, $this->per_page );
		$iterated = count( $result->products );

		// Only build the progress object once; the total/total batch count is stable across pages.
		if ( is_null( $progress ) ) {
			$progress = WalkerProgress::from_wc_get_products_result( $result );
		}
		$progress->processed_items += $iterated;
		++$progress->processed_batches;
		++$batches_processed;
		++$page;

		if ( is_callable( $callback ) && $iterated > 0 ) {
			$callback( $progress );
		}

		if ( $this->time_limit > 0 ) {
			set_time_limit( $this->time_limit );
		}

		// We don't want to use more than half of the available memory at the beginning of the script.
		$current_memory = $this->memory_manager->get_available_memory();
		if ( $initial_available_memory - $current_memory >= $initial_available_memory / 2 ) {
			$this->memory_manager->flush_caches();
		}
	} while (
		// If `wc_get_products()` returns less than the batch size, it was the last page.
		$iterated === $this->per_page

		// Stop once this call has processed its requested number of batches.
		&& $batches_processed < $max_batches

		// For the cases where the above are true, make sure that we do not exceed the total number of pages.
		&& ( $progress->total_batch_count <= 0 || ( $page - 1 ) < $progress->total_batch_count )
	);

	// The do-while body always executes at least once and assigns $progress on the first iteration.
	return $progress;
}