AJAX форма подписки пользователя с помощью Sendex. Часть 2.

07.06.2018
1944

Реализацию нашего функционала мы начнем с подписки на первом экране. Реализовывать ее будем с помощью компонента Sendex. Для начала нам нужно создать подписку в разделе “Приложения -> Sendex”:

[[*pagetitle:htmlent]]

Отлично! Подписка создана. Сам процесс подписки пользователя будет реализован на AJAX, поэтому нам нужно создать технический ресурс для подписки пользователей, где у нас будет размещен вызов сниппета Sendex. Обычно я создаю подобные ресурсы следующим образом:

[[*pagetitle:htmlent]]

Обязательно установите во всех трех ресурсах флажки “Опубликован” и “скрыть из меню”, а на вкладке “Настройки” снимите флажки “Доступен для поиска” и “Использовать 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>

Таким вот простым образом мы с вами реализовали форму подписки пользователя на новости.

AJAX форма подписки пользователя с помощью Sendex. Часть 2.

0 Число голосов: 3
5
5
1
3

Комментарии ()

    Наши клиенты

    Многие компании уже доверяют нам. Будьте в их числе!

    Хотите реализовать проект?

    Контакты

    Напишите нам - мы расскажем вам много интересного!


    Пермь, ул. Крупской 34, офис 510