*/ use HasFactory; use SoftDeletes; protected $guarded = []; /** * Laravel derives a factory's name by stripping the App\Models prefix, * which this module-namespaced model does not have — so name it here * rather than have the lookup miss. */ protected static function newFactory(): FileCommentFactory { return FileCommentFactory::new(); } protected function casts(): array { return [ 'visibility' => CommentVisibility::class, 'approved_at' => 'datetime', 'edited_at' => 'datetime', ]; } /** * @return BelongsTo */ public function file(): BelongsTo { return $this->belongsTo(File::class); } /** * @return BelongsTo */ public function author(): BelongsTo { return $this->belongsTo(User::class, 'author_id'); } /** * The client whose conversation this comment belongs to — not its * author. * * Null means the comment is not one client's: a Clients comment with no * context is staff addressing everyone on the file, and OnlyMe / * StaffOnly / Everyone have no client in them to begin with. A * staff-only note is its own audience now, not a null context. * * @return BelongsTo */ public function clientContext(): BelongsTo { return $this->belongsTo(User::class, 'client_context_id'); } public function isPending(): bool { return $this->approved_at === null; } public function isFromGuest(): bool { return $this->author_id === null; } /** * The name to show. Snapshotted for guests at write time; read live * for accounts so a rename is reflected everywhere at once. * * author_id cascades on delete, so a row that has one always has the * account behind it — there is no deleted-author case to snapshot * against, unlike the activity log's actor_name. */ public function authorName(): string { $author = $this->author; if ($author !== null) { return $author->name; } return $this->guest_name ?? (string) __('Anonymous'); } }