vybeauregard
2 years ago

Eloquent Model Events in Laravel 5.4

Posted 2 years ago by vybeauregard

In previous versions of Laravel, I was able to define an array of events and the listener action inside a trait which was then applied to several models in my app. In Laravel 5.4, I now get an error warning that the $events property was defined in Illuminate\Database\Eloquent\Model and my trait definition is incompatible. I see there's a new HasEvents trait that handles this functionality, but I haven't found any examples of it in use.

Here's a condensed version of what I had working in 5.3:

<?php

namespace App\Traits;

use Illuminate\Database\Eloquent\SoftDeletes;

trait SavesItem
{
    use SoftDeletes;

    /**
     * $events maps Eloquent events to trait methods.
     */
    protected $events = [
        'created'   =>  'createItem',
        'deleted'   =>  'deleteItem',
        'updating'  =>  'updateItem',
        'saving'    =>  'saveItem',
    ];

    /**
     * Set up event listeners for all Item types.
     * Named events are mapped to trait methods in $events.
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        foreach(static::getModelEvents() as $event) {
            static::$event(function($item) use ($event){
                $action = static::$events[$event];
                $item->$action($item);
            });
        }
    }

    /**
     * Retrieve events the model needs listeners for.
     *
     * @return array
     */
    protected static function getModelEvents()
    {
        if (isset(static::$modelEvents)){
            //if a model needs fewer events available to SavesItem, define in that model's $modelEvents array.
            return static::$modelEvents;
        }
        return [
            'created', 'deleted', 'updating', 'saving'
        ];
    }

    public function createItem($item)
    {
        //runs when created event is dispatched
    }

    public function updateItem($item)
    {
        //runs when updating event is dispatched
    }

    public function saveItem($item)
    {
        //runs when saving event is dispatched
    }

    public function deleteItem($item)
    {
        //runs when deleted event is dispatched
    }

}

Any pointers on how to proceed?

Please sign in or create an account to participate in this conversation.