Event listeners not firing in Laravel 5.1 - laravel

I am having an issue getting my event listeners to fire in Laravel 5.1.
I am firing the following event:
/**
* Add new project.
*
* #param AddNewProjectRequest $request
* #return Redirect
*/
public function add(AddNewProjectRequest $request)
{
// Event(s);
Event::fire(new ProjectAdded($project, $request->only('file')));
}
I have the following event setup:
<?php
namespace App\Events\Project;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class ProjectAdded extends Event
{
use SerializesModels;
public $project;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($project)
{
$this->project = $project;
}
/**
* Get the channels the event should be broadcast on.
*
* #return array
*/
public function broadcastOn()
{
return [];
}
}
Here is my EventServiceProvider file:
<?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 = [
\App\Events\ProjectAdded::class => [
\App\Listeners\Project\ImportFileListener::class,
],
];
/**
* Register any other events for your application.
*
* #param \Illuminate\Contracts\Events\Dispatcher $events
* #return void
*/
public function boot(DispatcherContract $events)
{
parent::boot($events);
//
}
}
Here is my ImportFileListener listener:
<?php
namespace Woodford\Listeners\Project;
use Woodford\Events\ProjectAdded;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class ImportFileListener
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
}
/**
* Handle the event.
*
* #param ProjectAdded $event
* #return void
*/
public function handle(ProjectAdded $event)
{
dd('listener');
}
}
As you can see above I have added dd('listener'); to see if the listener gets fired - it doesn't!
I have also tried running php artisan optimize and composer dump-autoload but still no luck!
Does anyone know what could be wrong?

Related

Adding a custom faker service provider?

I'm trying to add https://github.com/morawskim/faker-images to faker in Laravel.
I have a faker service provider...
<?php
namespace App\Providers;
use Faker\{Factory, Generator};
use Illuminate\Support\ServiceProvider;
class FakerServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* #return void
*/
public function register()
{
$this->app->singleton(Generator::class, function () {
$faker = Factory::create();
$faker->addProvider(new \Mmo\Faker\PicsumProvider($faker));
$faker->addProvider(new \Mmo\Faker\LoremSpaceProvider($faker));
$faker->addProvider(new \Mmo\Faker\LoremFacesProvider($faker));
return $faker;
});
}
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
//
}
}
This is conditionally loaded via the app service provider:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
if (!$this->app->environment('production')) {
$this->app->register('App\Providers\FakerServiceProvider');
}
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
//
}
}
Yet, fake()->picsumUrl() gives the error Unknown format "picsumUrl".
I've checked and the faker service provider is ran. There is no issues with the package either as I can do the following and get an image url...
$faker = \Faker\Factory::create('en_GB');
$faker->addProvider(new \Mmo\Faker\LoremFacesProvider($faker));
dd($faker->loremFacesUrl(1234));
So there must be something wrong with how the package is being added to faker.

How can i use the Queue::after on Laravel?

I'm using Queue to send my mails on my application, and it's working great:
class SendMail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
private $user_mail;
private $person_data;
private $title;
private $company_name;
private $html;
private $email_sender;
private $email_reply;
/**
* Create a new job instance.
*
* #return void
*/
public function __construct($user_mail, $person_data, $title, $company_name, $html, $email_sender, $email_reply)
{
$this->user_mail = $user_mail;
$this->person_data = $person_data;
$this->title = $title;
$this->company_name = $company_name;
$this->html = $html;
$this->email_sender = $email_sender;
$this->email_reply = $email_reply;
}
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
Mail::to($this->user_mail)
->queue(new DocumentMessage($this->person_data, $this->title, $this->company_name, $this->html,
$this->email_sender, $this->email_reply));
}
}
Now I want to get the log of the moment when the emails were sent by the queue and, following the documentation, I put this code in my AppServiceProvider for testing:
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Carbon::setLocale('pt_BR');
setlocale(LC_ALL, 'pt_BR');
Carbon::setUtf8(true);
Paginator::useBootstrapThree();
Blade::withoutDoubleEncoding();
Queue::after(function (JobProcessing $event) {
DB::raw("INSERT INTO activity_log (log_name, description, subject_id, subject_type, causer_id, causer_type, properties)
VALUES ('email_sent', now(), null, null, 1111,
'App\Models\User','');");
});
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
}
But nothing happens after i send mails using my queue. Should i restart my queue job or do something after modify AppServideProvider?
According to the documentation, JobProcessed is the right event class to use. You might want to update this:
Queue::after(function (JobProcessed $event) {
...
});
By the way, I suggest a bit cleaner approach that leverage the framework better. Laravel has already includes the Illuminate\Mail\Events\MessageSent out of the box. So you can listen to the mail event.

How to not add Notification broadcast in Queue? laravel 5.8

what I want to achieve is to broadcast notification immediately instead of need to run
php artisan queue:listen
If in Event class I just need to Implements ShouldBroadcastNow to make events broadcast immediately. But I tried same things in Notification but it is not working.
Notification
<?php
namespace App\Notifications;
use App\Tournament;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\BroadcastMessage;
use Illuminate\Notifications\Messages\MailMessage;
class TournamentAdded extends Notification implements ShouldBroadcastNow
{
use Queueable;
protected $tournament;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct(Tournament $tournament)
{
$this->tournament = $tournament;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['database', 'broadcast'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
$this->tournament
];
}
public function toBroadcast($notifiable)
{
return new BroadcastMessage([
$this->tournament
]);
}
}
Execute notification
$t = Tournament::latest()->first();
$user->notify(new AppTournamentAdded($t));

Can an Eloquent model has multiple Observer?

Hi I want write a trait to add an observer to model but I thought write boot method is not the right way and finnaly i find that i can boot trait like boot[TraitName] but i wonder if i add an observer with code like this:
trait CreateObserver
{
public static function bootCreateObserver()
{
static::creating(function (Model $model) {
// ...
});
}
}
can I add another observer for my model like below or it will overriding my trait observer?
class MyModel extends Model
{
use CreateObserver;
public static function boot()
{
static::creating(function ($model) {
// ...
});
}
...
}
That's not the right way. I think this might help you:
https://laravel.com/docs/5.6/eloquent#observers
You bind observers to your models using a service boot:
<?php
namespace App\Providers;
use App\User;
use App\Observers\UserObserver;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
User::observe(UserObserver::class);
}
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
//
}
}
Inside the observer you can add all desired functionality:
<?php
namespace App\Observers;
use App\User;
class UserObserver
{
/**
* Listen to the User created event.
*
* #param \App\User $user
* #return void
*/
public function created(User $user)
{
//
}
/**
* Listen to the User deleting event.
*
* #param \App\User $user
* #return void
*/
public function deleting(User $user)
{
//
}
}
And to elaborate. Yes it can have multiple observers. Although I never seen a useful situation for that:
public function boot()
{
User::observe(UserObserver::class);
User::observe(AuthenticableModelsObserver::class);
}
This way both the UserObserver() and AuthenticableModelsObserver() are binded to the User() model on boot.

Calling laravel artisan command from console

I am trying to teach myself Laravel command so that later I use it for scheduling them. This is my kernel file:
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
//
'App\Console\Commands\FooCommand',
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
$schedule->command('App\Console\Commands\FooCommand')->hourly();
}
/**
* Register the Closure based commands for the application.
*
* #return void
*/
protected function commands()
{
require base_path('routes/console.php');
}
}
And this is the command file inside \App\Console\Commands
namespace App\Console\Commands;
use Illuminate\Console\Command;
class FooCommand extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'command:name';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
//
}
public function fire()
{
$this->info('Test has fired.');
}
}
I want to test the FooCommand command. How do it call this command from shell so that the result is "Test has fired."?
to run your commands manually: php artisan command:name.
Remove your fire function, you can handle this inside handle function.
Fix your schedule function at Kernel class
class Kernel extends ConsoleKernel
{
....
protected function schedule(Schedule $schedule)
{
$schedule->command('command:name')
->hourly();
}
}
To config your schedule please read this:
https://laravel.com/docs/5.4/scheduling

Resources