Начиная с версии 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.
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.
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 нашим изменённым провайдером.
'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.
Если вы хотите использовать другое пространство имён, нет проблем!