Automattic\WooCommerce\Internal\Products
ProductsOrderingMoveService::move
Moves a product to the position between $previous_id and $next_id, triggering a full reindex first if positions are uninitialized or colliding. Indexed positions start at 1; menu_order = 0 is the sentinel for an unindexed product.
Designed for an HVM with 500K+ products catalog operating in a clustered environment. To satisfy this setup:
- if on-the-spot re-indexing is triggered: see design notes in \Automattic\WooCommerce\Internal\Products\ProductsOrderingReindexService::reindex_products
- otherwise, the move takes 5 SQLs for any catalog size (4 of them PK-driven, hence nearly instant; operating on the targeted range of positions)
Метод класса: ProductsOrderingMoveService{}
Хуков нет.
Возвращает
object{ moved:array<int,int>, reindexed:array<int,int> }.
Использование
$ProductsOrderingMoveService = new ProductsOrderingMoveService(); $ProductsOrderingMoveService->move( $previous_id, $product_id, $next_id ): object;
- $previous_id(int) (обязательный)
- ID of the product immediately before the target position, or 0 when moving to the start.
- $product_id(int) (обязательный)
- ID of the product being repositioned.
- $next_id(int) (обязательный)
- ID of the product immediately after the target position, or 0 when moving to the end.
Список изменений
| С версии 11.2.0 | Введена. |
Код ProductsOrderingMoveService::move() ProductsOrderingMoveService::move WC 11.2.2
public function move( int $previous_id, int $product_id, int $next_id ): object {
$result = array(
'moved' => array(),
'reindexed' => array(),
);
$anchor_positions = $this->compose_anchor_positions( $previous_id, $product_id, $next_id );
if ( ! $this->has_moved( $anchor_positions, $previous_id, $product_id, $next_id ) ) {
return (object) $result;
}
// Re-indexing is required when: a position collision is detected or moving between groups one of which is unindexed.
$map = $this->compose_move_map( $previous_id, $product_id, $next_id, $anchor_positions );
$needs_reindexing = $map->old_position === $map->new_position || 0 === $map->new_position || 0 === $map->old_position;
$needs_reindexing = $needs_reindexing || count( array_unique( $anchor_positions ) ) !== count( $anchor_positions );
if ( $needs_reindexing ) {
$result['reindexed'] = $this->reindex_service->reindex_products();
$anchor_positions = $this->compose_anchor_positions( $previous_id, $product_id, $next_id );
$map = $this->compose_move_map( $previous_id, $product_id, $next_id, $anchor_positions );
if ( ! $this->has_moved( $anchor_positions, $previous_id, $product_id, $next_id ) ) {
return (object) $result;
}
}
$result['moved'] = $this->apply( $map, $result['reindexed'] );
// Deduct the move related modification from re-indexing to de-duplicate change events in outside workflow.
foreach ( $result['moved'] as $id => $position ) {
unset( $result['reindexed'][ $id ] );
}
return (object) $result;
}