Browse Source

Merge pull request #16744 from cakephp/enum-coercion

Allow string to int coercion in EnumType:toPHP()
othercorey 3 years ago
parent
commit
c215ffff19
2 changed files with 11 additions and 16 deletions
  1. 8 10
      src/Database/Type/EnumType.php
  2. 3 6
      tests/TestCase/Database/Type/EnumTypeTest.php

+ 8 - 10
src/Database/Type/EnumType.php

@@ -43,13 +43,13 @@ class EnumType extends BaseType
     /**
      * The enum classname which is associated to the type instance
      *
-     * @var string
+     * @var class-string<\BackedEnum>
      */
     protected string $enumClassName;
 
     /**
      * @param string $name The name identifying this type
-     * @param string $enumClassName The associated enum class name
+     * @param class-string<\BackedEnum> $enumClassName The associated enum class name
      */
     public function __construct(
         string $name,
@@ -62,7 +62,7 @@ class EnumType extends BaseType
             $this->backingType = (string)$reflectionEnum->getBackingType();
         } catch (ReflectionException) {
             throw new DatabaseException(
-                sprintf('Unable to map enum %s for type %s, must be a backed enum.', $enumClassName, $name)
+                sprintf('Unable to use enum %s for type %s, must be a backed enum.', $enumClassName, $name)
             );
         }
     }
@@ -111,13 +111,11 @@ class EnumType extends BaseType
             return null;
         }
 
-        if (get_debug_type($value) !== $this->backingType) {
-            throw new InvalidArgumentException(sprintf(
-                'Cannot convert value of type %s to %s with type %s',
-                get_debug_type($value),
-                $this->enumClassName,
-                $this->backingType
-            ));
+        if ($this->backingType === 'int' && is_string($value)) {
+            $intVal = filter_var($value, FILTER_VALIDATE_INT);
+            if ($intVal !== false) {
+                $value = $intVal;
+            }
         }
 
         return $this->enumClassName::tryFrom($value);

+ 3 - 6
tests/TestCase/Database/Type/EnumTypeTest.php

@@ -145,23 +145,20 @@ class EnumTypeTest extends TestCase
     /**
      * Test toPHP with string backed enum
      */
-    public function testToPHPString(): void
+    public function testToPHPStringEnum(): void
     {
         $this->assertNull($this->stringType->toPHP(null, $this->driver));
         $this->assertSame(ArticleStatus::PUBLISHED, $this->stringType->toPHP('Y', $this->driver));
-        $this->expectException(InvalidArgumentException::class);
-        $this->stringType->toPHP(1, $this->driver);
     }
 
     /**
      * Test toPHP with integer backed enum
      */
-    public function testToPHPInteger(): void
+    public function testToPHPIntEnum(): void
     {
         $this->assertNull($this->intType->toPHP(null, $this->driver));
         $this->assertSame(Priority::HIGH, $this->intType->toPHP(3, $this->driver));
-        $this->expectException(InvalidArgumentException::class);
-        $this->intType->toPHP('N', $this->driver);
+        $this->assertSame(Priority::HIGH, $this->intType->toPHP('3', $this->driver));
     }
 
     /**