From 3541ecaac51ff30b442a28e186762743fdbc57f1 Mon Sep 17 00:00:00 2001 From: Jyrki De Neve Date: Thu, 4 Apr 2024 16:23:17 +0300 Subject: [PATCH 1/2] Add s3 support --- config/filament-media-library.php | 1 + docs/index.md | 34 +++++++++++++++- src/Conversions/S3Conversion.php | 62 ++++++++++++++++++++++++++++++ src/Models/Traits/HasFormats.php | 11 +++++- src/Support/TemporaryDirectory.php | 21 ++++++++++ 5 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 src/Conversions/S3Conversion.php create mode 100644 src/Support/TemporaryDirectory.php diff --git a/config/filament-media-library.php b/config/filament-media-library.php index d80339c..aa970fc 100644 --- a/config/filament-media-library.php +++ b/config/filament-media-library.php @@ -33,4 +33,5 @@ 'ogg', ], ], + 'temporary_directory_path' => storage_path('filament-media-library/tmp'), ]; diff --git a/docs/index.md b/docs/index.md index cb96965..fc98a99 100644 --- a/docs/index.md +++ b/docs/index.md @@ -91,9 +91,8 @@ return [ 'ogg', ], ], + 'temporary_directory_path' => storage_path('filament-media-library/tmp'), ]; - - ``` ### Extensions @@ -111,6 +110,37 @@ This configuration can be adjusted as desired. The format generation action is a button that will generate all the formats for the given attachment. This can be used on the Media Library as a bulk action. This action can be disabled by setting the `enable-format-generate-action` to false. +### S3 support + +To use S3 as a storage, you can use the `Codedor\MediaLibrary\Conversions\S3Conversion` class. + +```php +return [ + 'conversion' => \Codedor\MediaLibrary\Conversions\S3Conversion::class, + // ... +]; +``` + +Then switch your filesystem to S3 in the `config/filesystems.php` file. + +```php +return [ + 'disks' => [ + 'public' => [ + 'visibility' => 'public', + 'driver' => 's3', + 'endpoint' => env('AWS_ENDPOINT', 'http://127.0.0.1:9000'), + 'use_path_style_endpoint' => true, + 'key' => env('AWS_KEY'), + 'secret' => env('AWS_SECRET'), + 'region' => env('AWS_REGION'), + 'bucket' => env('AWS_BUCKET'), + 'root' => 'public', + ], + ], +]; +``` + ## Formats ### Register models diff --git a/src/Conversions/S3Conversion.php b/src/Conversions/S3Conversion.php new file mode 100644 index 0000000..5ad23d3 --- /dev/null +++ b/src/Conversions/S3Conversion.php @@ -0,0 +1,62 @@ +extension)) { + return false; + } + + $formatName = $format->filename($attachment); + $savePath = $attachment->directory . '/' . $formatName; + + if (array_key_exists('format', $format->definition()->toArray()[0])) { + $savePath = Str::replaceLast( + $attachment->extension, + $format->definition()->toArray()[0]['format'], + $savePath + ); + } + + $formatPath = "$attachment->directory/$formatName"; + + if ( + $force || + ! $attachment->getStorage()->exists($formatPath) + ) { + $temporaryDirectory = TemporaryDirectory::create(); + $tempPath = $temporaryDirectory->path(Str::random(16) . '.' . $attachment->extension); + $disk = $attachment->getStorage(); + + file_put_contents($tempPath, $disk->readStream($attachment->file_path)); + + Image::load($tempPath) + ->manipulate($format->definition()) + ->save(); + + $file = fopen($tempPath, 'r'); + + $disk->put( + $formatPath, + $file, + ); + + if (is_resource($file)) { + fclose($file); + } + + $temporaryDirectory->delete(); + } + + return true; + } +} diff --git a/src/Models/Traits/HasFormats.php b/src/Models/Traits/HasFormats.php index 9c72b07..63bdbf0 100644 --- a/src/Models/Traits/HasFormats.php +++ b/src/Models/Traits/HasFormats.php @@ -42,7 +42,16 @@ public function getFormat(string $name, ?string $extension = null): ?string return null; } - return $attachment->getStorage()->url( + $disk = $attachment->getStorage(); + + if ($disk->providesTemporaryUrls()) { + return $disk->temporaryUrl( + "{$attachment->directory}/{$format->filename($attachment)}", + now()->addMinutes(5) + ); + } + + return $disk->url( "{$attachment->directory}/{$format->filename($attachment)}" ); } diff --git a/src/Support/TemporaryDirectory.php b/src/Support/TemporaryDirectory.php new file mode 100644 index 0000000..fbe99f2 --- /dev/null +++ b/src/Support/TemporaryDirectory.php @@ -0,0 +1,21 @@ + Date: Fri, 5 Apr 2024 16:31:51 +0300 Subject: [PATCH 2/2] Set crossorigin to false, so cropper works with s3 urls --- resources/views/livewire/formatter-modal.blade.php | 2 ++ src/Models/Attachment.php | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/resources/views/livewire/formatter-modal.blade.php b/resources/views/livewire/formatter-modal.blade.php index 06e64ae..3079090 100644 --- a/resources/views/livewire/formatter-modal.blade.php +++ b/resources/views/livewire/formatter-modal.blade.php @@ -41,6 +41,7 @@ class="py-8 w-full flex-col gap-2" ready() { window.cropper.setData(previousData || {}) }, + checkCrossOrigin: false, }) }, submit () { @@ -79,6 +80,7 @@ class="py-8 w-full flex-col gap-2" id="filament-media-library::formatter" wire:key="filament-media-library::formatter-{{ $attachment->id }}" style="max-width: 100%; max-height: 68vh" + crossorigin="anonymous" > diff --git a/src/Models/Attachment.php b/src/Models/Attachment.php index 41e9c0c..583a88c 100644 --- a/src/Models/Attachment.php +++ b/src/Models/Attachment.php @@ -87,8 +87,16 @@ public function scopeSearch(Builder $query, ?string $search = ''): Builder public function getUrlAttribute(): string { - return $this->getStorage() - ->url("{$this->directory}/{$this->filename}"); + $disk = $this->getStorage(); + + if ($disk->providesTemporaryUrls()) { + return $disk->temporaryUrl( + "{$this->directory}/{$this->filename}", + now()->addMinutes(5) + ); + } + + return $disk->url("{$this->directory}/{$this->filename}"); } public function getFilenameAttribute(): string