In this article we will learn how to create event in Laravel with examples.
Table of Contents
Laravel event overview
Laravel events have a straightforward observer pattern implementation. We can subscribe and listen to different events that happen in our application.
The event class contains the information about the event. The event classes are stored in the app/Events directory.
The event listeners get the event instances in the handle method of the event. The listeners are in the app/Listeners directory.
We can learn more about Laravel events and listeners at https://laravel.com/docs/10.x/events.
Now we will try to understand Laravel events through a simple newsletter subscription project.
Create Laravel event
Now we will discuss the steps of simple newsletter subscription project in Laravel.
Steps to create Laravel event
We can create events in Laravel by following the below mentioned steps.
Step 1: Create controller
We can use the following artisan command to create the NewsletterController.
php artisan make:controller NewsletterController
This will create NewsletterController.php controller file in app/Http/Controllers.
Step 2: Modify the controller
Now we will modify the NewsletterController.php file.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Events\UserSubscribed;
class NewsletterController extends Controller
{
public function index(){
return view('index');
}
public function subscribe(Request $request){
$request->validate([
'email' => 'required|email|unique:newsletters,email'
]);
event(new UserSubscribed($request->email));
return back();
}
}
Step 3: Create model and migration
Now we will create the Newsletter model with migration file using the following artisan command.
php artisan make:model Newsletter -m
The abobe command will create Newsletter.php file in app/Models and <DATE>_create_newsletters_table.php file in database/migrations.
The model – Newsletter.php will be like:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Newsletter extends Model
{
use HasFactory;
}
Step 4: Modify the migration file
We will modify the migration file – <DATE>_create_newsletters_table.php.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('newsletters', function (Blueprint $table) {
$table->id();
$table->string('email');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('newsletters');
}
};
Step 5: Run the migration artisan command
Next, we will run the following migration artisan command.
php artisan migrate
This command will create newsletters table in database.
Step 6: Create new routes
We will create two routes to display newsletter form and submit newsletter form in routes/web.php.
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\NewsletterController;
// Event Listeners
Route::get('/newsletter', [NewsletterController::class, 'index']);
Route::post('/subscribe', [NewsletterController::class, 'subscribe']);
Step 7: Create event
We will create event using the following artisan command.
php artisan make:event UserSubscribed
This command above will create UserSubscribed.php in app/Events.
Step 8: Modify UserSubscribed event
We will modify the newly created UserSubscribed event.
<?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 UserSubscribed
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $email;
public function __construct($email)
{
$this->email = $email;
}
public function broadcastOn(): array
{
return [
new PrivateChannel('channel-name'),
];
}
}
Step 9: Create listener
We will create listener using the following artisan command.
php artisan make:listener EmailOwnerAboutSubscription
This will create a listener class file named EmailOwnerAboutSubscription.php in app/Listeners
Step 10: Modify listener
We will now Modify the newly created EmailOwnerAboutSubscription.php listener class file.
<?php
namespace App\Listeners;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Mail;
use App\Models\Newsletter;
use App\Events\UserSubscribed;
use App\Mail\UserSubscribedMessage;
class EmailOwnerAboutSubscription
{
public function __construct()
{
//
}
public function handle(UserSubscribed $event): void
{
Newsletter::insert(['email'=>$event->email]);
Mail::to($event->email)->send(new UserSubscribedMessage());
}
Step 11: Create Mail class
We will creating a Mail class using the following artisan command.
php artisan make:mail UserSubscribedMessage
This will create the mail class file named UserSubscribedMessage.php in app/Mail folder.
Step 12: Modify the mail class
We will now modify the UserSubscribedMessage.php mail class file.
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class UserSubscribedMessage extends Mailable
{
use Queueable, SerializesModels;
public function __construct()
{
//
}
public function envelope(): Envelope
{
return new Envelope(
subject: 'User Subscribed Message',
);
}
public function content(): Content
{
return new Content(
view: 'mail.subscribed',
);
}
public function attachments(): array
{
return [];
}
}
Step 13: Create view file for a simple mail content
We will create view subscribed.blade.php view file for a simple mail content in resources/views/mail. The code of the file is as follows.
<h1>User has subscribed.</h1
Step 14: Modify the EventServiceProvider
In this step, we will modify the EventServiceProvider.php file stored in app/Providers directory.
<?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;
use App\Events\UserSubscribed;
use App\Listeners\EmailOwnerAboutSubscription;
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
UserSubscribed::class => [
EmailOwnerAboutSubscription::class,
],
];
public function boot(): void
{
//
}
public function shouldDiscoverEvents(): bool
{
return false;
}
}
From the above mentioned code we can see that here we are mapping EmailOwnerAboutSubscription listener class with UserSubscribed event class in $listen property.
Step 15: Create view files for routes
In this step we will create index.blade.php view file resources/views directory for newsletter and subscribe routes.
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Newsletter</title>
</head>
<body class="antialiased">
<h2>Newsletter</h2>
<form action="/subscribe" method="post">
@csrf
<input type="email" id="email" name="email" required="required" />
<button type="submit">Subscribe</button>
</form>
</body>
</html>
Step 16: Browser action
Now, if we browse http://<SITEURL>/newsletter, it will open with an input box and subscribe button.
If we add email to the input field and click on the subscribe button, we will be redirected to http://<SITEURL>/subscribe page.
According to the route declaration, the subscribe method of the NewsletterController class is called and the event function is called and then redirected back to the newsletter page.
As the event is called and thus the listener is in action, email is added to the newsletter table and mail is sent to the user.