'boolean', 'metadata' => 'array', 'security_meta' => 'array', 'security_scanned_at' => 'datetime', 'moderated_at' => 'datetime', 'live_status' => PhotoLiveStatus::class, 'live_submitted_at' => 'datetime', 'live_approved_at' => 'datetime', 'live_reviewed_at' => 'datetime', ]; protected $attributes = [ 'security_scan_status' => 'pending', 'ingest_source' => self::SOURCE_GUEST_PWA, 'live_status' => PhotoLiveStatus::NONE->value, ]; public function mediaAsset(): BelongsTo { return $this->belongsTo(EventMediaAsset::class, 'media_asset_id'); } public function getImagePathAttribute(): ?string { return $this->file_path; } public function setImagePathAttribute(string $value): void { $this->attributes['file_path'] = $value; } public function event(): BelongsTo { return $this->belongsTo(Event::class); } public function emotion(): BelongsTo { return $this->belongsTo(Emotion::class); } public function task(): BelongsTo { return $this->belongsTo(Task::class); } public function moderator(): BelongsTo { return $this->belongsTo(User::class, 'moderated_by'); } public function liveReviewer(): BelongsTo { return $this->belongsTo(User::class, 'live_reviewed_by'); } public function markLivePending(): void { $this->forceFill([ 'live_status' => PhotoLiveStatus::PENDING, 'live_submitted_at' => now(), 'live_approved_at' => null, 'live_reviewed_at' => null, 'live_reviewed_by' => null, 'live_rejection_reason' => null, ])->save(); } public function approveForLiveShow(?User $reviewer = null): void { $now = now(); $this->forceFill([ 'live_status' => PhotoLiveStatus::APPROVED, 'live_approved_at' => $now, 'live_reviewed_at' => $now, 'live_reviewed_by' => $reviewer?->id, 'live_rejection_reason' => null, ])->save(); } public function rejectForLiveShow(?User $reviewer = null, ?string $reason = null): void { $now = now(); $this->forceFill([ 'live_status' => PhotoLiveStatus::REJECTED, 'live_approved_at' => null, 'live_reviewed_at' => $now, 'live_reviewed_by' => $reviewer?->id, 'live_rejection_reason' => $reason, ])->save(); } public function clearFromLiveShow(?User $reviewer = null): void { $this->forceFill([ 'live_status' => PhotoLiveStatus::NONE, 'live_approved_at' => null, 'live_reviewed_at' => now(), 'live_reviewed_by' => $reviewer?->id, 'live_rejection_reason' => null, ])->save(); } public function likes(): HasMany { return $this->hasMany(PhotoLike::class); } public function shareLinks(): HasMany { return $this->hasMany(PhotoShareLink::class); } public static function supportsFilenameColumn(): bool { return static::hasColumn('filename'); } public static function hasColumn(string $column): bool { if (static::$columnCache === null) { static::$columnCache = Schema::getColumnListing((new self)->getTable()); } return in_array($column, static::$columnCache, true); } public function tenant(): BelongsToThroughRelation { return $this->belongsToThrough( Tenant::class, Event::class ); } }