* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0 */ namespace App\Models; use App\Traits\Auditable; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; /** * App\Models\Topic. * * @property int $id * @property string $name * @property string|null $state * @property int $priority * @property bool $approved * @property bool $denied * @property bool $solved * @property bool $invalid * @property bool $bug * @property bool $suggestion * @property bool $implemented * @property int|null $num_post * @property int|null $first_post_user_id * @property int|null $last_post_id * @property int|null $last_post_user_id * @property \Illuminate\Support\Carbon|null $last_post_created_at * @property int|null $views * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property int $forum_id */ class Topic extends Model { use Auditable; /** @use HasFactory<\Database\Factories\TopicFactory> */ use HasFactory; protected $guarded = []; /** * Get the attributes that should be cast. * * @return array{last_post_created_at: 'datetime', priority: 'integer', approved: 'bool', denied: 'bool', solved: 'bool', invalid: 'bool', bug: 'bool', suggestion: 'bool', implemented: 'bool'} */ protected function casts(): array { return [ 'last_post_created_at' => 'datetime', 'priority' => 'integer', 'approved' => 'bool', 'denied' => 'bool', 'solved' => 'bool', 'invalid' => 'bool', 'bug' => 'bool', 'suggestion' => 'bool', 'implemented' => 'bool', ]; } /** * Belongs To A Forum. * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function forum(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Forum::class); } /** * Belongs To A User. * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(User::class, 'first_post_user_id', 'id'); } /** * Has Many Posts. * * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function posts(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(Post::class); } /** * Has Many Posts. * * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function reads(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(TopicRead::class); } /** * Has Many Subscriptions. * * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function subscriptions(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(Subscription::class); } /** * Has One Permissions through Forum. * * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function forumPermissions(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(ForumPermission::class, 'forum_id', 'forum_id'); } /** * Belongs to Many Subscribed Users. * * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function subscribedUsers(): \Illuminate\Database\Eloquent\Relations\BelongsToMany { return $this->belongsToMany(User::class, Subscription::class); } /** * Latest post. * * @return \Illuminate\Database\Eloquent\Relations\HasOne */ public function latestPostSlow(): \Illuminate\Database\Eloquent\Relations\HasOne { return $this->hasOne(Post::class)->latestOfMany(); } /** * Latest post. * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function latestPost(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Post::class, 'last_post_id'); } /** * Latest poster. * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function latestPoster(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(User::class, 'last_post_user_id'); } /** * Only include topics a user is authorized to. * * @param \Illuminate\Database\Eloquent\Builder $query * @return \Illuminate\Database\Eloquent\Builder */ public function scopeAuthorized( \Illuminate\Database\Eloquent\Builder $query, ?bool $canReadTopic = null, ?bool $canReplyTopic = null, ?bool $canStartTopic = null, ): \Illuminate\Database\Eloquent\Builder { return $query ->whereRelation( 'forumPermissions', fn ($query) => $query ->where('group_id', '=', auth()->user()->group_id) ->when($canReadTopic !== null, fn ($query) => $query->where('read_topic', '=', $canReadTopic)) ->when($canReplyTopic !== null, fn ($query) => $query->where('reply_topic', '=', $canReplyTopic)) ->when($canStartTopic !== null, fn ($query) => $query->where('start_topic', '=', $canStartTopic)) ) ->when($canReplyTopic && !auth()->user()->group->is_modo, fn ($query) => $query->where('state', '=', 'open')); } /** * Does User Have Permission To View Topic. */ public function viewable(): bool { if (auth()->user()->group->is_modo) { return true; } return $this->forum->getPermission()?->read_topic ?? false; } }