-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[8.x] More Convenient Model Broadcasting (#37491)
* Initial commit of model broadcasting conveniences * allow null return from broadcaston * add broadcast methods * Allow HasBroadcastChannel instances in routes This allows HasBroadcastChannel instances to be passed to broadcast routes. * Rename method * Do not broadcast if no channels for model event * add trait * use model basename * allow manual override of channels * add test * add test * allow specification of connection, queue, afterCommit * wip
- Loading branch information
1 parent
db89ad5
commit 71a83fb
Showing
9 changed files
with
404 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
src/Illuminate/Contracts/Broadcasting/HasBroadcastChannel.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace Illuminate\Contracts\Broadcasting; | ||
|
||
interface HasBroadcastChannel | ||
{ | ||
/** | ||
* Get the broadcast channel route definition that is associated with the given entity. | ||
* | ||
* @return string | ||
*/ | ||
public function broadcastChannelRoute(); | ||
|
||
/** | ||
* Get the broadcast channel name that is associated with the given entity. | ||
* | ||
* @return string | ||
*/ | ||
public function broadcastChannel(); | ||
} |
100 changes: 100 additions & 0 deletions
100
src/Illuminate/Database/Eloquent/BroadcastableModelEventOccurred.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
<?php | ||
|
||
namespace Illuminate\Database\Eloquent; | ||
|
||
use Illuminate\Broadcasting\InteractsWithSockets; | ||
use Illuminate\Broadcasting\PrivateChannel; | ||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast; | ||
use Illuminate\Queue\SerializesModels; | ||
|
||
class BroadcastableModelEventOccurred implements ShouldBroadcast | ||
{ | ||
use InteractsWithSockets, SerializesModels; | ||
|
||
/** | ||
* The model instance corresponding to the event. | ||
* | ||
* @var \Illuminate\Database\Eloquent\Model | ||
*/ | ||
public $model; | ||
|
||
/** | ||
* The event name (created, updated, etc.). | ||
* | ||
* @var string | ||
*/ | ||
protected $event; | ||
|
||
/** | ||
* The channels that the event should be broadcast on. | ||
* | ||
* @var array | ||
*/ | ||
protected $channels = []; | ||
|
||
/** | ||
* The queue connection that should be used to queue the broadcast job. | ||
* | ||
* @var string | ||
*/ | ||
public $connection; | ||
|
||
/** | ||
* The queue that should be used to queue the broadcast job. | ||
* | ||
* @var string | ||
*/ | ||
public $queue; | ||
|
||
/** | ||
* Create a new event instance. | ||
* | ||
* @param \Illuminate\Database\Eloquent\Model $model | ||
* @param string $event | ||
* @return void | ||
*/ | ||
public function __construct($model, $event) | ||
{ | ||
$this->model = $model; | ||
$this->event = $event; | ||
} | ||
|
||
/** | ||
* The channels the event should broadcast on. | ||
* | ||
* @return array | ||
*/ | ||
public function broadcastOn() | ||
{ | ||
$channels = empty($this->channels) | ||
? ($this->model->broadcastOn($this->event) ?: []) | ||
: $this->channels; | ||
|
||
return collect($channels)->map(function ($channel) { | ||
return $channel instanceof Model ? new PrivateChannel($channel) : $channel; | ||
})->all(); | ||
} | ||
|
||
/** | ||
* The name the event should broadcast as. | ||
* | ||
* @return string | ||
*/ | ||
public function broadcastAs() | ||
{ | ||
return class_basename($this->model).ucfirst($this->event); | ||
} | ||
|
||
/** | ||
* Manually specify the channels the event should broadcast on. | ||
* | ||
* @param array $channels | ||
* @return $this | ||
*/ | ||
public function onChannels(array $channels) | ||
{ | ||
$this->channels = $channels; | ||
|
||
return $this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
<?php | ||
|
||
namespace Illuminate\Database\Eloquent; | ||
|
||
use Illuminate\Support\Arr; | ||
|
||
trait BroadcastsEvents | ||
{ | ||
/** | ||
* Boot the event broadcasting trait. | ||
* | ||
* @return void | ||
*/ | ||
public static function bootBroadcastsEvents() | ||
{ | ||
static::created(function ($model) { | ||
$model->broadcastCreated(); | ||
}); | ||
|
||
static::updated(function ($model) { | ||
$model->broadcastUpdated(); | ||
}); | ||
|
||
if (method_exists(static::class, 'bootSoftDeletes')) { | ||
static::trashed(function ($model) { | ||
$model->broadcastTrashed(); | ||
}); | ||
|
||
static::restored(function ($model) { | ||
$model->broadcastRestored(); | ||
}); | ||
} | ||
|
||
static::deleted(function ($model) { | ||
$model->broadcastDeleted(); | ||
}); | ||
} | ||
|
||
/** | ||
* Broadcast that the model was created. | ||
* | ||
* @param \Illuminate\Broadcasting\Channel|\Illuminate\Contracts\Broadcasting\HasBroadcastChannel|array|null $channels | ||
* @return \Illuminate\Broadcasting\PendingBroadcast | ||
*/ | ||
public function broadcastCreated($channels = null) | ||
{ | ||
return $this->broadcastIfBroadcastChannelsExistForEvent( | ||
$this->newBroadcastableModelEvent('created'), 'created', $channels | ||
); | ||
} | ||
|
||
/** | ||
* Broadcast that the model was updated. | ||
* | ||
* @param \Illuminate\Broadcasting\Channel|\Illuminate\Contracts\Broadcasting\HasBroadcastChannel|array|null $channels | ||
* @return \Illuminate\Broadcasting\PendingBroadcast | ||
*/ | ||
public function broadcastUpdated($channels = null) | ||
{ | ||
return $this->broadcastIfBroadcastChannelsExistForEvent( | ||
$this->newBroadcastableModelEvent('updated'), 'updated', $channels | ||
); | ||
} | ||
|
||
/** | ||
* Broadcast that the model was trashed. | ||
* | ||
* @param \Illuminate\Broadcasting\Channel|\Illuminate\Contracts\Broadcasting\HasBroadcastChannel|array|null $channels | ||
* @return \Illuminate\Broadcasting\PendingBroadcast | ||
*/ | ||
public function broadcastTrashed($channels = null) | ||
{ | ||
return $this->broadcastIfBroadcastChannelsExistForEvent( | ||
$this->newBroadcastableModelEvent('trashed'), 'trashed', $channels | ||
); | ||
} | ||
|
||
/** | ||
* Broadcast that the model was restored. | ||
* | ||
* @param \Illuminate\Broadcasting\Channel|\Illuminate\Contracts\Broadcasting\HasBroadcastChannel|array|null $channels | ||
* @return \Illuminate\Broadcasting\PendingBroadcast | ||
*/ | ||
public function broadcastRestored($channels = null) | ||
{ | ||
return $this->broadcastIfBroadcastChannelsExistForEvent( | ||
$this->newBroadcastableModelEvent('restored'), 'restored', $channels | ||
); | ||
} | ||
|
||
/** | ||
* Broadcast that the model was deleted. | ||
* | ||
* @param \Illuminate\Broadcasting\Channel|\Illuminate\Contracts\Broadcasting\HasBroadcastChannel|array|null $channels | ||
* @return \Illuminate\Broadcasting\PendingBroadcast | ||
*/ | ||
public function broadcastDeleted($channels = null) | ||
{ | ||
return $this->broadcastIfBroadcastChannelsExistForEvent( | ||
$this->newBroadcastableModelEvent('deleted'), 'deleted', $channels | ||
); | ||
} | ||
|
||
/** | ||
* Broadcast the given event instance if channels are configured for the model event. | ||
* | ||
* @param mixed $instance | ||
* @param string $event | ||
* @param mixed $channels | ||
* @return \Illuminate\Broadcasting\PendingBroadcast|null | ||
*/ | ||
protected function broadcastIfBroadcastChannelsExistForEvent($instance, $event, $channels = null) | ||
{ | ||
if (! empty($this->broadcastOn($event)) || ! empty($channels)) { | ||
return broadcast($instance->onChannels(Arr::wrap($channels))); | ||
} | ||
} | ||
|
||
/** | ||
* Create a new broadcastable model event event. | ||
* | ||
* @param string $event | ||
* @return mixed | ||
*/ | ||
public function newBroadcastableModelEvent($event) | ||
{ | ||
return tap(new BroadcastableModelEventOccurred($this, $event), function ($event) { | ||
$event->connection = property_exists($this, 'broadcastConnection') | ||
? $this->broadcastConnection | ||
: $this->broadcastConnection(); | ||
|
||
$event->queue = property_exists($this, 'broadcastQueue') | ||
? $this->broadcastQueue | ||
: $this->broadcastQueue(); | ||
|
||
$event->afterCommit = property_exists($this, 'broadcastAfterCommit') | ||
? $this->broadcastAfterCommit | ||
: $this->broadcastAfterCommit(); | ||
}); | ||
} | ||
|
||
/** | ||
* Get the channels that model events should broadcast on. | ||
* | ||
* @param string $event | ||
* @return \Illuminate\Broadcasting\Channel|array | ||
*/ | ||
public function broadcastOn($event) | ||
{ | ||
return [$this]; | ||
} | ||
|
||
/** | ||
* Get the queue connection that should be used to broadcast model events. | ||
* | ||
* @return string|null | ||
*/ | ||
public function broadcastConnection() | ||
{ | ||
// | ||
} | ||
|
||
/** | ||
* Get the queue that should be used to broadcast model events. | ||
* | ||
* @return string|null | ||
*/ | ||
public function broadcastQueue() | ||
{ | ||
// | ||
} | ||
|
||
/** | ||
* Determine if the model event broadcast queued job should be dispatched after all transactions are committed. | ||
* | ||
* @return bool | ||
*/ | ||
public function broadcastAfterCommit() | ||
{ | ||
return false; | ||
} | ||
} |
Oops, something went wrong.