From c6301d27be34c2e016b2281e696d4cceb4db8b8e Mon Sep 17 00:00:00 2001 From: Quentin Gabriele Date: Fri, 25 Oct 2024 00:28:04 +0200 Subject: [PATCH] add transform --- src/Concerns/InteractWithFiles.php | 60 +++++++++++++++++++++++++ tests/Feature/InteractWithFilesTest.php | 54 ++++++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/src/Concerns/InteractWithFiles.php b/src/Concerns/InteractWithFiles.php index febe517..ea74bb3 100644 --- a/src/Concerns/InteractWithFiles.php +++ b/src/Concerns/InteractWithFiles.php @@ -3,9 +3,11 @@ namespace Elegantly\Media\Concerns; use Carbon\CarbonInterval; +use Closure; use DateTimeInterface; use Elegantly\Media\Enums\MediaType; use Elegantly\Media\Helpers\File; +use Elegantly\Media\TemporaryDirectory; use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Http\File as HttpFile; use Illuminate\Http\UploadedFile; @@ -174,6 +176,64 @@ public function moveFileTo( } + /** + * Transform the media file inside a temporary directory while keeping the same Model + * Usefull to optimize or convert the media file afterwards + * + * @param Closure(HttpFile $copy): HttpFile $transform + * @return $this + */ + public function transformFile(Closure $transform): static + { + + TemporaryDirectory::callback(function ($temporaryDirectory) use ($transform) { + + /** Used to delete the old file */ + $clone = clone $this; + + if ( + ! $this->path || + ! $this->disk || + ! $this->name + ) { + return $this; + } + + $storage = Storage::build([ + 'driver' => 'local', + 'root' => $temporaryDirectory->path(), + ]); + + $copy = $this->copyFileTo( + disk: $storage, + path: $this->path + ); + + if (! $copy) { + return; + } + + $file = $transform(new HttpFile($storage->path($copy))); + + $result = $this->putFile( + disk: $this->disk, + destination: dirname($this->path), + file: $file, + name: $this->name + ); + + if ( + $result && + $clone->path !== $this->path + ) { + $clone->deleteFile(); + } + + }); + + return $this; + } + public function humanReadableSize( int $precision = 0, ?int $maxPrecision = null diff --git a/tests/Feature/InteractWithFilesTest.php b/tests/Feature/InteractWithFilesTest.php index 1cebda4..0e5a87c 100644 --- a/tests/Feature/InteractWithFilesTest.php +++ b/tests/Feature/InteractWithFilesTest.php @@ -1,9 +1,12 @@ assertExists($copy); }); + +it('transforms a file and delete the original one', function () { + /** @var Media $media */ + $media = MediaFactory::new()->make(); + + Storage::fake('media'); + + $file = UploadedFile::fake()->image('foo.jpg', width: 16, height: 9); + + $media->storeFile( + file: $file, + disk: 'media' + ); + + $path = $media->path; + + Storage::disk('media')->assertExists($path); + + $media->transformFile(function ($file) { + + $path = $file->getRealPath(); + $basename = dirname($path); + $name = File::name($path); + + $new = "{$basename}/{$name}.png"; + + Image::load($path) + ->save($new); + + return new HttpFile($new); + }); + + Storage::disk('media')->assertMissing($path); + + Storage::disk('media')->assertExists($media->path); + + $path = $media->path; + + $media->transformFile(function ($file) { + $path = $file->getRealPath(); + + Image::load($path) + ->optimize() + ->save($path); + + return new HttpFile($path); + }); + + Storage::disk('media')->assertExists($path); + +});