Класс customer модуля emarket — различия между версиями

Материал из Umicms
Перейти к:навигация, поиск
(Новая страница: «'''Актуально для версии 2.9.5''' == Описание == Одним из классов, который необходим для работы м…»)
 
 
(не показано 60 промежуточных версий этого же участника)
Строка 1: Строка 1:
 
'''Актуально для версии 2.9.5'''
 
'''Актуально для версии 2.9.5'''
  
 +
=Класс customer=
  
 
== Описание ==
 
== Описание ==
Строка 8: Строка 9:
 
Исходный код класса находится в файле classes\modules\emarket\classes\customer\customer.php
 
Исходный код класса находится в файле classes\modules\emarket\classes\customer\customer.php
  
== Переменные ==
+
== Свойства класса ==
В класса объявлены две переменные.
 
  
Переменная $defaultExpiration, которая будет использована при создании cookie для указания времени ее жизни
+
 
 +
$defaultExpiration хранит время жизни cookie  
 
<source lang="php">
 
<source lang="php">
 
public static $defaultExpiration = 2678400; // 31 days
 
public static $defaultExpiration = 2678400; // 31 days
 
</source>
 
</source>
  
Переменная $isAuth будет хранить 1, если покупатель - авторизованный пользователь, 0 в противном случае
+
$isAuth хранит id пользователя, если покупатель - авторизованный пользователь, false в противном случае
 
<source lang="php">
 
<source lang="php">
 
protected $isAuth;
 
protected $isAuth;
Строка 22: Строка 23:
  
 
== Методы ==
 
== Методы ==
 +
 +
=== __construct() ===
 +
 +
Экземпляр класса создается с помощью <span style="font-weight:bold">__construct()</span>
 +
<p>'''Параметры:''' </p><br/>
 +
iUmiObject<span style="font-weight:bold"> $object</span>:
 +
содержит в себе либо объект "зарегистрированный пользователь" либо объект "незарегистрированный покупатель"<br/>
 +
<p>'''Результат:''' экземпляр класса customer</p>
 +
 +
При создании объекта, методом определяется, какое значение будет хранить переменная $isAuth:
 +
 
<source lang="php">
 
<source lang="php">
public function selected_groups($template = 'default'){
+
 
+
public function __construct(iUmiObject $object) {
$groups = new selector('objects');
+
$permissions = permissionsCollection::getInstance();
$groups->types('object-type')->id('36');
+
                        //получить id текущего пользователя
$groups->where('for_registration')->equals('1');
+
$userId = $permissions->getUserId();
+
                        //получить id гостя
list($itemsTemplate, $itemTemplate) = def_module::loadTemplates("users/{$template}", "items", "item");
+
$guestId = permissionsCollection::getGuestId();
$item = array();
+
                        // если id гостя равен id текущего пользователя записать в переменную $isAuth false, в противном 
$items = array();
+
                        случае записать id текущего пользователя
foreach($groups as $group){
+
$this->isAuth = ($userId == $guestId) ? false : $userId;
$item['attribute:id'] = $group->getId();
+
                        //создать экземпляр класса покупатель
$item['attribute:name'] = $group->getValue('nazvanie');
+
parent::__construct($object);
$items[] = def_module::parseTemplate($itemTemplate, $item);
+
}
}
 
$items = array('subnodes:items' => $items);
 
return def_module::parseTemplate($itemsTemplate, $items);
 
}
 
 
</source>
 
</source>
  
Теперь,идем в шаблон, по которому выводится форма регистрации(templates/demodizzy/xslt/modules/users/registration.xsl) и добавим туда вызов макроса:
+
=== get() ===
 +
Получить экземпляр класса можно с помощью функции <span style="font-weight:bold">get()</span>, если покупатель не существует, то метод создаст новый экземпляр класса
 +
  <p>'''Параметры:''' </p><br/>
 +
bool<span style="font-weight:bold"> $nocache</span>:
 +
не использовать данные кэша, по умолчанию false<br/>
 +
  <p>'''Результат:''' экземпляр класса customer</p>
 +
 
 +
<source lang="php">
 +
public static function get($nocache = false) {
 +
static $customer;
 +
//Сначала функция get() проверит создан ли уже объект покупатель
 +
if(!$nocache && !is_null($customer)) {
 +
 
 +
//вернет объект покупатель, если он существует
 +
return $customer;                         
 +
}
 +
 
 +
 
 +
$objects = umiObjectsCollection::getInstance();   
 +
$permissions = permissionsCollection::getInstance();
 +
 
 +
                        // если объект не существует, проверит авторизован ли пользователь
 +
if($permissions->isAuth()) {
 +
$userId = $permissions->getUserId();
 +
 
 +
                                //авторизован - запишет в переменную $object(входной параметр для конструктора класса)
 +
                                объект текущего пользователя
 +
$object = $objects->getObject($userId);
 +
} else {
 +
                                //не авторизован - запишет в переменную $object объект покупателя-гостя,
 +
                                получает этот объект функция getCustomerId()
 +
$object = self::getCustomerId();
  
<source lang="xml">
+
//выполнить повторную проверку, это может быть полезно при конфликтах после перезагрузки сервера
 +
if($object === false) $object = self::getCustomerId(true);
 +
}
  
<div>
+
if($object instanceof iUmiObject) {
    <label class="required">
+
                        //будет создан экземпляр класса customer, на основе объекта переданного в переменную $object
        <span>
+
$customer = new customer($object);
      <xsl:text>группа:</xsl:text>
+
                      //только что созданный экземпляр класса обратиться к функции  tryMerge()
</span>
+
$customer->tryMerge();
<xsl:apply-templates select="document('udata://users/selected_groups/')/udata" />
+
return $customer;
    </label>
+
}
</div>
+
}
 
</source>
 
</source>
  
и шаблон обработки результатов, который будет выводить выбранные группы в выпадающем списке:
 
  
<source lang="xml">
+
=== IsUser() ===
  
<xsl:template match="udata[@module = 'users'][@method = 'selected_groups']">
+
Метод <span style="font-weight:bold">isUser()</span> вернет значение типа boolean, 1 или 0, в зависимости от того является ли покупатель зарегистрированным пользователем, т.е. будет проверено содержит ли переменная $isAuth идентификатор пользователя, или же, содержит false
<select name = 'group' id = 'group'>
+
<p>'''Параметры:''' </p>
<xsl:for-each select = "./items/item">
+
<p>'''Результат:''' boolean</p>
<option value = "{./@id}">
+
        <xsl:value-of select = "./@name"/>
 
</option>
 
</xsl:for-each>
 
</select>
 
</xsl:template>
 
</source>
 
  
 +
=== getCustomerId() ===
  
Теперь нам нужно написать метод, который обработает введенные пользователем данные и запишет его в выбранную им же группу.
+
Метод <span style="font-weight:bold">getCustomerId()</span> вернет объект покупателя-гостя, если объект не существует, обратится к методу  <span style="font-weight:bold">createGuestCustomer()</span>, который создаст нового покупателя-гостя
Для этого можно воспользоваться стандартным методом registrate_do, немного его изменив. Идем в /classes/modules/users/_register.php,
+
  <p>'''Параметры:''' </p><br/>
полностью копируем оттуда метод registrate_do и вставляем в файл __custom.php, в этой же директории.
+
bool <span style="font-weight:bold">$noCookie</span>:
Переименуем его, например, в registrate_do_custom.
+
"не использовать данные кук", по умолчанию false<br/>
Начальный код метода:
+
<p>'''Результат:''' объект "покупатель-гость", записанный в переменную $customer</p>
  
 
<source lang="php">
 
<source lang="php">
public function registrate_do_custom($template = "default") {
 
if ($this->is_auth()) {
 
$this->redirect($this->pre_lang . "/");
 
}
 
if(!($template = getRequest('template'))) {
 
$template = 'default';
 
}
 
$objectTypes = umiObjectTypesCollection::getInstance();
 
$regedit = regedit::getInstance();
 
  
$refererUrl = getServer('HTTP_REFERER');
+
protected static function getCustomerId($noCookie = false) {
$without_act = (bool) $regedit->getVal("//modules/users/without_act");
 
  
$objectTypeId = $objectTypes->getBaseType("users", "user");
+
                        //в переменную $customerId записывается id покупателя-гостя
if ($customObjectTypeId = getRequest('type-id')) {
+
static $customerId;
$childClasses = $objectTypes->getChildClasses($objectTypeId);
+
 
if (in_array($customObjectTypeId, $childClasses)) {
+
                        //проверка на то, содержит ли переменная значение
$objectTypeId = $customObjectTypeId;
+
if(is_null($customerId)) {
 +
 
 +
                        //Если переменная  $customerId пуста, получит id покупателя из кук
 +
$customerId = (int) getCookie('customer-id');
 +
}
 +
                        //получить существующий объект "покупатель" по id
 +
$customer = selector::get('object')->id($customerId);
 +
 
 +
if($customer instanceof iUmiObject != false) {
 +
 
 +
                          //если полученный объект является экземпляром класса iUmiObject, получим тип объекта
 +
$type = selector::get('object-type')->id($customer->getTypeId());
 +
                                //получим метод, по которому был создан объект
 +
if($type->getMethod() != 'customer') {
 +
 
 +
                                //если метод не customer, в переменную $customer запишем null
 +
$customer = null;
 +
}
 +
} else {
 +
                              //если полученный объект не является экземпляром класса iUmiObject, в переменную $customer
 +
                                также запишем null
 +
$customer = null;
 +
}
 +
                        //если $customer не определена, создадим новый объект "покупатель-гость"
 +
if(!$customer) {
 +
$customerId = self::createGuestCustomer();
 +
                        //получим id объекта
 +
$customer = selector::get('object')->id($customerId);
 +
}
 +
                        // если у объекта не задан id(т.е. объект не сущетсвует),создадим новый объект "покупатель-гость"
 +
if(!$customerId) {
 +
$customerId = self::createGuestCustomer();
 +
}
 +
                        //если не активен консольный режим, создаем куку в браузере пользователя
 +
if (!defined('UMICMS_CLI_MODE') || !UMICMS_CLI_MODE) {
 +
setcookie('customer-id', $customerId, (time() + self::$defaultExpiration), '/');
 +
}
 +
                        // устанавливаем "время жизни" объекта "покупатель-гость"
 +
$expirations = umiObjectsExpiration::getInstance();
 +
$expirations->set($customerId, self::$defaultExpiration);
 +
 
 +
                        //возвращаем объект "покупатель-гость"
 +
return $customer;
 
}
 
}
}
+
</source>
  
$objectType = $objectTypes->getType($objectTypeId);
+
=== createGuestCustomer() ===
  
$this->errorSetErrorPage($refererUrl);
 
  
$login = $this->validateLogin(getRequest('login'), false, true);
+
Метод <span style="font-weight:bold">createGuestCustomer()</span> создаст новый объект "покупатель-гость"
$password = $this->validatePassword(getRequest('password'), getRequest('password_confirm'), getRequest('login'), true);
+
<p>'''Параметры:''' </p>
$email = $this->validateEmail(getRequest('email'), false, !$without_act);
+
<p>'''Результат:''' id "покупателя-гость", записанный в переменную $customer</p>
 +
 
 +
<source lang="php">
 +
protected static function createGuestCustomer() {
 +
                        //получить коллекцию типов объектов
 +
$objectTypes = umiObjectTypesCollection::getInstance();
  
//Captcha validation
+
                        //получить коллекцию объектов
if (isset($_REQUEST['captcha'])) {
+
$objects = umiObjectsCollection::getInstance();
$_SESSION['user_captcha'] = md5((int) getRequest('captcha'));
 
}
 
  
if (!umiCaptcha::checkCaptcha()) {
+
                        //получить тип данных "покупатель"
$this->errorAddErrors('errors_wrong_captcha');
+
$objectTypeId = $objectTypes->getBaseType('emarket', 'customer');
}
 
  
$this->errorThrow('public');
+
                        //добавить объект "покупатель-гость", имеющий тип данных "покупатель", записать в переменную $customerId
 +
                        id "покупателя-гостя"
 +
$customerId = $objects->addObject(getServer('REMOTE_ADDR'), $objectTypeId);
 +
                       
 +
                        //получить объект "покупатель-гость"
 +
$customer = $objects->getObject($customerId);
 +
                       
 +
                        //установить владельцем объекта пользователя гость
 +
$customer->setOwnerId($objects->getObjectIdByGUID('system-guest'));
  
$oEventPoint = new umiEventPoint("users_registrate");
+
                        //вернуть id объекта "покупатель-гость"
$oEventPoint->setMode("before");
+
return $customerId;
$oEventPoint->setParam("login", $login);
+
}
$oEventPoint->addRef("password", $password);
 
$oEventPoint->addRef("email", $email);
 
$this->setEventPoint($oEventPoint);
 
  
//Creating user...
+
</source>
$objectId = umiObjectsCollection::getInstance()->addObject($login, $objectTypeId);
 
$activationCode = md5($login . time());
 
  
$object = umiObjectsCollection::getInstance()->getObject($objectId);
+
=== tryMerge() ===
  
$object->setValue("login", $login);
+
Метод <span style="font-weight:bold">tryMerge()</span> попытается перенести товары "покупателя-гостя" авторизованному покупателю(пользователю), обратившись к методу <span style="font-weight:bold">merge()</span>
$object->setValue("password", md5($password));
+
<p>'''Параметры:''' </p>
$object->setValue("e-mail", $email);
+
<p>'''Результат:''' </p>
  
$object->setValue("is_activated", $without_act);
+
Данная функция используется, например, если пользователь положил товары в корзину, будучи не авторизован, а потом авторизовался на сайте
$object->setValue("activate_code", $activationCode);
+
<source lang="php">
$object->setValue("referer", urldecode(getSession("http_referer")));
+
public function tryMerge() {
$object->setValue("target", urldecode(getSession("http_target")));
+
                        //проверяет является ли текущий экземпляр класса авторизованным пользователем и есть лиу  него в браузере кука
$object->setValue("register_date", umiDate::getCurrentTimeStamp());
+
if($this->isUser() && getCookie('customer-id')) {
$object->setOwnerId($objectId);
 
  
if ($without_act) {
+
                                //получает объект "покупателя-гостя"
$_SESSION['cms_login'] = $login;
+
$guestCustomer = self::getCustomerId();
$_SESSION['cms_pass'] = md5($password);
+
                               
$_SESSION['user_id'] = $objectId;
+
                                //если объект является экземпляром класса iUmiObject, обратится к функции merge()
 +
if($guestCustomer instanceof iUmiObject) {
 +
$this->merge($guestCustomer);
 +
}
 +
}
 +
}
 +
</source>
  
session_commit();
+
=== merge() ===
}
 
  
$group_id = regedit::getInstance()->getVal("//modules/users/def_group");
+
Метод <span style="font-weight:bold">merge()</span> "переносит" товары "покупателя-гостя" авторизованному покупателю(пользователю), обратившись к методу <span style="font-weight:bold">mergeBasket()</span>
$object->setValue("groups", Array($group_id));
+
<p>'''Параметры:''' </p><br/>
 +
iUmiObject <span style="font-weight:bold">$customer</span>:
 +
содержит в себе объект "покупатель"<br/>
 +
<p>'''Результат:''' </p>
  
cmsController::getInstance()->getModule('data');
 
$data_module = cmsController::getInstance()->getModule('data');
 
$data_module->saveEditedObjectWithIgnorePermissions($objectId, true, true);
 
  
$object->commit();
+
<source lang="php">
 +
public function merge(umiObject $customer) {
 +
                        //получаем id текущего домена
 +
$cmsController = cmsController::getInstance();
 +
$domain = $cmsController->getCurrentDomain();
 +
$domainId = $domain->getId();
 +
                         
 +
                        //получаем список всех заказов текущего объекта "покупатель"
 +
$sel = new selector('objects');
 +
$sel->types('object-type')->name('emarket', 'order');
 +
$sel->where('customer_id')->equals($customer->id);
 +
$sel->where('domain_id')->equals($domainId);
 +
$sel->order('id')->desc();
 +
                       
  
if ($eshop_module = cmsController::getInstance()->getModule('eshop')) {
+
                        //получаем id текущего авторизованного пользователя
$eshop_module->discountCardSave($objectId);
+
$permissions = permissionsCollection::getInstance();
}
+
$userId = $permissions->getUserId();
  
//Forming mail...
+
foreach($sel as $order) {
list($template_mail, $template_mail_subject, $template_mail_noactivation, $template_mail_subject_noactivation) = def_module::loadTemplatesForMail("users/register/".$template,"mail_registrated", "mail_registrated_subject","mail_registrated_noactivation", "mail_registrated_subject_noactivation");
+
                                //ищем заказ, у которого нет статуса
 +
if(!$order->status_id) {
 +
                                        //обращаемся к методу mergeBasket(), передавая в качестве параметра текущий объект заказа
 +
$this->mergeBasket($order);
 +
continue;
 +
}
  
if ($without_act && $template_mail_noactivation && $template_mail_subject_noactivation) {
+
                                //присваиваем для текущего заказа в качестве id покупателя,id авторизованного пользователя
$template_mail = $template_mail_noactivation;
+
$order->customer_id = $userId;
$template_mail_subject = $template_mail_subject_noactivation;
+
                                //сохраняем изменения
}
+
$order->commit();
 +
}
 +
                        //если не активен консольный режим, создаем куку в браузере пользователя
 +
if (!defined('UMICMS_CLI_MODE') || !UMICMS_CLI_MODE) {
 +
setcookie('customer-id', 0, 1, '/');
 +
}
 +
                        //удаляем экземпляр класса "покупатель"
 +
$customer->delete();
 +
}
 +
</source>
  
$mailData = array(
 
'user_id' => $objectId,
 
'domain' => $domain = cmsController::getInstance()->getCurrentDomain()->getCurrentHostName(),
 
'activate_link' => "http://" . $domain . $this->pre_lang . "/users/activate/" . $activationCode . "/",
 
'login' => $login,
 
'password' => $password,
 
'lname' => $object->getValue("lname"),
 
'fname' => $object->getValue("fname"),
 
'father_name' => $object->getValue("father_name"),
 
);
 
  
$mailContent = def_module::parseTemplateForMail($template_mail, $mailData, false, $objectId);
+
=== mergeBasket() ===
$mailSubject = def_module::parseTemplateForMail($template_mail_subject, $mailData, false, $objectId);
 
  
$fio = $object->getValue("lname") . " " . $object->getValue("fname") . " " . $object->getValue("father_name");
+
Метод <span style="font-weight:bold">mergeBasket()</span> "переносит" товары "покупателя-гостя" авторизованному покупателю(пользователю), удаляя по завершению переноса объект "заказ"(корзина гостя)
 +
<p>'''Параметры:''' </p><br/>
 +
umiObject <span style="font-weight:bold">$guestBasket</span>:
 +
содержит в себе текущий объект "заказ"(корзина покупателя)<br/>
 +
<p>'''Результат:''' </p>
  
$email_from = regedit::getInstance()->getVal("//settings/email_from");
 
$fio_from = regedit::getInstance()->getVal("//settings/fio_from");
 
  
 +
<source lang="php">
 +
protected function mergeBasket(umiObject $guestBasket) {
 +
                        //получить все товары в корзине покупателя-гостя
 +
$orderItems = $guestBasket->order_items;
 +
                       
 +
                        //проверить являются ли полученные товары массивом
 +
if(is_array($orderItems)) {
 +
                              //передать в переменную $userBasket заказ, который представляет текущую корзину товаров
 +
$userBasket = __emarket_purchasing::getBasketOrder(false);
  
$registrationMail = new umiMail();
+
                                // проверить задана ли $userBasket
$registrationMail->addRecipient($email, $fio);
+
if($userBasket) {
$registrationMail->setFrom($email_from, $fio_from);
+
                                     
$registrationMail->setSubject($mailSubject);
+
                                       
$registrationMail->setContent($mailContent);
+
foreach($orderItems as $orderItemId) {
$registrationMail->commit();
+
$orderItem = orderItem::get($orderItemId);
$registrationMail->send();
+
if($orderItem) {
 +
                                                        //добавить в текущую корзину товаров, товары из корзины покупателя-гостя
 +
$userBasket->appendItem($orderItem);
 +
}
 +
}
 +
                                        //сохранить текущую корзину товаров
 +
$userBasket->commit();
 +
}
 +
}
 +
                        //удалить корзину покупателя-гостя
 +
$guestBasket->delete();
 +
}
 +
</source>
  
$oEventPoint = new umiEventPoint("users_registrate");
+
=== freeze() ===
$oEventPoint->setMode("after");
 
$oEventPoint->setParam("user_id", $objectId);
 
$oEventPoint->setParam("login", $login);
 
$this->setEventPoint($oEventPoint);
 
  
if ($without_act) {
+
Метод <span style="font-weight:bold">freeze()</span> "заморозит" покупателя, т.е. не удалит его по истечении 31 дня
$this->redirect($this->pre_lang . "/users/registrate_done/?result=without_activation");
+
<p>'''Параметры:''' </p>
}
+
<p>'''Результат:''' </p>
        else {
 
$this->redirect($this->pre_lang . "/users/registrate_done/");
 
}
 
  
}
+
<source lang="php">
 +
public function freeze() {
 +
                        //получить коллекцию "сроков жизни" объектов
 +
$expirations = umiObjectsExpiration::getInstance();
 +
                        //обнулить "срок жизни" для текущего экземпляра класса
 +
$expirations->clear($this->id);
 +
}
 
</source>
 
</source>
  
Чтобы не дать возможности пользователю зарегистрировать каким-либо образом в качестве супервайзера, перед тем как записывать пользователя в базу добавим проверку на то, не является ли переданный id группы id группы супервайзеров. Если пользователь попытался зарегистрироваться супервайзером, его будет редиректить на главную страницу, а ,на указанную при регистрации почту, будет выслано письмо с предупреждением. Находим в коде строку комментария //Creating user... и после нее вставляем следующий код:
+
=== __toString() ===
 +
 
 +
Метод <span style="font-weight:bold">__toString()</span> вернет id текущего экземпляра класса в качестве строки
 +
<p>'''Параметры:''' </p>
 +
<p>'''Результат:''' </p>
  
 
<source lang="php">
 
<source lang="php">
$igroup = getRequest('group');
+
public function __toString() {
$objects = umiObjectsCollection::getInstance();
+
                        //вернуть id покупателя в строковом виде
$SupervisorGroupId = $objects->getObjectIdByGUID('users-users-15');
+
return (string) $this->object->id;
if ($igroup != $SupervisorGroupId){  
+
}
    $group_id = $igroup;
 
}
 
else {
 
    $name = 'admin';
 
    $email = 'admin@adress.com';
 
    $recipient = $email;
 
    $mail_body = 'Зарегистрироваться супервайзером нельзя.';
 
    $subject = 'Даже не пытайтесь.';
 
    $header = "From: ". $name . " <" . $email . ">\r\n";
 
    mail($recipient, $subject, $mail_body, $header);
 
    $this->redirect('/');
 
    exit();
 
}
 
 
</source>
 
</source>
 +
 +
  
Теперь находим следующие строки:
+
=== getLastOrder() ===
 +
 
 +
 
 +
 
 +
 
 +
Метод <span style="font-weight:bold">getLastOrder()</span> получит id последнего заказа пользователя
 +
<p>'''Параметры:''' </p><br/>
 +
int <span style="font-weight:bold">$domainId</span>:
 +
id домена заказа<br/>
 +
<p>'''Результат:'''<br/>int $orderId идентификатор последнего заказа пользователя или false</p>
  
<source lang="php">
 
  
$group_id = regedit::getInstance()->getVal("//modules/users/def_group");
 
$object->setValue("groups", Array($group_id));
 
  
 +
<source lang="php">
 +
public function getLastOrder($domainId) {
 +
                        //присвоить id заказа идентификатор сессии админа(редактирование заказа под администратором). Если запишется не пустое значение, вернуть $orderId
 +
if ($orderId = getSession('admin-editing-order')) return $orderId;
 +
                        //присвоим переменной $lastOrders значение поля "последний заказ" у покупателя(является составным)
 +
if ($lastOrders = $this->last_order) {
 +
foreach($lastOrders as $lastOrder) {
 +
if (isset($lastOrder['float']) && $lastOrder['float'] == $domainId) {
 +
                                        //если $lastOrders не окажется пустым, присвоим в переменную $orderId номер последнего заказа
 +
$orderId = $lastOrder['rel'];
 +
                                                //получим объект последнего заказа
 +
$order = order::get($orderId);
 +
                                                //если $order пустая, функция возвращает false
 +
if (!$order) return false;
 +
                                                //получим код код статуса последнего заказа
 +
$status = order::getCodeByStatus($order->status_id);
 +
                                                //если $status пустая, или статус заказа - "редактируется", или "оплачивается" и, при
 +
                                                этом, оплата "инициализирована", метод вернет id последнего заказа
 +
if (!$status || $status == 'executing' || ($status == 'payment' && order::getCodeByStatus($order->payment_status_id) == 'initialized') ) return $orderId;
 +
}
 +
}
 +
}
 +
                        //при невыполнении вышеперечисленных условий метод вернет  false
 +
return false;
 +
}
 
</source>
 
</source>
  
Первую строку удаляем, а вторую вырезаем и вставляем после этих строк:
+
=== setLastOrder() ===
 +
 
 +
Метод <span style="font-weight:bold">setLastOrder()</span> установит последний заказ пользователя
 +
<p>'''Параметры:''' </p><br/>
 +
int <span style="font-weight:bold">$domainId</span>:
 +
id домена заказа<br/>
 +
int <span style="font-weight:bold">$orderId</span>:
 +
id заказа<br/>
 +
<p>'''Результат:'''</p>
  
  
 
<source lang="php">
 
<source lang="php">
 +
public function setLastOrder($orderId, $domainId) {
  
$object->setValue("register_date", umiDate::getCurrentTimeStamp());
+
                        //получим значение поля last_order(составное) у покупателя
$object->setOwnerId($objectId);
+
$lastOrders = $this->last_order;
 +
                        //объявим переменную $matchDomain, присвоив значение false
 +
$matchDomain = false;
 +
foreach($lastOrders as &$lastOrder) {
 +
                                //если у составного поля last_order существует  float и float равен переданному в качестве параметра
 +
                                id домена, установим в качестве id последнего заказа, переданный в функцию id
 +
if (isset($lastOrder['float']) && $lastOrder['float'] == $domainId) {
 +
$lastOrder['rel'] = $orderId;
 +
                                        //установим значение $matchDomain как true
 +
$matchDomain = true;
 +
}
 +
}
 +
                        //если  $matchDomain содержит false,  в id последнего заказа устанавливаем  переданный в функцию id заказа
 +
                        в  поле float запишем переданный id домена
 +
if (!$matchDomain) $lastOrders[] = array("rel" => $orderId, "float" => $domainId);
 +
$this->last_order = $lastOrders;
 +
                        //сохраним внесенные изменения
 +
$this->commit();
  
 +
}
 
</source>
 
</source>
  
  
Теперь, осталось только изменить в шаблоне  формы регистрации  action на "%pre_lang%/users/registrate_do_custom/ и добавить permissions.custom.php в директорию класса users
+
== Дополнительно ==
 +
 
 +
Другие статьи по классам emarket:
  
[[Категория:Написание кастомных макросов]][[Категория:Модуль Пользователи]]
+
<ul>
 +
<li>[[Класс order модуля emarket]]</li>
 +
<li>[[Класс orderItem модуля emarket]]</li>
 +
<li>[[Класс optionedOrderItem модуля emarket]]</li>
 +
<li>[[Класс delivery модуля emarket]]</li>
 +
<li>[[Класс discount модуля emarket]]</li>
 +
<li>[[Дочерние классы класса delivery модуля emarket]]</li>
 +
<li>[[Класс discountModificator и его дочерние классы (модуль emarket) ]]</li>
 +
<li>[[Дочерние классы класса discount модуля emarket]]</li>
 +
<li>[[Класс discountRule и его дочерние классы (модуль emarket) ]]</li>
 +
<li>[[Класс payment модуля emarket ]]</li>
 +
<li>[[Класс emarketTop модуля emarket ]]</li>
 +
<li>[[Класс currencyUpdater модуля emarket ]]</li>
 +
</ul>
 +
[[Категория:API]][[Категория:Модуль Интернет магазин]]

Текущая версия на 11:46, 5 мая 2014

Актуально для версии 2.9.5

Класс customer

Описание

Одним из классов, который необходим для работы модуля "интернет-магазин" является класс customer. Данный класс предоставляет доступ к управлению объектами-покупателями интернет-магазина. Исходный код класса находится в файле classes\modules\emarket\classes\customer\customer.php

Свойства класса

$defaultExpiration хранит время жизни cookie

public static $defaultExpiration = 2678400;	// 31 days

$isAuth хранит id пользователя, если покупатель - авторизованный пользователь, false в противном случае

protected $isAuth;

Методы

__construct()

Экземпляр класса создается с помощью __construct()

Параметры:


iUmiObject $object:

содержит в себе либо объект "зарегистрированный пользователь" либо объект "незарегистрированный покупатель"

Результат: экземпляр класса customer

При создании объекта, методом определяется, какое значение будет хранить переменная $isAuth:

	public function __construct(iUmiObject $object) {
			$permissions = permissionsCollection::getInstance();
                         //получить id текущего пользователя
			$userId = $permissions->getUserId();
                        //получить id гостя
			$guestId = permissionsCollection::getGuestId();
                        // если id гостя равен id текущего пользователя записать в переменную $isAuth false, в противном   
                         случае записать id текущего пользователя
			$this->isAuth = ($userId == $guestId) ? false : $userId;
                        //создать экземпляр класса покупатель
			parent::__construct($object);
		}

get()

Получить экземпляр класса можно с помощью функции get(), если покупатель не существует, то метод создаст новый экземпляр класса

Параметры:


bool $nocache:

не использовать данные кэша, по умолчанию false

Результат: экземпляр класса customer

		public static function get($nocache = false) {
			static $customer;
//Сначала функция get() проверит создан ли уже объект покупатель
			if(!$nocache && !is_null($customer)) {

//вернет объект покупатель, если он существует
				return $customer;                           
			}


			$objects = umiObjectsCollection::getInstance();     
			$permissions = permissionsCollection::getInstance();

                        // если объект не существует, проверит авторизован ли пользователь
			if($permissions->isAuth()) {
				$userId = $permissions->getUserId();

                                 //авторизован - запишет в переменную $object(входной параметр для конструктора класса)
                                 объект текущего пользователя
				$object = $objects->getObject($userId);
			} else {
                                //не авторизован - запишет в переменную $object объект покупателя-гостя, 
                                получает этот объект функция getCustomerId()
				$object = self::getCustomerId();

				//выполнить повторную проверку, это может быть полезно при конфликтах после перезагрузки сервера
				if($object === false) $object = self::getCustomerId(true);
			}

			if($object instanceof iUmiObject) {
                        //будет создан экземпляр класса customer, на основе объекта переданного в переменную $object
				$customer = new customer($object);
                       //только что созданный экземпляр класса обратиться к функции  tryMerge()
				$customer->tryMerge();
				return $customer;
			}
		}


IsUser()

Метод isUser() вернет значение типа boolean, 1 или 0, в зависимости от того является ли покупатель зарегистрированным пользователем, т.е. будет проверено содержит ли переменная $isAuth идентификатор пользователя, или же, содержит false

Параметры:

Результат: boolean


getCustomerId()

Метод getCustomerId() вернет объект покупателя-гостя, если объект не существует, обратится к методу createGuestCustomer(), который создаст нового покупателя-гостя

Параметры:


bool $noCookie:

"не использовать данные кук", по умолчанию false

Результат: объект "покупатель-гость", записанный в переменную $customer

protected static function getCustomerId($noCookie = false) {

                        //в переменную $customerId записывается id покупателя-гостя
			static $customerId;

                        //проверка на то, содержит ли переменная значение
			if(is_null($customerId)) {

                        //Если переменная  $customerId пуста, получит id покупателя из кук
				$customerId = (int) getCookie('customer-id');
			}
                        //получить существующий объект "покупатель" по id
			$customer = selector::get('object')->id($customerId);

			 if($customer instanceof iUmiObject != false) {

                          //если полученный объект является экземпляром класса iUmiObject, получим тип объекта
				$type = selector::get('object-type')->id($customer->getTypeId());
                                //получим метод, по которому был создан объект
				if($type->getMethod() != 'customer') {

                                //если метод не customer, в переменную $customer запишем null
					$customer = null;
				}
			} else {
                               //если полученный объект не является экземпляром класса iUmiObject, в переменную $customer 
                                также запишем null
				$customer = null;
			}
                        //если $customer не определена, создадим новый объект "покупатель-гость"
			if(!$customer) {
				$customerId = self::createGuestCustomer();
                        //получим id объекта
				$customer = selector::get('object')->id($customerId);
			}
                        // если у объекта не задан id(т.е. объект не сущетсвует),создадим новый объект "покупатель-гость"
			if(!$customerId) {
				$customerId = self::createGuestCustomer();
			}
                        //если не активен консольный режим, создаем куку в браузере пользователя
			if (!defined('UMICMS_CLI_MODE') || !UMICMS_CLI_MODE) {
				setcookie('customer-id', $customerId, (time() + self::$defaultExpiration), '/');
			}
                        // устанавливаем "время жизни" объекта "покупатель-гость"
			$expirations = umiObjectsExpiration::getInstance();
			$expirations->set($customerId, self::$defaultExpiration);

                        //возвращаем объект "покупатель-гость"
			return $customer;
		}

createGuestCustomer()

Метод createGuestCustomer() создаст новый объект "покупатель-гость"

Параметры:

Результат: id "покупателя-гость", записанный в переменную $customer

protected static function createGuestCustomer() {
                         //получить коллекцию типов объектов
			$objectTypes = umiObjectTypesCollection::getInstance();

                        //получить коллекцию объектов
			$objects = umiObjectsCollection::getInstance();

                        //получить тип данных "покупатель"
			$objectTypeId = $objectTypes->getBaseType('emarket', 'customer');

                        //добавить объект "покупатель-гость", имеющий тип данных "покупатель", записать в переменную $customerId
                        id "покупателя-гостя"
			$customerId = $objects->addObject(getServer('REMOTE_ADDR'), $objectTypeId);
                        
                        //получить объект "покупатель-гость"
			$customer = $objects->getObject($customerId);
                        
                        //установить владельцем объекта пользователя гость
			$customer->setOwnerId($objects->getObjectIdByGUID('system-guest'));

                        //вернуть id объекта "покупатель-гость"
			return $customerId;
		}

tryMerge()

Метод tryMerge() попытается перенести товары "покупателя-гостя" авторизованному покупателю(пользователю), обратившись к методу merge()

Параметры:

Результат:

Данная функция используется, например, если пользователь положил товары в корзину, будучи не авторизован, а потом авторизовался на сайте

	public function tryMerge() {
                        //проверяет является ли текущий экземпляр класса авторизованным пользователем и есть лиу  него в браузере кука
			if($this->isUser() && getCookie('customer-id')) {

                                //получает объект "покупателя-гостя"
				$guestCustomer = self::getCustomerId();
                                 
                                //если объект является экземпляром класса iUmiObject, обратится к функции merge()
				if($guestCustomer instanceof iUmiObject) {
					$this->merge($guestCustomer);
				}
			}
		}

merge()

Метод merge() "переносит" товары "покупателя-гостя" авторизованному покупателю(пользователю), обратившись к методу mergeBasket()

Параметры:


iUmiObject $customer:

содержит в себе объект "покупатель"

Результат:


		public function merge(umiObject $customer) {
                        //получаем id текущего домена
			$cmsController = cmsController::getInstance();
			$domain = $cmsController->getCurrentDomain();
			$domainId = $domain->getId();
                          
                        //получаем список всех заказов текущего объекта "покупатель"
			$sel = new selector('objects');
			$sel->types('object-type')->name('emarket', 'order');
			$sel->where('customer_id')->equals($customer->id);
			$sel->where('domain_id')->equals($domainId);
			$sel->order('id')->desc();
                        

                        //получаем id текущего авторизованного пользователя
			$permissions = permissionsCollection::getInstance();
			$userId = $permissions->getUserId();

			foreach($sel as $order) {
                                //ищем заказ, у которого нет статуса
				if(!$order->status_id) {
                                        //обращаемся к методу mergeBasket(), передавая в качестве параметра текущий объект заказа
					$this->mergeBasket($order);
					continue;
				}

                                //присваиваем для текущего заказа в качестве id покупателя,id авторизованного пользователя
				$order->customer_id = $userId;
                                //сохраняем изменения
				$order->commit();
			}
                        //если не активен консольный режим, создаем куку в браузере пользователя
			if (!defined('UMICMS_CLI_MODE') || !UMICMS_CLI_MODE) {
				setcookie('customer-id', 0, 1, '/');
			}
                        //удаляем экземпляр класса "покупатель"
			$customer->delete();
		}


mergeBasket()

Метод mergeBasket() "переносит" товары "покупателя-гостя" авторизованному покупателю(пользователю), удаляя по завершению переноса объект "заказ"(корзина гостя)

Параметры:


umiObject $guestBasket:

содержит в себе текущий объект "заказ"(корзина покупателя)

Результат:


		protected function mergeBasket(umiObject $guestBasket) {
                        //получить все товары в корзине покупателя-гостя
			$orderItems = $guestBasket->order_items;
                        
                        //проверить являются ли полученные товары массивом
			if(is_array($orderItems)) {
                               //передать в переменную $userBasket заказ, который представляет текущую корзину товаров
				$userBasket = __emarket_purchasing::getBasketOrder(false);

                                // проверить задана ли $userBasket
 				if($userBasket) {
                                       
                                        
					foreach($orderItems as $orderItemId) {
						$orderItem = orderItem::get($orderItemId);
						if($orderItem) {
                                                        //добавить в текущую корзину товаров, товары из корзины покупателя-гостя
							$userBasket->appendItem($orderItem);
						}
					}
                                        //сохранить текущую корзину товаров
					$userBasket->commit();
				}
			}
                        //удалить корзину покупателя-гостя
			$guestBasket->delete();
		}

freeze()

Метод freeze() "заморозит" покупателя, т.е. не удалит его по истечении 31 дня

Параметры:

Результат:

public function freeze() {
                        //получить коллекцию "сроков жизни" объектов
			$expirations = umiObjectsExpiration::getInstance();
                        //обнулить "срок жизни" для текущего экземпляра класса
			$expirations->clear($this->id);
}

__toString()

Метод __toString() вернет id текущего экземпляра класса в качестве строки

Параметры:

Результат:

		public function __toString() {
                        //вернуть id покупателя в строковом виде
			return (string) $this->object->id;
		}


getLastOrder()

Метод getLastOrder() получит id последнего заказа пользователя

Параметры:


int $domainId:

id домена заказа

Результат:
int $orderId идентификатор последнего заказа пользователя или false


		public function getLastOrder($domainId) {
                        //присвоить id заказа идентификатор сессии админа(редактирование заказа под администратором). Если запишется не пустое значение, вернуть $orderId
			if ($orderId = getSession('admin-editing-order')) return $orderId;
                        //присвоим переменной $lastOrders значение поля "последний заказ" у покупателя(является составным)
			if ($lastOrders = $this->last_order) {
				foreach($lastOrders as $lastOrder) {
					if (isset($lastOrder['float']) && $lastOrder['float'] == $domainId) {
                                         //если $lastOrders не окажется пустым, присвоим в переменную $orderId номер последнего заказа
						$orderId = $lastOrder['rel'];
                                                //получим объект последнего заказа
						$order = order::get($orderId);
                                                //если $order пустая, функция возвращает false
						if (!$order) return false;
                                                //получим код код статуса последнего заказа
						$status = order::getCodeByStatus($order->status_id);
                                                //если $status пустая, или статус заказа - "редактируется", или "оплачивается" и, при 
                                                 этом, оплата "инициализирована", метод вернет id последнего заказа
						if (!$status || $status == 'executing' || ($status == 'payment' && order::getCodeByStatus($order->payment_status_id) == 'initialized') ) return $orderId;
					}
				}
			}
                        //при невыполнении вышеперечисленных условий метод вернет  false
			return false;
		}

setLastOrder()

Метод setLastOrder() установит последний заказ пользователя

Параметры:


int $domainId:

id домена заказа
int $orderId: id заказа

Результат:


		public function setLastOrder($orderId, $domainId) {

                        //получим значение поля last_order(составное) у покупателя
			$lastOrders = $this->last_order;
                        //объявим переменную $matchDomain, присвоив значение false
			$matchDomain = false;
			foreach($lastOrders as &$lastOrder) {
                                //если у составного поля last_order существует  float и float равен переданному в качестве параметра 
                                id домена, установим в качестве id последнего заказа, переданный в функцию id
				if (isset($lastOrder['float']) && $lastOrder['float'] == $domainId) {
					$lastOrder['rel'] = $orderId;
                                        //установим значение $matchDomain как true
					$matchDomain = true;
				}
			}
                        //если  $matchDomain содержит false,  в id последнего заказа устанавливаем  переданный в функцию id заказа
                        в  поле float запишем переданный id домена
			if (!$matchDomain) $lastOrders[] = array("rel" => $orderId, "float" => $domainId);
			$this->last_order = $lastOrders;
                        //сохраним внесенные изменения
			$this->commit();

		}


Дополнительно

Другие статьи по классам emarket: