Полный цикл в digital

Отправка почты по событию

Пусть у нас есть форма обратной связи на сайте. После отправки сообщения происходит отправка письма с данными этой формы. Но вместо того, чтобы просто отправить письмо, мы возбудим событие, перехватим его в слушателе и только после этого отправим письмо. Смысла в этом особого нет, сделано с целью изучения 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));
        // Вместо отправки письма возбуждаем событие
        event(new FeedbackMailEvent($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(stdClass $feedback) {
        $this->data = $feedback;
    }
    // Создаем сообщение
    public function build() {
        // От кого письмо
        return $this->from('noreply@aurora.com', 'ООО ТД АВРОРА')
        // Тема письма
        ->subject('Форма обратной связи')
        // Вызываем представление и передаем объект data с данными
        ->view('email.feedback', ['data' => $this->data]);
    }
}

Класс события

Создаем событие с помощью artisan-команды:

php artisan make:event FeedbackMailEvent
App/Events/FeedbackMailEvent.php<?php
// Событие FeedbackMailEvent

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class FeedbackMailEvent
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    // Создайте новый экземпляр события @return void
    public function __construct($data)
    {
        $this->data = $data;
    }
    // Определите каналы, по которым должно транслироваться мероприятие @return \Illuminate\Broadcasting\Channel|array
    public function broadcastOn()
    {
        return [];
    }
}

Обработчик события

Создаем обработчика события с помощью artisan-команды:

php artisan make:listener FeedbackMailListener --event="FeedbackMailEvent"
App/Listeners/FeedbackMailListener.php<?php
// Обработчик события

namespace App\Listeners;

use App\Events\FeedbackMailEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use App\Mail\FeedbackMailer;
use Illuminate\Support\Facades\Mail;

class FeedbackMailListener
{
    // Создайте прослушиватель событий @return void
    public function __construct()
    {
        //
    }
    // Обработайте событие @return void @param  \App\Events\FeedbackMailEvent  $event
    public function handle(FeedbackMailEvent $event)
    {
        // обрабатываем событие, то есть отправляем письмо
        Mail::to($event->data->email)->send(new FeedbackMailer($event->data));
    }
}

Слушатель события

Открываем на редактирование файл класса EventServiceProvider:

App/Providers/EventServiceProvider.php<?php
// Регистрируем слушателя события

namespace App\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;

class EventServiceProvider extends ServiceProvider
{
    // Сопоставления события с прослушивателем для приложения @var array<class-string, array<int, class-string>>
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        // Класс события при отправке формы
        FeedbackMailEvent::class => [
            // Класс обработчика события
            FeedbackMailListener::class,
        ]
    ];
    // Регистрируйте любые события для вашего приложения @return void
    public function boot()
    {
        parent::boot();
    }
    // Определите, должны ли события и прослушиватели обнаруживаться автоматически @return bool
    public function shouldDiscoverEvents()
    {
        return true;
    }
}
Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!
Эйч Маркетинг