Hello , Welcome back, this example is regarding How to use Event and Listener in Laravel 9.
First we should know what is event?
Laravel’s events provide a simple observer pattern implementation, allowing you to subscribe and listen for various events that occur within your application. example like
- User Created
- New Post submission
- Notification
And What is Listener?
Listeners, like the name implies, listens for events that occur in your application, but they do not just listen to any event, each listener must be mapped to an event before it listens for that event.
Now i am coming on example, In this example i will create a post and send mail to users and admin.
i already installed laravel 9. First, i will check which version is installed for this project , we will check by running an artisan command.
$ php artisan --version;
Output
Laravel Framework 9.1.0
Now i will install JetSteam for Login and Registration.
$ composer require laravel/jetstream
$ php artisan jetstream:install livewire
$ npm install $ npm run dev $ php artisan migrate
Create a post controller and model for New Post submit
$ php artisan make:model Post -c -m
Above command will create 3 files, Controller and Model and Migration file for Post.
XXXX_XX_XX_085340_create_posts_table.php
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('posts', function (Blueprint $table) { $table->id(); $table->string('title'); $table->string('content'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('posts'); } };
$ php artisan migrate
Here i will create two routes . 1 for New post ans 2 for Save post
Route::get('/new-post', function () { return view('new_post'); }); Route::post("/save-post",[PostController::class,"save_post"]);
PostController.php
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Post; class PostController extends Controller { public function index(){ } public function save_post(Request $req){ $data = $req->input(); try{ $model = new Post; $model->content = $data['content']; $model->title = $data['title']; $last_id=$model->save(); // return redirect('new-post'); return back()->with('success','post added successfully.'); }catch(Exception $e){ return back()->with('error','Oops , Something went wrong please try again later!'); } } }
new_post.blade.php
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap CSS --> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> <title>Hello, world!</title> </head> <body> <div class="container"> </div> <h1>Hello, world!</h1> <div class="row"> <div class="col-sm-12"> <form action="/save-post" class="form-control" method="post"> @csrf <div class="mb-3"> <label for="exampleFormControlInput1" class="form-label">Post Title</label> <input type="text" class="form-control" name="title" id="exampleFormControlInput1" placeholder="Post Title" required> </div> <div class="mb-3"> <label for="exampleFormControlTextarea1" class="form-label">Post Description</label> <textarea class="form-control" name="content" id="exampleFormControlTextarea1" rows="3" required></textarea> </div> <div class="mb-3"> <input type="submit" class="btn btn-small btn-success"> </div> </form> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script> </body> </html>
Now you can check post is creating. It’s Time to Jump on Event and Listener.
for creating a event we will use below command
$ php artisan make:event PostCreated
output:
Event created successfully.
You can check this file “App/Events/PostCreated.php”.
<?php namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; class PostCreated { use Dispatchable, InteractsWithSockets, SerializesModels; public $post; /** * Create a new event instance. * * @return void */ public function __construct($post) { $this->post=$post; } /** * Get the channels the event should broadcast on. * * @return \Illuminate\Broadcasting\Channel|array */ public function broadcastOn() { return new PrivateChannel('channel-name'); } }
Next we will create a Listener
php artisan make:listener NotifyUser
You can check this file “App/Listeners/NotifyUser.php”.
<?php namespace App\Listeners; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; use App\Events\PostCreated; use App\Mail\PostMail; use App\Models\User; class NotifyUser { /** * Create the event listener. * * @return void */ public function __construct() { // } /** * Handle the event. * * @param object $event * @return void */ public function handle(PostCreated $event) { $user= User::get(); foreach($user as $v_user){ \Mail::to($v_user->email)->send(new PostMail($event->post)); } } }
In above code i am using Mail so we need to configure SMTP in .env file. And also a mail, I will create mail by using below command.
php artisan make:mail PostMail
You can check this file “App/Mail/PostMail.php”.
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; class PostMail extends Mailable { use Queueable, SerializesModels; public $post; /** * Create a new message instance. * * @return void */ public function __construct($post) { $this->post=$post; } /** * Build the message. * * @return $this */ public function build() { return $this->view('mail.post_mail',['post_data'=>$this->post]); } }
for mail we will create a mail/post_mail.blade.php inside resource/views.
Test mail {{ $post_data['post_title'] }} Test mail Content {{ $post_data['post_content'] }}
Note, Please you can style from your side, This is just for example.
Now the final step is to register our event and Listener in App\Providers\EventServiceProvider.php
and add this below line.
\App\Events\PostCreated::class=>[ \App\Listeners\NotifyUser::class ]
Your file will looks like
<?php namespace App\Providers; use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; use Illuminate\Support\Facades\Event; class EventServiceProvider extends ServiceProvider { /** * The event listener mappings for the application. * * @var array<class-string, array<int, class-string>> */ protected $listen = [ Registered::class => [ SendEmailVerificationNotification::class, ], \App\Events\PostCreated::class=>[ \App\Listeners\NotifyUser::class ] ]; /** * Register any events for your application. * * @return void */ public function boot() { // } /** * Determine if events and listeners should be automatically discovered. * * @return bool */ public function shouldDiscoverEvents() { return false; } }
And Now check you can check on every new post created, a mail is fired . Please check and comment below its is working or not.
Thanks