Письма в html-формате с вложенными изображеними

от автора

Резонный вопрос: зачем аттачить изображения, ведь это утяжеляет письма и увеличивает трафик? А чтобы не было такого:

image

Данный вид возникает в случае если пользователь читает полученную корреспонденцию оффлайн или почтовый клиент не открывает картинки из внешних источников, например из-за его настроек безопасности. Короче говоря, выглядит это может быть и читабельно, но не эстетично.

Если приаттачить картинки к письму, то оно обретёт целостный вид, и дырок уже не будет, если не допущено ошибок на этапе вёрстки.

Итак, необходимо получить возможность создавать полноценные html-шаблоны писем с картинками для их дальнейшего использования в программе (рассылка, автоматические уведомления и т.п.). В последующем шаблоны сможет готовить человек, занимающийся только версткой, без вмешательства в код программы.

Задача типичная, можно сказать обыденная, и реализаций уже придумано не мало. И чтобы не порождать 100500-й веолосипед, обратимся к небезызвестному Swift Mailer, немного расширив его функциональность применительно к нашей задаче.

Так будет выглядеть условный шаблон письма, назовём его index.html:

<html><head></head><body> <img src=”images/company_logo.gif” > Здравствуйте, {username}! Сообщаем Вам, что если сегодня вы навестите наш сайт, то сможете получить {something} абсолютно безвозмездно, то есть даром.  <div>Фото подарка: <img src=”images/{something_photo}”></div> </body></html> 

Структура каталогов для хранения шаблонов может выглядеть таким образом:

email_templates/ 	template1/ 		index.html 		images/ 			company_logo.gif 			photo1.png 			... 			photoN.png 	template2/ 	... 

Класс:

class SendEMail { 	static $transport = false;  	public $filename = 'index.html', 		   // путь к html шаблону 		   $tplFolder = '', 		   // каталог с картинками 		   $imgFolder = 'images/', 		   $subject = '', 		   $from = '', 		   $fromName = null, 		   $contentType = 'text/html', 		   $charset = 'utf-8';  	private $message, $data;  	public function __construct($options) 	{ 		foreach($options as $option => $value) 			$this->$option = $value; 		if (!self::$transport) 			self::$transport = Swift_SmtpTransport::newInstance(); 	}  	public function Send($data, $email, $name = null) 	{ 		$this->data = $data; 		$this->message = Swift_Message::newInstance(); 		$mess =& $this->message; 		 		// подставляем данные в subject письма, если там есть соответствующие теги 		$subject = $this->SubstituteData($this->subject); 		$body = $this->GetBody(); 		 		// email и имя получателя 		$mess->setTo($email, $name); 		// от кого 		$mess->setFrom($this->from, $this->fromName); 		// тема письма 		$mess->setSubject($subject); 		// сообщение 		$mess->setBody($body); 		$mess->setContentType($this->contentType); 		$mess->setCharset($this->charset); 		 		$mailer = Swift_Mailer::newInstance(self::$transport); 		return $mailer->send($this->message); 	}  	private function GetBody() 	{ 		// считываем шаблон письма 		$body = file_get_contents($this->tplPath.$this->filename); 		// подставляем данные в шаблон 		$body = $this->SubstituteData($body); 		// аттачим все картинки, с подходящими imgPath и расширениями jpg, png, gif, заменяем атрибуты src в тегах img 		// 'self::AddImage' будет работать для php > 5.3, для 5.2 нужно заменить на array($this, 'AddImage') 		return preg_replace_callback('/'.preg_quote($this->imgPath, '/').'((.+)\.(jpg|png|gif))/i', 'self::AddImage', $body); 	}  	// прикрепляем картинку, меняем src 	private function AddImage($matches) 	{ 		$path = $this->tplPath."/".$matches[0]; 		return $this->message->embed(Swift_Image::fromPath($path)); 	}  	// заменяем теги на соответствующие данные 	private function SubstituteData($str) 	{ 		if (empty($this->data)) 			return $str; 		foreach($this->data as $k => $v) 			$str = str_replace($k, $v, $str); 		return $str; 	} } 

Пример рассылки:

$sm = new SendEMail(array( 	'tplPath'  => '/path_to_emails/email_templates/template1/', 	'subject' => 'Чудесные подарки', 	'from'    => 'noreply@site.com' ));  $recipients[0] = array( 	'email'           => 'dima@blabla.com', 	'user'            => 'Дмитрий Владимирович', 	'something'       => 'Мялка', 	'something_photo' => 'myalka.jpg' ); $recipients[1] = array( 	'email'           => 'volodya@blabla.com', 	'user'            => 'Владимир Анатольевич', 	'something'       => 'Мешалка', 	'something_photo' => 'meshalka.jpg' ); $success = 0; foreach($recipients as $rec) { 	$data = array('{user}' => $rec['user'], '{something}' => $rec['something'], '{something_photo}' => $rec['something_photo']); 	$sended = $sm->Send($data, $rec['email'], $rec['user']); 	if ($sended) 		$success++; }  

Теперь необходимо следить за размерами создаваемых писем, и не превышать разумные объёмы, проявляя заботу о тех, у кого интернет с телефона, медленный, с оплатой по трафику.

Конечно, данные следует брать из БД, это всего лишь пример. В классе также отсутствуют обработчики ошибок для уменьшения количества строк, лучшей читаемости кода и понимания.

ссылка на оригинал статьи http://habrahabr.ru/post/172269/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *