Simpla CMS — модуль рассылки

// Сентябрь 29th, 2013 // PHP, Simpla CMS

mailing_01

Представляю Вашему вниманию модуль рассылки для Simpla CMS. Данный модуль не претендует на полноценную систему отправки писем по неимоверному множеству адресатов, однако предоставляет нужный функционал для создания рассылки новостей для интернет-магазина.

Данный модуль разрабатывался с учётом особенностей SimplaCMS v2.1.5. Для корректной работы на иных версиях SimplaCMS следует модифицировать код!

Для начала давайте откорректируем несколько файлов, для отображения нашего раздела «Рассылка» в панеле администрирования. Нам потребуются файлы settings.tpl, currency.tpl, deliveries.tpl, payment_method.tpl, payment_methods.tpl, расположенные в папке \simpla\design\html\.

Для каждого из файлов, перед 6 (шестой) строкой, приблизительно, содержащей

{/capture}

вставляем новую строку

	<li><a href="index.php?module=MailingMethodsAdmin">Рассылка</a></li>

Для хранения списка адресатов и их настроек (полную версию ожидайте позднее) нам потребуется отдельная таблица в базе данных.

CREATE TABLE IF NOT EXISTS `s_mailing` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(255) NOT NULL,
  `types` text NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`)
);

Внесением новых записей в БД будет заниматься страница пользователя. Поправим немного \view\UserView.php.

[1]Заменить:

if(empty($this->user))
[1]На:

if(empty($this->user) && !$this->request->post('mailing_email'))
[2]Заменить:

if($this->request->method('post') && $this->request->post('name'))
[2]На:

if(empty($this->user) && !$this->request->post('mailing_email'))
		{
			header('Location: '.$this->config->root_url.'/user/login');
			exit();
		}
		if($this->request->method('post') && $this->request->post('mailing_email'))
		{
			if(filter_var(trim($this->request->post('mailing_email')), FILTER_VALIDATE_EMAIL))
			{
				$query = $this->db->placehold('select id from __mailing where email=?', $this->request->post('mailing_email'));
				$this->db->query($query);
				if($this->db->num_rows() < 1)
				{
					$query = $this->db->placehold('insert into __mailing(`email`)VALUES(?)', $this->request->post('mailing_email'));
					$this->db->query($query);
				}
			}
			else
			{
				$this->design->assign('error', 'email_syntax');
			}
		}
		elseif($this->request->method('get') && $this->request->get('unsubscribe') && $this->request->get('mail'))
		{
			if(filter_var($this->request->get('mail'), FILTER_VALIDATE_EMAIL)){
				$query = $this->db->placehold('select id from __mailing where email=?', $this->request->get('mail'));
				$this->db->query($query);
				if($this->db->num_rows() > 0){
				$hash = md5($this->settings->license.$this->request->get('mail'));
					if($hash == $this->request->get('unsubscribe')){
						$query = $this->db->placehold('delete from __mailing where email=?', $this->request->get('mail'));
						$this->db->query($query);
					}else{
						$this->design->assign('error', '00001');
					}
				}else{
					$this->design->assign('error', '00001');
				}
			}else{
				$this->design->assign('error', 'email_syntax');
			}
		}
		elseif($this->request->method('post') && $this->request->post('name'))
[3]Заменить:

$this->design->assign('meta_title', $this->user->name);
[3]На:

if(!$this->request->post('mailing_email')){$this->design->assign('meta_title', $this->user->name);}else{$this->design->assign('meta_title', 'Подписка на рассылку');}

И собственно сам файл шаблона страницы пользователя \design\%mytempate%\html\user.tpl.

Заменить:

<h1>{$user->name|escape}</h1>

На:

{if $smarty.get.page && ($smarty.get.page == 'mailing' || $smarty.get.page == 'mailing_settings')}<h1>ПОДПИСКА</h1>
	{if $smarty.post.mailing_email && !$error}
		Вы успешно подписаны на рыссылку новостей.
	{/if}
	{if $smarty.get.unsubscribe && !$error}Вы успешно отписаны от рыссылки.{/if}
	{if $error}<div class="message_error">{if $error == 'email_syntax'}Некорректно введён email.{elseif $error == '00001'}Вы не подписаны на рассылку.{/if}</div>{/if}
{else} <h1>{$user->name|escape}</h1> {/if}

 

В завершение, нам понадобится создать два новых файла — шаблон и обработчик.
\simpla\design\html\mailing_methods.tpl

{capture name=tabs}
	<li><a href="index.php?module=SettingsAdmin">Настройки</a></li>
	<li><a href="index.php?module=CurrencyAdmin">Валюты</a></li>
	<li><a href="index.php?module=DeliveriesAdmin">Доставка</a></li>
	<li><a href="index.php?module=PaymentMethodsAdmin">Оплата</a></li>
	<li class="active"><a href="index.php?module=MailingMethodsAdmin">Рассылка</a></li>
{/capture}

{* Title *}
{$meta_title='Управление Рассылкой' scope=parent}

{* Подключаем Tiny MCE *}
{include file='tinymce_init.tpl'}

{* Заголовок *}
<div id="header">
	<h1><a{if !$smarty.get.show} class="dash_link"{/if} href="index.php?module=MailingMethodsAdmin">Рассылка</a></h1><h1>|</h1><h1><a{if $smarty.get.show} class="dash_link"{/if} href="index.php?module=MailingMethodsAdmin&show=subscribers">Список подписчиков</a></h1>
</div>
{literal}
<style>.interactive{margin:5px 20px;position:absolute;display:none;}</style>
<script type="text/javascript">
$(document).ready(function () {
	$('form#mailpost_form').submit(function(){
		mail_letter = tinyMCE.activeEditor.getContent();
		mail_header = $("#mailpost_form #mail_header").val();
		if(mail_letter != '' && mail_header != ''){
			$('#mail_submit').prop("disabled", true);
			$('.interactive').css('display', 'none');
			$('.interactive.loading').css('display', 'inline');
			$.ajax({
				type: 'POST',
				url: 'index.php?module=MailingMethodsAdmin',
				data: 'session_id='+$("#mailpost_form #session_id").val()+'&header='+mail_header+'&letter='+mail_letter,
				success: function(data){
					$('.interactive.loading').css('display', 'none');
					$('.interactive.complete').css('display', 'inline');
					$('.interactive.complete').css('display', 'inline');
					$('#mail_submit').val('Рассылка завершена');
				}
			});
		}
		return false;
	});
});
</script>
{/literal}
<div id="main_div">
	{if $smarty.get.show}
	<form id="list_form" method="post" action="index.php?module=MailingMethodsAdmin&show=subscribers">
	<input type="hidden" name="session_id" value="{$smarty.session.id}">
		<div id="list">
			{$a=1}{foreach $mailing_email item=email key=id}{$a=$a+1}
			<div class="row{if $a%2===0} even{/if}">
				<div class="checkbox cell">
					<input type="checkbox" name="remove[]" value="{$id}" />				
				</div>
				<div class="name cell">{$email}</div>
				<div class="icons cell">
					<a class="delete" title="Удалить" href="index.php?module=MailingMethodsAdmin&show=subscribers&remove={$id}"></a>
				</div>
				<div class="clear"></div>
			</div>
			{/foreach}
		</div>

		<div id="action">
		<label onclick="$('#list input[type=checkbox]').attr('checked', true);" class="dash_link">Выбрать все</label>
		<span id="select">
		<select name="action">
			<option value="delete">Удалить</option>
		</select>
		</span>

		<input id="apply_action" class="button_green" type="submit" value="Применить">

		</div>
	</form>
	{else}
		<form id="mailpost_form" method="post" action="index.php?module=MailingMethodsAdmin">
			<input type="hidden" id="session_id" name="session_id" value="{$smarty.session.id}">
			<p style="margin-bottom:10px"><label><b>Тема письма:&nbsp&nbsp</b></label><input id="mail_header" type="text" name="header" style="width:50%" /></p>
			<p><textarea id="mail_letter" name="letter" class="editor_small"></textarea></p>
			<p style="text-align:center;margin-top:20px;"><input class="button_green" id="mail_submit" type="submit" value="Разослать" style="margin-right: -12px;" /><img title="Выполняется рассылка" class="interactive loading" src="http://belfast.by/images/ajx_loading.gif"><img title="Рассылка завершена" class="interactive complete" src="design/images/accept.png"></p>
		</form>
	{/if}
	<div style="text-align:right">2013 © <a href="mailto:artyom.yakushev@gmail.com">Copyright</a></div>
</div>

\simpla\MailingMethodsAdmin.php

<?php
require_once('api/Simpla.php');

class MailingMethodsAdmin extends Simpla
{
  public function fetch()
  {
   	// Одиночное удаление
	if($this->request->method('get') && $this->request->get('remove'))
	{
		if(is_numeric($this->request->get('remove')) && $this->request->get('remove')>0)
		{
			$query = $this->db->placehold('delete from __mailing where id=?', $this->request->get('remove'));
			$this->db->query($query);
		}
	}
	// Множественное удаление
  	if($this->request->method('post') && $this->request->post('remove'))
  	{
		print_r($this->request->post('remove'));
 	}

	// Список адресатов
  	$query = $this->db->placehold('select * from __mailing');
	$this->db->query($query);
	$mails = array();
	foreach($this->db->results() as $tmp){$mails[$tmp->id] = $tmp->email;}

	// Обработчик рассылки
	if($this->request->method('post') && $this->request->post('letter'))
	{
		$mail_header = (trim($this->request->post('header'))==''?$this->config->site_name:$this->request->post('header'));
		$mail_headers  = 'MIME-Version: 1.0' . "\r\n";
		$mail_headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
		$mail_headers .= 'From: '.iconv("utf-8","windows-1251",$this->settings->site_name).' <'.$this->settings->notify_from_email.'>' . "\r\n";

		ignore_user_abort(true);
		foreach($mails as $mail)
		{
			$hash = md5($this->settings->license.$mail);
			$unsubscribe = '<p style="text-align:center; margin-top:100px; background-color:#343434; color:#cccccc;">Чтобы отписаться от рассылки, перейдите по <a style="color:#ffffff;" href="'.$this->config->root_url.'/user/?page=mailing_settings&unsubscribe='.$hash.'&mail='.$mail.'" target="_blank">ссылке</a>.</p>';
			mail($mail, $mail_header, $this->request->post('letter').$unsubscribe, $mail_headers);
			usleep(rand(10,20)*100000);
		}
		exit();
	}

 	$this->design->assign('mailing_email', $mails);
	return $this->design->fetch('mailing_methods.tpl');
  }
}
?>

Код формы для добавления адресатов:

<form action="/user/?page=mailing" method="post">
<p><input type="text" name="mailing_email" /></p><p><input class="submit_btn" type="submit" value="Подписаться" /></p>
</form>
! 10.10.2013  Обновил листинги MailingMethodsAdmin.php и mailing_methods.tpl — отправка происходит в фоновом режиме, посредством ajax-запроса. Почта рассылается с интервалом от 1 до 2 секунд между письмами.

!

 17.10.2013  Обновил листинг MailingMethodsAdmin.php, заменяемый текст в UserView.php и user.tpl — добавлена возможность отписки от рассылки.

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

  1. Спасибо за инструкцию..все сделал..только есть ряд вопросов:
    1. в рассылку можно будет выбирать только новых пользователей или еще и существующих?
    2. Так и не понял куда вставить Код формы для добавления адресатов) — подскажите пожалуйста.

    а так большой вам респект!

  2. Спасибо за проделанную работу.
    Нашел баг — если при подписке указать емайл существующего пользователя — откроется страница профиля и в ней вываливается список всех заказов — потенциальный баг.
    и еще чтобы избежать ошибки «Permission Denied», при выведении модуля в админку сделал следующее( симпла 2.x+
    )

    в файле: simpla/IndexAdmin.php
    Добавляем класс

    ‘MailingMethodsAdmin’ => ‘maillist’

    в файле: api/Managers.php
    в массив public $permissions_list
    добавляем еще один элемент
    , ‘maillist’);

    Готово.

  3. похоже ваш код для симплы первых версий. сейчас при выполнении post запроса — все равно вываливает список всех заказов из админки — что странно.пока отключил модуль буду думать.

  4. для того чтобы не показывались заказы, просто огорните вывод заказов в код:

    {if $smarty.server.REQUEST_URI != ‘/user/?page=mailing’}
    тут код
    {/if}

    это как простое решение

  5. Вроде все сделал по инструкции (включая рекомендации господина Терехова), однако, при нажатии «подписаться» перекидывает на страницу авторизации… ЧЯДНТ?

    ЗЫ. Версия 2.2.0

    Спасибо!

  6. Briz:

    Добрый день, подписчиков более 2 тыс человек, начинается рассылка крутиться кружочек, и все на этом так может быть часа 6-7 а то и больше, людям ничего не приходит, почему, подскажите?

  7. Vadik:

    Предлагаю обмен модулями и шаблонами для Simpla cms
    есть много интересного…
    пишите на obisz@bk.ru будем меняться. :)

  8. Blofield:

    Здравствуйте, спасибо за модуль. Можете подсказать, почему может не отображаться закладка рассылка. Все добавил как в инструкции. А закладка не появилась? при переходе по прямой ссылке index.php?module=MailingMethodsAdmin пишет «Permission denied». ? Во все файлы добавил права.?

Комментировать

, чтобы оставлять комментарии

Авторизация

Регистрация | Забыли пароль?