The Message model represents individual messages within conversations. It supports text messages, attachments, replies, and disappearing messages.
Namespace
Wirechat\Wirechat\Models\Message
Properties
Unique identifier for the message
ID of the conversation this message belongs to
ID of the participant who sent the message
ID of the message being replied to (if this is a reply)
Type of message (TEXT, ATTACHMENT, etc.)
Timestamp when message was kept from disappearing
Message creation timestamp
Relationships
conversation()
Get the conversation this message belongs to.
public function conversation(): BelongsTo
Relationship to Conversation model
Example:
$conversation = $message->conversation;
echo $conversation->type;
participant()
Get the participant who sent the message.
public function participant(): BelongsTo
Relationship to Participant model
Example:
$participant = $message->participant;
$user = $participant->participantable;
echo $user->name;
attachment()
Get the attachment associated with this message.
public function attachment(): MorphOne
Polymorphic relationship to Attachment model
parent()
Get the message being replied to.
public function parent(): BelongsTo
Relationship to parent Message (includes trashed)
Example:
if ($message->hasParent()) {
$parentMessage = $message->parent;
echo "Replying to: " . $parentMessage->body;
}
reply()
Get replies to this message.
public function reply(): HasOne
Relationship to reply Message
Accessors
user
Get the actual user model who sent the message.
public function getUserAttribute(): Model
The underlying user model (participantable)
Example:
$user = $message->user;
echo $user->name; // Direct access to user
sendable (Deprecated)
Legacy accessor for getting the sender. Use user instead.
public function getSendableAttribute(): Model
The user model (same as user attribute)
Message Status
readBy()
Check if the message has been read by a user.
public function readBy(Model|Participant $user): bool
user
Model|Participant
required
The user or participant to check
True if the message has been read
Example:
if ($message->readBy(auth()->user())) {
echo "Message has been read";
}
ownedBy()
Check if the message is owned by a specific user.
public function ownedBy($user): bool
The user to check ownership against
True if the message belongs to the user
belongsToAuth()
Check if the message belongs to the authenticated user.
public function belongsToAuth(): bool
True if the message belongs to the authenticated user
Attachment Methods
hasAttachment()
Check if the message has an attachment.
public function hasAttachment(): bool
True if an attachment exists
isAttachment()
Check if the message type is ATTACHMENT.
public function isAttachment(): bool
True if message type is ATTACHMENT
Example:
if ($message->isAttachment()) {
$attachment = $message->attachment;
echo $attachment->url;
}
Reply Methods
hasReply()
Check if this message has replies.
public function hasReply(): bool
hasParent()
Check if this message is a reply to another message.
public function hasParent(): bool
Example:
if ($message->hasParent()) {
$originalMessage = $message->parent;
echo "In reply to: {$originalMessage->body}";
}
if ($message->hasReply()) {
echo "This message has replies";
}
Message Management
deleteFor()
Delete the message for a specific user only.
public function deleteFor(Model|Authenticatable $user): bool|null
user
Model|Authenticatable
required
The user deleting the message
True if force deleted, null otherwise
Example:
// Delete for current user only
$message->deleteFor(auth()->user());
deleteForEveryone()
Delete the message for all participants.
public function deleteForEveryone(Model $user): void
The user requesting deletion (must own the message or be an admin)
Example:
// Delete for everyone (requires ownership or admin)
$message->deleteForEveryone(auth()->user());
Content Methods
isEmoji()
Check if the message body contains only emojis.
public function isEmoji(): bool
True if the message contains only emoji characters
Example:
if ($message->isEmoji()) {
// Render with larger emoji size
echo '<span class="large-emoji">' . $message->body . '</span>';
}
Query Scopes
whereIsNotOwnedBy()
Scope to exclude messages owned by a specific user.
public function scopeWhereIsNotOwnedBy($query, Model|Authenticatable $user): Builder
The query builder instance
user
Model|Authenticatable
required
The user to exclude
Example:
// Get messages not sent by current user
$messages = Message::whereIsNotOwnedBy(auth()->user())->get();
Example Usage
Basic Usage
Replies
Attachments
Deletion
use Wirechat\Wirechat\Models\Message;
// Create a message
$message = Message::create([
'conversation_id' => $conversation->id,
'participant_id' => $participant->id,
'body' => 'Hello, world!',
'type' => MessageType::TEXT,
]);
// Check ownership
if ($message->ownedBy(auth()->user())) {
echo "You sent this message";
}
// Get sender
$sender = $message->user;
echo "Sent by: {$sender->name}";
// Create a reply
$reply = Message::create([
'conversation_id' => $conversation->id,
'participant_id' => $participant->id,
'reply_id' => $originalMessage->id,
'body' => 'This is a reply',
'type' => MessageType::TEXT,
]);
// Check if it's a reply
if ($reply->hasParent()) {
$parent = $reply->parent;
echo "Replying to: {$parent->body}";
}
// Check for attachments
if ($message->isAttachment()) {
$attachment = $message->attachment;
echo "File: {$attachment->original_name}";
echo "URL: {$attachment->url}";
echo "Type: {$attachment->mime_type}";
}
// Delete for current user only
$message->deleteFor(auth()->user());
// Delete for everyone (requires permission)
if ($message->ownedBy(auth()->user()) || $participant->isAdmin()) {
$message->deleteForEveryone(auth()->user());
}
Notes
- Messages are soft-deleted by default using Laravel’s
SoftDeletes trait
- The
WithoutRemovedMessages global scope automatically filters deleted messages
- Deleting a message also deletes its attachment and associated actions
- Messages with replies are only soft-deleted, not force-deleted
- In private conversations, messages are force-deleted when both participants delete them