Задача: в интернет-магазине накапливается большое количество брошенных корзин, нужно их очистить. Включая и корзины зарегистрированных пользователей, которые просто не дооформили заказ. При этом используя API 1С-Битрикс, а не прямые запросы в базу данных.
Вообще, в модуле каталога есть такая настройка "Сохранять корзину (дней):" в которой можно указать количество дней, после которого брошенная корзина удаляется.

Но, по какой-то причине эта настройка не работает ни на одном сайте. И судя по тому, сколько тем создано на форуме, по данному вопросу, не работает настройка ни у кого.
На нескольких сайтах нашел способ удаления брошенных корзин с помощью прямого запроса в базу данных. Но этот способ мне не нравится, какой-то он не гибкий и монструзно не очевидный.
Получаем все корзины, всех пользователей через 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', то есть не оформленные корзины.
- C помощью 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 секунд (это 1 день).