Авторегистрация при заказе

Для одного из магазинов потребовалось создать авторегистрацию посетителей при оформлении заказа. За основу был взят метод "Оформление заказа в один шаг – 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);
 }