К содержанию

[miniShop2] Как тестировать письма без оформления заказа


Иногда приходится тестировать внешний вид писем, отсылаемых при оформлении заказа. Чтобы не оформлять постоянно заказ для просмотра внешнего вида, написал сниппет. Подробности под катом.

Код сниппета


Создаём сниппет msEmail:
<?php
$sp = &$scriptProperties;
if (!$ms2 = $modx->getService('miniShop2')) {
    return 'Class `miniShop2` not found.';
}
$sp['type'] = empty($sp['type']) ? 'user' : $sp['type'];
$sp['order'] = (int)(empty($sp['order']) ? 0 : $sp['order']);
$sp['status'] = (int)(empty($sp['status']) ? 0 : $sp['status']);
if (!in_array($sp['type'], ['user', 'manager'])) {
    return 'Bad type.';
}

/** @var msOrder $order */
if (!$order = $modx->getObject('msOrder', array('id' => $sp['order']))) {
    return $modx->lexicon('ms2_err_order_nf');
}
if (!$status = $modx->getObject('msOrderStatus', array('id' => $sp['status']))) {
    return $modx->lexicon('ms2_err_status_nf');
}

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

// Placeholders
$pls = $order->toArray();
$pls['status'] = $sp['status'];
$pls['cost'] = $ms2->formatPrice($pls['cost']);
$pls['cart_cost'] = $ms2->formatPrice($pls['cart_cost']);
$pls['delivery_cost'] = $ms2->formatPrice($pls['delivery_cost']);
$pls['weight'] = $ms2->formatWeight($pls['weight']);
$pls['payment_link'] = '';
if ($payment = $order->getOne('Payment')) {
    if ($class = $payment->get('class')) {
        $ms2->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;
            }
        }
    }
}

//
$output = [];
if ($type == 'user') {
    if (!$profile = $modx->getObject('modUserProfile', array('internalKey' => $pls['user_id']))) {
        return;
    }
    $emails = [$profile->get('email')];
} elseif ($type == 'manager') {
    $emails = array_map('trim', explode(',',
        $modx->getOption('ms2_email_manager', null, $modx->getOption('emailsender')))
    );
}
$tpl = '';
$subject = $ms2->pdoTools->getChunk('@INLINE ' . $status->get('subject_' . $type), $pls);
if ($chunk = $modx->getObject('modChunk', array('id' => $status->get('body_' . $type)))) {
    $tpl = $chunk->get('name');
}
$body = $modx->runSnippet('msGetOrder', array_merge($pls, array('tpl' => $tpl)));
if (!empty($subject)) {
    $output = $body;
}

return $output;

Как вызывать


Создаём ресурс с пустым шаблоном и кодом:
[[!msEmail?
    &type=`user`
    &order=`1`
    &status=`1`
]]

Параметры сниппета


  • type — тип письма, принимает user или manager,
  • order — ID заказа,
  • status — ID статуса.
Павел Гвоздь
Павел Гвоздь
25 ноября 2018, 15:48
modx.pro
5 103
Поблагодарить автора Отправить деньги
Реклама

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

Василий Наумкин
Василий Наумкин Администратор
25 ноября 2018, 15:53
На всякий случай, тестировать можно и без создания дополнительных сниппетов.
[[!msGetOrder?
    &id=`2404`
    &tpl=`tpl.msEmail.new.user`
]]

Вызвать в ресурсе с пустым шаблоном:
    Павел Гвоздь
    Павел Гвоздь Эксперт
    25 ноября 2018, 16:27
    Это я понял, когда писал сниппет. Однако мне проще вызвать вот в таком виде:
    [[!msEmail?
        &type=`user`
        &order=`1`
        &status=`1`
    ]]
    У статуса может быть и не стандартный шаблон указан, не хочется лезть и смотреть, какой шаблон подтягивает статус. Проще указать ID статуса.
      Николай Савин
      Николай Савин Администратор
      26 ноября 2018, 06:23
      Етить колотить. Так можно было? А почему тогда письма не отправляются каждый раз при обновлении страницы со сниппетом? Сессия?
        Василий Наумкин
        Василий Наумкин Администратор
        26 ноября 2018, 06:40
        Так это сниппет оформляет письмо, но не отправляет.

        Для отправки или используй сниппет из поста, или просто оформи заказ.
          Николай Савин
          Николай Савин Администратор
          26 ноября 2018, 06:47
          Да сейчас перечитал — понял что ты имел ввиду показ письма на экране просто, без отправки.
          Но это так себе решение с точки зрения Email верстки. Не поймешь какие стили сработают, а какие нет.
          Разве что вставку данных проверить.
            Павел Гвоздь
            Павел Гвоздь Эксперт
            26 ноября 2018, 06:59
            А почему не сработают? Вроде на мыло главное стили в атрибут style помещать, не?
              Николай Савин
              Николай Савин Администратор
              26 ноября 2018, 07:02
              Не. Работают только те стили, которые были в эпоху табличной верстки. Все новое будет вырезано. Но это еще от сервиса к сервису. Gmail еще ничего относительно свежие стили рендерит, а вот mail.ru совсем плохо.
              Василий Наумкин
              Василий Наумкин Администратор
              26 ноября 2018, 07:29
              У меня все письма перед отправкой проходят через pelago/emogrifier — так что на расхождений в отображении почти нет.

              Грузим свой почтовый класс раньше всех:
              $modx->getService('mail', 'extraMail', 'path/to/class');

              А в классе extraMail добавляем свою обработку:
              <?php
              if (!class_exists('modPHPMailer')) {
                  /** @noinspection PhpIncludeInspection */
                  require MODX_CORE_PATH . 'model/modx/mail/modphpmailer.class.php';
              }
              
              class extraMail extends modPHPMailer
              {
                  /** @var PHPMailer $mailer */
                  public $mailer;
                  
                  /**
                   * @param string $key
                   * @param mixed $value
                   */
                  public function set($key, $value)
                  {
                      if ($key == modMail::MAIL_BODY) {
                          $emogrifier = new \Pelago\Emogrifier($value);
                          $value = $emogrifier->emogrify();
                          $this->set(modMail::MAIL_BODY_TEXT, $this->mailer->html2text(nl2br($value)));
                      }
                      parent::set($key, $value);
                  }
        Stepan
        Stepan Проверенный
        09 августа 2022, 04:33
        я еще добавил в ваш сниппет событие чтобы подтянуть кастомные переводы(это вообще для любителей странного)
        /** check event*/
        $response = $ms2->invokeEvent('msOnChangeOrderStatus', array(
            'order' => $order,
            'status' => $order->get('status'),
        ));
        а в плагине прям кусок из минишопа
        case 'msOnChangeOrderStatus':
            	if ($tmp = $modx->getObject('modUserSetting', array('key' => 'cultureKey', 'user' => $order->get('user_id')))) {
                    $lang = $tmp->get('value');
        			$modx->setOption('cultureKey', $lang);
        			$modx->lexicon->load($lang.':***:ext');
        
                }
                break;
          Николай Савин
          Николай Савин Администратор
          09 августа 2022, 08:18
          Тогда уж нужно добавить просто код из события, а не вызов самого события.
            Stepan
            Stepan Проверенный
            09 августа 2022, 15:00
            Ну сам код события пригодится еще при отправке письма, а тут только тест
          Александр Мельник
          Александр Мельник Проверенный
          09 августа 2022, 08:35
          мне кажется есть огромная разница через что «смотреть» на письмо.
          Внешний вид письма, на который мы сморим через браузер, может сильно отличаться от вида этого же письма в почтовой системе и разительно отличаться от просмотра в какой то программе, например в Thunderbird.

          Поэтому если хотим увидеть, как реальные наши клиенты будут видеть — нужно все-же отправлять на почту.
          А для верстки письма, чтобы быстренько глянуть, да — удобно и в браузер вывести.
            Stepan
            Stepan Проверенный
            19 ноября 2022, 17:07
            нашел ошибку
            if (!in_array($sp['type'], ['user', 'admin'])) {
                return 'Bad type.';
            }
            тут admin нужно на manager поменять
              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
              13