Диагностика проблемы: почему нужно удалять товары из корзины по категории
В интернет-магазинах на WooCommerce часто возникает задача, когда при смене категории товара или пользовательском действии нужно автоматически удалять определённые товары из корзины. Например, если пользователь переключается на другую категорию, несовместимую с текущими товарами, или при изменении статуса заказа. Без автоматизации пользователь может столкнуться с конфликтами, ошибками оформления заказа или некорректным подсчётом стоимости.
Типичные сценарии
- Пользователь добавил товар из категории А, затем выбрал товары из категории Б, которые несовместимы;
- Необходимо очистить корзину от товаров определённых категорий при обновлении страницы или смене категории в фильтре;
- Автоматическая очистка корзины при изменении пользовательских настроек, связанных с категориями товаров.
Как проверить, что корзина содержит товары из нужных категорий
Для диагностики используем следующий код, который выводит категории товаров в корзине:
add_action('woocommerce_before_cart', function() {
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
$product_id = $cart_item['product_id'];
$terms = get_the_terms($product_id, 'product_cat');
if ($terms && ! is_wp_error($terms)) {
foreach ($terms as $term) {
echo '<p>Товар ID: ' . $product_id . ' Категория: ' . esc_html($term->name) . '</p>';
}
}
}
});Этот код добавляет на страницу корзины список категорий для каждого товара. По нему можно убедиться, что категории определяются корректно.
Пошаговое решение: автоматическое удаление товаров из корзины по категории
Задача – при определённом событии (например, при загрузке страницы или смене категории) удалить из корзины все товары из категории exclude-category.
Реализуем через хук woocommerce_before_cart или template_redirect:
function wc_remove_products_by_category_from_cart() {
if ( ! is_admin() && is_cart() ) {
$category_slug = 'exclude-category'; // Замените на нужный слаг категории
$cart = WC()->cart;
$removed = false;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product_id = $cart_item['product_id'];
if ( has_term( $category_slug, 'product_cat', $product_id ) ) {
$cart->remove_cart_item( $cart_item_key );
$removed = true;
}
}
if ( $removed ) {
wc_add_notice( 'Товары из категории "' . $category_slug . '" были удалены из корзины.', 'notice' );
}
}
}
add_action( 'woocommerce_before_cart', 'wc_remove_products_by_category_from_cart' );Объяснение кода:
- Проверяем, что это не админка и страница корзины;
- Циклом перебираем товары в корзине;
- Используем
has_termдля проверки категории; - Удаляем товар из корзины через
remove_cart_item; - Выводим уведомление пользователю.
Как запустить удаление по событию смены категории
Если нужно запускать удаление при смене категории товара на странице каталога, потребуется JavaScript + AJAX, чтобы отправлять запрос на сервер и вызывать функцию очистки корзины. Пример AJAX запроса:
// JS пример (jQuery)
jQuery(document).on('change', '#product-category-select', function() {
var category = jQuery(this).val();
jQuery.ajax({
url: wc_ajax_url, // нужно определить wc_ajax_url в скрипте
method: 'POST',
data: {
action: 'remove_cart_by_category',
category: category
},
success: function(response) {
if(response.success) {
location.reload(); // обновляем корзину
}
}
});
});// PHP обработчик AJAX
add_action('wp_ajax_remove_cart_by_category', 'remove_cart_by_category_callback');
add_action('wp_ajax_nopriv_remove_cart_by_category', 'remove_cart_by_category_callback');
function remove_cart_by_category_callback() {
$category_slug = sanitize_text_field($_POST['category']);
$cart = WC()->cart;
$removed = false;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product_id = $cart_item['product_id'];
if ( has_term( $category_slug, 'product_cat', $product_id ) ) {
$cart->remove_cart_item( $cart_item_key );
$removed = true;
}
}
if ( $removed ) {
wp_send_json_success();
} else {
wp_send_json_error();
}
}Проверка результата после внедрения
- Добавьте в корзину товары из категории
exclude-categoryи другие; - Перейдите на страницу корзины — товары из категории должны удалиться;
- Проверьте уведомление о удалении товаров;
- При использовании AJAX смените категорию через селектор и проверьте обновление корзины.
Частые ошибки и как их исправить
- Товары не удаляются из корзины: проверьте, что
WC()->cartинициализирован (не в админке), и что слаг категории указан правильно; - Уведомления не показываются: убедитесь, что тема выводит уведомления WooCommerce (
wc_print_notices()используется); - Удаление происходит на всех страницах: используйте условие
is_cart()или другие проверки; - AJAX не работает: проверьте правильность URL в JS (
wc_ajax_url) и регистрацию AJAX-хуков; - Если корзина кэшируется: отключите кэш для страниц корзины и AJAX-запросов.
Практические советы по безопасности и производительности
- В AJAX обработчике обязательно используйте
sanitize_text_field()для входных данных; - Ограничивайте область действия функции удаления конкретными проверками страниц или пользовательскими правами;
- Для больших корзин проверяйте нагрузку — перебор большого числа товаров может замедлить работу;
- Кэширование страниц корзины и AJAX запросов должно быть отключено, чтобы изменения были моментальными;
- Для SEO и UX используйте уведомления, чтобы пользователь понимал, почему товар удалён.
Сравнение вариантов реализации
| Вариант | Плюсы | Минусы | Пример |
|---|---|---|---|
| Удаление при загрузке корзины | Простая реализация, без JS | Не подходит для динамических действий вне корзины | woocommerce_before_cart хук |
| Удаление через AJAX при смене категории | Гибкая, динамичная реакция без перезагрузки | Сложнее в реализации, требует JS и AJAX | Ajax обработчик + JS |
| Плагин сторонний для управления корзиной | Много функций, готовые настройки | Может быть избыточным, нагружает сайт | Плагины типа WooCommerce Cart Manager |