Данный вид возникает в случае если пользователь читает полученную корреспонденцию оффлайн или почтовый клиент не открывает картинки из внешних источников, например из-за его настроек безопасности. Короче говоря, выглядит это может быть и читабельно, но не эстетично.
Если приаттачить картинки к письму, то оно обретёт целостный вид, и дырок уже не будет, если не допущено ошибок на этапе вёрстки.
Итак, необходимо получить возможность создавать полноценные 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/
Добавить комментарий