Participant
Participant is the membership pivot model between a conversation and one of your application's models.
This is the model that makes Wirechat polymorphic.
It is one of the most important models to keep compatible because message visibility, role checks, and delete or clear behavior all depend on it.
Core fields:
| Field | Purpose |
|---|---|
conversation_id |
The thread this membership belongs to. |
participantable_id |
The underlying app model id. |
participantable_type |
The morph class for the underlying app model. |
role |
Participant role enum, including owner and admin. |
exited_at |
Timestamp used to mark members who left a conversation. |
last_active_at |
Participant activity timestamp. |
conversation_read_at |
Last read marker for unread logic. |
conversation_cleared_at |
Last clear-history marker. |
conversation_deleted_at |
Last delete-for-user marker. |
Important Relationships
participantable()
Returns the real app model behind the participant row.
$participant->participantable
conversation()
Returns the parent conversation.
$participant->conversation
messages()
Returns messages sent by this participant.
$participant->messages()->latest()->get()
latestMessage()
Resolves the most recent message sent by this participant.
$participant->latestMessage
actions()
Returns actions recorded against this participant row.
$participant->actions()->latest()->get()
performedActions()
Returns actions this participant performed as an actor.
$participant->performedActions()->latest()->get()
Important Helpers
isAdmin()
Returns true when the participant is an admin or the owner. The owner is also treated as an admin by Wirechat.
$participant->isAdmin()
isOwner()
Returns true only when this participant is the conversation owner.
$participant->isOwner()
exitConversation()
Marks the participant as exited while enforcing package rules such as blocking owners from leaving their own group.
$participant->exitConversation()
hasExited()
Checks whether the participant already left the conversation.
$participant->hasExited()
isRemovedByAdmin()
Checks whether an admin-removal action exists for this participant.
$participant->isRemovedByAdmin()
removeByAdmin()
Records the admin-removal action using the admin's participant row as the actor, then downgrades the removed member's role.
$participant->removeByAdmin(auth()->user())
hasDeletedConversation()
Checks whether delete-for-user is active, optionally comparing it against the conversation's latest update timestamp.
$participant->hasDeletedConversation(true)
Important Query Helpers
whereParticipantable()
Filters participant rows for a specific app model.
Participant::query()->whereParticipantable(auth()->user())->first()
withExited()
Includes participants hidden by the default exited scope.
Participant::query()->withExited()->get()
withoutParticipantable()
Excludes a specific participantable model from the query.
$conversation->participants()->withoutParticipantable(auth()->user())->get()
Typical safe customizations:
- Add participant-level profile helpers.
- Add app-specific membership metadata.
- Add convenience methods that build on role and visibility state.
- Preserve the default global scopes unless you are intentionally replacing the membership rules.