From 74496e2683ba8da4b609b284f5965d95ba25c810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=CC=88nther=20Debrauwer?= Date: Fri, 2 Aug 2024 14:40:15 +0200 Subject: [PATCH] Upgrade to spatie/image v3 --- composer.json | 2 +- src/Conversions/LocalConversion.php | 20 ++-- src/Formats/Format.php | 1 - src/Formats/Manipulations.php | 138 ++++++++++++++++++++++++++++ src/Formats/Thumbnail.php | 4 +- tests/TestFormats/TestHero.php | 5 +- tests/TestFormats/TestHeroWebp.php | 7 +- tests/TestFormats/TestNoHeight.php | 5 +- 8 files changed, 163 insertions(+), 19 deletions(-) create mode 100644 src/Formats/Manipulations.php diff --git a/composer.json b/composer.json index f5c696e..24cf7fe 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "illuminate/contracts": "^10.0|^11.0", "livewire/livewire": "^3.0", "owenvoke/blade-fontawesome": "^2.2", - "spatie/image": "^2.2", + "spatie/image": "^3.0", "spatie/laravel-package-tools": "^1.12", "spatie/laravel-translatable": "^6.3" }, diff --git a/src/Conversions/LocalConversion.php b/src/Conversions/LocalConversion.php index a54678c..9e60448 100644 --- a/src/Conversions/LocalConversion.php +++ b/src/Conversions/LocalConversion.php @@ -19,10 +19,10 @@ public function convert(Attachment $attachment, Format $format, bool $force = fa $formatName = $format->filename($attachment); $savePath = $attachment->absolute_directory_path . '/' . $formatName; - if (array_key_exists('format', $format->definition()->toArray()[0])) { + if (!empty($format->definition()->toArray()['format'])) { $savePath = Str::replaceLast( $attachment->extension, - $format->definition()->toArray()[0]['format'], + $format->definition()->toArray()['format'], $savePath ); } @@ -31,9 +31,11 @@ public function convert(Attachment $attachment, Format $format, bool $force = fa $force || ! $attachment->getStorage()->exists("$attachment->directory/$formatName") ) { - Image::load($attachment->absolute_file_path) - ->manipulate($format->definition()) - ->save($savePath); + $image = Image::load($attachment->absolute_file_path); + + $format->definition()->apply($image); + + $image->save($savePath); } if ( @@ -42,9 +44,11 @@ public function convert(Attachment $attachment, Format $format, bool $force = fa ! $attachment->getStorage()->exists(WebP::path($savePath, $attachment->extension)) ) ) { - Image::load($attachment->absolute_file_path) - ->manipulate($format->definition()) - ->save(WebP::path($savePath, $attachment->extension)); + $image = Image::load($attachment->absolute_file_path); + + $format->definition()->apply($image); + + $image->save(WebP::path($savePath, $attachment->extension)); } return true; diff --git a/src/Formats/Format.php b/src/Formats/Format.php index ef6c6e6..12887ea 100644 --- a/src/Formats/Format.php +++ b/src/Formats/Format.php @@ -7,7 +7,6 @@ use Codedor\MediaLibrary\Models\Attachment; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Support\Str; -use Spatie\Image\Manipulations; abstract class Format implements Arrayable { diff --git a/src/Formats/Manipulations.php b/src/Formats/Manipulations.php new file mode 100644 index 0000000..cee8e08 --- /dev/null +++ b/src/Formats/Manipulations.php @@ -0,0 +1,138 @@ +manipulations = $manipulations; + } + + public function __call(string $method, array $parameters): self + { + $this->addManipulation($method, $parameters); + + return $this; + } + + public function addManipulation(string $name, array $parameters = []): self + { + $this->manipulations[$name] = $parameters; + + return $this; + } + + public function getManipulationArgument(string $manipulationName): null|string|array + { + return $this->manipulations[$manipulationName] ?? null; + } + + public function getFirstManipulationArgument(string $manipulationName): null|string|int + { + $manipulationArgument = $this->getManipulationArgument($manipulationName); + + if (! is_array($manipulationArgument)) { + return null; + } + + return $manipulationArgument[0]; + } + + public function isEmpty(): bool + { + return count($this->manipulations) === 0; + } + + public function apply(ImageDriver $image): void + { + foreach ($this->manipulations as $manipulationName => $parameters) { + $parameters = $this->transformParameters($manipulationName, $parameters); + $image->$manipulationName(...$parameters); + } + } + + public function mergeManipulations(self $manipulations): self + { + foreach ($manipulations->toArray() as $name => $parameters) { + $this->manipulations[$name] = array_merge($this->manipulations[$name] ?? [], $parameters ?: []); + } + + return $this; + } + + public function removeManipulation(string $name): self + { + unset($this->manipulations[$name]); + + return $this; + } + + public function toArray(): array + { + return $this->manipulations; + } + + public function transformParameters(int|string $manipulationName, mixed $parameters): mixed + { + switch ($manipulationName) { + case 'border': + if (isset($parameters['type']) && ! $parameters['type'] instanceof BorderType) { + $parameters['type'] = BorderType::from($parameters['type']); + } + break; + case 'watermark': + if (isset($parameters['fit']) && ! $parameters['fit'] instanceof Fit) { + $parameters['fit'] = Fit::from($parameters['fit']); + } + // Fallthrough intended for position + case 'resizeCanvas': + case 'insert': + if (isset($parameters['position']) && ! $parameters['position'] instanceof AlignPosition) { + $parameters['position'] = AlignPosition::from($parameters['position']); + } + break; + case 'resize': + case 'width': + case 'height': + if (isset($parameters['constraints']) && is_array($parameters['constraints'])) { + foreach ($parameters['constraints'] as &$constraint) { + if (! $constraint instanceof Constraint) { + $constraint = Constraint::from($constraint); + } + } + } + break; + case 'crop': + if (isset($parameters['position']) && ! $parameters['position'] instanceof CropPosition) { + $parameters['position'] = CropPosition::from($parameters['position']); + } + break; + case 'fit': + if (isset($parameters['fit']) && ! $parameters['fit'] instanceof Fit) { + $parameters['fit'] = Fit::from($parameters['fit']); + } + break; + case 'flip': + if (isset($parameters['flip']) && ! $parameters['flip'] instanceof FlipDirection) { + $parameters['flip'] = FlipDirection::from($parameters['flip']); + } + break; + default: + break; + } + + return $parameters; + } +} diff --git a/src/Formats/Thumbnail.php b/src/Formats/Thumbnail.php index ca51dff..e5ddebb 100644 --- a/src/Formats/Thumbnail.php +++ b/src/Formats/Thumbnail.php @@ -3,7 +3,7 @@ namespace Codedor\MediaLibrary\Formats; use Codedor\MediaLibrary\Models\Attachment; -use Spatie\Image\Manipulations; +use Spatie\Image\Enums\Fit; class Thumbnail extends Format { @@ -15,7 +15,7 @@ class Thumbnail extends Format public function definition(): Manipulations { - return $this->manipulations->fit(Manipulations::FIT_CROP, 350, 350); + return $this->manipulations->fit(Fit::Crop, 350, 350); } public function registerModelsForFormatter(): void diff --git a/tests/TestFormats/TestHero.php b/tests/TestFormats/TestHero.php index 5d3d2c6..a6753e3 100644 --- a/tests/TestFormats/TestHero.php +++ b/tests/TestFormats/TestHero.php @@ -3,8 +3,9 @@ namespace Codedor\MediaLibrary\Tests\TestFormats; use Codedor\MediaLibrary\Formats\Format; +use Codedor\MediaLibrary\Formats\Manipulations; use Codedor\MediaLibrary\Tests\TestModels\TestModel; -use Spatie\Image\Manipulations; +use Spatie\Image\Enums\Fit; class TestHero extends Format { @@ -13,7 +14,7 @@ class TestHero extends Format public function definition(): Manipulations { return $this->manipulations - ->fit(Manipulations::FIT_CROP, 100, 100) + ->fit(Fit::Crop, 100, 100) ->sepia(); } diff --git a/tests/TestFormats/TestHeroWebp.php b/tests/TestFormats/TestHeroWebp.php index de53905..e29b491 100644 --- a/tests/TestFormats/TestHeroWebp.php +++ b/tests/TestFormats/TestHeroWebp.php @@ -3,8 +3,9 @@ namespace Codedor\MediaLibrary\Tests\TestFormats; use Codedor\MediaLibrary\Formats\Format; +use Codedor\MediaLibrary\Formats\Manipulations; use Codedor\MediaLibrary\Tests\TestModels\TestModel; -use Spatie\Image\Manipulations; +use Spatie\Image\Enums\Fit; class TestHeroWebp extends Format { @@ -13,8 +14,8 @@ class TestHeroWebp extends Format public function definition(): Manipulations { return $this->manipulations - ->fit(Manipulations::FIT_CROP, 100, 100) - ->format(Manipulations::FORMAT_WEBP) + ->fit(Fit::Crop, 100, 100) + ->format('webp') ->sepia(); } diff --git a/tests/TestFormats/TestNoHeight.php b/tests/TestFormats/TestNoHeight.php index cbb6190..0ae8606 100644 --- a/tests/TestFormats/TestNoHeight.php +++ b/tests/TestFormats/TestNoHeight.php @@ -3,8 +3,9 @@ namespace Codedor\MediaLibrary\Tests\TestFormats; use Codedor\MediaLibrary\Formats\Format; +use Codedor\MediaLibrary\Formats\Manipulations; use Codedor\MediaLibrary\Tests\TestModels\TestModel; -use Spatie\Image\Manipulations; +use Spatie\Image\Enums\Fit; class TestNoHeight extends Format { @@ -13,7 +14,7 @@ class TestNoHeight extends Format public function definition(): Manipulations { return $this->manipulations - ->fit(Manipulations::FIT_CROP, 100) + ->fit(Fit::Crop, 100) ->sepia(); }