Найти в Дзене

Сохраняем корзину пользователя при авторизации в 1С-Битрикс

Оглавление
Сохраняем корзину пользователя после авторизации. Сгенерированно с помощью Perplexity
Сохраняем корзину пользователя после авторизации. Сгенерированно с помощью Perplexity

У платформы 1С-Битрикс: Управление сайтом есть одна интересная особенность. Неавторизованный пользователь накидывает корзину, потом решает авторизоваться и... теряет все то, что накидал в корзину.

Это происходит потому, что у неавторизованного и авторизованного пользователей разный FUSER и при авторизации происходит переключение с одного на другого.

Есть простое решение

Просто в файл bitrix/php_interface/init.php добавляем следующий код

use Bitrix\Sale\Basket;
use Bitrix\Sale\Fuser;
use Bitrix\Main\Context;

Loader::
includeModule('sale');
Loader::
includeModule('catalog');

{
$siteId = Context::
getCurrent()->getSite();
$fuserId = Fuser::
getId();
$basket = Basket::
loadItemsForFUser($fuserId, $siteId);
}

В данном случае мы просто подставляем корзину неавторизованного пользователя авторизованному. Но, теряем корзину авторизованного.

Делаем красивее

Все работы ведем там же или делаем подключаемый файл, тут как вам удобнее. И подключаем все необходимые классы.

use Bitrix\Main\Loader;
use Bitrix\Main\Context;
use Bitrix\Sale\Basket;
use Bitrix\Sale\Fuser;
use Bitrix\Sale\Internals\FuserTable;
use Bitrix\Main\Engine\CurrentUser;

Loader::includeModule('sale');
Loader::includeModule('catalog');
Loader::includeModule('iblock');

Работаем с двумя типами юзеров

Получим текущий FUSER - анонимный до авторизации, после же тот, что будет в сессии

$currentFuserId = Fuser::getId();

FUSER, который уже был привязан к авторизованному пользователю - это его старая корзинка

$userId = (int)CurrentUser::get()->getId();
if ($userId <= 0)
{
return;
}
$oldFuserId = Fuser::getIdByUserId($userId); // может совпасть с currentFuserId

Если старого FUSER нет или он совпадает с текущим — делать нечего

if (!$oldFuserId || $oldFuserId == $currentFuserId)
{
return;
}

Теперь работаем непосредственно с корзинками

Загружаем корзины и сохраняем их данные

Текущую корзину ставим основной

$currentBasket = Basket::loadItemsForFUser($currentFuserId, $siteId);

Старую же корзину всю переводим в статус отложенной

$oldBasket = Basket::loadItemsForFUser($oldFuserId, $siteId);
foreach ($oldBasket as $basketItem)
{
// Только не оформленные заказом позиции
if ($basketItem->getField('ORDER_ID') === null)
{
$basketItem->setField('DELAY', 'Y');
}
}

Таким образом мы те товары, что пользователи ранее накидывали себе в корзину просто будут в отложенных и всегда могут быть возвращены в основную корзину.

Если есть ошибки то их нужно обработать

$result = $oldBasket->save();
if (!$result->isSuccess())
{
// обработать ошибки при необходимости
}

Ну и наконец привязываем текущую корзину к пользователю, т.е. гостевую делаем боевой.

FuserTable::update($currentFuserId, [
'USER_ID' => $userId,
]);

Вот собственно и все.

Подпишитесь на наш телеграм - https://t.me/official_3rednet

#bitrix #разработка #корзина