- Fix EventType deletion error handling (constraint violations) - Fix Event update error (package_id column missing) - Fix Event Type dropdown options (JSON display issue) - Fix EventPackagesRelationManager query error - Add missing translations for deletion errors - Apply Pint formatting
157 lines
4.2 KiB
PHP
157 lines
4.2 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Storage;
|
|
|
|
use App\Models\Event;
|
|
use App\Models\EventMediaAsset;
|
|
use App\Models\EventStorageAssignment;
|
|
use App\Models\MediaStorageTarget;
|
|
use Illuminate\Support\Facades\Config;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class EventStorageManager
|
|
{
|
|
public function getHotDiskForEvent(Event $event): string
|
|
{
|
|
$target = $event->currentStorageTarget('hot') ?? $this->resolveDefaultHotTarget();
|
|
|
|
return $target?->key ?? Config::get('filesystems.default', 'local');
|
|
}
|
|
|
|
public function getArchiveDiskForEvent(Event $event): ?string
|
|
{
|
|
$assignment = $event->storageAssignments()
|
|
->where('role', 'archive')
|
|
->where('status', 'active')
|
|
->latest('assigned_at')
|
|
->first();
|
|
|
|
if ($assignment?->storageTarget) {
|
|
return $assignment->storageTarget->key;
|
|
}
|
|
|
|
$default = $this->resolveDefaultArchiveTarget();
|
|
|
|
if (! $default) {
|
|
return null;
|
|
}
|
|
|
|
$assignment = $this->ensureAssignment($event, $default, 'archive');
|
|
|
|
return $assignment->storageTarget?->key;
|
|
}
|
|
|
|
public function ensureAssignment(Event $event, ?MediaStorageTarget $target = null, string $role = 'hot'): EventStorageAssignment
|
|
{
|
|
if (! $target) {
|
|
$target = $role === 'archive'
|
|
? $this->resolveDefaultArchiveTarget()
|
|
: $this->resolveDefaultHotTarget();
|
|
}
|
|
|
|
$assignment = $event->storageAssignments()
|
|
->where('role', $role)
|
|
->where('status', 'active')
|
|
->where('media_storage_target_id', $target?->id)
|
|
->latest('assigned_at')
|
|
->first();
|
|
|
|
if ($assignment) {
|
|
return $assignment;
|
|
}
|
|
|
|
if (! $target) {
|
|
throw new \RuntimeException('No storage target available for role '.$role);
|
|
}
|
|
|
|
$assignment = $event->storageAssignments()->create([
|
|
'media_storage_target_id' => $target->id,
|
|
'role' => $role,
|
|
'status' => 'active',
|
|
'assigned_at' => now(),
|
|
]);
|
|
|
|
return $assignment;
|
|
}
|
|
|
|
public function recordAsset(
|
|
Event $event,
|
|
string $disk,
|
|
string $path,
|
|
array $attributes = [],
|
|
?EventMediaAsset $existing = null,
|
|
): EventMediaAsset {
|
|
$target = MediaStorageTarget::where('key', $disk)->first();
|
|
|
|
if (! $target) {
|
|
$target = $this->resolveDefaultHotTarget();
|
|
}
|
|
|
|
$payload = array_merge([
|
|
'event_id' => $event->id,
|
|
'media_storage_target_id' => $target?->id,
|
|
'disk' => $disk,
|
|
'path' => $path,
|
|
'status' => 'hot',
|
|
'processed_at' => now(),
|
|
], $attributes);
|
|
|
|
if ($existing) {
|
|
$existing->fill($payload)->save();
|
|
|
|
return $existing;
|
|
}
|
|
|
|
return EventMediaAsset::create($payload);
|
|
}
|
|
|
|
public function registerDynamicDisks(): void
|
|
{
|
|
if (! $this->targetsTableExists()) {
|
|
return;
|
|
}
|
|
|
|
$targets = MediaStorageTarget::active()->get();
|
|
|
|
foreach ($targets as $target) {
|
|
$config = $target->toFilesystemConfig();
|
|
Config::set('filesystems.disks.'.$target->key, $config);
|
|
}
|
|
}
|
|
|
|
protected function resolveDefaultHotTarget(): ?MediaStorageTarget
|
|
{
|
|
return MediaStorageTarget::active()
|
|
->where('is_hot', true)
|
|
->orderByDesc('is_default')
|
|
->orderByDesc('priority')
|
|
->first();
|
|
}
|
|
|
|
protected function resolveDefaultArchiveTarget(): ?MediaStorageTarget
|
|
{
|
|
return MediaStorageTarget::active()
|
|
->where('is_hot', false)
|
|
->orderByDesc('priority')
|
|
->first();
|
|
}
|
|
|
|
protected function targetsTableExists(): bool
|
|
{
|
|
static $cached;
|
|
|
|
if ($cached !== null) {
|
|
return $cached;
|
|
}
|
|
|
|
try {
|
|
$cached = \Schema::hasTable('media_storage_targets');
|
|
} catch (\Throwable $e) {
|
|
Log::debug('Skipping storage target bootstrap: '.$e->getMessage());
|
|
$cached = false;
|
|
}
|
|
|
|
return $cached;
|
|
}
|
|
}
|