Отправка Email о регистрации при оформлении заказа в miniShop2

Буквально на днях я столкнулся с вопросом, о котором как то не задумывался.
При оформлении заказа в minishop2 создается пользователь, но сам пользователь о собственной регистрации ничего не знает.

Как отправить пользователю письмо, с первоначальными регистрационными данными (логин, пароль)?

Стандартный комплект методов нашего любимого интернет-магазина такого не предусматривает. А значит руки в плечи и пишем плагин.


Насколько я понимаю, при регистрации пользователя со случайным паролем, пароль этот нигде не светится, и сохранить его не переписывая класс минишопа не получится. В событие он никак не попадет, только в виде хеша из объекта modUser. Значит в плагине нужно сгенерировать собственный случайный пароль, и сохранить его.

Для начала определимся с событием, на которое отрабатывает плагин. По идее это должно быть событие onUserSave с режимом NEW, но ведь наша задача предусматривает отправку писем, именно после оформления заказа, а не при любом создании пользователя.

Покопавшись в интернете, я наткнулся на статью в блоге Ильи Уткина, который в свою очередь сделал репост от Марата Марабара.

Автор предлагает использовать событие msOnChangeOrderStatus со следующей логикой
  1. Определяем что статус заказа именно, новый
  2. Получаем пользователя, проверяем, что он зарегистрирован менее 10 секунд назад, то есть новый пользователь
  3. Ну и далее меняем пароль, сохраняем пользователя, шлем письмо
Вполне рабочая схема. Настроил, проверил, но...!
Меня не устроили два момента.
1. Изменение пароля пользователя происходит через процессор, который требует определенных прав. Нужно предварительно, авторизовать скрипт в админке. А это мне не нравится из соображений безопасности. Да и громоздко как то.
2. Стандартный процессор, шлет письмо, используя текст системной настройки signupemail_message, которая не поддерживает fenom и файловые элементы, да и количество плейсхолдеров ограничено. А я не хочу писать текст письма прямо в строке системной настройки. Я хочу создать привычным образом файл — шаблон письма, подставить удобные для меня плейсхолдеры, сделать верстку письма. В общем хотя бы как это сделано в стандартных шаблонах писем от miniShop2.

Оставив скрипт Марата, как основу, я переписал часть, касающуюся изменения пароля и отправки письма.
По моему получилось гибче и проще. Без процессоров, но с MODX API

switch ($modx->event->name){
case 'msOnChangeOrderStatus':
        if ($status == 1) {
            $userId = $order->user_id;
            $user = $modx->getObject('modUser', $userId);
            $time = time();
            $newUser = 10; // Сколько секунд пользователь считается новым

            if ($user) {
                $username = $user->get('username');
                $createdon = strtotime($user->get('createdon')) + $newUser;

                if ($createdon > $time) {
                    //Генератор пароля. Взят из исходников MODX
                    //Длина пароля
                    $length = 8;

                    $pass = $modx->user->generatePassword($length);

                    //Сохраняем новый пароль
                    $user->set('password', $pass);
                    $user->save();

                    //Шлем письмо
                    $pdo = $modx->getService('pdoFetch');
                    $message = $pdo->getChunk('@FILE chunks/email/user.register.tpl', array('username' => $username, 'password' => $pass));
                    $sent = $user->sendEmail($message, array('subject' => 'Регистрация в интернет-магазине'));
                    //Мгновенная авторизация на сайте без набора пароля, кому надо раскомментируйте
                    //$user->addSessionContext('web');
                }

            }
        }
        break;
}
Саму верстку письма я не прикладываю, она почти полностью взята из примеров minishop2
Николай Савин
16 октября 2018, 12:30
25
1 365
+16
Поблагодарить автора Отправить деньги

Комментарии: 21

Pavel Zarubin
16 октября 2018, 12:42
0
Пароль хорошо бы генерировать так, он так генерируется с учетом настроек modx
modx.pro/help/2766#comment-32619
Pavel Zarubin
16 октября 2018, 13:45
0
Еще, пользователя у $order можно получить через связь, не обязательно получать через getObject.
github.com/bezumkin/miniShop2/blob/master/core/components/minishop2/model/schema/minishop2.mysql.schema.xml#L270
    Николай Савин
    16 октября 2018, 13:47
    0
    Думаешь быстрее будет? Все равно же запрос в базу. Или это ближе к Join чем к запросу?
      Pavel Zarubin
      16 октября 2018, 14:59
      0
      Быстрее не будет, но элегенатнее точно будет)
      Павел Гвоздь
      16 октября 2018, 15:27
      0
      Вряд ли, быстрее. Удобнее и проще — точно!
      Полезная статья, Николай! В идеале, пулл реквест в ядро miniShop2 не помешал бы, с системной настройкой включения данного функционала. :)
        Николай Савин
        16 октября 2018, 18:56
        0
        Боюсь Володя не пропустит, вон ругаться уже начал
Володя
16 октября 2018, 15:58
+2
Зачем это пихать в плагин на смену статуса? Ладно если еще пароль, так еще и письмо отправить.
Затем будем решать проблемы:
— долго создается заказ
— дублируется заказ, пользователь кликает на создании заказа
— и тд и тп.

проще вывести в форму создания чекбокс для неавторизованного юзера о намерением зарегаться на сайте.
далее скрипт на крон который выбирает данные заказы и если пользователь новый проводить подобные манипуляции и слать письмо.
При этом никаких задержек при оформлении заказа.
    Павел Гвоздь
    16 октября 2018, 18:18
    +1
    При этом никаких задержек при оформлении заказа.
    А как же задержки при отсылке писем менеджерам и юзеру о новом заказе?)
      Володя
      16 октября 2018, 19:17
      0
      От них тоже можно избавиться. Но а навешивать лишнее точно не стоит.
    Николай Савин
    16 октября 2018, 18:59
    0
    Твой вариант может и проще и правильнее. Но уж точно это не то решение, которое будет работать из коробки при минимуме затрат.
    А вообще я же не претендую на максимальную точность. Просто рассказал о том, как я сделал, показал возможное решение вопроса, и примерно дал понять в какую сторону думать, при кастомизации.
      Володя
      16 октября 2018, 19:19
      0
      Как вариант еще можно вместе с галкой о согласии регистрации показывать поле пароль. И в случае регистрации пользователя ставить выбранный пользователем пароль. Необходимость в оправке писем тогда вовсе пропадает.
      Можно еще что то придумать…
        Николай Савин
        17 октября 2018, 05:09
        +3
        Я что то упустил?
        Разве на данный момент, метод getCustomerId() не регистрирует пользователя в обязательном порядке? Если да, регистрирует — то по идее уведомление пользователю обязательно должно быть. Это как минимум хороший тон, а местами и соответствие законодательству.

        Если нет, не обязательна регистрация — то КОГДА ЭТО СЛУЧИЛОСЬ черт побери?
          Михаил
          17 октября 2018, 08:38
          +5
          Вообще в ядро бы конечно это тему закинуть, потому что пользователи пытаются заново зарегаться а им пишут, что вы уже есть. И он в ступоре, начинает думать когда и как, ну и восстанавливать пароль. Хотя принудительная регистрация тоже весьма спорна (
            Sem
            Sem
            17 октября 2018, 08:52
            +4
            Абсолютно согласен, сколько не делал магазинов на miniShop2, клиенты все без исключения просили потом как-нибудь допилить этот момент, пользоватлеи всё время пытались регатся на сайте, а им в ответ, а — Вы уже есть, и дальше им нужно делать какие-то действия чтобы восстановить пароль, который они никогда сами и не создавали.
        Николай Савин
        17 октября 2018, 08:55
        +4
        Видишь какую тему больную поднял. По любому нужно что то придумать в ядре
Михаил
17 октября 2018, 10:46
+2
Присоединяюсь к вопросу
Jury
19 октября 2018, 17:53
0
Это актуально очень! В последнем проекте я указал в письме с новым заказом пометку о том как войти в личный кабинет, но чуть ли не каждый 2 испытывает проблемы, так как, ему нужно сначала запросить сброс пароля.
Рони
20 октября 2018, 15:34
+2
Вообще, если в любой системе какое-либо действие пиводит к созданию сущности пользователя, то об этом нужно уведомлять. Обязательно. И это не оверхэд, а нормальное поведение системы. Кстати, хорошо бы еще мелким шрифтом хотя бы информировать юзера на сайте, о том, что при совершении действия в системе будет создана сущность пользователя с его реквизитами. Ну и закон о Персональных данных теперь нас обязывает это все учитывать. Автор фичи молодец!
Антон
13 февраля 2019, 23:38
0
Благодарствую, Николай, за публикацию, очень помогло
    Николай Савин
    14 февраля 2019, 12:34
    0
    В этом и смысл публикации. На здоровье.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.