Статьи

Регистрация почты в Laravel 5.3: Расширение драйвера почты

Эта статья была рецензирована Вираджем Хатавкаром . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!

Одним из многих лакомств, которые предлагает Laravel, является рассылка. Вы можете легко настраивать и отправлять электронные письма через несколько популярных сервисов, и в них даже есть помощник по ведению журнала для разработки.

Mail::send('emails.welcome', ['user' => $user], function ($m) use ($user) {
    $m->to($user->email, $user->name)->subject('Welcome to the website');
});

Это отправит электронное письмо новому зарегистрированному пользователю на веб-сайте, используя представление emails.welcome Это стало еще проще с Laravel 5.3 с использованием почтовых сообщений (но старый синтаксис все еще действует).

Laravel Logo

Вот пример:

 # Generate a new mailable class
php artisan make:mail WelcomeMail
 // app/Mail/WelcomeMail.php

class WelcomeUser extends Mailable
{

    use Queueable, SerializesModels;

    public $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function build()
    {
        return $this->view('emails.welcome');
    }
}
 // routes/web.php

Route::get('/', function () {
    $user = User::find(2);

    \Mail::to($user->email)->send(new WelcomeUser($user));

    return "done";
});

Laravel также обеспечивает хорошую отправную точку для отправки писем на этапе разработки с использованием драйвера logsmtpsparkpostmailgun В этом уроке мы узнаем, как расширить существующую систему драйверов почты, чтобы добавить нашу собственную.

Чтобы наш пример был простым и понятным, мы собираемся записывать наши электронные письма в таблицу БД.

Создание поставщика услуг

Предпочтительный способ сделать это — создать поставщика услуг, который будет взаимодействовать с нашим приложением во время загрузки и регистрировать наши сервисы. Давайте начнем с создания нового поставщика услуг с помощью помощника командной строки ремесленника.

 php artisan make:provider DBMailProvider

Это создаст новый класс в нашей папке app/Providers Если вы знакомы с поставщиками услуг Laravel, вы знаете, что мы расширяем класс ServiceProviderbootregister Подробнее о провайдерах вы можете прочитать в документации .

Использование провайдера почты

Вместо использования родительского класса поставщика услуг, мы можем воспользоваться ярлыком и расширить существующий класс Illuminate\Mail\MailServiceProvider Это означает, что метод register

 // vendor/Illuminate/Mail/MailServiceProvider.php

public function register()
{
    $this->registerSwiftMailer();

    // ...
}

Метод registerSwiftMailermail.driverregisterSwiftMailer Здесь мы можем выполнить проверку перед вызовом родительского метода // app/Providers/DBMailProvider.php

function registerSwiftMailer()
{
if ($this>app[‘config’][‘mail.driver’] == ‘db’) {
$this>registerDBSwiftMailer();
} else {
parent::registerSwiftMailer();
}
}
менеджер транспорта .

 swift.mailer

Использование диспетчера транспорта

Laravel разрешает экземпляр Swift_MailerSwift_Mailer SwiftMailer . Нам нужно привязать наш экземпляр почтового Swift к контейнеру.

 private function registerDBSwiftMailer()
{
    $this->app['swift.mailer'] = $this->app->share(function ($app) {
        return new \Swift_Mailer(new DBTransport());
    });
}

Вы можете думать о транспортном объекте как о фактическом водителе. Если вы проверите пространство имен Illuminate\Mail\TransportLogTransportSparkPostTransport

Класс Swift_MailerSwift_TransportIlluminate\Mail\Transport\Transport Это должно выглядеть примерно так.

 namespace App\Mail\Transport;

use Illuminate\Mail\Transport\Transport;
use Illuminate\Support\Facades\Log;
use Swift_Mime_Message;
use App\Emails;

class DBTransport extends Transport
{

    public function __construct()
    {
    }


    public function send(Swift_Mime_Message $message, &$failedRecipients = null)
    {
        Emails::create([
            'body'    => $message->getBody(),
            'to'      => implode(',', array_keys($message->getTo())),
            'subject' => $message->getSubject()
        ]);
    }

}

Единственный метод, который мы должны реализовать здесь — это метод send Он отвечает за логику отправки почты, и в этом случае он должен регистрировать наши электронные письма в базе данных. Что касается нашего конструктора, мы можем пока оставить его пустым, потому что нам не нужны никакие внешние зависимости.

Метод $message->getTo() Мы получаем список электронных писем, используя функцию array_keys

Вход Email в БД

Следующим шагом является создание необходимой миграции для нашей таблицы базы данных.

 php artisan make:migration create_emails_table --create="emails"
 class CreateEmailsTable extends Migration
{

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('emails', function (Blueprint $table) {
            $table->increments('id');
            $table->text('body');
            $table->string('to');
            $table->string('subject');
            $table->timestamps();
        });
    }


    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('emails');
    }
}

Наша миграция содержит только текст сообщения, тему и адрес электронной почты получателя, но вы можете добавить столько деталей, сколько захотите. Проверьте определение класса Swift_Mime_Message

Теперь нам нужно создать новую модель для взаимодействия с нашей таблицей и добавить необходимые поля в массив с возможностью заполнения.

 php artisan make:model Emails
 class Emails extends Model
{

    protected $fillable = [
        'body',
        'to',
        'subject'
    ];
}

Отправка писем

Хорошо, пришло время проверить, что у нас так далеко. Мы начнем с добавления нашего провайдера в список провайдеров в файле config/app.php

 return [
    // ...

    'providers' => [
        // ...

        App\Providers\DBMailProvider::class,

        // ...
    ],

    // ...
];

Затем мы регистрируем наш почтовый драйвер для dbconfig/mail.php

 return [
    'driver' => 'db',

    // ...
];

Единственная оставшаяся часть — отправить тестовое электронное письмо и проверить, было ли оно зарегистрировано в базе данных Я собираюсь отправить электронное письмо, когда домашний URL-адрес ударил. Вот код

 // routes/web.php

Route::get('/', function () {
    $user = User::find(2);

    Mail::send('emails.welcome', ['user' => $user], function ($m) use ($user) {
        $m->to($user->email, $user->name)->subject('Welcome to the website');
    });

    return "done";
});

После перехода по домашнему маршруту мы можем запустить команду php artisan tinker

Записи электронной почты

Вывод

В этой статье мы увидели, как расширить систему почтовых драйверов для перехвата писем в целях отладки. Одной из вещей, которыми я восхищаюсь в Laravel, является его беспрецедентная расширяемость: вы можете изменять или расширять практически любую функциональность от маршрутизатора и IOC до Mail и за ее пределами.

Если у вас есть какие-либо вопросы или комментарии, обязательно напишите их ниже, и я сделаю все возможное, чтобы ответить на них!