Skip to content

Commit

Permalink
Merge pull request #40 from kbond/double-register-event
Browse files Browse the repository at this point in the history
Add failing test demonstrating double registering of events
  • Loading branch information
calebporzio authored Mar 18, 2019
2 parents 6d3a955 + 607235e commit bb7d1bc
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 2 deletions.
34 changes: 32 additions & 2 deletions src/HasChildren.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,49 @@

trait HasChildren
{
protected static $parentBootMethods;

protected $hasChildren = true;

protected static function registerModelEvent($event, $callback)
{
parent::registerModelEvent($event, $callback);

if (static::class === self::class && property_exists(self::class, 'childTypes')) {
foreach ((new self)->childTypes as $childClass) {
$childClass::registerModelEvent($event, $callback);
// We don't want to register the callbacks that happen in the boot method of the parent, as they'll be called
// from the child's boot method as well.
if (! self::parentIsBooting()) {
foreach ((new self)->childTypes as $childClass) {
$childClass::registerModelEvent($event, $callback);
}
}
}
}

protected static function parentIsBooting()
{
if (! isset(self::$parentBootMethods)) {
self::$parentBootMethods[] = 'boot';

foreach (class_uses_recursive(self::class) as $trait) {
self::$parentBootMethods[] = 'boot'.class_basename($trait);
}

self::$parentBootMethods = array_flip(self::$parentBootMethods);
}

foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $trace) {
$class = isset($trace['class']) ? $trace['class'] : null;
$function = isset($trace['function']) ? $trace['function'] : '';

if ($class === self::class && isset(self::$parentBootMethods[$function])) {
return true;
}
}

return false;
}

public function newInstance($attributes = [], $exists = false)
{
$model = isset($attributes[$this->getInheritanceColumn()])
Expand Down
10 changes: 10 additions & 0 deletions tests/Features/ParentsObserveChildrenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,14 @@ public function registering_events_on_child_doesnt_affect_parent()
$train = Train::create();
$this->assertNull($train->driver_id);
}

/** @test */
public function registering_events_in_parent_boot_only_triggers_once()
{
$vehicle = Vehicle::create();
$this->assertEquals(1, $vehicle->boot_count);

$car = Car::create();
$this->assertEquals(1, $car->boot_count);
}
}
9 changes: 9 additions & 0 deletions tests/Models/Vehicle.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ class Vehicle extends Model

protected $guarded = [];

protected static function boot()
{
parent::boot();

static::created(function ($model) {
$model->boot_count = $model->boot_count ? $model->boot_count + 1 : 1;
});
}

public function driver()
{
return $this->belongsTo(Driver::class);
Expand Down

0 comments on commit bb7d1bc

Please sign in to comment.