Event Listeners in Laravel - Callbacks and AutoRegistrations

The next point that we are going to want to deal with is replicating what we have in the database, understood as the purchasing rite to the session, that is, the inverse when we do this exactly when the user is authenticated we are going to read what we have in the database and we dump it to the session that simple for this well there can be a couple of ways at least I suppose one is by writing the same method that you have for the login or we create a custom one and just at that point when we do the login we also establish the data or we do something much more modular that would be recommended, which is placing a listener What is a listener In case you do not know it as its name indicates, it is a listener, a listener based on events that occur throughout the application, we are not going to make an introduction as such to the events in laravel.

Login Event in Laravel

But it is important that you understand or indicate that when certain actions occur that are already predefined in the system in this case the Laravel login automatically triggers an event again or in summary when the user logs in you understand the login an event occurs and this is something that the framework internally does for us.

We can also create custom events that we can then listen to but in this case we already have half the task ready since the event again occurs at the time of login therefore we simply have to create a listener understand that on the one hand just as it happens in javascript that events occur or we can implement also in this case we can implement listeners so in a few words we are going to implement a listener a listener that is going to listen the redundancy will arrive when the login event occurs and when the login event occurs when here we authenticate for example then it is that simple I hope that at least that has been made clear because that is the most difficult part.

Listeners in Laravel

There are a couple of ways, you could say, one is by creating a listener, this has already changed a bit so don't read too much into it, here we go. Once we create a custom listener, well, we have a command here: make listener, we indicate the name and we indicate which event:

$ php artisan make:listener LoginSuccessful --event=Illuminate\Auth\Events\Login

We want to listen to what the Laravel people indicate here, as they automatically register and find the event for us, that is, there is no need to register it at the application level, since when we create it and the event occurs, Laravel automatically executes it because it performs a scan of the listeners directory here, which is where our listener, the one we are creating, would be created.

app\Providers\AppServiceProvider.php
<?php

namespace App\Providers;

use App\Models\ShoppingCart;
use Illuminate\Auth\Events\Login;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Event;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
   public function boot(): void
   {
       Event::listen(function (Login $event) {
           $this->setShoppindCartSession();
       });
   }

   private function setShoppindCartSession()
   {
       $cartDB = ShoppingCart::where('user_id', auth()->id())->get();
       $cartSession = session('cart', []);

       foreach ($cartDB as $c) {
           if (Arr::exists($cartSession, $c->post->id)) {
               // update
               $cartSession[$c->post->id][1] = $c->count;
           } else {
               // add
               $cartSession[$c->post->id] = [$c->post, $c->count];
           }

           session(['cart' => $cartSession]);
       }
   }
}

Another way is also what I think would be the simplest using a callback here directly here in the service Provider which would be this file that we have here eh Sorry for here Here we can also directly place a callback that indicates the event and it's over then you can use any one.

Listener para el login callback

In this case, use this one because I think it is the simplest and that would be practically all, so again we have two ways, one is by creating the listener so that the code is separated. Something similar to what happens with the Gate and the policies, to give an example, in which we can implement the Gate directly here or directly place a policy in a separate file, but in this case, since we want to make a simple Script, I think we can register it there without much problem, so remember that the official documentation has more information.

As it happens with several operations that are carried out in the framework, such as user registration, user verification and the same login, these generate events that can be heard through a Laravel listener, in this case, the Login event that is emitted via Fortify internally; we create the listener with:

$ php artisan make:listener LoginSuccessful --event=Illuminate\Auth\Events\Login

The event option is used to indicate the event you want to listen to; in this case, the login event; this is used internally by Laravel to define the basic structure, and the self-registering event is monitored internally by Laravel, meaning there is no need to register it.

Now, the only thing missing is to be able to make the replica; for this, we are going to take the add() method defined for the cart item component, and use it from the listener.

The listener looks for the cart items in the database, iterates them one by one and builds the session to be able to use it.

With this, if everything is configured correctly, when you log in, you should have the shopping cart items in the session (of course, if the user had items added in that session and replicated in the database).

app/Listeners/LoginSuccessful.php

<?php

namespace App\Listeners;

use App\Models\Post;
use App\Models\ShoppingCart;
use Illuminate\Auth\Events\Login;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Arr;

class LoginSuccessful
{
   public function __construct()
   {
       //
   }

   public function handle(Login $event): void
   {
       $cart = ShoppingCart::where('user_id', auth()->id())->get();
       foreach($cart as $c){
           $this->add($c->post,$c->count);
       }
   }


   public function add(Post $post, $count = 1)
   {
       $cart = session('cart', []);
       
       // add
       if (Arr::exists($cart, $post->id)) {
           $cart[$post->id][1] = $count;
       } else {
           $cart[$post->id] = [$post, $count];
       }
       // set en la sesion
       session(['cart' => $cart]);
   }

}

Another way we have available is using a callback directly in the AppServiceProvider:

app\Providers\AppServiceProvider.php

<?php

namespace App\Providers;

use App\Models\ShoppingCart;
use Illuminate\Auth\Events\Login;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Event;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
   public function boot(): void
   {
       Event::listen(function (Login $event) {
           $this->setShoppindCartSession();
       });
   }

   private function setShoppindCartSession()
   {
       $cartDB = ShoppingCart::where('user_id', auth()->id())->get();
       $cartSession = session('cart', []);

       foreach ($cartDB as $c) {
           if (Arr::exists($cartSession, $c->post->id)) {
               // update
               $cartSession[$c->post->id][1] = $c->count;
           } else {
               // add
               $cartSession[$c->post->id] = [$c->post, $c->count];
           }

           session(['cart' => $cartSession]);
       }
   }
}

- Andrés Cruz

En español

Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.