Столкнулся с простой казалось бы проблемой. Хочу управлять порядком товаров апсейл без дополнительных плагинов штатным функционалом WooCommerce.

Итак, вы хотите, чтобы порядок апсейл-товаров сохранялся в том порядке, в котором вы их выбираете при настройке продукта. Вот решение.
Вставьте этот код в файл functions.php дочерней темы WordPress:
/**
* Сортируем апсейл-продукты в порядке выбора
*/
function custom_upsell_display_order( $ids, $product ) {
$product_id = is_a( $product, 'WC_Product' ) ? $product->get_id() : 0;
// Получаем сохранённый порядок
$saved_order = get_post_meta( $product_id, '_upsell_display_order', true );
if ( ! empty( $saved_order ) && is_array( $saved_order ) ) {
// Сортируем массив ID в соответствии с сохранённым порядком
$sorted_ids = array();
foreach ( $saved_order as $ordered_id ) {
if ( in_array( $ordered_id, $ids ) ) {
$sorted_ids[] = $ordered_id;
}
}
// Добавляем продукты, которые есть в $ids, но отсутствуют в сохранённом порядке
foreach ( $ids as $id ) {
if ( ! in_array( $id, $sorted_ids ) ) {
$sorted_ids[] = $id;
}
}
return $sorted_ids;
}
return $ids;
}
add_filter( 'woocommerce_product_get_upsell_ids', 'custom_upsell_display_order', 10, 2 );
add_filter( 'woocommerce_product_upsell_ids', 'custom_upsell_display_order', 10, 2 );
/**
* Добавляем JavaScript для сохранения порядка выбора в админке
*/
function add_upsell_order_script() {
if ( get_post_type() !== 'product' ) {
return;
}
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
// Отслеживаем изменения в поле апсейл-продуктов и запоминаем порядок
$('body').on('select2:select select2:unselect', '.woocommerce_upsells select', function() {
var ids = [];
$(this).find('option').each(function() {
ids.push($(this).val());
});
var $input = $('input[name="upsell_display_order"]');
if ($input.length === 0) {
$input = $('<input type="hidden" name="upsell_display_order">').appendTo('#post');
}
$input.val(ids.join(','));
});
});
</script>
<?php
}
add_action( 'admin_footer-post.php', 'add_upsell_order_script' );
add_action( 'admin_footer-post-new.php', 'add_upsell_order_script' );
/**
* Сохраняем порядок в мета-поле при сохранении продукта
*/
function save_upsell_display_order( $post_id ) {
if ( isset( $_POST['upsell_display_order'] ) ) {
$order = array_map(
'absint',
explode( ',', sanitize_text_field( $_POST['upsell_display_order'] ) )
);
update_post_meta( $post_id, '_upsell_display_order', $order );
}
}
add_action( 'woocommerce_process_product_meta', 'save_upsell_display_order' );
Что делает этот код:
- Сохраняет порядок апсейл-продуктов именно в том порядке, в котором вы их выбираете
- Поддерживает этот порядок при отображении на фронтенде
Как это работает:
- При выборе апсейл-продуктов в админке порядок выбора автоматически фиксируется через JavaScript
- Этот порядок сохраняется в специальном мета-поле продукта (
_upsell_display_order) - При отображении на сайте продукты показываются в том же порядке, в котором были выбраны
Как использовать:
- Добавьте код в файл
functions.phpвашей темы или в плагин для кастомизации - Перейдите к редактированию продукта
- Добавьте апсейл-продукты в том порядке, в котором хотите их видеть
- Сохраните продукт
Этой статьёй хочу начать цикл маленьких лайфхаков для работы с WordPress и интернет-магазинами в частности.


