Включенная в Laravel 5.7 функция «проверки электронной почты» работает хорошо, но асинхронная отправка электронной почты (во время регистрации пользователя или страницы повторной отправки ссылки) не идеальна.
Есть ли способ отправить электронное письмо с подтверждением электронной почты через очередь без перезаписи всей проверки электронной почты в Laravel 5.7?






Да! Возможно. И для этого вам нужно будет перезаписать sendEmailVerificationNotification в вашем App\User. Этот метод обеспечивается признаком Illuminate\Auth\MustVerfiyEmail. Метод sendEmailVerificationNotification уведомляет созданный user, отправляя электронное письмо, как определено в классе уведомлений Illuminate\Auth\Notifications\VerifyEmail.
// This is the code defined in the sendEmailVerificationNotification
public function sendEmailVerificationNotification()
{
$this->notify(new Notifications\VerifyEmail);
}
Вы можете изменить этот метод, чтобы не уведомлять пользователя напрямую. Вам нужно будет определить Job, который вы будете отправлять в методе sendEmailVerificationNotification вместо уведомления созданного пользователя.
В классе Job вы создадите метод handle, в котором вы можете отправить электронное письмо на user, но вы должны предоставить $user в задание, которое можно выполнить, передав его в качестве параметра методу dispatch следующим образом:
public function sendEmailVerificationNotification()
{
VerifyEmail::dispatch($this);
}
$this представляет собой созданный user, и задание App\Jobs\VerififyEmail (которое вы создадите) получит все параметры, переданные в dispatch в его __construct.
Код VerifyEmail будет выглядеть так:
namespace App\Jobs;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Auth\Notifications\VerifyEmail;
class VerifyEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function handle()
{
// Here the email verification will be sent to the user
$this->user->notify(new VerifyEmail);
}
}
спасибо за ответ, работает! просто пришлось переименовать класс Job QueuedVerifyEmail из-за двойного объявления имени класса.
Добро пожаловать. Даже если оба класса имеют одинаковое имя, потому что они находятся в разных пространствах имен App\Jobs\VerifyEmail и Illuminate\Auth\Notification\VerifyEmail, это не вызовет никаких проблем.
Вы могли бы использовать то же имя класса, присвоив классу Laravel другое имя, например use Illuminate\Auth\Notifications\VerifyEmail as VerifyEmailNotification;, и в методе handle$this->user->notify(new VerifyEmailNotification);. На мой взгляд, это немного чище, но это просто придирки.
Нет встроенного способа, но вы можете легко это сделать, расширив и переопределив.
Сначала создайте новое уведомление, которое расширяет встроенное уведомление, а также реализует контракт ShouldQueue (для включения очереди). В следующем классе предполагается, что вы создали уведомление на app/Notifications/VerifyEmailQueued.php:
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Auth\Notifications\VerifyEmail;
class VerifyEmailQueued extends VerifyEmail implements ShouldQueue
{
use Queueable;
// Nothing else needs to go here unless you want to customize
// the notification in any way.
}
Теперь вам нужно указать фреймворку использовать ваше настраиваемое уведомление вместо уведомления по умолчанию. Вы делаете это путем перезаписи sendEmailVerificationNotification() на вашей модели User. Это просто меняет тип отправляемого уведомления.
public function sendEmailVerificationNotification()
{
$this->notify(new \App\Notifications\VerifyEmailQueued);
}
Работал как мультик!
это намного проще, чем принятый ответ, и он работает
Это работает, но при нажатии на ссылку подтверждения (отправленную по электронной почте) происходит перенаправление на страницу 403, недействительная подпись. (Laravel 6)
@IrfanGondal Теперь уведомление будет помещено в очередь, поэтому URL-адрес в уведомлении будет построен с использованием вашего APP_URL в файле среды. Этот APP_URL должен соответствовать окончательному URL-адресу. Так, например, если ваш сайт находится на https, вам необходимо убедиться, что ваш APP_URL также является https.
Решение довольно простое:
Steps:
Настроить драйвер очереди
Перейдите в -> Illuminate \ Auth \ Notifications \ VerifyEmail.
Реализуйте интерфейс ShouldQueue и добавьте черту Queueable в вышеупомянутый класс, например, VerifyEmail, например:
class VerifyEmail extends Notification реализует ShouldQueue { используйте В очереди;
.... .... ... }
3. вот и все
Путь интерфейса и черты: используйте Illuminate \ Contracts \ Queue \ ShouldQueue; используйте Illuminate \ Bus \ Queueable;
Пожалуйста, проверьте также документы: https://laravel.com/docs/5.7/notifications#queueing-notifications
Не лучшая идея изменять классы laravel, поэтому приведенные выше решения предлагают делать это путем расширения и переопределения.
Не рекомендуется вносить изменения в файлы в папке поставщика laravel, потому что при следующей команде обновления композитора ваши изменения в файлах в папке поставщика будут удалены.
Мое решение - если вы собираетесь вручную регистрировать пользователя в контроллере. Laravel уже создал зарегистрированное событие и его прослушиватель SendEmailVerificationNotification.
-сначала настроить очередь в приложении
в обновлении файла .env QUEUE_CONNECTION=database.
для получения дополнительной документации по очереди прочтите https://laravel.com/docs/6.x/queues
опубликовать таблицу очереди от php artisan queue:table
php artisan migrate
php artisan make:job EmailVerificationJob
в EmailVerificationJob.php добавить общедоступную переменную
общедоступный пользователь $;
в конструкторе EmailVerificationJob.php
публичная функция __construct (Пользователь $ user) { $ this-> user = $ user; }
в функции дескриптора EmailVerificationJob.php напишите event(new Registered($this->user)).
в вашем контроллере, если пользователь успешно создал, добавьте этот код для работы.
EmailVerificationJob :: dispatch ($ пользователь) -> задержка (сейчас () -> addSeconds (5)); здесь задержка задания на 5 секунд.
в конце необходимо запустить очередь работника php artisan queue:work --tries=3. здесь пытается означает, сколько раз очередь должна пытаться выполнить задание.
это решение я использовал в Laravel 8.
сначала создайте класс уведомлений SendEmailVerificationNotification
php artisan make:notification SendEmailVerificationNotification
Это будет содержимое файла app / Notifications / SendEmailVerificationNotification.php. здесь мы собираемся расширить класс Laravel по умолчанию SendEmailVerificationNotification и реализовать очередь
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class SendEmailVerificationNotification extends \Illuminate\Auth\Listeners\SendEmailVerificationNotification implements ShouldQueue
{
use Queueable;
}
последний шаг - это редактирование массива $ listen класса EventServiceProvider. Закомментируйте уведомление по умолчанию о зарегистрированном событии и добавьте собственное уведомление, которое мы создали.
use App\Notifications\SendEmailVerificationNotification as QueuedSendEmailVerificationNotification;
use Illuminate\Auth\Events\Registered;
//use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
protected $listen = [
Registered::class => [
// SendEmailVerificationNotification::class,
QueuedSendEmailVerificationNotification::class
],
];
Я не думаю, что на данный момент это возможно. Новый признак отправляет это письмо, который в настоящее время не может быть поставлен в очередь.