Диагностика проблемы: зачем удалять неактивные товары из корзины
В WooCommerce корзина покупателя может содержать товары, которые стали неактивными или недоступными для покупки (товары сняты с публикации, отсутствуют на складе без разрешения на предзаказ, отключены вручную). Это приводит к проблемам при оформлении заказа, сбоям в подсчёте стоимости и ухудшению пользовательского опыта.
Проверьте, есть ли в вашей корзине такие товары, выполнив следующий сниппет через консоль браузера на странице корзины:
jQuery('.woocommerce-cart-form .cart_item').each(function() {
const productName = jQuery(this).find('.product-name').text();
console.log('В корзине:', productName);
});Затем в админке проверьте статус этих товаров и доступность для продажи.
Пошаговое решение: как автоматически удалять неактивные товары из корзины
1. Определяем неактивные товары
Под неактивными товарами понимаем те, у которых статус draft, pending, private или у которых отключена возможность покупки (is_purchasable() === false).
2. Добавляем проверку и удаление при загрузке страницы корзины
В файл functions.php вашей темы или в кастомный плагин добавьте следующий код:
add_action('woocommerce_before_cart', 'remove_inactive_products_from_cart');
function remove_inactive_products_from_cart() {
$cart = WC()->cart;
if ( ! $cart ) {
return;
}
$removed = false;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
// Проверяем статус поста и purchasable
if ( ! $product || ! $product->is_purchasable() ) {
$cart->remove_cart_item( $cart_item_key );
$removed = true;
} else {
$post_status = get_post_status( $product->get_id() );
if ( in_array( $post_status, array('draft', 'pending', 'private'), true ) ) {
$cart->remove_cart_item( $cart_item_key );
$removed = true;
}
}
}
if ( $removed ) {
wc_add_notice( 'Ваша корзина обновлена: удалены недоступные товары.', 'notice' );
}
}3. Автоматическое обновление корзины на фронтенде
Чтобы пользователь сразу видел изменения без ручного обновления, добавим AJAX-обновление:
add_action('wp_footer', 'refresh_cart_on_load_script');
function refresh_cart_on_load_script() {
if ( is_cart() ) {
?>
<script type="text/javascript">
jQuery(document).ready(function($){
$.ajax({
url: wc_cart_params.ajax_url,
type: 'POST',
data: {
action: 'woocommerce_update_cart_action'
},
success: function() {
// Обновляем корзину визуально
$(document.body).trigger('updated_wc_div');
}
});
});
</script>
<?php
}
}Этот скрипт инициирует обновление корзины через AJAX при загрузке страницы.
Проверка результата после внедрения
- Добавьте в корзину товар со статусом
draftили недоступный для покупки. - Перейдите на страницу корзины — товар должен автоматически исчезнуть, а сверху появится уведомление «Ваша корзина обновлена: удалены недоступные товары.».
- Обычные товары остаются в корзине без изменений.
Частые ошибки и их исправление
- Товар не удаляется из корзины: возможно, кеширование страницы мешает обновлению. Очистите кеш, отключите плагины кеширования на время теста.
- Сообщение об обновлении не появилось: проверьте, что функция
wc_add_noticeвызывается и шаблон корзины поддерживает вывод уведомлений. - AJAX-обновление не работает: убедитесь, что скрипт подключён только на странице корзины, и jQuery доступен.
Практические советы по безопасности и производительности
- Проверка статуса продукта и возможности покупки не должна вызываться на каждой странице, ограничивайте вызов только страницей корзины.
- Используйте transient-кеширование, если проверка товаров в корзине занимает слишком много времени при большом количестве товаров.
- Для крупных магазинов с высокой нагрузкой рассмотрите вариант фонового скрипта, очищающего корзины пользователей от неактивных товаров по CRON.
Сравнение способов реализации
| Метод | Преимущества | Недостатки |
|---|---|---|
| Код в functions.php | Простота, контроль над логикой, нет лишних плагинов | Требует навыков, риск ошибок при обновлениях |
| Плагин очистки корзины | Легко подключить, готовое решение | Может быть избыточным, нагрузка, меньше контроля |
| CRON-фоновая очистка | Не влияет на скорость загрузки страницы | Удаление не сразу, сложнее в настройке |