attributes->get('tenant_id'); $showSensitive = $this->tenant_id === $tenantId; $settings = is_array($this->settings) ? $this->settings : []; $settings = $this->attachWatermarkAssetUrl($settings); $eventPackage = null; $memberPermissions = null; $user = $request->user(); if ($user && $user->role === 'member') { $memberPermissions = TenantMemberPermissions::resolveEventPermissions($request, $this->resource); } if ($this->relationLoaded('eventPackages')) { $related = $this->getRelation('eventPackages'); if (! $related instanceof MissingValue) { $eventPackage = $related->first(); } } elseif ($this->relationLoaded('eventPackage')) { $related = $this->getRelation('eventPackage'); if (! $related instanceof MissingValue) { $eventPackage = $related; } } $limitEvaluator = null; if ($eventPackage) { $limitEvaluator = app()->make(PackageLimitEvaluator::class); } $settings['watermark_removal_allowed'] = WatermarkConfigResolver::determineRemovalAllowed($this->resource); return [ 'id' => $this->id, 'name' => $this->name, 'slug' => $this->slug, 'description' => $this->description, 'event_date' => $this->date ? $this->date->toISOString() : null, 'location' => $this->location, 'max_participants' => $this->max_participants, 'current_participants' => $showSensitive ? ($this->photos_count ?? null) : null, 'public_url' => $settings['public_url'] ?? null, 'custom_domain' => $showSensitive ? ($settings['custom_domain'] ?? null) : null, 'theme_color' => $settings['theme_color'] ?? null, 'status' => $this->status ?? 'draft', 'is_active' => (bool) ($this->is_active ?? false), 'features' => $settings['features'] ?? [], 'engagement_mode' => $settings['engagement_mode'] ?? 'tasks', 'branding' => $settings['branding'] ?? null, 'settings' => $settings, 'event_type_id' => $this->event_type_id, 'event_type' => $this->whenLoaded('eventType', function () { return new EventTypeResource($this->eventType); }), 'created_at' => $this->created_at?->toISOString(), 'updated_at' => $this->updated_at?->toISOString(), 'photo_count' => (int) ($this->photos_count ?? 0), 'pending_photo_count' => isset($this->pending_photos_count) ? (int) $this->pending_photos_count : null, 'like_count' => isset($this->likes_sum) ? (int) $this->likes_sum : $this->whenLoaded('photos', fn () => (int) $this->photos->sum('likes_count'), 0), 'tasks_count' => isset($this->tasks_count) ? (int) $this->tasks_count : null, 'active_invites_count' => isset($this->active_join_tokens_count) ? (int) $this->active_join_tokens_count : null, 'total_invites_count' => isset($this->total_join_tokens_count) ? (int) $this->total_join_tokens_count : null, 'is_public' => $this->status === 'published', 'public_share_url' => null, 'qr_code_url' => null, 'package' => $eventPackage ? [ 'id' => $eventPackage->package_id, 'name' => $eventPackage->package?->getNameForLocale(app()->getLocale()) ?? $eventPackage->package?->name, 'price' => $eventPackage->purchased_price, 'purchased_at' => $eventPackage->purchased_at?->toIso8601String(), 'expires_at' => $eventPackage->gallery_expires_at?->toIso8601String(), 'branding_allowed' => (bool) optional($eventPackage->package)->branding_allowed, 'watermark_allowed' => (bool) optional($eventPackage->package)->watermark_allowed, ] : null, 'limits' => $eventPackage && $limitEvaluator ? $limitEvaluator->summarizeEventPackage($eventPackage) : null, 'addons' => $eventPackage ? $this->formatAddons($eventPackage) : [], 'member_permissions' => $memberPermissions, ]; } /** * @param array $settings * @return array */ protected function attachWatermarkAssetUrl(array $settings): array { $watermark = Arr::get($settings, 'watermark'); $base = config('watermark.base', []); $base = is_array($base) ? $base : []; $baseSetting = null; if (class_exists(WatermarkSetting::class) && Schema::hasTable('watermark_settings')) { try { $baseSetting = WatermarkSetting::query()->first(); } catch (\Throwable) { $baseSetting = null; } } if ($baseSetting) { $base = array_merge($base, array_filter([ 'asset' => $baseSetting->asset, 'position' => $baseSetting->position, 'opacity' => $baseSetting->opacity, 'scale' => $baseSetting->scale, 'padding' => $baseSetting->padding, 'offset_x' => $baseSetting->offset_x, 'offset_y' => $baseSetting->offset_y, ], static fn ($value) => $value !== null)); } if (! is_array($watermark)) { $watermark = []; } $mode = $watermark['mode'] ?? null; if (! is_string($mode) || $mode === '') { $mode = 'base'; $watermark['mode'] = $mode; } if ($mode !== 'off') { foreach (['position', 'opacity', 'scale', 'padding', 'offset_x', 'offset_y'] as $key) { if (! array_key_exists($key, $watermark) && array_key_exists($key, $base)) { $watermark[$key] = $base[$key]; } } } $asset = $watermark['asset'] ?? null; if ((! is_string($asset) || $asset === '') && $mode !== 'off') { $asset = $base['asset'] ?? null; if (is_string($asset) && $asset !== '') { $watermark['asset'] = $asset; } } if (! is_string($asset) || $asset === '') { $settings['watermark'] = $watermark; return $settings; } $normalized = ltrim($asset, '/'); if (str_starts_with($normalized, 'storage/')) { $normalized = substr($normalized, strlen('storage/')); } $watermark['asset_url'] = URL::temporarySignedRoute( 'api.v1.branding.asset', now()->addSeconds(3600), ['path' => $normalized] ); $settings['watermark'] = $watermark; return $settings; } protected function formatAddons(?\App\Models\EventPackage $eventPackage): array { if (! $eventPackage) { return []; } $addons = $eventPackage->relationLoaded('addons') ? $eventPackage->addons : $eventPackage->addons()->latest()->take(10)->get(); return $addons->map(function ($addon) { return [ 'id' => $addon->id, 'key' => $addon->addon_key, 'label' => $addon->metadata['label'] ?? null, 'status' => $addon->status, 'price_id' => $addon->price_id, 'transaction_id' => $addon->transaction_id, 'extra_photos' => (int) $addon->extra_photos, 'extra_guests' => (int) $addon->extra_guests, 'extra_gallery_days' => (int) $addon->extra_gallery_days, 'purchased_at' => $addon->purchased_at?->toIso8601String(), 'metadata' => Arr::only($addon->metadata ?? [], ['price_eur']), ]; })->all(); } }