Where do I run code after successful login in Laravel 8? - laravel

I want to register a user log in immediately after successful login. I found a suggestion that I can use EventServiceProvider to listen to LOGIN event like this:
public function boot(DispatcherContract $events)
{
parent::boot($events);
// Fired on successful logins...
$events->listen('auth.login', function ($user, $remember) {
//
});
}
However, that throws this error:
Declaration of App\Providers\EventServiceProvider::boot(App\Providers\DispatcherContract $events) must be compatible with Illuminate\Foundation\Support\Providers\EventServiceProvider::boot()
So, where is the approriate place to register Log immediately after user Logs in in Laravel 8? or how do I format the above code to work for Laravel 8?

You can create a listener using php artisan make:listener and define your logic in the handle method of that listener class. Then bind listener class to the event in $listen property of EventServiceProvider
protected $listen = [
\Illuminate\Auth\Events\Login::class=>[
\App\Listener\YourCustomListener::class
]
];

Related

How to avoid user take long time to wait while controller is processing

let's me explain example
User click button
run function trigger in Controller
User wait 30sec because MyModel::doSomeThing take long time to process
MyModel::doSomeThing do many thing. I don't want user to wait for it.
Is it possible to run MyModel::doSomeThing by don't care about result and return to user immediately?
function trigger(Request $request){
$id= $request->get('id');
MyModel::doSomeThing($id); // this one take 30 sec.
return response()->json([], 200);
}
If the result of doSomeThing() method isn't necessary for your response & can be done in background, I suggest using Events and Listeners, which will use queues to run in the background, and the user won't need to wait for this procces to finish. The process is fairly simple. Create event and it's listened with these two commands:
php artisan make:event YourEvent
php artisan make:listener YourListener --event=YourEvent
After that, register your event and listener in the App\Providers\EventServiceProvider, under the $listen array:
protected $listen = [
YourEvent::class => [
YourListener::class,
],
];
Now, when you have that sorted out, you need to build your event instance. Inside your newly created method, in the construct method, add this:
public $yourModel;
public function __construct(YourModel $yourModel)
{
$this->yourModel = $yourModel;
}
After you created your model, time to edit your listener, which will hanlde all the logic ghat you need. Inside this handle method, you will have the access to $yourModel instance that we defined in our event:
public function handle(YourEvent $event)
{
// Access your model using $event->yourModel...
YourModel::doSomeThing($event->yourModel);
}
The only thing left do to is to make your listener queueable. You can do this by adding implements ShouldQueue your listened definition:
class YourListener implements ShouldQueue
{
//
}
Now when we have everything setup, you can change your controller code to call this newly created event, and let the queue handle all the logic:
function trigger(Request $request){
$id= $request->get('id');
YourEvent::dispatch($id); //Calling event which will handle all the logic
return response()->json([], 200);
}
And that should be it. I haven't tested this code, so if you encounter any problems, let me know.

Laravel auth attempting event is firing in the wrong segment / name

Inside EventServiceProvider I have this.
public function boot()
{
parent::boot();
Auth::guard('admin')->attempting(function($user){
GoogleAuthenticator::onLogin($user);
});
}
When I go Auth::guard('admin')->attempt(...) the event is triggered as expected.
But, when I go Auth::guard('web')->attempt(...) the event is also triggered, this is not expected. why? isn't the name supposed to be the trigger segment?
Thanks

Change SMTP user according to the user in Laravel 5

I want to assign different SMTP hosts to different authenticated users so that the privileged users can send mails faster through a dedicated SMTP server.
I can change the host in the service provider like:
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->extend('swift.transport', function ($transportManager, $app) {
$app->make('config')->set('mail.host', 'just.testing.com');
return new TransportManager($app);
});
}
}
However since I need the authenticated user I created a listener listening to "Authenticated" event and moved the code there like:
class ChangeSmtpServer
{
public function handle($event)
{
app()->extend('swift.transport', function ($transportManager, $app) use ($event) {
$app->make('config')->set('mail.host', $event->user->smtp_server);
return new TransportManager($app);
});
}
}
The host is not changed this time... So inside the service provider I can overwrite the setting but not inside the listener.
Any ideas why?
Your code works on my setup just fine. Actually it should still work if you keep it in AppServiceProvider because Laravel will only resolve bindings when they are relevant. So the code pertaining to Mail driver configuration will not be run until you actually try to send a Mail. By that point your user will already be authenticated. However...
This will only work when you send your mail synchronously. When you want to send from a Queue worker, there won't be any authenticated user and the Authenticated event will never be called. You need a way to keep track of which user is sending the e-mail.
Here is my solution:
Add a sender argument to your Mail class constructor (the one in App\Mail) that takes in the User object that's sending the e-mail.
public $sender;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(User $sender)
{
$this->sender = $sender;
}
Then add this method that configures your SwiftMailer instance
private function usingSendersSmtp()
{
$mailTransport = app()->make('mailer')
->getSwiftMailer()
->getTransport();
if ($mailTransport instanceof \Swift_SmtpTransport) {
/** #var \Swift_SmtpTransport $mailTransport */
$mailTransport->setHost($this->sender->smtp_host);
$mailTransport->setUsername($this->sender->smtp_username);
$mailTransport->setPassword($this->sender->smtp_password);
// Port and authentication can also be configured... You get the picture
}
return $this;
}
And finally call it inside your build method:
public function build()
{
return $this->usingSendersSmtp()
->view('test');
}
When sending the mail, instantiate your class like new YourMailClass(auth()->user()) and then send it or queue it with the Mail facade to whomever you like. It also might be a good idea to create an abstract class that inherits Illuminate\Mail\Mailable and move these extra stuff over there so you won't have to duplicate this in every other mail class. Hope this helps!

How to hook into Spark Events on Register

I know that spark has events that can be listened to when user has registered but I'm totally new to laravel and Events, are there examples that I can make use of to access the events? My goal is to listen to the user created event and send a welcome email to the user.
Finally, here i came up with solution.
Basically, Events call listeners that is defined in the EventServiceProvider class that is store in the providers inside the app folder of the application.
In the EventServiceProvider.php find
'Laravel\Spark\Events\Auth\UserRegistered' => [
'Laravel\Spark\Listeners\Subscription\CreateTrialEndingNotification',
],
it will be store in the $listen of the EventServiceProvider class, this means that the UserRegistered event will call the CreateTrialEndingNotification listener, so we need to create a listerner and attach here , creating listener is easy just create a new
file with name HookRegisteredUser(or your choice) some thing like below in app/Listeners sand add its path into the $listen of the "Laravel\Spark\Events\Auth\UserRegistered"
namespace App\Listeners;
use Laravel\Spark\Events\Auth\UserRegistered;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class HookRegisteredUser
{
/**
* Handle the event.
*
* #param UserRegistered $event
* #return void
*/
public function handle(UserRegistered $event)
{
//your code goes here
}
}
After this add HookRegisteredUser listener in EventServiceProvider.php as follows,
'Laravel\Spark\Events\Auth\UserRegistered' => [
'Laravel\Spark\Listeners\Subscription\CreateTrialEndingNotification',
'App\Listeners\HookRegisteredUser',
],
Now the UserRegistered event will call two listeners i.e CreateTrialEndingNotification , HookRegisteredUser and the method handle will get executed on call to listeners and thats it!

Queueable entity App\Setting not found for ID error in Laravel

I am trying to send emails in laravel 5.1 by using queues. When running queue listen command on terminal,
php artisan queue:listen
Displays below error on terminal,
[Illuminate\Contracts\Queue\EntityNotFoundException]
Queueable entity [App\Setting] not found for ID [].
Values of jobs table is not process. Any idea ?
How can I process my queue ?
I know this question is a few months old, but I'd like to add an observation of mine while encountering this very same error message. It is due to the EventListener (interface of ShouldQueue in this example for asynchronous) not being able to resolve a dependant variable correctly (out of scope or not included in scope of Event object passed through the handle(Event $event) method of EventListener).
For me, this error was fired when I put my code within the __construct block within the EventListener:
public function __construct(Event $event)
{
$localProperty = $event->property
Mail::queue(etc...);
}
public function handle()
{
// Yeah I left this blank... whoops
}
Instead, the handle() method of the EventListener takes an Event interface and when called processes the job in the queue:
In the Event:
public function __construct(Object $ticket, AnotherObject $user)
{
$this->ticket = $ticket;
$this->user = $user;
}
And in Event Listener
class SomeEventListener implements ShouldQueue
{
use InteractsWithQueue;
use SerializesModels;
public function __construct()
{
// Leave me blank!
}
public function handle(Event $event)
{
$someArray = [
'ticket' = $event->ticket,
'user' = $event->user,
];
Mail::queue('some.view', $someArray, function($email) use ($someArray) {
// Do your code here
});
}
}
Although a tad late, I hope this helps someone. Queues are similar to Events (with the exception of Jobs being the main driving force behind Queues), so most of this should be relevant.
Turned out that it was because a model was added to the queue, that has since been deleted.

Resources