Initial project
This commit is contained in:
83
app/Models/Conversation.php
Normal file
83
app/Models/Conversation.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Database\Factories\ConversationFactory;
|
||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
#[Fillable(['created_by_id', 'type', 'name', 'description'])]
|
||||
class Conversation extends Model
|
||||
{
|
||||
/** @use HasFactory<ConversationFactory> */
|
||||
use HasFactory;
|
||||
|
||||
public const string TypeDirect = 'direct';
|
||||
|
||||
public const string TypeGroup = 'group';
|
||||
|
||||
/**
|
||||
* @return BelongsTo<User, $this>
|
||||
*/
|
||||
public function creator(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'created_by_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasMany<ConversationParticipant, $this>
|
||||
*/
|
||||
public function participants(): HasMany
|
||||
{
|
||||
return $this->hasMany(ConversationParticipant::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsToMany<User, $this>
|
||||
*/
|
||||
public function users(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(User::class, 'conversation_participants')
|
||||
->withPivot(['role', 'joined_at', 'last_read_at', 'muted_until'])
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasMany<Message, $this>
|
||||
*/
|
||||
public function messages(): HasMany
|
||||
{
|
||||
return $this->hasMany(Message::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasOne<Message, $this>
|
||||
*/
|
||||
public function latestMessage(): HasOne
|
||||
{
|
||||
return $this->hasOne(Message::class)->latestOfMany();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Builder<Conversation> $query
|
||||
* @return Builder<Conversation>
|
||||
*/
|
||||
public function scopeForUser(Builder $query, User|int $user): Builder
|
||||
{
|
||||
$userId = $user instanceof User ? $user->id : $user;
|
||||
|
||||
return $query->whereHas('participants', fn (Builder $participants) => $participants
|
||||
->where('user_id', $userId));
|
||||
}
|
||||
|
||||
public function isGroup(): bool
|
||||
{
|
||||
return $this->type === self::TypeGroup;
|
||||
}
|
||||
}
|
||||
48
app/Models/ConversationParticipant.php
Normal file
48
app/Models/ConversationParticipant.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Database\Factories\ConversationParticipantFactory;
|
||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
#[Fillable(['conversation_id', 'user_id', 'role', 'joined_at', 'last_read_at', 'muted_until'])]
|
||||
class ConversationParticipant extends Model
|
||||
{
|
||||
/** @use HasFactory<ConversationParticipantFactory> */
|
||||
use HasFactory;
|
||||
|
||||
public const string RoleAdmin = 'admin';
|
||||
|
||||
public const string RoleMember = 'member';
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'joined_at' => 'datetime',
|
||||
'last_read_at' => 'datetime',
|
||||
'muted_until' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo<Conversation, $this>
|
||||
*/
|
||||
public function conversation(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Conversation::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo<User, $this>
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
53
app/Models/Message.php
Normal file
53
app/Models/Message.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Database\Factories\MessageFactory;
|
||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
#[Fillable(['conversation_id', 'user_id', 'type', 'body', 'metadata', 'edited_at'])]
|
||||
class Message extends Model
|
||||
{
|
||||
/** @use HasFactory<MessageFactory> */
|
||||
use HasFactory;
|
||||
|
||||
public const string TypeText = 'text';
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'metadata' => 'array',
|
||||
'edited_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo<Conversation, $this>
|
||||
*/
|
||||
public function conversation(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Conversation::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo<User, $this>
|
||||
*/
|
||||
public function sender(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo<User, $this>
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
74
app/Models/User.php
Normal file
74
app/Models/User.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Database\Factories\UserFactory;
|
||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||
use Illuminate\Database\Eloquent\Attributes\Hidden;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Str;
|
||||
use Laravel\Fortify\TwoFactorAuthenticatable;
|
||||
|
||||
#[Fillable(['name', 'email', 'password'])]
|
||||
#[Hidden(['password', 'two_factor_secret', 'two_factor_recovery_codes', 'remember_token'])]
|
||||
class User extends Authenticatable
|
||||
{
|
||||
/** @use HasFactory<UserFactory> */
|
||||
use HasFactory, Notifiable, TwoFactorAuthenticatable;
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasMany<ConversationParticipant, $this>
|
||||
*/
|
||||
public function conversationParticipants(): HasMany
|
||||
{
|
||||
return $this->hasMany(ConversationParticipant::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsToMany<Conversation, $this>
|
||||
*/
|
||||
public function conversations(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Conversation::class, 'conversation_participants')
|
||||
->withPivot(['role', 'joined_at', 'last_read_at', 'muted_until'])
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HasMany<Message, $this>
|
||||
*/
|
||||
public function messages(): HasMany
|
||||
{
|
||||
return $this->hasMany(Message::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user's initials
|
||||
*/
|
||||
public function initials(): string
|
||||
{
|
||||
return Str::of($this->name)
|
||||
->explode(' ')
|
||||
->take(2)
|
||||
->map(fn ($word) => Str::substr($word, 0, 1))
|
||||
->implode('');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user