Search code examples
eventslaravellaravel-4observers

Laravel 4.2 custom Observer Event


I have a directory under my app folder named observers and I listen for various events such as created , updated , ... and I handle them ! my observer events bootstrap is in my model boot function ! for example I have User Model under models folder and I have UserObserver under observers folder! now I need to add my specific event to eloquent observer ! consider I want fire event when one column such as "enable" of my user table has changed. I know I should extend eloquent Model and add a function like userchangestate() coz I already have looked up Eloquent Model it has a function for every event ('creating' , 'created' , 'saving' , 'saved' , ....) but still I'm not sure how handle it ! thanks !


Solution

  • I'm assuming that my comment above is true having read the question a number of times to try and make sense of it.

    I would do this by checking if an attribute is dirty (changed) during the saving event and firing a custom event if it has changed with it's new value.

    In your observer class dependency inject the dispatcher (the IoC will do this for you automatically).

    use Illuminate\Events\Dispatcher;
    
    class UserObserver {
    
        protected $events;
    
        public function __construct(Dispatcher $dispatcher)
        {
            $this->events = $dispatcher;
    
            // Set up a listener for your modified event to run a method
            // on this class
            $this->events->listen('myevent.modified', [$this, 'changeState']);
        }
    
        public function saving($model)
        {
            if ($model->isDirty(['attribute'])
            {
                $this->events->fire('myevent.modified', [$model->attribute]);
            }
        }
    
        public function changeState($value)
        {
            // Handle your event here
        }
    }
    

    You can now listen to this event anywhere using the signature myevent.modified.

    Edit Added in a listener to the constructor and pushed the event callback to the changeState method.

    If you don't need an event fired you could just push the result straight through.

    use Illuminate\Events\Dispatcher;
    
    class UserObserver {
    
        protected $events;
    
        public function __construct(Dispatcher $dispatcher)
        {
            $this->events = $dispatcher;
        }
    
        public function saving($model)
        {
            if ($model->isDirty(['attribute'])
            {
                $this->changeState($model->attribute);
            }
        }
    
        public function changeState($value)
        {
            // Handle your event here
        }
    }