Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Почта и уведомления

Подтверждение регистрации, чек после оплаты, напоминание о брошенной корзине — письма нужны почти любому сайту. В Laravel письмо описывают классом и шаблоном Blade, а способ доставки задают настройками.

Настройка

Параметры почтового сервера лежат в .env:

MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=robot@example.com
MAIL_PASSWORD=secret
MAIL_FROM_ADDRESS=robot@example.com
MAIL_FROM_NAME="Мой блог"

При разработке удобно значение MAIL_MAILER=log: письма не отправляются, а записываются в журнал storage/logs/laravel.log.

Класс письма

php artisan make:mail OrderShipped
namespace App\Mail;
 
use App\Models\Order;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
 
class OrderShipped extends Mailable
{
    public function __construct(public Order $order) {}
 
    public function envelope(): Envelope
    {
        return new Envelope(subject: 'Ваш заказ отправлен');
    }
 
    public function content(): Content
    {
        return new Content(view: 'mail.order-shipped');
    }
}

Публичные свойства класса доступны в шаблоне.

Шаблон

{{-- resources/views/mail/order-shipped.blade.php --}}
<h1>Заказ № {{ $order->id }} отправлен</h1>
 
<p>Сумма: {{ $order->total }} ₽</p>
 
<a href="{{ route('orders.show', $order) }}">Посмотреть заказ</a>

Отправка

use App\Mail\OrderShipped;
use Illuminate\Support\Facades\Mail;
 
Mail::to($order->user)->send(new OrderShipped($order));

В to() можно передать адрес строкой или модель пользователя — Laravel возьмёт её свойство email.

Через очередь

Соединение с почтовым сервером занимает секунды. Метод queue() отправит письмо в фоне:

Mail::to($order->user)->queue(new OrderShipped($order));

Уведомления

Уведомление — сообщение, которое можно доставить сразу несколькими способами: письмом, в базу данных для колокольчика на сайте, в мессенджер:

php artisan make:notification InvoicePaid
namespace App\Notifications;
 
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
 
class InvoicePaid extends Notification
{
    public function __construct(public int $amount) {}
 
    public function via(object $notifiable): array
    {
        return ['mail', 'database'];
    }
 
    public function toMail(object $notifiable): MailMessage
    {
        return (new MailMessage)
            ->subject('Счёт оплачен')
            ->line("Мы получили оплату: {$this->amount} ₽.")
            ->action('Открыть счёт', url('/invoices'));
    }
 
    public function toArray(object $notifiable): array
    {
        return ['amount' => $this->amount];
    }
}

Отправляют его методом модели пользователя:

$user->notify(new InvoicePaid(1500));
 
$unread = $user->unreadNotifications;

Частая ошибка

Письмо, отправленное во время запроса, задерживает ответ, а при сбое почтового сервера пользователь увидит ошибку вместо страницы «Заказ оформлен». Отправляйте письма через очередь — queue() вместо send() — и проверяйте их вид без настоящей отправки, с MAIL_MAILER=log.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.