Для одного из магазинов потребовалось создать авторегистрацию посетителей при оформлении заказа. За основу был взят метод "Оформление заказа в один шаг – tpl шаблонизатор" //wiki.umisoft.ru/Оформление_заказа_в_один_шаг_–_tpl_шаблонизатор
Почему был выбран одношаговый метод.
Во-первых, штатная политика весьма удивительна: вам предлагают указать адрес доставки, и лишь потом интересуются не хотите ли вы самовывоз. Сказать, что это нелогично - не сказать ничего. Это все равно пришлось бы переделывать, и раз уж переделывать одно, то почему бы и не все.
Во-вторых, у меня возникли проблемы с сохранением заказа при регистрации. Я захожу как гость. Набираю товаров в корзину. И потом вдруг нелегкая несет меня регистрироваться! Все, после этого корзина обнуляется. Хотя, если не регистрироваться, а только авторизовываться, то все пучком, товары остаются. Так оставлять дело нельзя, товар из корзины пропадать не должен.
Посчитал, что самый простой путь будет оформить заказ в один шаг, зарегистрировать клиента, и потом поменять владельца заказа с гостя на свежеполученный id.
Я не буду приводить весь код, поскольку по приведенной в начале ссылке на вики все подробно расписано. Далее два метода: авторегистрация и основной метод сохранения данных в одношаговом заказе, поскольку у меня еще была необходимость регистрировать и юрлицо.
Авторегистрация
Метод полностью списан со штатной регистрации. В конце добавлена запись куков и сессии и успешной активации
public function auto_registrate_do($data,$customerId) {
$usersModule = $dataModule = cmsController::getInstance()->getModule('users');
if ($usersModule->is_auth()) {
return $customerId;
}
$objectTypes = umiObjectTypesCollection::getInstance();
$regedit = regedit::getInstance();
$objectTypeId = $objectTypes->getBaseType("users", "user");
if($customObjectTypeId = getRequest('type-id')) {
$childClasses = $objectTypes->getChildClasses($objectTypeId);
if(in_array($customObjectTypeId, $childClasses)) {
$objectTypeId = $customObjectTypeId;
}
}
$objectType = $objectTypes->getType($objectTypeId);
$login = (string) $data[$customerId]['email'];
$password = (string) substr(md5(uniqid(rand(),true)),0,8);
$email = (string) $data[$customerId]['email'];
$oEventPoint = new umiEventPoint("users_registrate");
$oEventPoint->setMode("before");
$oEventPoint->setParam("login", $login);
$oEventPoint->addRef("password", $password);
$oEventPoint->addRef("email", $email);
$this->setEventPoint($oEventPoint);
if(!$usersModule->checkIsUniqueEmail($email)) {
$this->errorNewMessage("%error_users_non_unique_email%");
$this->errorPanic();
}
$login_field_id = $objectType->getFieldId("login");
$sel = new umiSelection;
$sel->addLimit(1);
$sel->addObjectType($objectTypeId);
$sel->addPropertyFilterEqual($login_field_id, $login);
$is_exists = (bool) umiSelectionsParser::runSelectionCounts($sel);
if($is_exists) {
$this->errorNewMessage("%err_users_user_exists%");
$this->errorPanic();
}
//Creating user...
$object_id = umiObjectsCollection::getInstance()->addObject($login, $objectTypeId);
$activate_code = md5($login . time());
$object = umiObjectsCollection::getInstance()->getObject($object_id);
$object->setValue("login", $login);
$object->setValue("password", md5($password));
$object->setValue("e-mail", $email);
$object->setValue("is_activated", 1);
$object->setValue("activate_code", $activate_code);
$_SESSION['cms_login'] = $login;
$_SESSION['cms_pass'] = md5($password);
$_SESSION['user_id'] = $object_id;
session_commit();
$group_id = regedit::getInstance()->getVal("//modules/users/def_group");
$object->setValue("groups", Array($group_id));
$object->setValue('fname',$data[$customerId]['fname']);
$object->setValue('lname',$data[$customerId]['lname']);
$object->setValue('father_name',$data[$customerId]['father_name']);
$object->setValue('telefon_1',$data[$customerId]['phone']);
$data_module = cmsController::getInstance()->getModule('data');
$data_module->saveEditedObject($object_id, true);
$object->commit();
if ($eshop_module = cmsController::getInstance()->getModule('eshop')) {
$eshop_module->discountCardSave($object_id);
}
//Forming mail...
list(
$template_mail, $template_mail_subject
) = def_module::loadTemplates("users/register/autoregister",
"mail_registrated", "mail_registrated_subject"
);
$mail_arr = Array();
$mail_arr['user_id'] = $object_id;
$mail_arr['domain'] = $domain = $_SERVER['HTTP_HOST'];
$mail_arr['activate_link'] = "//" . $domain . $this->pre_lang . "/users/activate/" . $activate_code . "/";
$mail_arr['password'] = $password;
$mail_arr['login'] = $login;
$mail_arr['lname'] = $object->getValue("lname");
$mail_arr['fname'] = $object->getValue("fname");
$mail_arr['father_name'] = $object->getValue("father_name");
$mail_content = def_module::parseContent($template_mail, $mail_arr, false, $object_id);
$template_mail_subject = def_module::parseContent($template_mail_subject, $mail_arr, false, $object_id);
$fio = $object->getValue("lname") . " " . $object->getValue("fname") . " " . $object->getValue("father_name");
$email_from = "указать_почту";
$fio_from = "от кого";
$someMail = new umiMail();
$someMail->addRecipient($email, $fio);
$someMail->setFrom($email_from, $fio_from);
$someMail->setSubject($template_mail_subject);
$someMail->setContent($mail_content);
$someMail->commit();
$someMail->send();
$oEventPoint = new umiEventPoint("users_registrate");
$oEventPoint->setMode("after");
$oEventPoint->setParam("user_id", $object_id);
$this->setEventPoint($oEventPoint);
return $object_id;
}
Сохранение регистрационных данных
Здесь создаем заказ, создаем адреса доставки и юрлицо, затем меняем владельца заказа, адресов и юрлица
Обращаю внимание, что местами я указывал специфические id и пути; их следует скорректировать
public function saveinfo(){
$order = $this->getBasketOrder(false);
$cmsController = cmsController::getInstance();
$types = umiObjectTypesCollection::getInstance();
$o = $collection = umiObjectsCollection::getInstance();
$data = getRequest('data');
$customerId = customer::get()->id;
//регистрируем клиента
$customerId2 = self::auto_registrate_do($data,$customerId);
$order = $this->getBasketOrder(false);
//сохранение регистрационных данных.
$dataModule = $cmsController->getModule('data');
$dataModule->saveEditedObject($customerId, false, true);
$customer = customer::get();
// Если выбрано юр. лицо, то сохраняем его
$payment_type = getRequest('payment-id');
if($payment_type == 38862){//если это юр лицо. ИЗМЕНИТЬ ДЛЯ КОНКРЕТНОЙ РЕАЛИЗАЦИИ
$personId = getRequest('legal-person');
$isNew = ($personId == null || $personId == 'new');
if($isNew) {
$typeId = $types->getBaseType("emarket", "legal_person");
$customer = customer::get();
$personId = $collection->addObject("", $typeId);
$customer->legal_persons = array_merge($customer->legal_persons, array($personId));
}
if($data && $dataModule) {
$key = $isNew ? 'new' : $personId;
$person = $collection->getObject($personId);
if ($isNew) {
//поскольку часть полей для физ. и юр лиц совпадает, то подставляем их из формы физ. лица
if (permissionsCollection::getInstance()->isAuth()){
$permissions = permissionsCollection::getInstance();
$userId = $permissions->getUserId();
$oUser = $collection -> getObject($userId);
$data['new']['contact_person'] = $oUser->fname;
$data['new']['phone_number'] = $oUser->phone;
$data['new']['email'] = $oUser->email;
$person->setName($oUser->name);
}
else{
$data['new']['contact_person'] = $data[$customerId]['fname'];
$data['new']['phone_number'] = $data[$customerId]['phone'];
$data['new']['email'] = $data[$customerId]['email'];
$person->setName($data[$key]['name']);
}
$dataModule->saveEditedObject($personId, $isNew, true);
}
}
$order->legal_person = $personId;
$order->payment_document_num = $order->id;
}
//сохранение способа доставки
$deliveryId = getRequest('delivery-id');
if($deliveryId){
$delivery = delivery::get($deliveryId);
$deliveryPrice = (float) $delivery->getDeliveryPrice($order);
$order->setValue('delivery_id', $deliveryId);
$order->setValue('delivery_price', $deliveryPrice);
}
//сохранение адреса доставки
$addressId = getRequest('delivery-address');
if($addressId == 'new') {
$typeId = $types->getBaseType("emarket", "delivery_address");
$customer = customer::get();
$addressId = $collection->addObject("Address for customer #".$customerId, $typeId);
$dataModule->saveEditedObject($addressId, true, false);
$customer->delivery_addresses = array_merge( $customer->delivery_addresses, array($addressId) );
}
$order->delivery_address = $addressId;
//сохранение способа оплаты и редирект на итоговую страницу
$order->setValue('payment_id', getRequest('payment-id'));
$comment = htmlspecialchars(getRequest('comment'));//Это комментарий к заказу. См вики
$order->comment = $comment;
$order->commit();
$order->refresh();
//меняем владельца заказа
$order->setValue('customer_id', $customerId2);
$order->commit();
$order->refresh();
$oAddress = $o -> getObject($addressId);
if($oAddress){
$oAddress->setOwnerId($customerId2);
$oAddress->commit();
}
$oUser = $collection -> getObject($customerId2);
$oUser->setValue('legal_persons', $customer->legal_persons);
$oUser->setValue('delivery_addresses', $customer->delivery_addresses);
$oOrder = $collection -> getObject($order->id);
$oOrder->setOwnerId($customerId2);
$oOrder->commit();
if(isset($personId)){//это юрлицо
$oPerson = $collection -> getObject($personId);
$oPerson->setOwnerId($customerId2);
$oPerson->commit();
$oOrder->legal_person = $personId;
$oOrder->commit();
}
setcookie('customer-id', $customerId2, (time() + 2678400), '/');
$paymentId = getRequest('payment-id');
if(!$paymentId) {
$this->errorNewMessage(getLabel('error-emarket-choose-payment'));
$this->errorPanic();
}
$payment = payment::get($paymentId);
if($payment instanceof payment) {
$paymentName = $payment->getCodeName();
$url = "{$this->pre_lang}/".cmsController::getInstance()->getUrlPrefix()."emarket/purchase/payment/{$paymentName}/";
} else {
$url = "{$this->pre_lang}/".cmsController::getInstance()->getUrlPrefix()."emarket/cart/";
}
$this->redirect($url);
}