*/ public function toArray(Request $request): array { $tenantId = $request->attributes->get('tenant_id'); $showSensitive = $this->event->tenant_id === $tenantId; $fullUrl = $this->getSignedUrl('full'); $thumbnailUrl = $this->getSignedUrl('thumbnail'); return [ 'id' => $this->id, 'filename' => $this->filename, 'original_name' => $this->original_name, 'mime_type' => $this->mime_type, 'size' => (int) ($this->size ?? 0), 'url' => $showSensitive ? ($fullUrl ?? $thumbnailUrl) : ($thumbnailUrl ?? $fullUrl), 'thumbnail_url' => $thumbnailUrl ?? $fullUrl, 'width' => $this->width, 'height' => $this->height, 'is_featured' => (bool) ($this->is_featured ?? false), 'status' => $showSensitive ? $this->status : 'approved', 'moderation_notes' => $showSensitive ? $this->moderation_notes : null, 'likes_count' => (int) ($this->likes_count ?? $this->likes()->count()), 'is_liked' => false, 'uploaded_at' => $this->created_at->toISOString(), 'uploader_name' => $this->guest_name ?? null, 'ingest_source' => $this->ingest_source, 'event' => [ 'id' => $this->event->id, 'name' => $this->event->name, 'slug' => $this->event->slug, ], ]; } /** * Get signed URL for variant */ private function getSignedUrl(string $variant): ?string { if (empty($this->id) || empty($this->event?->slug)) { return null; } $route = $variant === 'thumbnail' ? 'api.v1.gallery.photos.asset' : 'api.v1.gallery.photos.asset'; return \URL::temporarySignedRoute( $route, now()->addMinutes(30), [ 'token' => $this->event->slug, // tenant/admin views are trusted; token not used server-side for signed validation 'photo' => $this->id, 'variant' => $variant === 'thumbnail' ? 'thumbnail' : 'full', ] ); } }