I'm struggling with queues in Laravel as I never used them before. I'm overriding the default reset password email with help of the toMailUsing
method and a dedicated service provider:
class MailServiceProvider extends ServiceProvider
{
public function boot()
{
ResetPassword::toMailUsing(function ($notifiable, $token) {
$url = url(route('password.reset', ['token' => $token, 'email' => $notifiable->getEmailForPasswordReset()]));
dispatch(new SendEmail($url, $notifiable));
});
}
}
Here is my SendEmail
job class:
class SendEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $user;
protected $url;
public function __construct($url, $user)
{
$this->user = $user;
$this->url = $url;
}
public function handle()
{
$email = new ResetPassword($this->url, $this->user);
Mail::to($this->user->email)->send($email);
}
}
And the mailable itself:
class ResetPassword extends Mailable
{
use Queueable, SerializesModels;
protected $url;
protected $user;
public function __construct($url, $user)
{
$this->url = $url;
$this->user = $user;
}
public function build()
{
return $this->markdown('emails.password_reset', ['url' => $this->url, 'user' => $this->user]);
}
}
Where is the problem? I successfully queue the job and receive email, but get an error:
Trying to get property 'view' of non-object
Stack trace: https://flareapp.io/share/87nOGYM5#F59
Here is my previous, working code:
//Provider
ResetPassword::toMailUsing(function ($notifiable, $token) {
$url = url(route('password.reset', ['token' => $token, 'email' => $notifiable->getEmailForPasswordReset()]));
return new ResetPasswordMail($url, $notifiable);
});
//Mailable
class ResetPassword extends Mailable
{
use Queueable, SerializesModels;
protected $url;
protected $user;
public function __construct($url, $user)
{
$this->url = $url;
$this->user = $user;
}
public function build()
{
$address = 'noreply@' . config('app.domain');
$name = 'Lorem ipsum';
$subject = config('app.name') . ' - Próba zresetowania hasła';
$this->to($this->user)->subject($subject)->from($address, $name)->markdown('emails.password_reset', ['url' => $this->url, 'user' => $this->user]);
}
}
I would really appreciate any help.
This looks very complicated, so I'm not sure where your problem is. But if it helps, here's what I do to send a queued custom password reset email.
Illuminate\Auth\Passwords\CanResetPassword::sendPasswordResetNotification()
is inherited by the User
model; override it to use your custom notification.
<?php
namespace App;
use App\Notifications\UserPasswordReset;
class User extends Authenticatable
{
public function sendPasswordResetNotification(string $token): void
{
$url = route('password.reset', [
'token' => $token,
'email' => $this->getEmailForPasswordReset()
]);
$this->notify(new UserPasswordReset($url));
}
}
Build a custom notification and make sure it is queuable
<?php
namespace App\Notifications;
use App\Mail\UserPasswordReset as UserPasswordResetMailable;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
class UserPasswordReset extends Notification implements ShouldQueue
{
use Queueable;
protected $url;
public function __construct(string $url)
{
$this->url = $url;
}
public function via(User $notifiable)
{
return ["mail"];
}
public function toMail(User $notifiable)
{
return new UserPasswordResetMailable($this->url, $notifiable);
}
}
Your existing mailable should work fine, though here's what mine looks like:
<?php
namespace App\Mail;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class UserPasswordReset extends Mailable
{
use Queueable;
use SerializesModels;
public $user;
public $url;
public function __construct(string $url, User $user)
{
$this->user = $user;
$this->url = $url;
}
public function build()
{
return $this->
->with(["message" => $this])
->to($this->user->email)
->from(config("mail.from.address"))
->subject(__("Password Reset"))
->text("email.reset_plaintext")
->view("email.reset_html");
}
}
No service provider needed, no job class needed.