Skip to content

Commit

Permalink
added support for object eloquent events
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorotwell committed Oct 28, 2016
1 parent 6a1f671 commit e7a724d
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
22 changes: 20 additions & 2 deletions src/Illuminate/Database/Eloquent/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,15 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
*/
protected $touches = [];

/**
* The event map for the model.
*
* Allows for object-based events for native Eloquent events.
*
* @var array
*/
protected $events = [];

/**
* User exposed observable events.
*
Expand Down Expand Up @@ -1655,13 +1664,22 @@ protected function fireModelEvent($event, $halt = true)
return true;
}

$method = $halt ? 'until' : 'fire';

// If a custom event type has been configured for this event we'll fire that
// instead of the string version of the event. This provides for a custom
// "object-based" event more consistent with the rest of the framework.
if (isset($this->events[$event])) {
return static::$dispatcher->$method(
new $this->events[$event]($this)
);
}

// We will append the names of the class to the event to distinguish it from
// other model events that are fired, allowing us to listen on each model
// event set individually instead of catching event for all the models.
$event = "eloquent.{$event}: ".static::class;

$method = $halt ? 'until' : 'fire';

return static::$dispatcher->$method($event, $this);
}

Expand Down
23 changes: 22 additions & 1 deletion tests/Database/DatabaseEloquentModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,21 @@ public function testUpdateIsCancelledIfUpdatingEventReturnsFalse()
$this->assertFalse($model->save());
}

public function testEventsCanBeFiredWithCustomEventObjects()
{
$model = $this->getMockBuilder('EloquentModelEventObjectStub')->setMethods(['newQueryWithoutScopes'])->getMock();
$query = m::mock('Illuminate\Database\Eloquent\Builder');
$model->expects($this->once())->method('newQueryWithoutScopes')->will($this->returnValue($query));
$model->setEventDispatcher($events = m::mock('Illuminate\Contracts\Events\Dispatcher'));
$events->shouldReceive('until')->once()->with(m::type(EloquentModelSavingEventStub::class))->andReturn(false);
$model->exists = true;

$this->assertFalse($model->save());
}

public function testUpdateProcessWithoutTimestamps()
{
$model = $this->getMockBuilder('EloquentModelStub')->setMethods(['newQueryWithoutScopes', 'updateTimestamps', 'fireModelEvent'])->getMock();
$model = $this->getMockBuilder('EloquentModelEventObjectStub')->setMethods(['newQueryWithoutScopes', 'updateTimestamps', 'fireModelEvent'])->getMock();
$model->timestamps = false;
$query = m::mock('Illuminate\Database\Eloquent\Builder');
$query->shouldReceive('where')->once()->with('id', '=', 1);
Expand Down Expand Up @@ -1804,3 +1816,12 @@ class EloquentModelNonIncrementingStub extends Illuminate\Database\Eloquent\Mode
protected $guarded = [];
public $incrementing = false;
}

class EloquentModelSavingEventStub {}

class EloquentModelEventObjectStub extends Illuminate\Database\Eloquent\Model
{
protected $events = [
'saving' => EloquentModelSavingEventStub::class
];
}

0 comments on commit e7a724d

Please sign in to comment.