Skip to content

Commit

Permalink
Check for enum instances when applying manipulations (#3661)
Browse files Browse the repository at this point in the history
* Switch match to switch-case in apply method and check for enum instances

* Add tests
  • Loading branch information
dennisvandalen authored Jul 15, 2024
1 parent c38b804 commit e8d9f9f
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 12 deletions.
69 changes: 57 additions & 12 deletions src/Conversions/Manipulations.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Spatie\Image\Drivers\ImageDriver;
use Spatie\Image\Enums\AlignPosition;
use Spatie\Image\Enums\BorderType;
use Spatie\Image\Enums\ColorFormat;
use Spatie\Image\Enums\Constraint;
use Spatie\Image\Enums\CropPosition;
use Spatie\Image\Enums\Fit;
Expand Down Expand Up @@ -59,17 +58,7 @@ public function isEmpty(): bool
public function apply(ImageDriver $image): void
{
foreach ($this->manipulations as $manipulationName => $parameters) {
match ($manipulationName) {
'border' => (isset($parameters['type'])) && $parameters['type'] = BorderType::from($parameters['type']),
'watermark' => (isset($parameters['fit'])) && $parameters['fit'] = Fit::from($parameters['fit']),
'watermark','resizeCanvas','insert' => (isset($parameters['position'])) && $parameters['position'] = AlignPosition::from($parameters['position']),
'pickColor' => (isset($parameters['colorFormat'])) && $parameters['colorFormat'] = ColorFormat::from($parameters['colorFormat']),
'resize','width','height' => (isset($parameters['constraints'])) && $parameters['constraints'] = Constraint::from($parameters['constraints']),
'crop' => (isset($parameters['position'])) && $parameters['position'] = CropPosition::from($parameters['position']),
'fit' => (isset($parameters['fit'])) && $parameters['fit'] = Fit::from($parameters['fit']),
'flip' => (isset($parameters['flip'])) && $parameters['flip'] = FlipDirection::from($parameters['flip']),
default => ''
};
$parameters = $this->transformParameters($manipulationName, $parameters);
$image->$manipulationName(...$parameters);
}
}
Expand All @@ -94,4 +83,60 @@ public function toArray(): array
{
return $this->manipulations;
}

/**
* @param int|string $manipulationName
* @param mixed $parameters
* @return mixed
*/
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;
}
}
90 changes: 90 additions & 0 deletions tests/Conversions/ImageManipulationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

use Spatie\Image\Enums\BorderType;
use Spatie\Image\Enums\Fit;
use Spatie\Image\Enums\AlignPosition;
use Spatie\Image\Enums\Constraint;
use Spatie\Image\Enums\CropPosition;
use Spatie\Image\Enums\FlipDirection;
use Spatie\Image\Image;
use Spatie\MediaLibrary\Conversions\Manipulations;

it('transforms parameters correctly', function () {
// Mock the image object
$image = Image::load(pathToImage: $this->getTestJpg());

// Define manipulations
$manipulations = [
'border' => ['width' => 10, 'type' => 'expand'],
'watermark' => ['fit' => 'contain', 'watermarkImage' => $this->getTestPng()],
'resizeCanvas' => ['position' => 'center'],
'resize' => ['constraints' => ['preserveAspectRatio'], 'width' => 100, 'height' => 100],
'crop' => ['width' => 50, 'height'=> 50, 'position' => 'topLeft'],
'fit' => ['fit' => 'contain'],
'flip' => ['flip' => 'horizontal'],
];

$transformedParameters = [];

// Create an instance of the class containing the logic
$manipulator = new Manipulations($manipulations);

foreach ($manipulations as $manipulationName => $parameters) {
$parameters = $manipulator->transformParameters($manipulationName, $parameters);

// Apply the manipulation
$image->$manipulationName(...$parameters);

// Store the transformed parameters for assertions
$transformedParameters[$manipulationName] = $parameters;
}

// Assertions to check if parameters have been correctly transformed
expect($transformedParameters['border']['type'])->toBeInstanceOf(BorderType::class)
->and($transformedParameters['watermark']['fit'])->toBeInstanceOf(Fit::class)
->and($transformedParameters['resizeCanvas']['position'])->toBeInstanceOf(AlignPosition::class)
->and($transformedParameters['resize']['constraints'][0])->toBeInstanceOf(Constraint::class)
->and($transformedParameters['crop']['position'])->toBeInstanceOf(CropPosition::class)
->and($transformedParameters['fit']['fit'])->toBeInstanceOf(Fit::class)
->and($transformedParameters['flip']['flip'])->toBeInstanceOf(FlipDirection::class);
});

it('handles parameters that are already enum instances', function () {
// Mock the image object
$image = Image::load(pathToImage: $this->getTestJpg());

// Define manipulations with parameters already as enum instances
$manipulations = [
'border' => ['width' => 10, 'type' => BorderType::Expand],
'watermark' => ['fit' => Fit::Contain, 'watermarkImage' => $this->getTestPng()],
'resizeCanvas' => ['position' => AlignPosition::Center],
'resize' => ['constraints' => [Constraint::PreserveAspectRatio], 'width' => 100, 'height' => 100],
'crop' => ['width' => 50, 'height'=> 50, 'position' => CropPosition::TopLeft],
'fit' => ['fit' => Fit::Contain],
'flip' => ['flip' => FlipDirection::Horizontal],
];

$transformedParameters = [];

// Create an instance of the class containing the logic
$manipulator = new Manipulations($manipulations);

foreach ($manipulations as $manipulationName => $parameters) {
$parameters = $manipulator->transformParameters($manipulationName, $parameters);

// Apply the manipulation
$image->$manipulationName(...$parameters);

// Store the transformed parameters for assertions
$transformedParameters[$manipulationName] = $parameters;
}

// Assertions to check if parameters remain unchanged
expect($transformedParameters['border']['type'])->toBeInstanceOf(BorderType::class)
->and($transformedParameters['watermark']['fit'])->toBeInstanceOf(Fit::class)
->and($transformedParameters['resizeCanvas']['position'])->toBeInstanceOf(AlignPosition::class)
->and($transformedParameters['resize']['constraints'][0])->toBeInstanceOf(Constraint::class)
->and($transformedParameters['crop']['position'])->toBeInstanceOf(CropPosition::class)
->and($transformedParameters['fit']['fit'])->toBeInstanceOf(Fit::class)
->and($transformedParameters['flip']['flip'])->toBeInstanceOf(FlipDirection::class);
});

0 comments on commit e8d9f9f

Please sign in to comment.