Вообще, в модуле каталога есть такая настройка "Сохранять корзину (дней):", в которой можно указать количество дней, после которого брошенная корзина удаляется.
Но по какой-то причине эта настройка не работает ни на одном сайте. И, судя по количеству тем на форуме по данному вопросу, она не работает ни у кого.
На нескольких сайтах я нашёл способ удаления брошенных корзин с помощью прямых запросов к базе данных. Однако этот способ мне не нравится: он кажется недостаточно гибким и излишне «монструозно» очевидным.
Получаем все корзины всех пользователей через API и удаляем
Всё просто: получаем все корзины всех пользователей (включая незарегистрированных) методом \Bitrix\Sale\Basket::getList и очищаем их.
use \Bitrix\Main\Loader;
Loader::includeModule('catalog');
Loader::includeModule('sale');
$obBasket = \Bitrix\Sale\Basket::getList(
array(
'select' => array(
'FUSER_ID'
),
'filter' => array(
'ORDER_ID' => 'NULL',
),
)
);
while($bItem = $obBasket->Fetch()){
CSaleBasket::DeleteAll(
$bItem['FUSER_ID'],
False
);
}
- Для удаления корзин нам достаточно знать только FUSER_ID — ID пользователя-владельца корзины (это не то же самое, что USER_ID).
- Отбираем корзины, не связанные с заказом: 'ORDER_ID' => 'NULL', то есть неоформленные корзины.
- С помощью CSaleBasket::DeleteAll, зная FUSER_ID владельца, удаляем корзину.
Этот способ более очевидный и гибкий, чем прямые запросы к БД: можно очищать корзины по параметрам, добавляя в фильтр нужные условия отбора.
Например: только корзины за определённый период или корзины определённых пользователей.
Очистить брошенные корзины за заданный период
Чтобы не запускать этот скрипт вручную, можно сделать консольный скрипт и запускать его по расписанию.
И, наверное, не стоит очищать все корзины — пользователь может вернуться на сайт и дооформить заказ. Лучше удалять корзины старше определённого периода. Например: оставляем корзины, которые не были оформлены за последние 15 дней, а остальные удаляем.
$_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/../..");
$DOCUMENT_ROOT = $_SERVER["DOCUMENT_ROOT"];
// скрипт для запуска по cron
define("NO_KEEP_STATISTIC", true);
define("NOT_CHECK_PERMISSIONS", true);
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');
@set_time_limit(0);
use \Bitrix\Main\Loader;
Loader::includeModule('catalog');
Loader::includeModule('sale');
$date = date('d.m.Y', time() - 86400 * 15);
$obBasket = \Bitrix\Sale\Basket::getList(
array(
'select' => array(
'FUSER_ID'
),
'filter' => array(
'ORDER_ID' => 'NULL',
'<=DATE_INSERT' => $date
),
)
);
while($bItem = $obBasket->Fetch()){
CSaleBasket::DeleteAll(
$bItem['FUSER_ID'],
False
);
}
В переменной $date хранится текущая дата минус 15 дней. Она используется в фильтре корзин: '<=DATE_INSERT' => $date, чтобы получить корзины старше 15 дней.
Увеличить или уменьшить срок можно в выражении 86400 * 15, изменив множитель (86400 секунд — это один день).