diff --git a/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php b/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php index 14d7a5eefaa2..009d9d8d63d4 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php +++ b/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php @@ -25,21 +25,38 @@ trait HasEvents protected $observables = []; /** - * Register an observer with the Model. + * Register observers with the Model. * - * @param object|string $class + * @param object|string|array $classes * @return void */ - public static function observe($class) + public static function observe($classes) { $instance = new static; + if (! is_array($classes)) { + $classes = [$classes]; + } + + foreach ($classes as $class) { + $instance->registerObserver($class); + } + } + + /** + * Registers a single observer with the Model. + * + * @param object|string $class + * @return void + */ + private function registerObserver($class) + { $className = is_string($class) ? $class : get_class($class); // When registering a model observer, we will spin through the possible events // and determine if this observer has that method. If it does, we will hook // it into the model's event system, making it convenient to watch these. - foreach ($instance->getObservableEvents() as $event) { + foreach ($this->getObservableEvents() as $event) { if (method_exists($class, $event)) { static::registerModelEvent($event, $className.'@'.$event); } diff --git a/tests/Database/DatabaseEloquentModelTest.php b/tests/Database/DatabaseEloquentModelTest.php index 28d1fb7a813b..b16d74df08f2 100755 --- a/tests/Database/DatabaseEloquentModelTest.php +++ b/tests/Database/DatabaseEloquentModelTest.php @@ -1271,6 +1271,35 @@ public function testModelObserversCanBeAttachedToModelsWithString() EloquentModelStub::flushEventListeners(); } + public function testModelObserversCanBeAttachedToModelsThroughAnArray() + { + EloquentModelStub::setEventDispatcher($events = m::mock('Illuminate\Contracts\Events\Dispatcher')); + $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\Tests\Database\EloquentModelStub', 'Illuminate\Tests\Database\EloquentTestObserverStub@creating'); + $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\Tests\Database\EloquentModelStub', 'Illuminate\Tests\Database\EloquentTestObserverStub@saved'); + $events->shouldReceive('forget'); + EloquentModelStub::observe(['Illuminate\Tests\Database\EloquentTestObserverStub']); + EloquentModelStub::flushEventListeners(); + } + + public function testModelObserversCanBeAttachedToModelsThroughCallingObserveMethodOnlyOnce() + { + EloquentModelStub::setEventDispatcher($events = m::mock('Illuminate\Contracts\Events\Dispatcher')); + $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\Tests\Database\EloquentModelStub', 'Illuminate\Tests\Database\EloquentTestObserverStub@creating'); + $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\Tests\Database\EloquentModelStub', 'Illuminate\Tests\Database\EloquentTestObserverStub@saved'); + + $events->shouldReceive('listen')->once()->with('eloquent.creating: Illuminate\Tests\Database\EloquentModelStub', 'Illuminate\Tests\Database\EloquentTestAnotherObserverStub@creating'); + $events->shouldReceive('listen')->once()->with('eloquent.saved: Illuminate\Tests\Database\EloquentModelStub', 'Illuminate\Tests\Database\EloquentTestAnotherObserverStub@saved'); + + $events->shouldReceive('forget'); + + EloquentModelStub::observe([ + 'Illuminate\Tests\Database\EloquentTestObserverStub', + 'Illuminate\Tests\Database\EloquentTestAnotherObserverStub', + ]); + + EloquentModelStub::flushEventListeners(); + } + public function testSetObservableEvents() { $class = new EloquentModelStub; @@ -1719,6 +1748,17 @@ public function saved() } } +class EloquentTestAnotherObserverStub +{ + public function creating() + { + } + + public function saved() + { + } +} + class EloquentModelStub extends Model { public $connection;