RPeraltaJr
8/5/2019 - 6:58 PM

Custom Events & Listeners

Generate Event

php artisan make:event ProjectCreated

Call Event within Controller (Option #1)

  1. See ProjectsController.php line 22
  2. An event makes an announcement to the entire Laravel system. Use Listeners to attach a response/action to that event.

Call Event within Model (Option #2)

  1. In this case, remove line 22 from ProjectsController.php
  2. Update the Project model Project.php

Generate Listener (tied to Event)

php artisan make:listener SendProjectCreatedNotification --event=ProjectCreated

Register the Event

  1. Add the event within app/Providers/EventServiceProvider.php
<?php

namespace App\Events;

use Illuminate\Queue\SerializesModels;
use Illuminate\Foundation\Events\Dispatchable;

class ProjectCreated
{
    use Dispatchable, SerializesModels;

    public $project; // $event->project

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($project)
    {
        $this->project = $project;
    }
}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Events\ProjectCreated;
use App\Project;

class ProjectsController extends Controller
{
  // ...
  // ...
 
  public function store() {

    $attributes = $this->validateProject();
    
    $attributes['owner_id'] = auth()->id();

    $project = Project::updateOrCreate($attributes);

    event(new ProjectCreated($project)); 

    return redirect('/projects'); 

  } 
  
  // ...
  
}
<?php

namespace App\Listeners;

use App\Events\ProjectCreated;
use Illuminate\Support\Facades\Mail;
use App\Mail\ProjectCreated as ProjectCreatedMail; // use 'as' to prevent duplicate name

class SendProjectCreatedNotification
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  ProjectCreated  $event
     * @return void
     */
    public function handle(ProjectCreated $event)
    {
        Mail::to($event->project->owner->email)->send(
            new ProjectCreatedMail($event->project)
        );
    }
}
<?php

// ...
// ...

use App\Events\ProjectCreated;
use App\Listeners\SendProjectCreatedNotification;

class EventServiceProvider extends ServiceProvider
{
    // ...
    // ...
    protected $listen = [ 
        Registered::class => [
            // ...
        ],
        ProjectCreated::class => [
            SendProjectCreatedNotification::class
        ]
    ];

    // ...
}
<?php

namespace App;

use App\Events\ProjectCreated;
// ...

class Project extends Model
{
    // ...

    protected $dispatchesEvents = [
        'created'   => ProjectCreated::class
    ];

    // ...
    // ...

}