Laravel 5 model event doesn't work (in production) - php

I've got saving model event in my EventServiceProvider.php
<?php namespace App\Providers;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use App\UnprotectedLead;
class EventServiceProvider extends ServiceProvider {
/**
* The event handler mappings for the application.
*
* #var array
*/
protected $listen = [
'event.name' => [
'EventListener',
],
];
/**
* Register any other events for your application.
*
* #param \Illuminate\Contracts\Events\Dispatcher $events
* #return void
*/
public function boot(DispatcherContract $events)
{
parent::boot($events);
UnprotectedLead::saving(function($lead)
{
dd($lead->lead_phone);
$lead->lead_phone_clean = preg_replace('/[^0-9]/', '', $lead->lead_phone);
});
}
}
This code work fine on localhost, but in production saving event does not work (I use dd() to check it in prod, but script didn't die)
How to debug this? Maybe EventServiceProvider.php didn't loaded in production?

Related

Capturing rows affected by query with Event

I am trying to write an event that will display how many rows were affected by a query.
I found the Illuminate\Database\Events\QueryExecuted Event. I have added a listener for the event and registered it in Event service Provider:
EventServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* #var array
*/
protected $listen = [
'Illuminate\Database\Events\QueryExecuted' => [
'App\Listeners\QueryExecutedListener#handle'
],
];
/**
* Register any other events for your application.
*
* #param \Illuminate\Contracts\Events\Dispatcher $events
* #return void
*/
public function boot(DispatcherContract $events)
{
parent::boot($events);
//
}
}
and in my handle method I can see the queries being run:
public function handle(QueryExecuted $event)
{
var_dump($event);
}
However, I can't find a way to see how many rows were updated/deleted by the query run.
I'd appreciate any advice.
The EventServiceProvider included with your Laravel application provides a convenient place to register all of your application's event listeners.
https://laravel.com/docs/5.4/events

Event listener in laravel 5.4

I am using laravel 5.4 for creating my project and i used auth controller for login and register what I need is to get the last login time of user and store it in database when i referred that i came about an idea of creating event listeners and i done it..
login event handling in laravel 5
This is in my
EventServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* #var array
*/
protected $listen = [
'App\Events\SomeEvent' => [
'App\Listeners\EventListener',
],
'Illuminate\Auth\Events\Login' => [
'App\Listeners\AuthLoginListener',
],
];
/**
* Register any events for your application.
*
* #return void
*/
public function boot()
{
parent::boot();
}
}
I defined listener as AuthLoginListner and my
> AuthLoginListner.php
<?php
namespace App\Listeners;
use Carbon\Carbon;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\User;
use Illuminate\Auth\Events\Login;
class AuthLoginListener
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param auth.login $event
* #return void
*/
public function handle(Login $event)
{
return "yes";
}
}
Here i just return one text now what my doubt is how its working and where i get this yes message it doesnot show me any error now have an doubt its working correcty or not if yes where i get this message ..please any one help me out i just confused with this ...
Here is how I achieved it.
I created a new Listenener here App/Listeners/LogSuccessfullLogin.php
namespace App\Listeners;
use Illuminate\Auth\Events\Login;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use \Carbon\Carbon;
class LogSuccessfulLogin
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param Login $event
* #return void
*/
public function handle(Login $event)
{
$event->user->last_login = Carbon::now();
$event->user->save();
}
}
and then in the EventServiceProvider, I observed for the Illuminate\Auth\Events\Login event as such:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* #var array
*/
protected $listen = [
'Illuminate\Auth\Events\Login' => [
'App\Listeners\LogSuccessfulLogin',
]
];
/**
* Register any events for your application.
*
* #return void
*/
public function boot()
{
parent::boot();
//
}
}
So each time a user is logging in, it will save the timestamp in the last_login field in the users table.
Hope this helps!

Event not firing Laravel 5.0.*

I am using Laravel 5.0.* and followed the following answer: login event handling in laravel 5 but I am still not able to see the event firing.
Anyone could help me with this:
This is how my Event Handler Class looks like:
<?php namespace App\Handlers\Events;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldBeQueued;
use App\User;
use Illuminate\Support\Facades\Log;
class AuthLoginEventHandler {
/**
* Create the event handler.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param User $user
* #param $remember
* #return void
*/
public function handle(User $user, $remember)
{
//
$user->login_counter = 1;
$user->save();
// $user->increment('login_counter');
Log::error('something wrong happened');
// dd("login fired and handled by class with User instance and remember variable");
}
}
And this is the EventServiceProvider:
<?php namespace App\Providers;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider {
/**
* The event handler mappings for the application.
*
* #var array
*/
protected $listen = [
'auth.login' => [
'App\Handlers\Events\AuthLoginEventHandler',
],
];
/**
* Register any other events for your application.
*
* #param \Illuminate\Contracts\Events\Dispatcher $events
* #return void
*/
public function boot(DispatcherContract $events)
{
parent::boot($events);
//
}
}
Appreciate your help
I use Laravel 5.2. I spent hours trying to figure out why my listener is not responding not knowing that I misspelled the event class name in the $listen array. Basically, if you fire your event like event(new SameEventClass(...)) make sure it is the same name you used in $listen => ['SameEventClass' => ['SameListener']]

Laravel 5 Event Handler Not Firing

So I'm trying out the new Laravel 5 Event methodology.
In my repository, I'm firing the event "KitchenStored" as so:
// Events
use App\Events\KitchenStored;
class EloquentKitchen implements KitchenInterface {
public function store($input) {
$kitchen = new $this->kitchen;
$kitchen->name = $input['name'];
$kitchen->save();
\Event::fire(new KitchenStored($kitchen));
return $kitchen;
}
Which successfully fires this event:
<?php namespace App\Events;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;
class KitchenStored extends Event {
use SerializesModels;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($kitchen)
{
$this->kitchen = $kitchen;
}
}
However, it doesn't link up to this handler:
<?php namespace App\Handlers\Events;
use App\Events\KitchenStored;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldBeQueued;
class AttachCurrentUserToKitchen {
/**
* Create the event handler.
*
* #return void
*/
public function __construct()
{
dd('handler');
}
/**
* Handle the event.
*
* #param KitchenStored $event
* #return void
*/
public function handle(KitchenStored $event)
{
//
}
}
which I know because the dd('handler'); isn't fired during the request lifecycle.
I have registered the event with its listener here:
<?php namespace App\Providers;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider {
/**
* The event handler mappings for the application.
*
* #var array
*/
protected $listen = [
App\Events\KitchenStored::class => [
App\Handlers\Events\AttachCurrentUserToKitchen::class
]
];
/**
* Register any other events for your application.
*
* #param \Illuminate\Contracts\Events\Dispatcher $events
* #return void
*/
public function boot(DispatcherContract $events)
{
parent::boot($events);
Event::listen('App\Events\KitchenStored',
'App\Handlers\Events\AttachCurrentUserToKitchen');
}
}
Can anyone explain this process better so I can keep going with the cleanest code I have to date?
Many thanks
In EventServiceProvider.php, include the leading \ when referencing a class using the ::class notation:
protected $listener = [
\App\Events\KitchenStored::class => [
\App\Handlers\Events\AttachCurrentUserToKitchen::class,
],
];
You could also add use statements and keep your listener mappings short:
use App\Events\KitchenStored;
use App\Handlers\Events\AttachCurrentUserToKitchen;
...
protected $listener = [
KitchenStored::class => [
AttachCurrentUserToKitchen:class,
],
];
Or just use the string notation:
protected $listener = [
'App\Events\KitchenStored' => [
'App\Handlers\Events\AttachCurrentUserToKitchen',
],
];
If you run php artisan optimize, your event handlers should start listening.
Credit to mattstauffer from the larachat slack channel for that one.
I ran
composer dumpautoload
followed by
php artisan clear-compiled
Then my events began firing.
Don't be like me and cache your events locally to test something, then forget to clear that cache 😅
php artisan event:clear
Make sure your EventServiceProvider is calling the parent register function.
public function register() {
parent::register():
}
I had a similar issue and I fixed it by deleting the vendor\compiled.php file. Then I run "composer update" again and now the handler is firing as expected.
For me, I had the issue where I had multiple listeners for a single event. In that case, the listeners are executed in order. However, if one of the listeners return false, then all of the others listeners are not executed.
This is an older question, but I came across this same issue and for me, it was because I'd added my new Event to the service provider but crucially I had not imported it. For anyone in 2020 with this issue, check that you have imported the event.

How do I solve "Target [Interface] is not instantiable" in Laravel 4?

My error message:
Illuminate \ Container \ BindingResolutionException
Target [Project\Backend\Service\Validation\ValidableInterface] is not instantiable.
I understand that interfaces and abstract classes are not instantiable so I know that Laravel should not be trying to instantiate my interface. Yet somehow it's trying to and I suspect this may be a binding issue...even though I believe I have bound it correctly and have registered it as a service provider.
I should mention that I have taken this example out of Chris Fidao's "Implementing Laravel" and it's almost identical!
This is the first couple of lines of my form class:
namespace Project\Backend\Service\Form\Job;
use Project\Backend\Service\Validation\ValidableInterface;
use Project\Backend\Repo\Job\JobInterface;
class JobForm {
/**
* Form Data
*
* #var array
*/
protected $data;
/**
* Validator
*
* #var \Project\Backend\Form\Service\ValidableInterface
*/
protected $validator;
/**
* Job repository
*
* #var \Project\Backend\Repo\Job\JobInterface
*/
protected $job;
public function __construct(ValidableInterface $validator, JobInterface $job)
{
$this->validator = $validator;
$this->job = $job;
}
This is the first few lines of my validator class:
namespace Project\Backend\Service\Form\Job;
use Project\Backend\Service\Validation\AbstractLaravelValidator;
class JobFormValidator extends AbstractLaravelValidator {
// Includes some validation rules
This is the abstract validator:
namespace Project\Backend\Service\Validation;
use Illuminate\Validation\Factory;
abstract class AbstractLaravelValidator implements ValidableInterface {
/**
* Validator
*
* #var \Illuminate\Validation\Factory
*/
protected $validator;
/**
* Validation data key => value array
*
* #var Array
*/
protected $data = array();
/**
* Validation errors
*
* #var Array
*/
protected $errors = array();
/**
* Validation rules
*
* #var Array
*/
protected $rules = array();
/**
* Custom validation messages
*
* #var Array
*/
protected $messages = array();
public function __construct(Factory $validator)
{
$this->validator = $validator;
}
This is the code where I bind it all to the app:
namespace Project\Backend\Service\Validation;
use Illuminate\Support\ServiceProvider;
use Project\Backend\Service\Form\Job\JobFormValidator;
class ValidationServiceProvider extends ServiceProvider {
public function register()
{
$app = $this->app;
$app->bind('Project\Backend\Service\Form\Job\JobFormValidator', function($app)
{
return new JobFormValidator($app['validator']);
});
}
}
This is then registered in app/config/app.php:
.....
'Project\Backend\Service\Validation\ValidationServiceProvider',
....
Finally these are the first few lines of my controller:
use Project\Backend\Repo\Job\JobInterface;
use Project\Backend\Service\Form\Job\JobForm;
class JobController extends \BaseController {
protected $jobform;
function __construct(JobInterface $job, JobForm $jobform)
{
$this->job = $job;
$this->jobform = $jobform;
}
You need to tell Laravel which instance it should use for a certain interface when injecting it into the constructor via type hinting.
You do this using the bind() method (in your service provider for example)
$app->bind('JobInterface', 'Job'); // Job being the class you want to be used
I highly recommend you watch the video here where Taylor Otwell, the creator of Laravel, explains this and some other things.
First you need to bind using
/app/Providers/AppServiceProvider.php
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider {
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
$this->app->bind('JobInterface', 'Job');
}
}
Once you complete this change
Run composer update

Categories