Laravel 5.3: Расширяем возможности драйвера Mail

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

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

В результате выполнения данного кода пользователю отправится письмо на базе шаблона emails.welcome. Это же можно реализовать, используя mailables.

Пример:

# Генерирование класса
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 поддерживает такие сервисы как smtp, sparkpost, mailgun и др. В какой-то момент этого может показаться мало и тогда потребуется расширить возможности драйвера.

В этом примере будем записывать лог сообщения в таблицу базы данных.

Создание сервис провайдера

Чтобы создать провайдер достаточно выполнить команду:

php artisan make:provider DBMailProvider

В результате файл будет помещён в каталог app/Providers. Теперь необходимо реализовать методы перечислены в интерфейсе ServiceProvider, а именно boot и register. Подробнее можно узнать в документации.

Используем провайдер Mail

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

// vendor/Illuminate/Mail/MailServiceProvider.php

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

    // ...
}

Метод registerSwiftMailer вернёт подходящий транспортный драйвер, на основе конфигурационного значения mail.driver. В registerSwiftMailer можем организовать проверку и вернуть объект своего класса.

// app/Providers/DBMailProvider.php

function registerSwiftMailer()
{
    if ($this->app['config']['mail.driver'] == 'db') {
        $this->registerDBSwiftMailer();
    } else {
        parent::registerSwiftMailer();
    }
}

Работаем с “транспортным менеджером”

Laravel считывает swift.mailer и создаёт объект Swift_Mailer (SwiftMailer). Нам необходимо передать наш Swift mailer в контейнер.

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

Если кликнуть на пространство имён Illuminate\Mail\Transport, то можно увидеть список всех транспортных драйверов (к примеру: LogTransport, SparkPostTransport и т.д.).

Объекту класса Swift_Mailer требуется объект Swift_Transport. Расширим класс Illuminate\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 чтобы вытащить только нужные нам поля.

Логирование почтовых сообщений в БД

Далее необходимо создать миграцию для создания новой таблицы в БД.

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,

        // ...
    ],

    // ...
];

Затем регистрируем почтовый драйвер в файле config/mail.php.

return [
    'driver' => 'db',

    // ...
];

Теперь осталось только протестить. Создаём маршрут и организуем отправку письма.

// 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.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: https://www.sitepoint.com/mail-logging-in-laravel-5-3-extending-the-mail-driver/
Перевел: Станислав Протасевич
Урок создан: 16 Октября 2016
Просмотров: 4041
Правила перепечатки


5 последних уроков рубрики "PHP"

  • Фильтрация данных с помощью zend-filter

    Когда речь идёт о безопасности веб-сайта, то фраза "фильтруйте всё, экранируйте всё" всегда будет актуальна. Сегодня поговорим о фильтрации данных.

  • Контекстное экранирование с помощью zend-escaper

    Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

  • Подключение Zend модулей к Expressive

    Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.

  • Совет: отправка информации в Google Analytics через API

    Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.

  • Подборка PHP песочниц

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

^ Наверх ^