Регистрируем пользователя после совершения заказа miniShop2

Недавно наткнулся на платный компонент msCustomerAutoReg (490 руб.), который позволяет регистрировать пользователей после оформления заказа. Сказать, что я удивился, это не сказать ничего. Мало того, что компонент платный, так и способ реализации задачи достаточно некорректный, с моей точки зрения. На вопрос: можно сделать лучше и штатными средствами? Я отвечу: можно! И даже нужно!

Начнем с того, что после оформления заказа miniShop2 автоматически регистрирует пользователя на сайте, только данные пользователя на почту не высылаются. В сети предлагают кучу решений данной задачи, но все они сводятся к тому, что после оформления заказа пользователю отсылается второе письмо с данными от личного кабинета. Не считаю, что два письма отсылать корректно. Поэтому делюсь своими наработками в данном направлении.

Компонент miniShop2 обладает широкими возможностями для масштабирования, за что разработчику огромное спасибо. В частности, мы можем переопределить стандартные методы классов. Что и послужит нам отличным инструментом для решения данной задачи. Нам нужно переопределить всего один метод changeOrderStatus, для этого создаем файл orderCustomHandler.class.php в директории /core/components/minishop2/custom/order/ со следующим содержимым:

<?php

class orderCustomHandler extends msOrderHandler{
	/**
     * Switch order status
     *
     * @param integer $order_id The id of msOrder
     * @param integer $status_id The id of msOrderStatus
     *
     * @return boolean|string
     */
    public function changeOrderStatus($order_id, $status_id)
    {
        /** @var msOrder $order */
        if (!$order = $this->modx->getObject('msOrder', array('id' => $order_id), false)) {
            return $this->modx->lexicon('ms2_err_order_nf');
        }

        $ctx = $order->get('context');
        $this->modx->switchContext($ctx);
        $this->initialize($ctx);
        // This method could be overwritten from custom order handler
        if (is_object($this->order) && method_exists($this->order, 'changeOrderStatus')) {
            return $this->order->changeOrderStatus($order_id, $status_id);
        }

        $error = '';
        /** @var msOrderStatus $status */
        if (!$status = $this->modx->getObject('msOrderStatus', array('id' => $status_id, 'active' => 1))) {
            $error = 'ms2_err_status_nf';
        } /** @var msOrderStatus $old_status */
        else {
            if ($old_status = $this->modx->getObject('msOrderStatus',
                array('id' => $order->get('status'), 'active' => 1))
            ) {
                if ($old_status->get('final')) {
                    $error = 'ms2_err_status_final';
                } else {
                    if ($old_status->get('fixed')) {
                        if ($status->get('rank') <= $old_status->get('rank')) {
                            $error = 'ms2_err_status_fixed';
                        }
                    }
                }
            }
        }
        if ($order->get('status') == $status_id) {
            $error = 'ms2_err_status_same';
        }

        if (!empty($error)) {
            return $this->modx->lexicon($error);
        }

        $response = $this->ms2->invokeEvent('msOnBeforeChangeOrderStatus', array(
            'order' => $order,
            'status' => $order->get('status'),
        ));
        if (!$response['success']) {
            return $response['message'];
        }

        $order->set('status', $status_id);

        if ($order->save()) {
            $this->ms2->orderLog($order->get('id'), 'status', $status_id);
            $response = $this->ms2->invokeEvent('msOnChangeOrderStatus', array(
                'order' => $order,
                'status' => $status_id,
            ));
            if (!$response['success']) {
                return $response['message'];
            }

            $lang = $this->modx->getOption('cultureKey', null, 'en', true);
            if ($tmp = $this->modx->getObject('modUserSetting', array('key' => 'cultureKey', 'user' => $order->get('user_id')))) {
                $lang = $tmp->get('value');
            }
            else if ($tmp = $this->modx->getObject('modContextSetting', array('key' => 'cultureKey', 'context_key' => $order->get('context')))) {
                $lang = $tmp->get('value');
            }
            $this->modx->setOption('cultureKey', $lang);
            $this->modx->lexicon->load($lang . ':minishop2:default', $lang . ':minishop2:cart');

            $pls = $order->toArray();
            $pls['cost'] = $this->ms2->formatPrice($pls['cost']);
            $pls['cart_cost'] = $this->ms2->formatPrice($pls['cart_cost']);
            $pls['delivery_cost'] = $this->ms2->formatPrice($pls['delivery_cost']);
            $pls['weight'] = $this->ms2->formatWeight($pls['weight']);
            $pls['payment_link'] = '';
            if ($payment = $order->getOne('Payment')) {
                if ($class = $payment->get('class')) {
                    $this->loadCustomClasses('payment');
                    if (class_exists($class)) {
                        /** @var msPaymentHandler|PayPal $handler */
                        $handler = new $class($order);
                        if (method_exists($handler, 'getPaymentLink')) {
                            $link = $handler->getPaymentLink($order);
                            $pls['payment_link'] = $link;
                        }
                    }
                }
            }
			
			$userId = $pls["user_id"];
			$user = $this->modx->getObject("modUser", $userId);
			if($user){
				$time = time();
				$newUser = 10;
				$username = $user->get("username");
				$createdon = strtotime($user->get("createdon")) + $newUser;
				if($createdon > $time){
					$length = 8;
					$pass = $this->modx->user->generatePassword($length);
				}
				$user->set("password", $pass);
				$user->save();
				$pls["userdata"] = array(
					"username" => $username,
					"password" => $pass,
				);
				$user->addSessionContext("web");
			}

            if ($status->get('email_manager')) {
                $subject = $this->ms2->pdoTools->getChunk('@INLINE ' . $status->get('subject_manager'), $pls);
                $tpl = '';
                if ($chunk = $this->modx->getObject('modChunk', array('id' => $status->get('body_manager')))) {
                    $tpl = $chunk->get('name');
                }
                $body = $this->modx->runSnippet('msGetOrder', array_merge($pls, array('tpl' => $tpl)));
                $emails = array_map('trim', explode(',',
                        $this->modx->getOption('ms2_email_manager', null, $this->modx->getOption('emailsender')))
                );
                if (!empty($subject)) {
                    foreach ($emails as $email) {
                        if (preg_match('#.*?@.*#', $email)) {
                            $this->ms2->sendEmail($email, $subject, $body);
                        }
                    }
                }
            }

            if ($status->get('email_user')) {
                if ($profile = $this->modx->getObject('modUserProfile', array('internalKey' => $pls['user_id']))) {
                    $subject = $this->ms2->pdoTools->getChunk('@INLINE ' . $status->get('subject_user'), $pls);
                    $tpl = '';
                    if ($chunk = $this->modx->getObject('modChunk', array('id' => $status->get('body_user')))) {
                        $tpl = $chunk->get('name');
                    }
                    $body = $this->modx->runSnippet('msGetOrder', array_merge($pls, array('tpl' => $tpl)));
                    $email = $profile->get('email');
                    if (!empty($subject) && preg_match('#.*?@.*#', $email)) {
                        $this->ms2->sendEmail($email, $subject, $body);
                    }
                }
            }
        }

        return true;
    }
}

Как видите, мы просто добавили небольшой блок, который позволяет нам вывести данные по личному кабинету прямо в письме о новом заказе. Что чертовски круто. Теперь переходим в системные настройки в разде miniShop2 и меняем значение настройки ms2_order_handler_class на orderCustomHandler.

Далее просто редактируем стандартный чанк tpl.msEmail, добавляя блок с данными о заказе (всегда мучал вопрос почему из коробки этого нет) и данными от личного кабинета:

    <div style="width:90%;margin:auto;">
        {if $user.fullname}<p><strong>Ф.И.О.:</strong> {$user.fullname}</p>{/if}
        {if $user.email}<p><strong>E-mail:</strong> {$user.email}</p>{/if}
        {if $address.phone}<p><strong>Телефон:</strong> {$address.phone}</p>{/if}
        {if $address.city}<p><strong>Город:</strong> {$address.city}</p>{/if}
        {if $address.street}<p><strong>Адрес:</strong> {$address.street}{/if} 
        {if $address.building} {$address.building}{/if}  
        {if $address.room} {$address.room}</p>{/if}
        {if $address.comment}<p><strong>Комментарии:</strong> {$address.comment}</p>{/if}
        {if $delivery.name}<p><strong>Доставка:</strong> {$delivery.name}</p>{/if}
        {if $payment.name}<p><strong>Оплата:</strong> {$payment.name}</p>{/if}
        {if $userdata}
            <h3 style="{$style.h}{$style.h3}">Данные для входа в личный кабинет:</h3>
            <div style="padding: 0 20px;">
                <strong>Логин:</strong> {$userdata.username}<br/>
                <strong>Пароль:</strong> {$userdata.password}
            </div>
        {/if}
    </div>

Вот и все! Несколько минут работы, сэкономленные 490 руб. и полученные новые навыки. Неплохо правда?

Регистрируем пользователя после совершения заказа miniShop2

0 Число голосов: 2
5
5
1
2

Комментарии ()

Ваш комментарий будет первым!

Наши клиенты

Многие компании уже доверяют нам. Будьте в их числе!

Хотите реализовать проект?

Контакты

Напишите нам - мы расскажем вам много интересного!


Пермь, ул. Крупской 34, офис 510