<?php namespace Common\Comments; use App\Models\Episode; use App\Models\User; use Common\Core\BaseModel; use Common\Files\Traits\HandlesEntryPaths; use Common\Votes\OrdersByWeightedScore; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\MorphTo; class Comment extends BaseModel { use HandlesEntryPaths, HasFactory, OrdersByWeightedScore; const MODEL_TYPE = 'comment'; protected $guarded = ['id']; protected $hidden = ['commentable_type', 'commentable_id', 'path']; protected $casts = [ 'id' => 'integer', 'user_id' => 'integer', 'deleted' => 'boolean', ]; protected $appends = ['depth', 'model_type']; public function votes(): HasMany { return $this->hasMany(CommentVote::class); } public function reports(): HasMany { return $this->hasMany(CommentReport::class); } public function user(): BelongsTo { return $this->belongsTo(User::class); } public function commentable(): MorphTo { return $this->morphTo(); } public function scopeRootOnly(Builder $builder): Builder { return $builder->whereNull('parent_id'); } public function scopeChildrenOnly(Builder $builder): Builder { return $builder->whereNotNull('parent_id'); } public function scopeForCommentable(Builder $builder, $commentable): Builder { return $builder->when( config('common.site.demo'), // load comments for this commentable as well as demo comments function (Builder $builder) use ($commentable) { $builder->where(function (Builder $builder) use ($commentable) { $builder ->where(function (Builder $builder) use ($commentable) { $type = $commentable instanceof Episode ? 'episode' : ($commentable->is_series ? 'series' : 'movie'); $builder ->where('commentable_id', 0) ->where('commentable_type', "demo-$type"); }) ->orWhere(function (Builder $builder) use ( $commentable, ) { $builder ->where('commentable_id', $commentable->id) ->where( 'commentable_type', $commentable->getMorphClass(), ); }); }); }, // load comments for this commentable only function (Builder $builder) use ($commentable) { $builder ->where('commentable_id', $commentable->id) ->where('commentable_type', $commentable->getMorphClass()); }, ); } public function getDepthAttribute(): int { if (!$this->path || !$this->parent_id) { return 0; } return count(explode('/', $this->getRawOriginal('path'))); } public function toNormalizedArray(): array { return [ 'id' => $this->id, 'name' => $this->content, 'model_type' => self::MODEL_TYPE, ]; } public function toSearchableArray(): array { return [ 'id' => $this->id, 'content' => $this->content, 'parent_id' => $this->parent_id, 'user_id' => $this->user_id, 'deleted' => $this->deleted, 'commentable_id' => $this->commentable_id, 'commentable_type' => $this->commentable_type, 'created_at' => $this->created_at->timestamp ?? '_null', 'updated_at' => $this->updated_at->timestamp ?? '_null', ]; } public static function filterableFields(): array { return [ 'id', 'parent_id', 'user_id', 'deleted', 'commentable_id', 'commentable_type', 'created_at', 'updated_at', ]; } protected static function newFactory() { return CommentFactory::new(); } public static function getModelTypeAttribute(): string { return self::MODEL_TYPE; } }