Реализацию нашего функционала мы начнем с подписки на первом экране. Реализовывать ее будем с помощью компонента Sendex. Для начала нам нужно создать подписку в разделе “Приложения -> Sendex”:
Отлично! Подписка создана. Сам процесс подписки пользователя будет реализован на AJAX, поэтому нам нужно создать технический ресурс для подписки пользователей, где у нас будет размещен вызов сниппета Sendex. Обычно я создаю подобные ресурсы следующим образом:
Обязательно установите во всех трех ресурсах флажки “Опубликован” и “скрыть из меню”, а на вкладке “Настройки” снимите флажки “Доступен для поиска” и “Использовать HTML-редактор”. Шаблон же у данных ресурсов должен быть “пустой”. В контентную часть помещаем вызов сниппета Sendex:
[[!Sendex? &id=`1` ]]
Где параметр id – это идентификатор нашей рассылки. В анонсе данного курса я писал, что мы будем модернизировать наш сниппет Sendex, так как в таком виде он нам не подходит из-за того, что отдает HTML-код, нам же необходимо, чтобы он отдавал JSON строку, которую мы с вами могли бы легко распарсить с помощью jQuery.
Чтобы это реализовать, я скопировал стандартный сниппет Sendex и назвал его SendexAjax. В видео я подробно рассказал, что мы делали с ним, поэтому здесь я приведу только код данного сниппета:
<?php
/** @var array $scriptProperties */
/** @var Sendex $Sendex */
$output = array();
$Sendex = $modx->getService('sendex','Sendex',$modx->getOption('sendex_core_path',null,$modx->getOption('core_path').'components/sendex/').'model/sendex/',$scriptProperties);
if (!($Sendex instanceof Sendex)) return '';
if (empty($linkTTL)) {$linkTTL = 1800;}
if (empty($id) || !$newsletter = $modx->getObject('sxNewsletter', $id)) {
$output['success'] = false;
$output['message'] = $modx->lexicon('sendex_newsletter_err_ns');
}
/** @var sxNewsletter $newsletter */
if (!$newsletter->active && empty($showInactive)) {
$output['success'] = false;
$output['message'] = $modx->lexicon('sendex_newsletter_err_disabled');
}
$placeholders = $newsletter->toArray();
$placeholders['message'] = '';
$placeholders['error'] = 0;
if ($modx->user->isAuthenticated($modx->context->key)) {
$placeholders = array_merge(
$modx->user->toArray(),
$modx->user->Profile->toArray(),
$placeholders
);
}
$isAuthenticated = $modx->user->isAuthenticated($modx->context->key);
if (!empty($_REQUEST['sx_action'])) {
$isAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
$params = $_GET;
unset($params[$modx->getOption('request_param_alias')]);
unset($params[$modx->getOption('request_param_id')]);
switch ($_REQUEST['sx_action']) {
case 'subscribe':
if ($isAuthenticated && $modx->user->id) {
if (!$response = $newsletter->Subscribe($modx->user->id)) {
$output['success'] = false;
$output['message'] = $modx->lexicon('sendex_subscribe_err_email_wrong');
}
}
elseif (!empty($_REQUEST['email'])) {
$email = htmlentities(strip_tags(urldecode($_REQUEST['email'])));
$response = $newsletter->checkEmail($email, $modx->user->id, $linkTTL);
if ($response === true) {
$output['success'] = false;
$output['message'] = $modx->lexicon('sendex_subscribe_err_already');
}
elseif ($response === false) {
$output['success'] = false;
$output['message'] = $modx->lexicon('sendex_subscribe_err_email_wrong');
}
else {
$params['hash'] = $response;
$params['sx_action'] = 'confirm';
$placeholders['link'] = $modx->makeUrl($modx->resource->id, $modx->context->key, $params, 'full');
$placeholders['email_body'] = $modx->getChunk($tplActivate, $placeholders);
$response = $Sendex->sendEmail($email, $placeholders);
if ($response !== true) {
$output['success'] = false;
$output['message'] = $modx->lexicon('sendex_subscribe_err_email_send');
} else {
$params['sx_subscribed'] = 1;
$output['success'] = true;
$output['message'] = "На ваш почтовый ящик было отправлено письмо со ссылкой, по которой нужно перейти, чтобы подтвердить подписку!";
}
}
}
else {
$output['success'] = false;
$output['message'] = $modx->lexicon('sendex_subscribe_err_email_ns');
}
unset($params['email'], $params['hash']);
break;
case 'confirm':
if (!empty($_REQUEST['hash'])) {
$response = $newsletter->confirmEmail($_REQUEST['hash']);
$params['sx_confirmed'] = 1;
unset($params['hash']);
}
break;
case 'unsubscribe':
if (!empty($_REQUEST['code'])) {
$response = $newsletter->unSubscribe($_REQUEST['code']);
$params['sx_unsubscribed'] = 1;
}
unset($params['code']);
break;
}
unset($params['sx_action']);
if (!$isAjax && empty($placeholders['message'])) {
$modx->sendRedirect($modx->makeUrl($modx->getOption("site_start"), $modx->context->key, $params, 'full'));
}
}
return json_encode($output);
Теперь в нашем ресурсе нам нужно поменять наименование сниппета на SendexAjax вместо Sendex и получать уже JSON массив.
Чтобы у нас заработала отправка уведомлений, нам необходимо модернизировать HTML-код с формой подписки и добавить туда некоторые моменты, а именно класс, заполнить атрибут action и добавить скрытый параметр sx_action. Код формы у меня получился следующий:
<div class="col-sm-6">
<div class="wecome-content newsletter-content">
<h1>Connected With Us. Subscribe For Product Update News</h1>
<form action="[[~4]]" method="post" class="subscribe-form">
<input type="hidden" name="sx_action" value="subscribe">
<input type="text" class="form-control" name="email" placeholder="Enter Tour Email">
<button type="submit">Subscribe Now</button>
</form>
</div>
</div>
Теперь напишем JS обработчик на jQuery в чанк scripts, который позволит нам получать данные с сервера по технологии AJAX. Код обработчика:
$('.subscribe-form').submit(function(e){
e.preventDefault();
var msg = $(this).serialize();
var url = $(this).attr("action");
$.ajax({
type: "POST",
url: url,
data: msg,
dataType: "json",
success: function(data){
if(data.success){
miniShop2.Message.success(data.message);
}else{
miniShop2.Message.error(data.message);
}
}
})
})
Если вы попытаетесь отправить форму, то в консоли браузер выдаст ошибку из-за того, что у нас не инициализирован miniShop2, поэтому нам с вами необходимо модернизировать код плагина miniShop2 и добавить строку перед словом “break” в событии “OnMODXInit” (примерно 10 строчка):
$miniShop2->initialize($modx->context->key);
Попробуйте снова отправить форму и увидите, что наши уведомления начали уходить и стала появляться симпатичное окошко со статусами.
Также нам нужно предусмотреть события, когда пользователь подтверждает подписку с email и отписывается. Для этого я нашел простенький плагин jQuery, которые поможет нам извлечь из адресной строки GET-параметры.
$.extend({
getUrlVars: function(){
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
},
getUrlVar: function(name){
return $.getUrlVars()[name];
}
});
И напишем обработчик для наших GET-параметров на jQuery в разделе $(document).ready():
var confirmed = $.getUrlVar('sx_confirmed');
var unsubscribe = $.getUrlVar('sx_unsubscribed');
if(confirmed){
setTimeout(function(){
miniShop2.Message.success("Ваш email был успешно подтвержден!");
}, 1000);
}
if(unsubscribe){
setTimeout(function(){
miniShop2.Message.success("Вы успешно отписались от рассылки!");
}, 1000);
}
Полный код чанка scripts получился следующий:
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/owl.carousel.min.js"></script>
<script src="assets/js/magnific-popup.min.js"></script>
<script src="assets/js/bootsnav.js"></script>
<script src="assets/js/custom.js"></script>
<script>
$.extend({
getUrlVars: function(){
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
},
getUrlVar: function(name){
return $.getUrlVars()[name];
}
});
$(document).ready(function(){
var confirmed = $.getUrlVar('sx_confirmed');
var unsubscribe = $.getUrlVar('sx_unsubscribed');
if(confirmed){
setTimeout(function(){
miniShop2.Message.success("Ваш email был успешно подтвержден!");
}, 1000);
}
if(unsubscribe){
setTimeout(function(){
miniShop2.Message.success("Вы успешно отписались от рассылки!");
}, 1000);
}
$('.subscribe-form').submit(function(e){
e.preventDefault();
var msg = $(this).serialize();
var url = $(this).attr("action");
$.ajax({
type: "POST",
url: url,
data: msg,
dataType: "json",
success: function(data){
if(data.success){
miniShop2.Message.success(data.message);
}else{
miniShop2.Message.error(data.message);
}
}
})
})
});
</script>
Таким вот простым образом мы с вами реализовали форму подписки пользователя на новости.
else { $params['hash'] = $response; $params['sx_action'] = 'confirm'; $placeholders['link'] = $modx->makeUrl($modx->resource->id, $modx->context->key, $params, 'full'); $placeholders['email_body'] = $modx->getChunk($tplActivate, $placeholders); $response = $Sendex->sendEmail($email, $placeholders); if ($response !== true) { $output['success'] = false; $output['message'] = $modx->lexicon('sendex_subscribe_err_email_send');Причём вручную рассылки Sendex проходят, а вот при отправке email через форму — нет. Также данные с других форм фидбэка прекрасно уходят по аяксу, Куда копать, подскажите, пожалуйста.Вот она:
public function sendEmail($email, array $options = array()) { /** @var modPHPMailer $mail */ $mail = $this->modx->getService('mail', 'mail.modPHPMailer'); $mail->set(modMail::MAIL_BODY, $this->modx->getOption('email_body', $options, '')); $mail->set(modMail::MAIL_FROM, $this->modx->getOption('email_from', $options, $this->modx->getOption('emailsender'), true)); $mail->set(modMail::MAIL_FROM_NAME, $this->modx->getOption('email_from_name', $options, $this->modx->getOption('site_name'), true)); $mail->set(modMail::MAIL_SUBJECT, $this->modx->getOption('email_subject', $options, $this->modx->lexicon('sendex_subscribe_activate_subject'), true)); $mail->address('to', $email); $mail->address('reply-to', $this->modx->getOption('email_from', $options, $this->modx->getOption('emailsender'), true)); $mail->setHTML(true); $response = !$mail->send() ? $mail->mailer->errorInfo : true; $mail->reset(); return $response; }Следовательно, modPHPMailer не может отправить письмо. Чтобы посмотреть почему, вы можете проверить логи MODX (Управление->Отчеты->Журнал ошибок). Или же вы можете после этой строки:if ($response !== true) {Написать:Тогда в журнале ошибок вы сможете увидеть на что ругается modPHPMailer$tplActivate = $modx->getOption('tplActivate',$scriptProperties,'tpl.Sendex.activate');Может кому поможет