Files
construprogress/app/Models/Comment.php
T

102 lines
2.8 KiB
PHP
Raw Normal View History

<?php
namespace App\Models;
use App\Notifications\TaskCommentNotification;
use App\Traits\LogsActivity;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
class Comment extends Model
{
use HasFactory, LogsActivity;
protected $fillable = [
'commentable_type',
'commentable_id',
'user_id',
'body',
'parent_id',
];
protected $casts = [
'body' => 'string',
];
// ============================================================
// Events / Observers
// ============================================================
protected static function booted(): void
{
static::created(function (Comment $comment) {
// Notify if comment is on a Task
if ($comment->commentable_type === Task::class) {
$task = $comment->commentable;
if ($task) {
// Notify creator and assignee (except the commenter)
$usersToNotify = collect([$task->creator, $task->assignee])
->unique('id')
->filter(fn ($u) => $u && $u->id !== $comment->user_id);
foreach ($usersToNotify as $user) {
$user->notify(new TaskCommentNotification($task, $comment));
}
}
}
});
}
// ============================================================
// Relationships
// ============================================================
public function commentable(): MorphTo
{
return $this->morphTo();
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function parent(): BelongsTo
{
return $this->belongsTo(Comment::class, 'parent_id');
}
public function replies(): HasMany
{
return $this->hasMany(Comment::class, 'parent_id')->orderBy('created_at');
}
// ============================================================
// Scopes
// ============================================================
public function scopeTopLevel($query)
{
return $query->whereNull('parent_id');
}
public function scopeWithReplies($query)
{
return $query->with('replies.user');
}
// ============================================================
// Accessors
// ============================================================
public function getExcerptAttribute(): string
{
return strlen($this->body) > 150
? substr($this->body, 0, 150).'...'
: $this->body;
}
}