Стандартный компонент одношагового оформления заказа (sale.order.ajax) уже умеет создавать заказ под гостем, но с регистрацией пользователя. А если надо привязать гостевой заказ по e-mail к существующему пользователю? Уже никак, выдастся ошибка, что с таким e-mail пользователь есть и либо выбирайте другой e-mail, или авторизуйтесь.
Ох и намучился я с разными вариантами подхода к решению задачи :) ведь стояло главное условие - нельзя трогать шаблон, и, тем более, компонент (идеальное условие). Но вроде бы все решил в итоге.
Итак, дан компонент sale.order.ajax с включенной опцией "Оформлять заказ с автоматической регистрацией пользователя".
1. Убираем галочку в настройках главного модуля "Проверять E-mail на уникальность".
Что теперь имеем? Теперь всегда заказ создастся, даже если с таким e-mail уже есть пользователь в базе. Но мы получаем разрозненность заказов для уникальных адресов. Об этом ниже.
2. Если вам критичны дубли регистраций (последствия п.1), ставите для обычной регистрации обработчик, который проверяет e-mail на уникальность:
AddEventHandler('main', 'OnBeforeUserRegister', array('CMainhandlers', 'OnBeforeUserRegisterHandler'));
class CMainhandlers
{
public static function OnBeforeUserRegisterHandler(&$arFields)
{
if (CUser::GetList($by='id', $order='desc', array('=EMAIL' => $arFields['EMAIL']))->Fetch())
{
$GLOBALS['APPLICATION']->throwException('Пользователь с таким E-Mail уже зарегистрирован.');
return false;
}
}
}
3. Сердце решения.
AddEventHandler('sale', 'OnSaleComponentOrderOneStepComplete', array('CSalehandlers', 'OnSaleComponentOrderOneStepCompleteHandler'));
class CSalehandlers
{
public static function OnSaleComponentOrderOneStepCompleteHandler($ID, $arFields)
{
if ($arFields['ID'] > 0)
{
if ($arFields['USER_ID'] > 0)
{
$arExtUser = CUser::GetByID($arFields['USER_ID'])->Fetch();//1
if ($arOldUser = CUser::GetList($by='id', $order='desc', array('=EMAIL' => $arExtUser['EMAIL'], '!ID' => $arExtUser['ID']))->Fetch())//2
{
CSaleOrder::Update($arFields['ID'], array('USER_ID' => $arOldUser['ID']));//3
CUser::Delete($arExtUser['ID']);//4
$GLOBALS['USER']->Logout();//5
echo 'Some text for guest';//6
exit();//7
}
}
}
}
}
Этот обработчик вызывается в самом компоненте когда все сделано, заказ оформлен. Что делаем, шаги?
1. Дергаем информацию пользователя созданного заказа.
2. Ищем по базе пользователей с таким же адресом, но не с таким же ID. Если такой пользователь есть, значит надо привязать заказ к найденному пользователю и забрать у текущего.
3. Обновляем созданный заказ на привязку к существующему пользователю.
4. Удаляем текущего, только что созданного, пользователя.
5. Делаем логаут.
6-7. Так как этот код делает вывод в ajax-режиме, то редирект не подойдет, тут надо написать вручную, что мол ваш заказ оформлен, или уже javascript-кодом сделать редирект куда вам надо. В общем. частные случаи пошли.
Теперь главный минус. Заказ создан, но его надо оплатить, а на страницу оплаты заказа допускается только хозяин заказа. Авторизовать текущего пользователя по e-mail мы естественно не можем (безопасность).
Какие варианты?
1. Скорее всего, если вы пошли на этот шаг, то у вас есть простые варианты оплаты (наличные то бишь), то гостю и не критична оплата заказа через сайт. То есть можно написать в п.6 выше, что мол заказ оформлен, менеджер с вами свяжется, ждите.
2. Редиректить на страницу с оплатой текущего заказа... тут затык. Как его авторизовывать там? Или вывести данные для оплаты (например, форму для оплаты по карте)? Тут очень частные случаи пошли, прямиком упирающиеся в то, что безопасно ли будет выводить детали заказа для его оплаты, поэтому я здесь это рассматривать не буду. Но такая задача наверняка поднимется в текущем мною делаемом проекте, если решено будет по какому-то здесь варианту идти, напишу решения.
3. Авторизация по его данным (то бишь выводить окно авторизации после редиректа) - пусть сначала вводит логин и пароль. Но тогда весь смысл этой статьи отпадает, ведь он мог авторизоваться сразу же.
Присоединяйтесь — мы покажем вам много интересного
Присоединяйтесь к ОК, чтобы подписаться на группу и комментировать публикации.
Нет комментариев