Проблема: товары долго остаются в корзине WooCommerce
В WooCommerce корзина пользователя может храниться долгое время, что влияет на доступность товаров и корректность учёта остатков. Особенно актуально для товаров с ограниченным запасом или акционных предложений. Автоматическое удаление товаров из корзины через заданный промежуток времени помогает поддерживать актуальность корзин и улучшает пользовательский опыт.
Диагностика проблемы
Чтобы понять, что товары в корзине не удаляются своевременно, проверьте следующие моменты:
- Оставьте товар в корзине, закройте браузер и вернитесь через несколько дней — товар всё ещё там?
- Проверьте настройки сессий WooCommerce и время их хранения.
- Проверьте, не сохраняется ли корзина в cookie слишком долго.
По умолчанию WooCommerce не удаляет товары из корзины автоматически, корзина хранится в сессии пользователя до её истечения или очистки cookie.
Что нужно сделать: реализовать удаление товаров из корзины через таймер
Реализуем механизм, который будет очищать корзину пользователя, если товары в ней находятся дольше определённого времени, например 1 час. Для этого добавим метку времени при добавлении товара и будем проверять её при каждом обновлении корзины.
Шаг 1. Добавляем метку времени при добавлении товара в корзину
add_action('woocommerce_add_to_cart', 'set_cart_item_added_time', 10, 6);
function set_cart_item_added_time($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
if ( ! WC()->session ) return;
$cart = WC()->cart->get_cart();
if ( isset($cart[$cart_item_key]) ) {
$cart[$cart_item_key]['added_time'] = time();
}
}Этот хук срабатывает при добавлении товара в корзину, мы сохраняем текущий timestamp в дополнительное поле added_time.
Шаг 2. Проверяем корзину на устаревшие товары и удаляем их
add_action('woocommerce_before_cart', 'remove_expired_cart_items');
function remove_expired_cart_items() {
$expiration_seconds = 3600; // 1 час
$cart = WC()->cart->get_cart();
$removed = false;
foreach ( $cart as $cart_item_key => $cart_item ) {
if ( isset($cart_item['added_time']) && ( time() - $cart_item['added_time'] > $expiration_seconds ) ) {
WC()->cart->remove_cart_item( $cart_item_key );
$removed = true;
}
}
if ( $removed ) {
wc_add_notice('Некоторые товары были удалены из корзины из-за истечения времени хранения.', 'notice');
}
}При загрузке страницы корзины проверяем время каждого товара и удаляем устаревшие, если время хранения превышено.
Проверка результата
- Добавьте товар в корзину.
- Измените значение
$expiration_secondsна небольшой промежуток, например 10 секунд для теста. - Обновите или откройте страницу корзины спустя указанное время.
- Проверьте, что устаревшие товары удаляются и появляется уведомление.
Частые ошибки и их исправление
- Товары не удаляются: Проверьте, что сессия WooCommerce работает корректно, и корзина не кешируется внешними плагинами.
- Код не срабатывает на страницах не связанных с корзиной: Хук
woocommerce_before_cartсрабатывает только на странице корзины, для удаления на других страницах добавьте аналогичный код на другие хуки, напримерtemplate_redirect, с проверкой текущей страницы. - Ошибка undefined WC()->cart: Убедитесь, что код выполняется после инициализации WooCommerce, например через хук
initили позднее.
Практические советы по безопасности и производительности
- Не храните лишние данные в сессии или корзине, чтобы не перегружать базу данных.
- Ограничивайте время хранения корзины, чтобы избежать накопления устаревших данных.
- Для сайтов с высокой нагрузкой рассмотрите оптимизацию кода, чтобы не выполнять лишние проверки на каждой загрузке страницы.
Альтернативы: плагины vs собственный код
| Вариант | Преимущества | Недостатки |
|---|---|---|
| Собственный код (пример выше) | Полный контроль, легковесность, отсутствие зависимостей | Требует поддержки и тестирования, нет интерфейса управления |
| Плагины для очистки корзины | Готовое решение, настройки через админку, поддержка разработчика | Могут нагружать сайт, зависимость от стороннего кода, возможны конфликты |