Skip to main content
The Participant model represents a user’s participation in a conversation. It handles roles, permissions, read receipts, and user-specific conversation state.

Namespace

Wirechat\Wirechat\Models\Participant

Properties

id
int
Unique identifier for the participant
conversation_id
int
ID of the conversation
participantable_id
int
ID of the underlying user model
participantable_type
string
Class name of the user model (polymorphic)
role
ParticipantRole
Role in the conversation: OWNER, ADMIN, or PARTICIPANT
exited_at
Carbon|null
Timestamp when participant exited the group
last_active_at
Carbon|null
Last activity timestamp
conversation_cleared_at
Carbon|null
Timestamp when participant cleared the conversation history
conversation_deleted_at
Carbon|null
Timestamp when participant deleted the conversation
conversation_read_at
Carbon|null
Timestamp when participant last read the conversation
created_at
Carbon|null
Participant creation timestamp
updated_at
Carbon|null
Last update timestamp

Relationships

participantable()

Get the underlying user model.
public function participantable(): MorphTo
return
MorphTo
Polymorphic relationship to the user model
Example:
$participant = Participant::find(1);
$user = $participant->participantable;
echo $user->name; // Access user properties

conversation()

Get the conversation this participant belongs to.
public function conversation(): BelongsTo
return
BelongsTo
Relationship to Conversation model

messages()

Get all messages sent by this participant.
public function messages(): HasMany
return
HasMany
Relationship to Message models

latestMessage()

Get the most recent message from this participant.
public function latestMessage(): HasOne
return
HasOne
Relationship to the latest Message

Role Methods

isAdmin()

Check if the participant is an admin (ADMIN or OWNER role).
public function isAdmin(): bool
return
bool
True if participant has ADMIN or OWNER role
Example:
if ($participant->isAdmin()) {
    // Allow admin actions
    echo "User has admin privileges";
}

isOwner()

Check if the participant is the owner.
public function isOwner(): bool
return
bool
True if participant has OWNER role
Example:
if ($participant->isOwner()) {
    // Allow owner-only actions
    echo "User is the group owner";
}

Conversation State

exitConversation()

Mark the participant as having exited the conversation.
public function exitConversation(): bool
return
bool
True if successfully exited, false if already exited
Example:
$participant->exitConversation();
// User is now marked as exited from the group

hasExited()

Check if the participant has exited the conversation.
public function hasExited(): bool
return
bool
True if the participant has exited

hasDeletedConversation()

Check if the participant has deleted the conversation.
public function hasDeletedConversation(bool $checkDeletionExpired = false): bool
checkDeletionExpired
bool
default:"false"
If true, checks if deletion is still valid (conversation hasn’t been updated since deletion)
return
bool
True if conversation is deleted (and valid if checking expiration)
Example:
// Simple check
if ($participant->hasDeletedConversation()) {
    echo "Conversation is marked as deleted";
}

// Check if deletion is still valid
if ($participant->hasDeletedConversation(checkDeletionExpired: true)) {
    echo "Conversation is deleted and no new activity";
}

Admin Actions

isRemovedByAdmin()

Check if the participant was removed by an admin.
public function isRemovedByAdmin(): bool
return
bool
True if removed by admin

removeByAdmin()

Remove the participant from the conversation as an admin action.
public function removeByAdmin(Model|Authenticatable $admin): void
admin
Model|Authenticatable
required
The admin user performing the removal
Example:
$adminUser = auth()->user();
$participant->removeByAdmin($adminUser);
// Participant is removed and action is logged

Query Scopes

whereParticipantable()

Scope to filter by the underlying user model.
public function scopeWhereParticipantable(Builder $query, Model|Authenticatable $model): void
query
Builder
required
The query builder instance
model
Model|Authenticatable
required
The user model to filter by
Example:
$userParticipants = Participant::whereParticipantable($user)->get();

withExited()

Include exited participants in the query (removes global scope).
public function scopeWithExited(Builder $query): void
Example:
// Get all participants including those who exited
$allParticipants = Participant::withExited()->get();

withoutParticipantable()

Exclude a specific user from the query.
public function scopeWithoutParticipantable($query, Model|Authenticatable $user): Builder
query
Builder
required
The query builder instance
user
Model|Authenticatable
required
The user to exclude
Example:
// Get all participants except the current user
$otherParticipants = $conversation->participants()
    ->withoutParticipantable(auth()->user())
    ->get();

Example Usage

use Wirechat\Wirechat\Models\Participant;
use Wirechat\Wirechat\Enums\ParticipantRole;

// Get participant's user
$participant = Participant::find(1);
$user = $participant->participantable;
echo "Name: {$user->name}";

// Check role
if ($participant->isAdmin()) {
    echo "Has admin privileges";
}

// Get conversation
$conversation = $participant->conversation;
echo "Conversation type: {$conversation->type->value}";

Global Scopes

Notes

  • Participants are polymorphic - they can relate to any user model
  • The withoutExited global scope filters out exited participants by default
  • Deleting a participant also deletes associated actions
  • Role is automatically downgraded when exiting or being removed
  • Owner role has all admin permissions plus owner-specific actions
  • Last activity and read timestamps enable read receipts and online status