Из-за часто меняющегося компонента оформления заказа приведенное здесь решение не является полным и окончательным, а следить за актуальностью я не могу. Поэтому прошу пост рассматривать лишь для подспорья в написании собственного кода, а не использовать "как есть".
ЗЫ: Вот последняя актуальная (примерно на июнь 2014) версия компонента, которую я запилил под одного клиента: . Пользуйтесь как есть, пожалуйста. Измененные блоки (менялся только component.php) я выделил фразой customization (конкретно для клиента менял еще некоторые строчки). Кодировка cp1251.
Оформление заказа почти идеально, но есть минус - если гость вводит e-mail, который есть в базе, ему дадут от ворот поворот - мол такой пользователь уже есть. А если подойти с точки зрения покупателя, это ломает - вспоминать пароль, или еще что. В общем, лояльность падает. Исправим ситуацию (сразу хочу огорчить - решение подразумевает +2 байта в системном компоненте, так что если вам не пойдет - пост бесполезен (хотя, вы можете просто вынести компонент в свое пространство, код все равно будет рабочим).
[spoiler]
Речь пойдет про компонент sale.order.ajax, одношаговое оформление заказа. Почему нельзя вынести компонент в свое пространство и изменить? Потому что это центровой компонент магазина, который постоянно улучшается компанией Битрикс, и лично я против его изменения. Так как же подошел к проблеме я.
Все методы ниже - методы класса CSaleHandlers, внутри которого содержатся необходимые .
Также класс имеет переменную
Поехали
1. Событие OnSaleComponentOrderOneStepProcess
Перед самым созданием заказа, перехватываем исполнение и смотрим - если пользователь с введенным e-mail, есть, то авторизуем его. От греха подальше, НЕ авторизуем если пользователь из группы админов. Это достаточно важный момент, потому что ошибка может произойти на любой строчке кода, и тогда гость может остаться админом.
В переменной self::$bGuestOrder запоминаем, что заказ создает гость.
2. Событие OnOrderUpdate
Разавторизовываем пользователя после создания заказа (в понятиях кода, а не сайта). Почему нельзя использовать OnOrderAdd? Потому что после добавления идет еще привязка корзины пользователя, и мы потеряем ее в случае OnOrderAdd. Также в сессии запоминаем предыдущий ID пользователя, который нам пригодится
3. Событие OnSaleComponentOrderOneStepComplete
Здесь мы страхуемся и делаем логаут пользователю, если случилась ошибка при создании заказа.
4. Событие OnSaleComponentOrderOneStepFinal
Здесь мы запрещаем просмотр заказа на финальном шаге (оплата), если это гость и не создал его только что сам.
По идее все. Где же надо поправить системный компонент sale.order.ajax/component.php?
Для версии Магазина до 12.5.4. примерно на 2079 строчке (но строчки постоянно скачут при изменениях, так что ориентироваться лучше на окружающий код) идет выборка созданного заказа с проверкой пользователя - вот пользователя надо закомментировать:

После версии 12.5.4 модуля Магазин, код иной:

Обратите внимание. Данное изменение компонента может работать только вкупе с данными обработчиками. Иначе доступ к финальному шагу (системе оплаты) получает любой пользователь.
Изменения компонента не было бы, если бы реализованная , просьба поддержать.
Класс необходимых обработчиков вы можете скачать ниже. Достаточно просто подключить его в init.php
ЗЫ: Вот последняя актуальная (примерно на июнь 2014) версия компонента, которую я запилил под одного клиента: . Пользуйтесь как есть, пожалуйста. Измененные блоки (менялся только component.php) я выделил фразой customization (конкретно для клиента менял еще некоторые строчки). Кодировка cp1251.
Оформление заказа почти идеально, но есть минус - если гость вводит e-mail, который есть в базе, ему дадут от ворот поворот - мол такой пользователь уже есть. А если подойти с точки зрения покупателя, это ломает - вспоминать пароль, или еще что. В общем, лояльность падает. Исправим ситуацию (сразу хочу огорчить - решение подразумевает +2 байта в системном компоненте, так что если вам не пойдет - пост бесполезен (хотя, вы можете просто вынести компонент в свое пространство, код все равно будет рабочим).
[spoiler]
Речь пойдет про компонент sale.order.ajax, одношаговое оформление заказа. Почему нельзя вынести компонент в свое пространство и изменить? Потому что это центровой компонент магазина, который постоянно улучшается компанией Битрикс, и лично я против его изменения. Так как же подошел к проблеме я.
Все методы ниже - методы класса CSaleHandlers, внутри которого содержатся необходимые .
Также класс имеет переменную
private static $bGuestOrder = false; |
Поехали
1. Событие OnSaleComponentOrderOneStepProcess
//AddEventHandler('sale', 'OnSaleComponentOrderOneStepProcess', Array('CSaleHandlers', 'OnSaleComponentOrderOneStepProcessHandler'));
public static function OnSaleComponentOrderOneStepProcessHandler($arResult, $arUserResult, $arParams) {
if (empty($arResult['ERROR']) && $arUserResult['CONFIRM_ORDER']=='Y' && !$GLOBALS['USER']->IsAuthorized()) {
if ($arUser = CUser::GetList($by='id', $order='asc', array('=EMAIL' => $arUserResult['USER_EMAIL']))->Fetch()) {
if (!in_array(1, CUser::GetUserGroup($arUser['ID']))) {
$GLOBALS['USER']->Authorize($arUser['ID']);
self::$bGuestOrder = true;
}
}
}
} |
Перед самым созданием заказа, перехватываем исполнение и смотрим - если пользователь с введенным e-mail, есть, то авторизуем его. От греха подальше, НЕ авторизуем если пользователь из группы админов. Это достаточно важный момент, потому что ошибка может произойти на любой строчке кода, и тогда гость может остаться админом.
В переменной self::$bGuestOrder запоминаем, что заказ создает гость.
2. Событие OnOrderUpdate
//AddEventHandler('sale', 'OnOrderUpdate', Array('CSaleHandlers', 'OnOrderUpdateHandler'));
public static function OnOrderUpdateHandler($ID, $arFields) {
if (self::$bGuestOrder && $GLOBALS['USER']->IsAuthorized() && isset($arFields['PRICE'])) {
$_SESSION['SAVED_UID'] = $GLOBALS['USER']->GetID();
$GLOBALS['USER']->Logout();
}
} |
Разавторизовываем пользователя после создания заказа (в понятиях кода, а не сайта). Почему нельзя использовать OnOrderAdd? Потому что после добавления идет еще привязка корзины пользователя, и мы потеряем ее в случае OnOrderAdd. Также в сессии запоминаем предыдущий ID пользователя, который нам пригодится
3. Событие OnSaleComponentOrderOneStepComplete
//AddEventHandler('sale', 'OnSaleComponentOrderOneStepComplete', Array('CSaleHandlers', 'OnSaleComponentOrderOneStepCompleteHandler'));
public static function OnSaleComponentOrderOneStepCompleteHandler($ID, $arOrder, $arParams) {
if ($ID <= 0) {
if (self::$bGuestOrder) {
$GLOBALS['USER']->Logout();
}
}
}
|
Здесь мы страхуемся и делаем логаут пользователю, если случилась ошибка при создании заказа.
4. Событие OnSaleComponentOrderOneStepFinal
//AddEventHandler('sale', 'OnSaleComponentOrderOneStepFinal', Array('CSaleHandlers', 'OnSaleComponentOrderOneStepFinalHandler'));
public static function OnSaleComponentOrderOneStepFinalHandler($ID, $arOrder, $arParams) {
if ((!$GLOBALS['USER']->IsAuthorized() && $_SESSION['SAVED_UID']!=$arOrder['USER_ID']) ||
($GLOBALS['USER']->IsAuthorized() && $GLOBALS['USER']->GetID()!=$arOrder['USER_ID'])
) {
$arOrder = array();
}
} |
Здесь мы запрещаем просмотр заказа на финальном шаге (оплата), если это гость и не создал его только что сам.
По идее все. Где же надо поправить системный компонент sale.order.ajax/component.php?
Для версии Магазина до 12.5.4. примерно на 2079 строчке (но строчки постоянно скачут при изменениях, так что ориентироваться лучше на окружающий код) идет выборка созданного заказа с проверкой пользователя - вот пользователя надо закомментировать:

После версии 12.5.4 модуля Магазин, код иной:

Обратите внимание. Данное изменение компонента может работать только вкупе с данными обработчиками. Иначе доступ к финальному шагу (системе оплаты) получает любой пользователь.
Изменения компонента не было бы, если бы реализованная , просьба поддержать.
Класс необходимых обработчиков вы можете скачать ниже. Достаточно просто подключить его в init.php
идет выполнение скрипта - авторизовались.... создался заказ... логаут... На выходе все равно гость. Есть риск, что во время создания заказа вывалится баг (крашнутая таблица, кривые апдейты), вот тут есть риск остаться авторизованным. Случай на миллион (для админа), поэтому я не стал рисковать.