[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', 'admin'])) {
    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
23
590
+13
Поблагодарить автора Отправить деньги

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

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

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

      Для отправки или используй сниппет из поста, или просто оформи заказ.
        Николай Савин
        26 ноября 2018, 06:47
        +2
        Да сейчас перечитал — понял что ты имел ввиду показ письма на экране просто, без отправки.
        Но это так себе решение с точки зрения Email верстки. Не поймешь какие стили сработают, а какие нет.
        Разве что вставку данных проверить.
          Павел Гвоздь
          26 ноября 2018, 06:59
          1
          0
          А почему не сработают? Вроде на мыло главное стили в атрибут style помещать, не?
            Николай Савин
            26 ноября 2018, 07:02
            +2
            Не. Работают только те стили, которые были в эпоху табличной верстки. Все новое будет вырезано. Но это еще от сервиса к сервису. Gmail еще ничего относительно свежие стили рендерит, а вот mail.ru совсем плохо.
          Василий Наумкин
          26 ноября 2018, 07:29
          4
          +4
          У меня все письма перед отправкой проходят через 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);
              }
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.