[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 статуса.
Поблагодарить автора
Отправить деньги
Комментарии: 13
Это я понял, когда писал сниппет. Однако мне проще вызвать вот в таком виде:
[[!msEmail?
&type=`user`
&order=`1`
&status=`1`
]]
У статуса может быть и не стандартный шаблон указан, не хочется лезть и смотреть, какой шаблон подтягивает статус. Проще указать ID статуса.
Етить колотить. Так можно было? А почему тогда письма не отправляются каждый раз при обновлении страницы со сниппетом? Сессия?
Так это сниппет оформляет письмо, но не отправляет.
Для отправки или используй сниппет из поста, или просто оформи заказ.
Для отправки или используй сниппет из поста, или просто оформи заказ.
Да сейчас перечитал — понял что ты имел ввиду показ письма на экране просто, без отправки.
Но это так себе решение с точки зрения Email верстки. Не поймешь какие стили сработают, а какие нет.
Разве что вставку данных проверить.
Но это так себе решение с точки зрения Email верстки. Не поймешь какие стили сработают, а какие нет.
Разве что вставку данных проверить.
А почему не сработают? Вроде на мыло главное стили в атрибут style помещать, не?
Не. Работают только те стили, которые были в эпоху табличной верстки. Все новое будет вырезано. Но это еще от сервиса к сервису. Gmail еще ничего относительно свежие стили рендерит, а вот mail.ru совсем плохо.
У меня все письма перед отправкой проходят через pelago/emogrifier — так что на расхождений в отображении почти нет.
Грузим свой почтовый класс раньше всех:
А в классе extraMail добавляем свою обработку:
Грузим свой почтовый класс раньше всех:
$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);
}
я еще добавил в ваш сниппет событие чтобы подтянуть кастомные переводы(это вообще для любителей странного)
/** 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;
Тогда уж нужно добавить просто код из события, а не вызов самого события.
Ну сам код события пригодится еще при отправке письма, а тут только тест
мне кажется есть огромная разница через что «смотреть» на письмо.
Внешний вид письма, на который мы сморим через браузер, может сильно отличаться от вида этого же письма в почтовой системе и разительно отличаться от просмотра в какой то программе, например в Thunderbird.
Поэтому если хотим увидеть, как реальные наши клиенты будут видеть — нужно все-же отправлять на почту.
А для верстки письма, чтобы быстренько глянуть, да — удобно и в браузер вывести.
Внешний вид письма, на который мы сморим через браузер, может сильно отличаться от вида этого же письма в почтовой системе и разительно отличаться от просмотра в какой то программе, например в Thunderbird.
Поэтому если хотим увидеть, как реальные наши клиенты будут видеть — нужно все-же отправлять на почту.
А для верстки письма, чтобы быстренько глянуть, да — удобно и в браузер вывести.
нашел ошибку
admin нужно на manager поменять
if (!in_array($sp['type'], ['user', 'admin'])) {
return 'Bad type.';
}
тут
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.