1

I wan to create a Laravel signup system where I would send an email to verify the email once a user has signed up. I tried adding an event dispatched to the created method but I got an error

 Fatal error: Non-static method Illuminate\Contracts\Events\Dispatcher::fire() cannot be called statically

Here is what I came up with.

  <?php

namespace App;

use Laravel\Cashier\Billable;
use Laravel\Spark\Teams\CanJoinTeams;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as BaseUser;
use Laravel\Spark\Auth\TwoFactor\Authenticatable as TwoFactorAuthenticatable;
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher; 
use Laravel\Spark\Contracts\Auth\TwoFactor\Authenticatable as TwoFactorAuthenticatableContract;

class User extends BaseUser implements TwoFactorAuthenticatableContract
{
    use Billable, TwoFactorAuthenticatable,CanJoinTeams;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'email',
        'name',
        'password',
    ];

    /**
     * The accessors to append to the model's array form.
     *
     * @var array
     */
    protected $appends = [

    ];


    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [
        'card_brand',
        'card_last_four',
        'extra_billing_info',
        'password',
        'remember_token',
        'stripe_id',
        'stripe_subscription'       
    ];

    /**
     * Boot the model.
     *
     * @return void
     */
    public static function boot()
    {
        parent::boot();

        static::creating(function ($user) {
            $user->token = str_random(30);
        });

        static::created(function ( $user) {        

           EventDispatcher::fire('UserCreated');   

        });
    }


    /**
     * Confirm the user.
     *
     * @return void
     */
    public function confirmEmail()
    {
        $this->verified = true;
        $this->token = null;

        $this->save();
    }    

}

I also tried changing the code to

  use Billable, TwoFactorAuthenticatable,CanJoinTeams, EventDispatcher;

and replacing the boot part with

 static::created(function ( $user, EventDispatcher $event) {        

       $event->fire('UserCreated');   

    });

But it gave me another error

App\User cannot use Illuminate\Contracts\Events\Dispatcher - it is not a trait

How do I fire the event once the model has been created ?

jedrzej.kurylo
  • 39,591
  • 9
  • 98
  • 107
Bazinga777
  • 5,140
  • 13
  • 53
  • 92

2 Answers2

3

In Laravel >5.4 and higher, you can associate eloquent event in your Model class to fire a custom event - e.g. 'created' => ProjectCreated::class. So basically, on Eloquent model created fire ProjectCreated Event.

class Project extends Model
{
    /**
     * @var array
     */
    protected $fillable = ['title', 'description', 'client_id'];

    /**
     *
     * Eloquent model events
     *
     * @var array
     */
    protected $dispatchesEvents = [
        'created' => ProjectCreated::class,
    ];
}
Rytis Dereskevicius
  • 1,261
  • 14
  • 15
  • Question: Inside the `ProjectCreated::class` how do I retrieve the current `Project::class` record information? Is `ProjectCreated` an event or listener? – Pathros May 27 '22 at 23:25
1

Model's lifecycle events are fired by Eloquent already so no need to fire them yourself. Event name is created with the following code:

$event = "eloquent.{$event}: ".get_class($model);

Therefore, if you want to listen on the created event, you need to listen on "eloquent.created: App\User". The event handler will get the related User model as one of handle() parameters.

If you hovewer want to dispatch an event of your own, you can do that using Event facade:

Event::fire('UserCreated', $user);

You can read more about events in Laravel here: https://laravel.com/docs/5.1/events

jedrzej.kurylo
  • 39,591
  • 9
  • 98
  • 107
  • Since I am pretty new to Laravel and am not very well aware of the event lifecycle I tried using the Event::fire way but I got an Fatal error: Class 'App\Event' not found Do i need to call it elsewhere ? – Bazinga777 Jan 11 '16 at 10:44
  • Add "use Event;" at the top of your file or call \Event::fire – jedrzej.kurylo Jan 11 '16 at 11:08