1
0
mirror of https://github.com/Intervention/image.git synced 2025-08-13 17:34:04 +02:00

Refactor config handling

This commit is contained in:
Oliver Vogel
2024-05-10 10:04:11 +02:00
parent 51a81c845b
commit b79650acee
10 changed files with 143 additions and 49 deletions

View File

@@ -4,10 +4,19 @@ declare(strict_types=1);
namespace Intervention\Image; namespace Intervention\Image;
use Intervention\Image\Exceptions\InputException;
use Intervention\Image\Interfaces\ConfigInterface; use Intervention\Image\Interfaces\ConfigInterface;
class Config implements ConfigInterface class Config implements ConfigInterface
{ {
/**
* Create config object instance
*
* @param bool $autoOrientation
* @param bool $decodeAnimation
* @param mixed $blendingColor
* @return void
*/
public function __construct( public function __construct(
protected bool $autoOrientation = true, protected bool $autoOrientation = true,
protected bool $decodeAnimation = true, protected bool $decodeAnimation = true,
@@ -15,39 +24,47 @@ class Config implements ConfigInterface
) { ) {
} }
public function decodeAnimation(): bool /**
* {@inheritdoc}
*
* @see ConfigInterface::option()
*/
public function option(string $name, mixed $default = null): mixed
{ {
return $this->decodeAnimation; if (!property_exists($this, $name)) {
return $default;
} }
public function setDecodeAnimation(bool $status): self return $this->{$name};
}
/**
* {@inheritdoc}
*
* @see ConfigInterface::setOption()
*/
public function setOption(string $name, mixed $value): self
{ {
$this->decodeAnimation = $status; if (!property_exists($this, $name)) {
throw new InputException('Property ' . $name . ' does not exists for ' . $this::class . '.');
}
$this->{$name} = $value;
return $this; return $this;
} }
public function autoOrientation(): bool /**
* {@inheritdoc}
*
* @see COnfigInterface::setOptions()
*/
public function setOptions(mixed ...$options): self
{ {
return $this->autoOrientation; foreach ($options as $name => $value) {
$this->setOption($name, $value);
} }
public function setAutoOrientation(bool $status): self
{
$this->autoOrientation = $status;
return $this;
}
public function blendingColor(): mixed
{
return $this->blendingColor;
}
public function setBlendingColor(mixed $color): self
{
$this->blendingColor = $color;
return $this; return $this;
} }
} }

View File

@@ -23,12 +23,17 @@ use ReflectionClass;
abstract class AbstractDriver implements DriverInterface abstract class AbstractDriver implements DriverInterface
{ {
/** /**
* @param ConfigInterface $config * Driver options
*/
protected ConfigInterface $config;
/**
* @throws DriverException * @throws DriverException
* @return void * @return void
*/ */
public function __construct(protected ConfigInterface $config = new Config()) public function __construct()
{ {
$this->config = new Config();
$this->checkHealth(); $this->checkHealth();
} }

View File

@@ -60,7 +60,7 @@ class BinaryImageDecoder extends NativeObjectDecoder implements DecoderInterface
} }
// adjust image orientation // adjust image orientation
if ($this->driver()->config()->autoOrientation()) { if ($this->driver()->config()->option('autoOrientation') === true) {
$image->modify(new AlignRotationModifier()); $image->modify(new AlignRotationModifier());
} }

View File

@@ -50,7 +50,7 @@ class FilePathImageDecoder extends NativeObjectDecoder implements DecoderInterfa
$image->setExif($this->extractExifData($input)); $image->setExif($this->extractExifData($input));
// adjust image orientation // adjust image orientation
if ($this->driver()->config()->autoOrientation()) { if ($this->driver()->config()->option('autoOrientation') === true) {
$image->modify(new AlignRotationModifier()); $image->modify(new AlignRotationModifier());
} }

View File

@@ -60,7 +60,7 @@ class NativeObjectDecoder extends AbstractDecoder
protected function decodeGif(mixed $input): ImageInterface protected function decodeGif(mixed $input): ImageInterface
{ {
// create non-animated image depending on config // create non-animated image depending on config
if (!$this->driver()->config()->decodeAnimation()) { if (!$this->driver()->config()->option('decodeAnimation') === true) {
$native = match (true) { $native = match (true) {
$this->isGifFormat($input) => @imagecreatefromstring($input), $this->isGifFormat($input) => @imagecreatefromstring($input),
default => @imagecreatefromgif($input), default => @imagecreatefromgif($input),

View File

@@ -40,12 +40,12 @@ class NativeObjectDecoder extends SpecializableDecoder
); );
// discard animation depending on config // discard animation depending on config
if (!$this->driver()->config()->decodeAnimation()) { if (!$this->driver()->config()->option('decodeAnimation') === true) {
$image->modify(new RemoveAnimationModifier()); $image->modify(new RemoveAnimationModifier());
} }
// adjust image rotatation // adjust image rotatation
if ($this->driver()->config()->autoOrientation()) { if ($this->driver()->config()->option('autoOrientation') === true) {
$image->modify(new AlignRotationModifier()); $image->modify(new AlignRotationModifier());
} }

View File

@@ -408,7 +408,7 @@ final class Image implements ImageInterface
public function blendingColor(): ColorInterface public function blendingColor(): ColorInterface
{ {
return $this->driver()->handleInput( return $this->driver()->handleInput(
$this->driver()->config()->blendingColor() $this->driver()->config()->option('blendingColor')
); );
} }
@@ -419,7 +419,8 @@ final class Image implements ImageInterface
*/ */
public function setBlendingColor(mixed $color): ImageInterface public function setBlendingColor(mixed $color): ImageInterface
{ {
$this->driver()->config()->setBlendingColor( $this->driver()->config()->setOption(
'blendingColor',
$this->driver()->handleInput($color) $this->driver()->handleInput($color)
); );

View File

@@ -20,9 +20,9 @@ final class ImageManager implements ImageManagerInterface
* @link https://image.intervention.io/v3/basics/image-manager#create-a-new-image-manager-instance * @link https://image.intervention.io/v3/basics/image-manager#create-a-new-image-manager-instance
* @param string|DriverInterface $driver * @param string|DriverInterface $driver
*/ */
public function __construct(string|DriverInterface $driver) public function __construct(string|DriverInterface $driver, mixed ...$options)
{ {
$this->driver = $this->resolveDriver($driver); $this->driver = $this->resolveDriver($driver, ...$options);
} }
/** /**
@@ -32,9 +32,9 @@ final class ImageManager implements ImageManagerInterface
* @param string|DriverInterface $driver * @param string|DriverInterface $driver
* @return ImageManager * @return ImageManager
*/ */
public static function withDriver(string|DriverInterface $driver): self public static function withDriver(string|DriverInterface $driver, mixed ...$options): self
{ {
return new self(self::resolveDriver($driver)); return new self(self::resolveDriver($driver, ...$options));
} }
/** /**
@@ -47,7 +47,7 @@ final class ImageManager implements ImageManagerInterface
*/ */
public static function gd(mixed ...$options): self public static function gd(mixed ...$options): self
{ {
return self::withDriver(new GdDriver(new Config(...$options))); return self::withDriver(new GdDriver(), ...$options);
} }
/** /**
@@ -60,7 +60,7 @@ final class ImageManager implements ImageManagerInterface
*/ */
public static function imagick(mixed ...$options): self public static function imagick(mixed ...$options): self
{ {
return self::withDriver(new ImagickDriver(new Config(...$options))); return self::withDriver(new ImagickDriver(), ...$options);
} }
/** /**
@@ -115,12 +115,11 @@ final class ImageManager implements ImageManagerInterface
* @param string|DriverInterface $driver * @param string|DriverInterface $driver
* @return DriverInterface * @return DriverInterface
*/ */
private static function resolveDriver(string|DriverInterface $driver): DriverInterface private static function resolveDriver(string|DriverInterface $driver, mixed ...$options): DriverInterface
{ {
if (is_object($driver)) { $driver = is_string($driver) ? new $driver() : $driver;
$driver->config()->setOptions(...$options);
return $driver; return $driver;
} }
return new $driver();
}
} }

View File

@@ -4,13 +4,34 @@ declare(strict_types=1);
namespace Intervention\Image\Interfaces; namespace Intervention\Image\Interfaces;
use Intervention\Image\Exceptions\InputException;
interface ConfigInterface interface ConfigInterface
{ {
public function decodeAnimation(): bool; /**
* Return value of given config option
*
* @param string $name
* @return mixed
*/
public function option(string $name, mixed $default = null): mixed;
public function autoOrientation(): bool; /**
* Set value of given config option
*
* @param string $name
* @param mixed $value
* @throws InputException
* @return ConfigInterface
*/
public function setOption(string $name, mixed $value): self;
public function blendingColor(): mixed; /**
* Set values of given config options
public function setBlendingColor(mixed $color): mixed; *
* @param mixed $options
* @throws InputException
* @return ConfigInterface
*/
public function setOptions(mixed ...$options): self;
} }

View File

@@ -13,6 +13,57 @@ final class ConfigTest extends BaseTestCase
{ {
public function testConstructor(): void public function testConstructor(): void
{ {
$this->assertInstanceOf(Config::class, new Config()); $config = new Config();
$this->assertInstanceOf(Config::class, $config);
$this->assertTrue($config->option('autoOrientation'));
$this->assertTrue($config->option('decodeAnimation'));
$this->assertEquals('ffffff00', $config->option('blendingColor'));
$config = new Config(
autoOrientation: false,
decodeAnimation: false,
blendingColor: 'f00',
);
$this->assertInstanceOf(Config::class, $config);
$this->assertFalse($config->option('autoOrientation'));
$this->assertFalse($config->option('decodeAnimation'));
$this->assertEquals('f00', $config->option('blendingColor'));
}
public function testGetSetOptions(): void
{
$config = new Config();
$this->assertTrue($config->option('autoOrientation'));
$this->assertTrue($config->option('decodeAnimation'));
$this->assertEquals('ffffff00', $config->option('blendingColor'));
$result = $config->setOptions(
autoOrientation: false,
decodeAnimation: false,
blendingColor: 'f00',
);
$this->assertFalse($config->option('autoOrientation'));
$this->assertFalse($config->option('decodeAnimation'));
$this->assertEquals('f00', $config->option('blendingColor'));
$this->assertFalse($result->option('autoOrientation'));
$this->assertFalse($result->option('decodeAnimation'));
$this->assertEquals('f00', $result->option('blendingColor'));
$result = $config->setOption('blendingColor', '000');
$this->assertFalse($config->option('autoOrientation'));
$this->assertFalse($config->option('decodeAnimation'));
$this->assertEquals('000', $config->option('blendingColor'));
$this->assertFalse($result->option('autoOrientation'));
$this->assertFalse($result->option('decodeAnimation'));
$this->assertEquals('000', $result->option('blendingColor'));
$this->assertNull($config->option('unknown'));
$this->assertEquals('test', $config->option('unknown', 'test'));
} }
} }