Hi I am a beginner for events and listeners in laravel. So please explain me how to achieve this :
Aim :
Send an email to user. And know whether email is sent or not.
My Understanding :
Laravel has in-built event Illuminate\Mail\Events\MessageSent
to fire after email is sent and I have to write a listener to listen the event.
What I did :
To send email :
Mail::to($receiverAddress)->send(new SendNewUserPassword($content));
This is working fine. Able to send email to user successfully.
To listen messageSent event, I created this listener :
<?php
namespace App\Listeners;
use Illuminate\Mail\Events\MessageSent;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class LogSentMessage
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param MessageSent $event
* @return void
*/
public function handle(MessageSent $event)
{
return $event->message;
}
}
To Register Event :
protected $listen = [
'App\Events\Event' => [
'App\Listeners\EventListener',
],
'Illuminate\Mail\Events\MessageSent' => [
'App\Listeners\LogSentMessage',
],
];
In Controller :
event(new MessageSent())
Please guide me how to return the message handled in Listener from controller. If my above approach is wrong explain me how to achieve it. This I am using for an api, so if sending mail is success/fail I want to know.
You can pass data from the controller to the mailable, and then from the mailable to the listener
For example I have a model called SendOrder
that I use to keep track the status of the email, so I pass this model from the controller to the listener
This is what you have to do from scratch
Pass the model to your Mailable constructor
$send_order = SendOrder::create(['status' => 'received', 'email' => '[email protected]']);
Mail::to($receiverAddress)->send(new SendNewMail($send_order));
SendNewMail
Class Mailable has a method withSwiftMessage()
which you can use to store variables/objects that you can access later from the listener.
We will make a constructor that pass the model to the build()
method where we can execute the withSwiftMessage()
to store it for later.
use App\SendOrder;
class SendNewMail extends Mailable
{
protected $send_order;
public function __construct( SendOrder $send_order )
{
$this->send_order = $send_order;
}
public function build()
{
$send_order = $this->send_order;
$this->withSwiftMessage(function ($message) use($send_order) {
$message->send_order = $send_order;
});
// Do more stuffs
}
}
protected $listen =
'Illuminate\Mail\Events\MessageSent' => [
'App\Listeners\LogSentMessage',
],
];
php artisan event:generate
This will automatically generate the new listener app\Listeners\LogSentMessage with a template code that's connected to the built-in event Illuminate\Mail\Events\MessageSent
LogSentMessage
You can access the model this way:
public function handle(MessageSent $event)
{
$send_order = $event->message->send_order;
$send_order->update(['status' => 'sent']);
}
In your EventServiceProvider
add your event and listener
protected $listen = [
'Illuminate\Notifications\Events\NotificationSent' => [
'App\Listeners\YourListenerClass',
],
];
and in YourListnerClass
public function handle(NotificationSent $event)
{
//access your $event data here
//which includes notification details too
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With