Почта
- Введение
- Создание почтовых сообщений
- Написание почтовых сообщений
- Почтовые отправления в формате Markdown
- Отправка почты
- Рендеринг почтовых сообщений
- Локализация почтовых сообщений
- Тестирование почтовых сообщений
- Почта и локальная разработка
- События
Введение
Отправка электронной почты не должна быть сложной. Laravel предоставляет чистый и простой API электронной почты на основе популярной библиотеки SwiftMailer. Laravel и SwiftMailer предоставляют драйверы для отправки электронной почты через SMTP, Mailgun, Postmark, Amazon SES и sendmail
, что позволяет вам быстро приступить к отправке почты через локальную или облачную службу по вашему выбору.
Конфигурация
Почтовые сервисы Laravel можно настроить с помощью файла конфигурации config/mail.php
вашего приложения. Каждая почтовая программа, настроенная в этом файле, может иметь свою собственную уникальную конфигурацию и даже свой собственный уникальный «транспорт», позволяющий вашему приложению использовать различные службы электронной почты для отправки определенных сообщений электронной почты. Например, ваше приложение может использовать Postmark для отправки транзакционных электронных писем, а Amazon SES — для массовой рассылки электронных писем.
В вашем конфигурационном файле mail
вы найдете конфигурационный массив mailers
. Этот массив содержит образец записи конфигурации для каждого из основных почтовых драйверов/транспортов, поддерживаемых Laravel, в то время как значение конфигурации default
определяет, какая почтовая программа будет использоваться по умолчанию, когда вашему приложению необходимо отправить сообщение электронной почты.
Требования к Драйверу / Транспорту
Драйверы на основе API, такие как Mailgun и Postmark, часто проще и быстрее, чем отправка почты через SMTP-серверы. По возможности рекомендуется использовать один из этих драйверов. Для всех драйверов на основе API требуется библиотека Guzzle HTTP, которую можно установить через диспетчер пакетов Composer:
composer require guzzlehttp/guzzle
Mailgun Driver
Чтобы использовать драйвер Mailgun, сначала установите библиотеку Guzzle HTTP. Затем установите параметр default
в файле конфигурации config/mail.php
на mailgun
. Затем убедитесь, что ваш файл конфигурации config/services.php
содержит следующие параметры:
'mailgun' => [ 'domain' => env('MAILGUN_DOMAIN'), 'secret' => env('MAILGUN_SECRET'),],
Если вы не используете США Mailgun region, вы можете определить конечную точку вашего региона в конфигурации services
файл:
'mailgun' => [ 'domain' => env('MAILGUN_DOMAIN'), 'secret' => env('MAILGUN_SECRET'), 'endpoint' => env('MAILGUN_ENDPOINT', 'api.eu.mailgun.net'),],
Postmark Driver
Чтобы использовать драйвер Postmark, установите транспорт Postmark SwiftMailer через Composer:
composer require wildbit/swiftmailer-postmark
Затем установите HTTP-библиотеку Guzzle и установите параметр default
в файле конфигурации config/mail.php
на postmark
. Наконец, убедитесь, что ваш файл конфигурации config/services.php
содержит следующие параметры:
'postmark' => [ 'token' => env('POSTMARK_TOKEN'),],
Если вы хотите указать поток сообщений Postmark, который должен использоваться данной почтовой программой, вы можете добавить параметр конфигурации message_stream_id
в массив конфигурации почтовой программы. Этот массив конфигурации можно найти в файле конфигурации config/mail.php
вашего приложения:
'postmark' => [ 'transport' => 'postmark', 'message_stream_id' => env('POSTMARK_MESSAGE_STREAM_ID'),],
Таким образом, вы также можете настроить несколько почтовых программ Postmark с разными потоками сообщений.
SES Driver
Чтобы использовать драйвер Amazon SES, необходимо сначала установить Amazon AWS SDK для PHP. Вы можете установить эту библиотеку через менеджер пакетов Composer:
composer require aws/aws-sdk-php
Затем установите параметр default
в файле конфигурации config/mail.php
на ses
и убедитесь, что ваш файл конфигурации config/services.php
содержит следующие параметры:
'ses' => [ 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),],
Чтобы использовать временные учетные данные AWS через токен сеанса, вы можете добавить ключ token
в конфигурацию SES вашего приложения. :
'ses' => [ 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 'token' => env('AWS_SESSION_TOKEN'),],
Если вы хотите определить дополнительные параметры, которые Laravel должен перейти к методу SendRawEmail
AWS SDK при отправке электронной почты, вы можете определить массив options
в вашей конфигурации ses
:
'ses' => [ 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 'options' => [ 'ConfigurationSetName' => 'MyConfigurationSet', 'Tags' => [ ['Name' => 'foo', 'Value' => 'bar'], ], ],],
Отказоустойчивая конфигурация
Иногда внешняя служба, которую вы настроили для отправки почты вашего приложения, может быть недоступна. В этих случаях может быть полезно определить одну или несколько резервных конфигураций доставки почты, которые будут использоваться в случае, если ваш основной драйвер доставки не работает.
Чтобы выполнить это, вы должны определить почтовую программу в файле конфигурации mail
вашего приложения, который использует транспорт failover
. Массив конфигурации почтовой программы failover
вашего приложения должен содержать массив mailers
, которые ссылаются на порядок, в котором почтовые драйверы должны быть выбраны для доставки:
'mailers' => [ 'failover' => [ 'transport' => 'failover', 'mailers' => [ 'postmark', 'mailgun', 'sendmail', ], ], // ...],
Как только ваша отказоустойчивая почтовая программа была определена, вы должны установить эту почтовую программу в качестве почтовой программы по умолчанию, используемой вашим приложением, указав ее имя в качестве значения ключа конфигурации default
в файле конфигурации mail
вашего приложения:
'default' => env('MAIL_MAILER', 'failover'),
Создание почтовых сообщений
При создании приложений Laravel каждый тип электронной почты, отправляемой вашим приложением, представляется как "mailable" класс. Эти классы хранятся в каталоге app/Mail
. Не волнуйтесь, если вы не видите этот каталог в своем приложении, так как он будет сгенерирован для вас, когда вы создадите свой первый почтовый класс с помощью Artisan-команды make:mail
:
php artisan make:mail OrderShipped
Написание почтовых сообщений
После того, как вы создали класс для отправки по почте, откройте его, чтобы мы могли изучить его содержимое. Во-первых, обратите внимание, что вся конфигурация почтового класса выполняется в методе build
. В этом методе вы можете вызывать различные методы, такие как from
, subject
, view
и attach
, чтобы настроить представление и доставку электронной почты.
{tip} Вы можете указывать зависимости от метода
build
почтового объекта. Laravel сервисный контейнер автоматически внедряет эти зависимости.
Настройка отправителя
Использование метода from
Во-первых, давайте рассмотрим настройку отправителя электронной почты. Или, другими словами, от кого будет отправлено электронное письмо. Есть два способа настроить отправителя. Во-первых, вы можете использовать метод from
в методе build
вашего почтового класса:
/** * Build the message. * * @return $this */public function build(){ return $this->from('example@example.com', 'Example') ->view('emails.orders.shipped');}
Использование глобального адреса from
Однако, если ваше приложение использует один и тот же адрес "from" для всех своих электронных писем, вызов метода from
в каждом сгенерированном вами почтовом классе может стать громоздким. Вместо этого вы можете указать глобальный адрес "from" отправителя в файле конфигурации config/mail.php
. Этот адрес будет использоваться, если в почтовом классе не указан другой адрес отправителя "from":
'from' => ['address' => 'example@example.com', 'name' => 'App Name'],
Кроме того, вы можете определить глобальный адрес "reply_to" в вашем конфигурационном файле config/mail.php
:
'reply_to' => ['address' => 'example@example.com', 'name' => 'App Name'],
Настройка представления
В методе сборки почтового класса' build
вы можете использовать метод представления view
, чтобы указать, какой шаблон следует использовать при отображении содержимого электронной почты. Поскольку каждое электронное письмо обычно использует шаблон Blade для отображения своего содержимого, у вас есть все возможности и удобство механизма шаблонов Blade при создании HTML-кода вашего электронного письма:
/** * Build the message. * * @return $this */public function build(){ return $this->view('emails.orders.shipped');}
{tip} Вы можете создать каталог
resources/views/emails
для размещения всех ваших шаблонов электронной почты; тем не менее, вы можете разместить их где угодно в вашем каталогеresources/views
.
Электронные письма с обычным текстом
Если вы хотите определить текстовую версию своей электронной почты, вы можете использовать метод text
. Как и метод view
, метод text
принимает имя шаблона, которое будет использоваться для отображения содержимого электронной почты. Вы можете определить как HTML-версию, так и текстовую версию вашего сообщения:
/** * Build the message. * * @return $this */public function build(){ return $this->view('emails.orders.shipped') ->text('emails.orders.shipped_plain');}
Просмотр данных
Через общедоступные ресурсы
Как правило, вы захотите передать в представление некоторые данные, которые можно использовать при отображении HTML-кода электронной почты. Есть два способа сделать данные доступными для вашего представления. Во-первых, любое общедоступное свойство, определенное в вашем почтовом классе, будет автоматически доступно для представления. Так, например, вы можете передать данные в конструктор вашего почтового класса и установить эти данные в общедоступные свойства, определенные в классе:
<?php namespace App\Mail; use App\Models\Order;use Illuminate\Bus\Queueable;use Illuminate\Mail\Mailable;use Illuminate\Queue\SerializesModels; class OrderShipped extends Mailable{ use Queueable, SerializesModels; /** * The order instance. * * @var \App\Models\Order */ public $order; /** * Create a new message instance. * * @param \App\Models\Order $order * @return void */ public function __construct(Order $order) { $this->order = $order; } /** * Build the message. * * @return $this */ public function build() { return $this->view('emails.orders.shipped'); }}
Как только данные будут установлены в общедоступное свойство, они автоматически станут доступны в вашем представлении, поэтому вы можете получить к ним доступ, как и к любым другим данным в ваших шаблонах Blade:
<div> Price: {{ $order->price }}</div>
С помощью метода with
:
Если вы хотите настроить формат данных вашего электронного письма перед его отправкой в шаблон, вы можете вручную передать свои данные в представление с помощью метода with
. Как правило, вы по-прежнему будете передавать данные через конструктор почтового класса; однако вы должны установить для этих данных свойства protected
или private
, чтобы данные не становились автоматически доступными для шаблона. Затем при вызове метода with
передайте массив данных, который вы хотите сделать доступным для шаблона:
<?php namespace App\Mail; use App\Models\Order;use Illuminate\Bus\Queueable;use Illuminate\Mail\Mailable;use Illuminate\Queue\SerializesModels; class OrderShipped extends Mailable{ use Queueable, SerializesModels; /** * The order instance. * * @var \App\Models\Order */ protected $order; /** * Create a new message instance. * * @param \App\Models\Order $order * @return void */ public function __construct(Order $order) { $this->order = $order; } /** * Build the message. * * @return $this */ public function build() { return $this->view('emails.orders.shipped') ->with([ 'orderName' => $this->order->name, 'orderPrice' => $this->order->price, ]); }}
Как только данные будут переданы методу with
, они автоматически станут доступны в вашем представлении, поэтому вы можете получить к ним доступ, как и к любым другим данным в ваших шаблонах Blade:
<div> Price: {{ $orderPrice }}</div>
Вложения
Чтобы добавить вложения в электронное письмо, используйте метод attach
в методе почтового класса build
. Метод attach
принимает полный путь к файлу в качестве первого аргумента:
/** * Build the message. * * @return $this */public function build(){ return $this->view('emails.orders.shipped') ->attach('/path/to/file');}
При прикреплении файлов к сообщению вы также можете указать отображаемое имя и/или тип MIME, передав array
в качестве второго аргумента методу attach
:
/** * Build the message. * * @return $this */public function build(){ return $this->view('emails.orders.shipped') ->attach('/path/to/file', [ 'as' => 'name.pdf', 'mime' => 'application/pdf', ]);}
Прикрепление файлов с диска
Если вы сохранили файл на одном из ваших дисков с файловой системой, вы можете прикрепить его к электронному письму с помощью метода attachFromStorage
:
/** * Build the message. * * @return $this */public function build(){ return $this->view('emails.orders.shipped') ->attachFromStorage('/path/to/file');}
При необходимости вы можете указать имя вложения файла и дополнительные параметры, используя второй и третий аргументы метода attachFromStorage
:
/** * Build the message. * * @return $this */public function build(){ return $this->view('emails.orders.shipped') ->attachFromStorage('/path/to/file', 'name.pdf', [ 'mime' => 'application/pdf' ]);}
Метод attachFromStorageDisk
можно использовать, если вам нужно указать диск для хранения, отличный от вашего диска по умолчанию:
/** * Build the message. * * @return $this */public function build(){ return $this->view('emails.orders.shipped') ->attachFromStorageDisk('s3', '/path/to/file');}
Вложения необработанных данных
Метод attachData
может использоваться для присоединения необработанной строки байтов в качестве вложения. Например, вы можете использовать этот метод, если вы создали PDF-файл в памяти и хотите прикрепить его к электронному письму, не записывая его на диск. Метод attachData
принимает необработанные байты данных в качестве первого аргумента, имя файла в качестве второго аргумента и массив опций в качестве третьего аргумента:
/** * Build the message. * * @return $this */public function build(){ return $this->view('emails.orders.shipped') ->attachData($this->pdf, 'name.pdf', [ 'mime' => 'application/pdf', ]);}
Встроенные вложения
Встраивание встроенных изображений в ваши электронные письма обычно обременительно; однако Laravel предоставляет удобный способ прикреплять изображения к вашим электронным письмам. Чтобы встроить встроенное изображение, используйте метод embed
для переменной $message
в шаблоне электронной почты. Laravel автоматически делает переменную $message
доступной для всех ваших шаблонов электронной почты, поэтому вам не нужно беспокоиться о ее передаче вручную:
<body> Here is an image: <img src="{{ $message->embed($pathToImage) }}"></body>
{note} Переменная
$message
недоступна в шаблонах сообщений с открытым текстом, поскольку сообщения с открытым текстом не используют встроенные вложения.
Встраивание вложений необработанных данных
Если у вас уже есть необработанная строка данных изображения, которую вы хотите встроить в шаблон электронной почты, вы можете вызвать метод embedData
для переменной $message
. При вызове метода embedData
вам нужно будет указать имя файла, которое должно быть присвоено встроенному изображению:
<body> Here is an image from raw data: <img src="{{ $message->embedData($data, 'example-image.jpg') }}"></body>
Настройка сообщения SwiftMailer
Метод withSwiftMessage
базового класса Mailable
позволяет зарегистрировать замыкание, которое будет вызываться с экземпляром сообщения SwiftMailer перед отправкой сообщения. Это дает вам возможность глубоко настроить сообщение перед его доставкой:
/** * Build the message. * * @return $this */public function build(){ $this->view('emails.orders.shipped'); $this->withSwiftMessage(function ($message) { $message->getHeaders()->addTextHeader( 'Custom-Header', 'Header Value' ); }); return $this;}
Почтовые отправления в формате Markdown
Почтовые сообщения Markdown позволяют вам воспользоваться преимуществами готовых шаблонов и компонентов почтовых уведомлений в ваших почтовых сообщениях. Поскольку сообщения написаны в Markdown, Laravel может отображать красивые, отзывчивые HTML-шаблоны для сообщений, а также автоматически генерировать текстовый аналог.
Генерация почтовых сообщений в формате Markdown
Чтобы сгенерировать почтовое сообщение с соответствующим шаблоном Markdown, вы можете использовать параметр --markdown
команды Artisan make:mail
:
php artisan make:mail OrderShipped --markdown=emails.orders.shipped
Затем, при настройке почтового объекта в его методе build
, вызовите метод markdown
вместо метода view
. Метод markdown
принимает имя шаблона Markdown и необязательный массив данных, чтобы сделать его доступным для шаблона:
/** * Build the message. * * @return $this */public function build(){ return $this->from('example@example.com') ->markdown('emails.orders.shipped', [ 'url' => $this->orderUrl, ]);}
Написание сообщений Markdown
Почтовые сообщения Markdown используют комбинацию компонентов Blade и синтаксиса Markdown, которые позволяют легко создавать почтовые сообщения, используя предварительно созданные компоненты пользовательского интерфейса электронной почты Laravel:
@component('mail::message')# Order Shipped Your order has been shipped! @component('mail::button', ['url' => $url])View Order@endcomponent Thanks,<br>{{ config('app.name') }}@endcomponent
{tip} Не используйте лишние отступы при написании электронных писем в формате Markdown. В соответствии со стандартами Markdown синтаксические анализаторы Markdown будут отображать содержимое с отступом в виде блоков кода.
Компонент кнопки
Компонент кнопки отображает центрированную ссылку кнопки. Компонент принимает два аргумента: url
и необязательный color
. Поддерживаемые цвета: primary
, success
и error
. Вы можете добавить в сообщение столько кнопок, сколько пожелаете:
@component('mail::button', ['url' => $url, 'color' => 'success'])View Order@endcomponent
Компонент панели
Компонент панели отображает заданный блок текста в панели, цвет фона которой немного отличается от остального сообщения. Это позволяет привлечь внимание к заданному блоку текста:
@component('mail::panel')This is the panel content.@endcomponent
Табличный компонент
Компонент таблицы позволяет преобразовать таблицу Markdown в таблицу HTML. Компонент принимает таблицу Markdown в качестве своего содержимого. Выравнивание столбцов таблицы поддерживается с использованием синтаксиса выравнивания таблиц Markdown по умолчанию:
@component('mail::table')| Laravel | Table | Example || ------------- |:-------------:| --------:|| Col 2 is | Centered | $10 || Col 3 is | Right-Aligned | $20 |@endcomponent
Настройка компонентов
Вы можете экспортировать все почтовые компоненты Markdown в собственное приложение для настройки. Чтобы экспортировать компоненты, используйте Artisan-команду vendor:publish
, чтобы опубликовать тег актива laravel-mail
:
php artisan vendor:publish --tag=laravel-mail
Эта команда опубликует почтовые компоненты Markdown в каталоге resources/views/vendor/mail
. Каталог mail
будет содержать каталог html
и text
, каждый из которых содержит соответствующие представления каждого доступного компонента. Вы можете настроить эти компоненты по своему усмотрению.
Настройка CSS
После экспорта компонентов в каталоге resources/views/vendor/mail/html/themes
будет находиться файл default.css
. Вы можете настроить CSS в этом файле, и ваши стили будут автоматически преобразованы во встроенные стили CSS в HTML-представлениях ваших почтовых сообщений Markdown.
Если вы хотите создать совершенно новую тему для компонентов Laravel Markdown, вы можете поместить файл CSS в каталог html/themes
. После присвоения имени и сохранения файла CSS обновите параметр theme
в файле конфигурации config/mail.php
вашего приложения, чтобы он соответствовал имени вашей новой темы.
Чтобы настроить тему для отдельного почтового сообщения, вы можете установить свойство $theme
класса почтового сообщения на имя темы, которая должна использоваться при отправке этого почтового сообщения.
Отправка почты
Чтобы отправить сообщение, используйте метод to
на Mail
facade. Метод to
принимает адрес электронной почты, экземпляр пользователя или набор пользователей. Если вы передаете объект или набор объектов, почтовая программа автоматически использует их свойства email
и name
при определении получателей электронной почты, поэтому убедитесь, что эти атрибуты доступны для ваших объектов. После того, как вы указали своих получателей, вы можете передать экземпляр вашего почтового класса методу send
:
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller;use App\Mail\OrderShipped;use App\Models\Order;use Illuminate\Http\Request;use Illuminate\Support\Facades\Mail; class OrderShipmentController extends Controller{ /** * Ship the given order. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $order = Order::findOrFail($request->order_id); // Ship the order... Mail::to($request->user())->send(new OrderShipped($order)); }}
Вы не ограничены простым указанием получателей "to" при отправке сообщения. Вы можете установить получателей "to", "cc", и "bcc", объединив их соответствующие методы вместе:
Mail::to($request->user()) ->cc($moreUsers) ->bcc($evenMoreUsers) ->send(new OrderShipped($order));
Перебор получателей
Иногда вам может понадобиться отправить почтовые сообщения списку получателей, перебирая массив получателей/адресов электронной почты. Однако, поскольку метод to
добавляет адреса электронной почты в список получателей почтового сообщения, каждая итерация цикла будет отправлять новое электронное письмо каждому предыдущему получателю. Следовательно, вы всегда должны заново создавать почтовый экземпляр для каждого получателя:
foreach (['taylor@example.com', 'dries@example.com'] as $recipient) { Mail::to($recipient)->send(new OrderShipped($order));}
Отправка почты через конкретный Mailer
По умолчанию Laravel будет отправлять электронную почту, используя почтовую программу, настроенную как почтовая программа default
в файле конфигурации mail
вашего приложения. Однако вы можете использовать метод mailer
для отправки сообщения, используя определенную конфигурацию почтовой программы:
Mail::mailer('postmark') ->to($request->user()) ->send(new OrderShipped($order));
Постановка почты в очередь
Постановка почтового сообщения в очередь
Поскольку отправка сообщений электронной почты может негативно повлиять на время отклика вашего приложения, многие разработчики предпочитают ставить сообщения электронной почты в очередь для отправки в фоновом режиме. Laravel упрощает это, используя встроенный унифицированный API очередей. Чтобы поставить почтовое сообщение в очередь, используйте метод queue
на фасаде Mail
после указания получателей сообщения:
Mail::to($request->user()) ->cc($moreUsers) ->bcc($evenMoreUsers) ->queue(new OrderShipped($order));
Этот метод автоматически позаботится о помещении задания в очередь, чтобы сообщение отправлялось в фоновом режиме. Вам потребуется настроить очереди перед использованием этой функции.
Отложенная очередь сообщений
Если вы хотите отложить доставку сообщения электронной почты, находящегося в очереди, вы можете использовать метод later
. В качестве первого аргумента метод later
принимает экземпляр DateTime
, указывающий, когда сообщение должно быть отправлено:
Mail::to($request->user()) ->cc($moreUsers) ->bcc($evenMoreUsers) ->later(now()->addMinutes(10), new OrderShipped($order));
Отправка в определенные очереди
Поскольку все почтовые классы, сгенерированные с помощью команды make:mail
, используют трейт Illuminate\Bus\Queueable
, вы можете вызывать методы onQueue
и onConnection
для любого экземпляра почтового класса, позволяя вам указать соединение и имя очереди для сообщения:
$message = (new OrderShipped($order)) ->onConnection('sqs') ->onQueue('emails'); Mail::to($request->user()) ->cc($moreUsers) ->bcc($evenMoreUsers) ->queue($message);
Очередь по умолчанию
Если у вас есть почтовые классы, которые вы хотите всегда ставить в очередь, вы можете реализовать контракт ShouldQueue
для класса. Теперь, даже если вы вызовете метод send
при отправке почты, письмо все равно будет поставлено в очередь, поскольку оно реализует контракт:
use Illuminate\Contracts\Queue\ShouldQueue; class OrderShipped extends Mailable implements ShouldQueue{ //}
Почтовые сообщения в очереди и транзакции базы данных
Когда почтовые сообщения, находящиеся в очереди, отправляются в рамках транзакций базы данных, они могут быть обработаны очередью до того, как транзакция базы данных будет зафиксирована. Когда это происходит, любые обновления, которые вы внесли в модели или записи базы данных во время транзакции базы данных, могут еще не отражаться в базе данных. Кроме того, любые модели или записи базы данных, созданные в рамках транзакции, могут не существовать в базе данных. Если ваше почтовое сообщение зависит от этих моделей, при обработке задания, отправляющего поставленное в очередь почтовое сообщение, могут возникнуть непредвиденные ошибки.
Если для параметра конфигурации after_commit
вашего соединения с очередью установлено значение false
, вы все равно можете указать, что конкретное почтовое сообщение, находящееся в очереди, должно быть отправлено после того, как все открытые транзакции базы данных были зафиксированы, вызвав метод afterCommit
при отправке почтового сообщения:
Mail::to($request->user())->send( (new OrderShipped($order))->afterCommit());
Кроме того, вы можете вызвать метод afterCommit
из конструктора вашего почтового объекта:
<?php namespace App\Mail; use Illuminate\Bus\Queueable;use Illuminate\Contracts\Queue\ShouldQueue;use Illuminate\Mail\Mailable;use Illuminate\Queue\SerializesModels; class OrderShipped extends Mailable implements ShouldQueue{ use Queueable, SerializesModels; /** * Create a new message instance. * * @return void */ public function __construct() { $this->afterCommit(); }}
{tip} Чтобы узнать больше о том, как обойти эти проблемы, ознакомьтесь с документацией по заданиям в очереди и транзакциям базы данных.
Рендеринг почтовых сообщений
Иногда вам может понадобиться захватить HTML-содержимое почтового сообщения, не отправляя его. Для этого вы можете вызвать метод render
почтового объекта. Этот метод вернет оцененное HTML-содержимое почтового сообщения в виде строки:
use App\Mail\InvoicePaid;use App\Models\Invoice; $invoice = Invoice::find(1); return (new InvoicePaid($invoice))->render();
Предварительный просмотр почтовых сообщений в браузере
При разработке шаблона почтового сообщения удобно быстро просмотреть обработанное почтовое сообщение в браузере, как обычный шаблон Blade. По этой причине Laravel позволяет вам возвращать любые почтовые сообщения непосредственно из замыкания маршрута или контроллера. Когда сообщение будет возвращено, оно будет обработано и отображено в браузере, что позволит вам быстро просмотреть его дизайн без необходимости отправлять его на фактический адрес электронной почты:
Route::get('/mailable', function () { $invoice = App\Models\Invoice::find(1); return new App\Mail\InvoicePaid($invoice);});
{note} Встроенные вложения не будут отображаться при предварительном просмотре почтового сообщения в браузере. Чтобы просмотреть эти почтовые сообщения, вы должны отправить их в приложение для тестирования электронной почты, такое как MailHog или HELO.
Локализация почтовых сообщений
Laravel позволяет вам отправлять почтовые сообщения в локали, отличной от текущей локали запроса, и даже запомнит эту локаль, если почта поставлена в очередь.
Для этого фасад Mail
предлагает метод locale
для установки нужного языка. Приложение переключится на эту локаль, когда будет оцениваться шаблон почтового сообщения, а затем вернется к предыдущей локали, когда оценка будет завершена:
Mail::to($request->user())->locale('es')->send( new OrderShipped($order));
Предпочтительные локали пользователя
Иногда приложения сохраняют предпочтительную локаль каждого пользователя. Реализуя контракт HasLocalePreference
в одной или нескольких ваших моделях, вы можете указать Laravel использовать эту сохраненную локаль при отправке почты:
use Illuminate\Contracts\Translation\HasLocalePreference; class User extends Model implements HasLocalePreference{ /** * Get the user's preferred locale. * * @return string */ public function preferredLocale() { return $this->locale; }}
После того, как вы реализовали интерфейс, Laravel будет автоматически использовать предпочтительную локаль при отправке почтовых сообщений и уведомлений в модель. Поэтому нет необходимости вызывать метод locale
при использовании этого интерфейса:
Mail::to($request->user())->send(new OrderShipped($order));
Тестирование почтовых сообщений
Laravel предоставляет несколько удобных методов для проверки того, что ваши почтовые сообщения содержат ожидаемый контент. Это следующие методы: assertSeeInHtml
, assertDontSeeInHtml
, assertSeeInText
и assertDontSeeInText
.
Как и следовало ожидать, утверждения "HTML" утверждают, что HTML-версия вашего почтового сообщения содержит заданную строку, в то время как утверждения "text" утверждают, что версия вашего почтового сообщения в виде обычного текста содержит заданную строку:
use App\Mail\InvoicePaid;use App\Models\User; public function test_mailable_content(){ $user = User::factory()->create(); $mailable = new InvoicePaid($user); $mailable->assertSeeInHtml($user->email); $mailable->assertSeeInHtml('Invoice Paid'); $mailable->assertSeeInText($user->email); $mailable->assertSeeInText('Invoice Paid');}
Тестирование отправки по почте
Мы предлагаем тестировать содержимое ваших почтовых сообщений отдельно от ваших тестов, которые утверждают, что данное почтовое сообщение было «отправлено» конкретному пользователю. Чтобы узнать, как проверить, что почтовые сообщения были отправлены, ознакомьтесь с нашей документацией по Подделка почты.
Почта и локальная разработка
При разработке приложения, которое отправляет электронную почту, вы, вероятно, не хотите на самом деле отправлять электронные письма на действующие адреса электронной почты. Laravel предоставляет несколько способов «отключить» фактическую отправку электронных писем во время локальной разработки.
Журнал Драйвера
Вместо того, чтобы отправлять ваши электронные письма, почтовый драйвер log
будет записывать все сообщения электронной почты в ваши лог-файлы для проверки. Обычно этот драйвер используется только во время локальной разработки. Дополнительные сведения о настройке приложения для каждой среды см. в документации по настройке.
HELO / Mailtrap / MailHog
В качестве альтернативы вы можете использовать такие службы, как HELO или Mailtrap и драйвер smtp
для отправки ваших сообщений электронной почты на «фиктивный» почтовый ящик. где вы можете просмотреть их в настоящем почтовом клиенте. Преимущество этого подхода заключается в том, что вы можете фактически проверять окончательные электронные письма в средстве просмотра сообщений Mailtrap.
Если вы используете Laravel Sail, вы можете просмотреть свои сообщения с помощью MailHog. Когда Sail запущен, вы можете получить доступ к интерфейсу MailHog по адресу: http://localhost:8025
.
Использование глобального адреса to
Наконец, вы можете указать глобальный адрес "to", вызвав метод alwaysTo
, предлагаемый фасадом Mail
. Как правило, этот метод следует вызывать из метода boot
одного из сервис-провайдеров вашего приложения:
use Illuminate\Support\Facades\Mail; /** * Bootstrap any application services. * * @return void */public function boot(){ if ($this->app->environment('local')) { Mail::alwaysTo('taylor@example.com'); }}
События
Laravel запускает два события в процессе отправки почтовых сообщений. Событие MessageSending
запускается до отправки сообщения, а событие MessageSent
запускается после отправки сообщения. Помните, что эти события запускаются, когда почта отправляется, а не когда она ставится в очередь. Вы можете зарегистрировать прослушиватели событий для этого события в поставщике услуг App\Providers\EventServiceProvider
:
/** * The event listener mappings for the application. * * @var array */protected $listen = [ 'Illuminate\Mail\Events\MessageSending' => [ 'App\Listeners\LogSendingMessage', ], 'Illuminate\Mail\Events\MessageSent' => [ 'App\Listeners\LogSentMessage', ],];