feat/docker-compose-update (#18)

Co-authored-by: jon brookes <marshyon@gmail.com>
Reviewed-on: https://codeberg.org/headshed/share-lt/pulls/18
This commit is contained in:
Jon Brookes 2026-02-08 18:04:18 +01:00
parent fd43495e2d
commit 1a22fd156d
70 changed files with 1068 additions and 745 deletions

View file

@ -52,6 +52,7 @@ class EntryForm
->visible(fn($get) => $get('type') === 'article')
->columnSpanFull(),
SpatieMediaLibraryFileUpload::make('featured_image')
->multiple() // <- force array handling for Filament v4 bug
->visible(
fn($get) =>
$get('type') === 'article' || $get('type') === 'image'
@ -64,9 +65,63 @@ class EntryForm
->columnSpanFull()
->dehydrated(false)
->saveUploadedFileUsing(function ($file, $record) {
$diskName = config('media-library.disk_name', 'public');
if (is_array($file)) {
$file = reset($file);
}
if (config('app.env') === 'local') {
// Validate upload object early
if (
! is_object($file) ||
! (method_exists($file, 'getRealPath') || method_exists($file, 'getPathname') || method_exists($file, 'getStream') || method_exists($file, 'store'))
) {
Log::error('Invalid upload object', ['type' => gettype($file)]);
throw new \Exception('Invalid upload object provided to saveUploadedFileUsing');
}
// Use safe variables for further calls
$realPath = method_exists($file, 'getRealPath') ? $file->getRealPath() : null;
$exists = $realPath ? file_exists($realPath) : false;
$name = method_exists($file, 'getClientOriginalName') ? $file->getClientOriginalName() : null;
Log::info('TemporaryUploadedFile Debug', [
'path' => $file->getRealPath(),
'exists' => file_exists($file->getRealPath()),
'name' => $file->getClientOriginalName(),
'temp_dir' => sys_get_temp_dir(),
'disk_root' => config('filesystems.disks.local.root'),
'is_readable' => is_readable($file->getRealPath()),
'is_writable' => is_writable($file->getRealPath()),
]);
// Additional debug: Check if the file is being moved to livewire-tmp
$livewireTmpPath = storage_path('framework/livewire-tmp');
Log::info('Livewire Temp Directory Debug', [
'livewire_tmp_path' => $livewireTmpPath,
'exists' => file_exists($livewireTmpPath),
'is_writable' => is_writable($livewireTmpPath),
]);
// Check if the file is being moved
$tempFilePath = $file->getRealPath();
$newFilePath = $livewireTmpPath . '/' . $file->getClientOriginalName();
if (file_exists($tempFilePath)) {
Log::info('File exists in temp directory', ['temp_file_path' => $tempFilePath]);
} else {
Log::error('File does not exist in temp directory', ['temp_file_path' => $tempFilePath]);
}
// $diskName = config('media-library.disk_name', 'public');
$diskName = config('media-library.disk_name');
if (config('logging.channels.' . config('logging.default') . '.level') === 'debug') {
Log::info('Featured Image Upload Debug', [
'disk' => $diskName,
'file_name' => $file->getClientOriginalName(),
@ -97,7 +152,7 @@ class EntryForm
$disk->put($testFile, 'test content');
$disk->delete($testFile);
if (config('app.env') === 'local') {
if (config('logging.channels.' . config('logging.default') . '.level') === 'debug') {
Log::info('S3 connectivity test passed');
}
}
@ -112,12 +167,114 @@ class EntryForm
$encodedName = base64_encode($originalName);
$secureFileName = Str::random(32) . '-meta' . $encodedName . '-.' . $extension;
$media = $record->addMedia($file->getRealPath())
->usingName($baseName) // Keep original name for display/search
->usingFileName($secureFileName) // Use secure filename for storage
// Resolve possibly-relative Livewire temp path + safe fallbacks
$realPath = $realPath ?: (method_exists($file, 'getRealPath') ? $file->getRealPath() : null);
$candidates = [];
if ($realPath && str_starts_with($realPath, '/')) {
$candidates[] = $realPath;
} else {
$candidates[] = sys_get_temp_dir() . '/' . ltrim((string)$realPath, '/');
$candidates[] = storage_path('framework/' . ltrim((string)$realPath, '/'));
$candidates[] = storage_path(ltrim((string)$realPath, '/'));
$candidates[] = base_path(ltrim((string)$realPath, '/'));
}
if ($realPath) {
$candidates[] = storage_path('framework/livewire-tmp/' . basename($realPath));
$candidates[] = sys_get_temp_dir() . '/' . basename($realPath);
}
// 1) Try storing to local disk (creates an absolute path we control)
$stored = null;
if (method_exists($file, 'store')) {
try {
$stored = $file->store('livewire-temp', 'local'); // storage/app/livewire-temp/...
if ($stored && \Storage::disk('local')->exists($stored)) {
$resolved = \Storage::disk('local')->path($stored);
}
} catch (\Throwable $e) {
Log::debug('store() fallback failed', ['err' => $e->getMessage()]);
}
}
// 2) If not resolved, check candidates
if (! isset($resolved)) {
foreach ($candidates as $p) {
if ($p && file_exists($p)) {
$resolved = $p;
break;
}
}
}
// 3) If still not resolved, try stream -> temp file copy
$is_tmp_copy = false;
if (! isset($resolved)) {
try {
$stream = null;
if (method_exists($file, 'getStream')) {
$stream = $file->getStream();
} elseif (method_exists($file, 'getRealPath') && is_readable($file->getRealPath())) {
$stream = fopen($file->getRealPath(), 'r');
}
if ($stream) {
$tmpPath = tempnam(sys_get_temp_dir(), 'filament-upload-');
$out = fopen($tmpPath, 'w');
stream_copy_to_stream($stream, $out);
fclose($out);
if (is_resource($stream)) {
@fclose($stream);
}
$resolved = $tmpPath;
$is_tmp_copy = true;
}
} catch (\Throwable $e) {
Log::debug('stream fallback failed', ['err' => $e->getMessage()]);
}
}
// 4) Still nothing -> error
if (empty($resolved)) {
Log::error('Featured Image Upload: could not resolve temp path', [
'original' => $realPath,
'checked_candidates' => $candidates,
'stored' => $stored,
]);
throw new \Exception("File `{$realPath}` does not exist");
}
// 5) Use resolved absolute path
$media = $record->addMedia($resolved)
->usingName($baseName)
->usingFileName($secureFileName)
->toMediaCollection('featured-image', $diskName);
if (config('app.env') === 'local') {
// 6) Cleanup short-lived artifacts
if (! empty($is_tmp_copy) && file_exists($resolved)) {
@unlink($resolved);
}
if (! empty($stored) && \Storage::disk('local')->exists($stored)) {
\Storage::disk('local')->delete($stored);
}
Log::info('Featured image resolved', ['resolved' => $resolved, 'media_id' => $media->id ?? null]);
if (config('logging.channels.' . config('logging.default') . '.level') === 'debug') {
Log::info('Featured Image Upload Success', [
'media_id' => $media->id,
'media_url' => $media->getUrl(),
@ -189,7 +346,7 @@ class EntryForm
$record = $component->getRecord();
$diskName = config('media-library.disk_name', 'public');
if (config('app.env') === 'local') {
if (config('logging.channels.' . config('logging.default') . '.level') === 'debug') {
Log::info('Featured Image Picker Action Debug', [
'disk' => $diskName,
'record_id' => $record?->id,
@ -223,7 +380,7 @@ class EntryForm
try {
// For S3, we need to handle file copying differently
if ($sourceMedia->disk === 's3') {
if (config('app.env') === 'local') {
if (config('logging.channels.' . config('logging.default') . '.level') === 'debug') {
Log::info('Copying S3 media to new collection', [
'source_disk' => $sourceMedia->disk,
'source_path' => $sourceMedia->getPathRelativeToRoot(),
@ -267,7 +424,7 @@ class EntryForm
->usingFileName($sourceMedia->file_name)
->toMediaCollection('featured-image', $diskName);
if (config('app.env') === 'local') {
if (config('logging.channels.' . config('logging.default') . '.level') === 'debug') {
Log::info('Featured Image Picker Success', [
'new_media_id' => $newMedia->id,
'new_media_disk' => $newMedia->disk,