Форма связи
Отправку почты рассмотрим на примере формы обратной связи с полями Имя
, Почта
, Сообщение
.
- Создаем контроллер, который будет показывать фому и обрабатывать POST-запрос от клиента
- Добавляем два роута
- Создаем форму
- Создаем шаблон письма
- Добавляем класс
FeedbackMailer
, расширяющийIlluminate\Mail\Mailable
- Настраиваем Laravel
Контроллер
Создаем контроллер FeedbackController
:
php artisan make:controller FeedbackController
app/Http/Controllers/FeedbackController.php<?php
namespace App\Http\Controllers;
use stdClass;
use App\Mail\FeedbackMailer;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
class FeedbackController extends Controller {
// Выводим форму на странице
public function index() {
return view('feedback.index');
}
// Отправляем данные формы на почту
public function send(Request $request) {
// Валидация полей формы
$request->validate([
'name' => 'required|max:100',
'email' => 'required|email|max:100',
'message' => 'required|max:500',
]);
// Создаем динамический объект
$data = new stdClass();
// Данные из поля формы name
$data->name = $request->name;
// Данные из поля формы email
$data->email = $request->email;
// Данные из поля формы message
$data->message = $request->message;
// В метод Mail::to первым аргументом передаем почту куда будет отправка письма, вторым методом передаем класс отправки почты в который передаем аргументом объект с данными формы $data который попадет в конструктор класса FeedbackMailer
Mail::to($data->email)->send(new FeedbackMailer($data));
// Редирект через имя роута на ту же страницу с формой
return redirect()->route('feedback.index')
// Вывод сообщения
->with('success', 'Ваше сообщение успешно отправлено');
}
}
Роуты
Добавляем два маршрута:
routes/web.phpRoute::get('/feedback', [FeedbackController::class, 'index'])->name('feedback.index');
Route::post('/feedback', [FeedbackController::class, 'send'])->name('feedback.send');
Форма связи
Создаем шаблон:
resources/views/feedback/index.blade.php@extends('layouts.app')
@section('content')
<h1>Обратная связь</h1>
@if (session('success'))
<div class="alert alert-success" role="alert">
{{ session('success') }}
</div>
@endif
@if ($errors->any())
<div class="alert alert-danger" role="alert">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="post" action="{{ route('feedback.send') }}">
@csrf
<div class="form-group">
<input type="text" class="form-control" name="name" placeholder="Имя, фамилия"
required maxlength="100" value="{{ old('name') ?? '' }}">
</div>
<div class="form-group">
<input type="email" class="form-control" name="email" placeholder="Адрес почты"
required maxlength="100" value="{{ old('email') ?? '' }}">
</div>
<div class="form-group">
<textarea class="form-control" name="message" placeholder="Ваше сообщение"
required maxlength="500" rows="3">{{ old('message') ?? '' }}</textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Отправить</button>
</div>
</form>
@endsection
Шаблон почтового сообщения
Нам потребуется шаблон для письма:
resources/views/email/feedback.blade.php<h1>Форма обратной связи</h1>
<p><strong>Имя:</strong> {{ $data->name }}</p>
<p><strong>Почта:</strong> {{ $data->email }}</p>
<p><strong>Сообщение:</strong> {{ $data->message }}</p>
Класс отправки почты
В Laravel каждый тип почтового сообщения (обратная связь, заказ в магазине), отправляемых приложением, представлен классом Mailable
. Эти классы хранятся в директории app/Mail
, которая будет создана при создании первого такого класса.
Создаем класс:
php artisan make:mail FeedbackMailer
Заполняем класс:
app/Mail/FeedbackMailer.php<?php
namespace App\Mail;
use Illuminate\Support\Facades\Storage;
use stdClass;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class FeedbackMailer extends Mailable {
use Queueable, SerializesModels;
// Публичная переменная в которую запишем переданные данные формы из контроллера FeedbackController
public $data;
// Плучаем данные формы из контроллера FeedbackController
public function __construct($feedback) {
$this->data = $feedback;
}
// Создаем сообщение
public function build() {
// От кого письмо
return $this->from('noreply@aurora.com', 'ООО ТД АВРОРА')
// Тема письма
->subject('Форма обратной связи')
// Вызываем представление и передаем объект data с данными
->view('email.feedback', ['data' => $this->data]);
}
}
Чтобы не указывать заголовок письма From
(от кого), можно задать это в файле .env
:
.envMAIL_FROM_ADDRESS=noreply@aurora.com
MAIL_FROM_NAME=ООО ТД АВРОРА
Эти три значения используются далее в файле конфигурации отправки почты config/mail.php
:
config/mail.phpreturn [
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'noreply@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
];
app/Mail/FeedbackMailer.phpclass FeedbackMailer extends Mailable {
public function build() {
return $this->subject('Форма обратной связи')->view('email.feedback', ['data' => $this->data]);
}
}
Обязательно должны быть заданы поля от кого письмо from
и тема subject
, либо в классе отправки письма, либо на глобальном уровне, иначе будет ошибка!
Все доступные методы
Основные
->subject('Welcome to the Tutorials Point')
->from('email@example.com', 'Mr. Example')
->to('email@example.com', 'Mr. Example')
Менее распространенные
->sender('email@example.com', 'Mr. Example')
->returnPath('email@example.com')
->cc('email@example.com', 'Mr. Example')
->bcc('email@example.com', 'Mr. Example')
->replyTo('email@example.com', 'Mr. Example')
->priority(2)
Прикрепление файлов
->attach('path/to/attachment.txt')
->embed('path/to/attachment.jpg')
Вместо заключения
Передать данные в шаблон письма resources/views/email/feedback.blade.php
можно через публичное свойство класса FeedbackMailer
. Все публичные поля этого класса будут доступны в шаблоне как переменные, в нашем случае $data
:
app/Mail/FeedbackMailer.phpclass FeedbackMailer extends Mailable {
use Queueable, SerializesModels;
public $data;
public function __construct($data) {
$this->data = $data;
}
public function build() {
return $this->subject('Форма обратной связи')->view('email.feedback');
}
}
Чтобы изменить данные, прежде чем передать их шаблону, свойство должно быть объявлено как protected
или private
:
app/Mail/FeedbackMailer.phpclass FeedbackMailer extends Mailable {
use Queueable, SerializesModels;
private $data;
public function __construct($data) {
$this->data = $data;
}
public function build() {
return $this->subject('Форма обратной связи')
->view('email.feedback')
->with([ // в шаблоне будут доступны $name, $email, $message
'name' => $this->data->name,
'email' => $this->data->email,
'message' => $this->data->message,
]);
}
}
Метод withSwiftMessage()
класса Mailable
позволяет зарегистрировать анонимную функцию, которая будет вызываться экземпляром класса SwiftMailer
перед отправкой сообщения. Это дает возможность кастомизировать сообщение перед тем как оно будет отправлено:
app/Mail/FeedbackMailer.phpclass FeedbackMailer extends Mailable {
public function build() {
$this->subject('Форма обратной связи')
->view('email.feedback');
$this->withSwiftMessage(function ($message) {
$message->getHeaders()->addTextHeader('Custom-Header', 'HeaderValue');
});
}
}