3

So I'm using the Laravel model event observerables to fire custom event logic, but they only accept the model as a single argument. What I'd like to do is call a custom event that I can also pass some extra arguments to that would in turn get passed to the Observer method. Something like this:

    $this->fireModelEvent('applied', $user, $type);

And then in the Observer

    /**
     * Listen to the applied event.
     *
     * @param  Item    $item
     * @param  User    $user
     * @param  string  $type
     * @return void
     */
    public function applied(Item $item, $user, string $type) {
       Event::fire(new Applied($video, $user, $type));
    }

As you can see i'm interested in passing a user that performed this action, which is not the one that necessarily created the item. I don't think temporary model attributes are the answer because my additional event logic gets queued off as jobs to keep response time as low as possible. Anyone have any ideas on how I could extend Laravel to let me do this?

My theory would be to do a custom trait that overrides one or more functions in the base laravel model class that handles this logic. Thought I'd see if anyone else has needed to do this while I look into it.

Also here's the docs reference

Throttlehead
  • 1,927
  • 6
  • 22
  • 36
  • IMO, this sort of thing doesn't belong on your mode when other context is involved. I generally dislike the idea of custom model events. I believe firing an event should be an explicit thing, not a side-effect of altering a model instance. If you separate the two concerns (updating the model and firing the event), you can use an actual Event class as a value object for your `$user`, `$type`, and whatever else. – deefour May 11 '17 at 19:37
  • So I mainly use the Observables just to keep my model scope cleaner. These really only ever fire Events, it just keeps my custom events a little cleaner and easier to follow. I'll update my code above. – Throttlehead May 11 '17 at 19:45
  • I've actually been firing events within the models up until recently because I like the observables array and the event firing logic in a separate file. Makes it easier to keep track of them. It seems like an oversight on the merge for observable event firings not to accept a list of arguments like Event::fire does, but I'll have to dig around. – Throttlehead May 11 '17 at 19:47

1 Answers1

2

I've accomplished this task by implementing some custom model functionality using a trait.

/**
 * Stores event key data
 *
 * @var array
 */
public $eventData = [];


/**
 * Fire the given event for the model.
 *
 * @param  string  $event
 * @param  bool    $halt
 * @param  array   $data
 * @return mixed
 */
protected function fireModelEvent($event, $halt = true, array $data = []) {
  $this->eventData[$event] = $data;
  return parent::fireModelEvent($event, $halt);
}


/**
 * Get the event data by event
 *
 * @param  string  $event
 * @return array|NULL
 */
public function getEventData(string $event) {
  if (array_key_exists($event, $this->eventData)) {
    return $this->eventData[$event];
  }

  return NULL;
}
Throttlehead
  • 1,927
  • 6
  • 22
  • 36