Может войдёшь?
Черновики Написать статью Профиль

Встраивание CSS при отправке e-mail с помощью Mailgun

перевод

Начиная с версии Laravel 4.2, можно использовать внешние провайдеры электронной почты для отправки e-mail из вашего приложения, такие как Mailgun и Mandrill. До этого я использовал отличный плагин fedeisas/laravel-mail-css-inliner для встраивания CSS прямо перед отправкой e-mail. Благодаря этому, мои представления (views) очень чисты и мои сообщения до сих пор отображаются корректно в различных почтовых клиентах и почтовых веб-сервисах. Этот плагин использовал PHPSwiftMailer для встраивания CSS при отправке сообщений путём регистрации плагина. К сожалению, он не работает с внешними провайдерами, потому что PHPSwiftMailer не используется с тех пор, как вместо него сделали вызов API.

Унаследуем некоторые классы, чтобы исправить это

Решением, которое я нашёл, стало наследование двух классов: PHPIlluminate\Mail\MailServiceProvider и PHPIlluminate\Mail\Transport\MailgunTransport.

Я создал новый файл app/lib/TeenQuotes/Mail/Transport/MailgunTransport.php. Целью было редактирование сообщения до вызова Mailgun API.

PHP
namespace TeenQuotes\Mail\Transport;

use 
Swift_Transport;
use 
Swift_Mime_Message;
use 
GuzzleHttp\Post\PostFile;
use 
Swift_Events_EventListener;
use 
TijsVerkoyen\CssToInlineStyles\CssToInlineStyles;

class 
MailgunTransport extends \Illuminate\Mail\Transport\MailgunTransport {

    
/**
     * {@inheritdoc}
     */
    
public function send(Swift_Mime_Message $message, &$failedRecipients null)
    {
        
$client $this->getHttpClient();

        
// Встраивание CSS здесь
        
$converter = new CssToInlineStyles();
        
$converter->setEncoding($message->getCharset());
        
$converter->setUseInlineStylesBlock();
        
$converter->setCleanup();

        if (
$message->getContentType() === 'text/html' ||
            (
$message->getContentType() === 'multipart/alternative' && $message->getBody())
        ) {
            
$converter->setHTML($message->getBody());
            
$message->setBody($converter->convert());
        }

        foreach (
$message->getChildren() as $part) {
            if (
strpos($part->getContentType(), 'text/html') === 0) {
                
$converter->setHTML($part->getBody());
                
$part->setBody($converter->convert());
            }
        }

        
// Вызов API
        
$client->post($this->url, ['auth' => ['api'$this->key],
            
'body' => [
                
'to' => $this->getTo($message),
                
'message' => new PostFile('message', (string) $message),
            ],
        ]);
    }
}

Поскольку у нас есть новый PHPMailgunTransport, нам надо использовать наш изменённый PHPMailgunTransport при отправке email. Я создал новый файл app/lib/TeenQuotes/Mail/MailServiceProvider.php.

PHP
namespace TeenQuotes\Mail;

use 
TeenQuotes\Mail\Transport\MailgunTransport;

class 
MailServiceProvider extends \Illuminate\Mail\MailServiceProvider {

    
/**
     * Регистрация экземпляра Mailgun Swift Transport.
     *
     * @param  array  $config
     * @return void
     */
    
protected function registerMailgunTransport($config)
    {
        
$mailgun $this->app['config']->get('services.mailgun', array());

        
$this->app->bindShared('swift.transport', function() use ($mailgun)
        {
            return new 
MailgunTransport($mailgun['secret'], $mailgun['domain']);
        });
    }
}

Не так уж много работы, я просто использовал мой изменённый PHPMailgunTransport, который только что создал.

Замена провайдера почты (Mail Provider)

Вам надо обновить провайдеры в app/config/app.php, чтобы заменить MailServiceProvider нашим изменённым провайдером.

PHP
'providers' => array(
  
// Какие-то другие провайдеры...
  
'Illuminate\Log\LogServiceProvider',
  
// Comment this 'Illuminate\Mail\MailServiceProvider',
  // Мы добавляем наш новый MailServiceProvider
  
'TeenQuotes\Mail\MailServiceProvider',
  
// Ещё какие-то провайдеры...
),

Обновление composer.json

Нам нужны некоторые новые плагины.

js"require": {
  // Ваши плагины
  "tijsverkoyen/css-to-inline-styles": "1.2.*",
  "guzzlehttp/guzzle": "~4.0"
},

И нам надо обновить секцию автозагрузки, для того чтобы загружать нашу изменённую библиотеку.

js"autoload": {
  "classmap": [
    "app/commands",
    "app/controllers",
    "app/models",
    "app/database/migrations",
    "app/database/seeds",
    "app/exceptions.php",
    "app/tests/TestCase.php"
  ],
  "psr-0": {
    "TeenQuotes": "app/lib"
  }
},

Просто выполните composer dump-autoload, и всё будет хорошо! Не забудьте задать ключ вашего API и ваш почтовый домен для Mailgun в app/config/services.php.

Если вы хотите использовать другое пространство имён, нет проблем!

Как вы считаете, полезен ли этот материал? Да Нет

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.