05
Feb '18

So we all know about Laravel’s built-in ‘creating’, ‘created’, ‘updating’, ‘updated’ etc model events. Seriously useful events for all manner of purposes.

Recently I found myself needing to add a couple more; one to trigger when a model was loaded (for logging purposes), and one before a model was updated (so that I could archive a copy of it before the data was changed).

I came up with the following code and inserted it into an abstract base model class, which all the other models extend.

protected $observables = ['loaded', 'beforeUpdate'];

/**
 * Register a loaded model event with the dispatcher.
 *
 * @param  \Closure|string  $callback
 * @return void
 */
public static function loaded($callback)
{
    static::registerModelEvent('loaded', $callback);
}

/**
 * Register a before update model event with the dispatcher.
 *
 * @param  \Closure|string  $callback
 * @return void
 */
public static function beforeUpdate($callback)
{
    static::registerModelEvent('beforeUpdate', $callback);
}

/**
 * Create a new model instance.
 *
 * @param  array  $attributes
 * @return \Illuminate\Database\Eloquent\Model|static
 */
public function newFromBuilder($attributes = array(), $connection = null)
{
    $instance = parent::newFromBuilder($attributes);

    $instance->fireModelEvent('loaded', false);

    return $instance;
}

/**
 * Trigger before update
 *
 * @param  array  $attributes
 * @return \Illuminate\Database\Eloquent\Model|static
 */
public function update(array $attributes = [], array $options = [])
{
    $this->fireModelEvent('beforeUpdate', false);

    return parent::update($attributes);
}