Очистить брошенные корзины с помощью API 1С-Битрикс

Просмотров: 4400

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

Вообще, в модуле каталога есть такая настройка "Сохранять корзину (дней):" в которой можно указать количество дней, после которого брошенная корзина удаляется.

Очистить брошенные корзины с помощью 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 день).

Михаил Базаров 15.03.2023
Лучше на расписание повесить, ни к чему init.php засирать)
Гость 24.03.2023
Цитата
написал:
Лучше на расписание повесить, ни к чему init.php засирать)
Попробовал запустить через командную строку PHP в админке. Пишет, что не может найти класс.
Class 'Bitrix\Sale\Basket' not found (0)

Это битрикс поменял правила работы кода, или в другое место смотреть нужно?))
Заранее. спасибо за ответ))
Гость 24.03.2023
А если добавить Loader::includeModule('sale'); то начинает выполняться. Может дополнить или тут как на везение?))
Гость 24.03.2023
Ещё заметил, что после удачного выполнения скрипта, таблица b_sale_fuser оказалось такой же полной. А в админке нет не одной брощенной корзины. Очень странно!
Михаил Базаров 24.03.2023
Цитата
Гость написал:
А если добавить Loader::includeModule('sale'); то начинает выполняться. Может дополнить или тут как на везение?))

Да, добавил в заметку подключение модуля sale, без него перестало работать (хотя точно работало, применял скрипт не раз).
Спасибо, что написали.
Михаил Базаров 24.03.2023
Цитата
Гость написал:
Ещё заметил, что после удачного выполнения скрипта, таблица b_sale_fuser оказалось такой же полной. А в админке нет не одной брощенной корзины. Очень странно!

Проверил на одном проекте, все в порядке, таблица почти пустая. Проверьте что в ней за записи, возможно там очень много пустых корзин. Могут плодиться компонентом bitrix.basket.basket.small
При каждом заходе пользователей или ботов (хоть поисковиков) создается пустая корзина готовая к наполнению.
Вообще, проверю позже на другом проекте, допишу в заметку как и их грохать периодически.
Гость 24.03.2023
Спасибо большое! Это заметка очень помогает! Так же на одном совём проекте, стандартная функция работает. Так, что как повезёт. Про корзину, большое спасибо! Посмотрим))
Гость 24.03.2023
Можете ещё подсказать как быть. Сравнили с боевым сайтом. Размер таблицы реально уменьшился и уменьшелись записи в ней. В приложении небольшой скрин данных который остался в таблице. Я так понимаю, если они созданы корзиной как вы выше писали, то их можно просто удалить все. И не должно в принципе не чего слететь?
Валентин 06.11.2023
Подскажите, куда лучше разместить этот скрипт? В папку local или другую? И в настройках cron указать отдельно именно его?
Михаил Базаров 06.11.2023
Цитата
Валентин написал:
Подскажите, куда лучше разместить этот скрипт? В папку local или другую? И в настройках cron указать отдельно именно его?

Можно в local - тут исходите из своего проекта