From d73ccf5271b01980d57201e64cff1ace185fa09b Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Tue, 4 Feb 2025 19:35:42 +0100 Subject: [PATCH] Implement create() & tryCreate() for FileExtension & MediaType --- src/FileExtension.php | 52 ++++++++++++++++++++++++++++++++ src/MediaType.php | 52 ++++++++++++++++++++++++++++++++ tests/Unit/FileExtensionTest.php | 28 +++++++++++++++++ tests/Unit/MediaTypeTest.php | 28 +++++++++++++++++ 4 files changed, 160 insertions(+) diff --git a/src/FileExtension.php b/src/FileExtension.php index ccedccc5..33ab3e61 100644 --- a/src/FileExtension.php +++ b/src/FileExtension.php @@ -4,6 +4,9 @@ namespace Intervention\Image; +use Error; +use Intervention\Image\Exceptions\NotSupportedException; + enum FileExtension: string { case JPG = 'jpg'; @@ -27,6 +30,55 @@ enum FileExtension: string case HEIC = 'heic'; case HEIF = 'heif'; + /** + * Create file extension from given identifier + * + * @param string|Format|MediaType|FileExtension $identifier + * @throws NotSupportedException + * @return FileExtension + */ + public static function create(string|self|Format|MediaType $identifier): self + { + if ($identifier instanceof self) { + return $identifier; + } + + if ($identifier instanceof Format) { + return $identifier->fileExtension(); + } + + if ($identifier instanceof MediaType) { + return $identifier->fileExtension(); + } + + try { + $extension = FileExtension::from(strtolower($identifier)); + } catch (Error) { + try { + $extension = MediaType::from(strtolower($identifier))->fileExtension(); + } catch (Error) { + throw new NotSupportedException('Unable to create file extension from "' . $identifier . '".'); + } + } + + return $extension; + } + + /** + * Try to create media type from given identifier and return null on failure + * + * @param string|Format|MediaType|FileExtension $identifier + * @return FileExtension|null + */ + public static function tryCreate(string|self|Format|MediaType $identifier): ?self + { + try { + return self::create($identifier); + } catch (NotSupportedException) { + return null; + } + } + /** * Return the matching format for the current file extension * diff --git a/src/MediaType.php b/src/MediaType.php index 32d1e6e5..fa564677 100644 --- a/src/MediaType.php +++ b/src/MediaType.php @@ -4,6 +4,9 @@ namespace Intervention\Image; +use Error; +use Intervention\Image\Exceptions\NotSupportedException; + enum MediaType: string { case IMAGE_JPEG = 'image/jpeg'; @@ -35,6 +38,55 @@ enum MediaType: string case IMAGE_X_HEIC = 'image/x-heic'; case IMAGE_HEIF = 'image/heif'; + /** + * Create media type from given identifier + * + * @param string|Format|MediaType|FileExtension $identifier + * @throws NotSupportedException + * @return MediaType + */ + public static function create(string|self|Format|FileExtension $identifier): self + { + if ($identifier instanceof self) { + return $identifier; + } + + if ($identifier instanceof Format) { + return $identifier->mediaType(); + } + + if ($identifier instanceof FileExtension) { + return $identifier->mediaType(); + } + + try { + $type = MediaType::from(strtolower($identifier)); + } catch (Error) { + try { + $type = FileExtension::from(strtolower($identifier))->mediaType(); + } catch (Error) { + throw new NotSupportedException('Unable to create media type from "' . $identifier . '".'); + } + } + + return $type; + } + + /** + * Try to create media type from given identifier and return null on failure + * + * @param string|Format|MediaType|FileExtension $identifier + * @return MediaType|null + */ + public static function tryCreate(string|self|Format|FileExtension $identifier): ?self + { + try { + return self::create($identifier); + } catch (NotSupportedException) { + return null; + } + } + /** * Return the matching format for the current media (MIME) type * diff --git a/tests/Unit/FileExtensionTest.php b/tests/Unit/FileExtensionTest.php index 04f7c917..33d73c6e 100644 --- a/tests/Unit/FileExtensionTest.php +++ b/tests/Unit/FileExtensionTest.php @@ -5,6 +5,7 @@ namespace Intervention\Image\Tests\Unit; use Generator; +use Intervention\Image\Exceptions\NotSupportedException; use Intervention\Image\FileExtension; use Intervention\Image\Format; use Intervention\Image\MediaType; @@ -15,6 +16,33 @@ #[CoversClass(FileExtension::class)] final class FileExtensionTest extends BaseTestCase { + public function testCreate(): void + { + $this->assertEquals(FileExtension::JPG, FileExtension::create(MediaType::IMAGE_JPEG)); + $this->assertEquals(FileExtension::JPG, FileExtension::create(Format::JPEG)); + $this->assertEquals(FileExtension::JPG, FileExtension::create(FileExtension::JPG)); + $this->assertEquals(FileExtension::JPG, FileExtension::create('jpg')); + $this->assertEquals(FileExtension::JPEG, FileExtension::create('jpeg')); + $this->assertEquals(FileExtension::JPG, FileExtension::create('image/jpeg')); + } + + public function testCreateUnknown(): void + { + $this->expectException(NotSupportedException::class); + FileExtension::create('foo'); + } + + public function testTryCreate(): void + { + $this->assertEquals(FileExtension::JPG, FileExtension::tryCreate(MediaType::IMAGE_JPEG)); + $this->assertEquals(FileExtension::JPG, FileExtension::tryCreate(Format::JPEG)); + $this->assertEquals(FileExtension::JPG, FileExtension::tryCreate(FileExtension::JPG)); + $this->assertEquals(FileExtension::JPG, FileExtension::tryCreate('jpg')); + $this->assertEquals(FileExtension::JPEG, FileExtension::tryCreate('jpeg')); + $this->assertEquals(FileExtension::JPG, FileExtension::tryCreate('image/jpeg')); + $this->assertNull(FileExtension::tryCreate('no-format')); + } + public function testFormatJpeg(): void { $ext = FileExtension::JPEG; diff --git a/tests/Unit/MediaTypeTest.php b/tests/Unit/MediaTypeTest.php index 32fb8364..b9643bcb 100644 --- a/tests/Unit/MediaTypeTest.php +++ b/tests/Unit/MediaTypeTest.php @@ -5,6 +5,7 @@ namespace Intervention\Image\Tests\Unit; use Generator; +use Intervention\Image\Exceptions\NotSupportedException; use Intervention\Image\FileExtension; use Intervention\Image\Format; use Intervention\Image\MediaType; @@ -15,6 +16,33 @@ #[CoversClass(MediaType::class)] final class MediaTypeTest extends BaseTestCase { + public function testCreate(): void + { + $this->assertEquals(MediaType::IMAGE_JPEG, MediaType::create(MediaType::IMAGE_JPEG)); + $this->assertEquals(MediaType::IMAGE_JPEG, MediaType::create(Format::JPEG)); + $this->assertEquals(MediaType::IMAGE_JPEG, MediaType::create(FileExtension::JPG)); + $this->assertEquals(MediaType::IMAGE_JPEG, MediaType::create('jpg')); + $this->assertEquals(MediaType::IMAGE_JPEG, MediaType::create('jpeg')); + $this->assertEquals(MediaType::IMAGE_JPEG, MediaType::create('image/jpeg')); + } + + public function testCreateUnknown(): void + { + $this->expectException(NotSupportedException::class); + MediaType::create('foo'); + } + + public function testTryCreate(): void + { + $this->assertEquals(MediaType::IMAGE_JPEG, MediaType::tryCreate(MediaType::IMAGE_JPEG)); + $this->assertEquals(MediaType::IMAGE_JPEG, MediaType::tryCreate(Format::JPEG)); + $this->assertEquals(MediaType::IMAGE_JPEG, MediaType::tryCreate(FileExtension::JPG)); + $this->assertEquals(MediaType::IMAGE_JPEG, MediaType::tryCreate('jpg')); + $this->assertEquals(MediaType::IMAGE_JPEG, MediaType::tryCreate('jpeg')); + $this->assertEquals(MediaType::IMAGE_JPEG, MediaType::tryCreate('image/jpeg')); + $this->assertNull(Format::tryCreate('no-format')); + } + public function testFormatJpeg(): void { $mime = MediaType::IMAGE_JPEG;