diff --git a/src/Model/Casts/CastInterface.php b/src/Model/Casts/CastInterface.php new file mode 100644 index 00000000..df9c4f97 --- /dev/null +++ b/src/Model/Casts/CastInterface.php @@ -0,0 +1,12 @@ + new DateTimeCast(), + self::IMMUTABLE_DATE_TIME => new DateTimeImmutableCast(), + default => null, + }; + } +} diff --git a/src/Model/Casts/DateTime/BaseDateTimeCast.php b/src/Model/Casts/DateTime/BaseDateTimeCast.php index 028904df..4d536f3f 100644 --- a/src/Model/Casts/DateTime/BaseDateTimeCast.php +++ b/src/Model/Casts/DateTime/BaseDateTimeCast.php @@ -6,18 +6,21 @@ use MongoDB\BSON\UTCDateTime; use MongoDB\BSON\UTCDateTimeInterface; use Mongolid\Model\Casts\CasterInterface; +use Mongolid\Model\Casts\CastInterface; -abstract class BaseDateTimeCast +abstract class BaseDateTimeCast implements CastInterface { - private const DATE_TIME = 'datetime'; - private const IMMUTABLE_DATE_TIME = 'immutable_datetime'; - - - abstract public static function get(?UTCDateTime $value): ?DateTimeInterface; - - public static function set( - null|DateTimeInterface|UTCDateTimeInterface $value - ): ?UTCDateTime + /** + * @param UTCDateTime|null $value + * @return DateTimeInterface|null + */ + abstract public static function get(mixed $value): mixed; + + /** + * @param DateTimeInterface|UTCDateTimeInterface|null $value + * @return UTCDateTime|null + */ + public static function set(mixed $value): mixed { if (is_null($value)) { return null; @@ -29,13 +32,4 @@ public static function set( return new UTCDateTime($value); } - - public static function resolve(?string $cast): ?self - { - return match($cast) { - self::DATE_TIME => new DateTimeCast(), - self::IMMUTABLE_DATE_TIME => new DateTimeImmutableCast(), - default => null, - }; - } } diff --git a/src/Model/Casts/DateTime/DateTimeCast.php b/src/Model/Casts/DateTime/DateTimeCast.php index 1280680f..9acdbf4d 100644 --- a/src/Model/Casts/DateTime/DateTimeCast.php +++ b/src/Model/Casts/DateTime/DateTimeCast.php @@ -8,9 +8,14 @@ class DateTimeCast extends BaseDateTimeCast { - public static function get(?UTCDateTime $value): ?DateTime + /** + * @param UTCDateTime|null $value + * @return DateTime|null + */ + public static function get(mixed $value): mixed { if (is_null($value)) { + return null; } diff --git a/src/Model/Casts/DateTime/DateTimeImmutableCast.php b/src/Model/Casts/DateTime/DateTimeImmutableCast.php index b308cf05..82b3b106 100644 --- a/src/Model/Casts/DateTime/DateTimeImmutableCast.php +++ b/src/Model/Casts/DateTime/DateTimeImmutableCast.php @@ -12,7 +12,7 @@ class DateTimeImmutableCast extends BaseDateTimeCast * @param UTCDateTime|null $value * @return DateTimeImmutable|null */ - public static function get(?UTCDateTime $value): ?DateTimeImmutable + public static function get(mixed $value): mixed { if (is_null($value)) { return null; diff --git a/src/Model/Casts/Exceptions/InvalidCastException.php b/src/Model/Casts/Exceptions/InvalidCastException.php new file mode 100644 index 00000000..1b9bedae --- /dev/null +++ b/src/Model/Casts/Exceptions/InvalidCastException.php @@ -0,0 +1,17 @@ +mutableCache[$key]; } - if ($caster = BaseDateTimeCast::resolve($this->casts[$key] ?? null)) { - $value = $caster->get($this->attributes[$key]); + if ($caster = CastResolver::resolve($this->casts[$key] ?? null)) { + $value = $caster->get($this->attributes[$key] ?? null); return $value; } @@ -188,7 +187,7 @@ public function setDocumentAttribute(string $key, $value) $value = $this->{$this->buildMutatorMethod($key, 'set')}($value); } - if ($caster = BaseDateTimeCast::resolve($this->casts[$key] ?? null)) { + if ($caster = CastResolver::resolve($this->casts[$key] ?? null)) { $value = $caster->set($value); $this->attributes[$key] = $value; diff --git a/src/Model/HasLegacyAttributesTrait.php b/src/Model/HasLegacyAttributesTrait.php index e353b9e5..9bd1a842 100644 --- a/src/Model/HasLegacyAttributesTrait.php +++ b/src/Model/HasLegacyAttributesTrait.php @@ -1,6 +1,7 @@ attributes); - if ($inAttributes) { - if ($caster = BaseDateTimeCast::resolve($this->casts[$key] ?? null)) { - $value = $caster->get($this->attributes[$key]); - $this->attributes[$key] = $value; + if ($caster = CastResolver::resolve($this->casts[$key] ?? null)) { + $value = $caster->get($this->attributes[$key] ?? null); + $this->attributes[$key] = $value; - return $this->attributes[$key]; - } + return $this->attributes[$key]; + } + if ($inAttributes) { return $this->attributes[$key]; } elseif ('attributes' == $key) { return $this->attributes; @@ -140,7 +141,7 @@ public function cleanAttribute(string $key) */ public function setAttribute(string $key, $value) { - if ($caster = BaseDateTimeCast::resolve($this->casts[$key] ?? null)) { + if ($caster = CastResolver::resolve($this->casts[$key] ?? null)) { $value = $caster->set($value); } diff --git a/tests/Unit/Model/Casts/CastResolverTest.php b/tests/Unit/Model/Casts/CastResolverTest.php new file mode 100644 index 00000000..1011b66b --- /dev/null +++ b/tests/Unit/Model/Casts/CastResolverTest.php @@ -0,0 +1,32 @@ +assertInstanceOf(DateTimeCast::class, $dateTimeCast); + $this->assertInstanceOf(DateTimeImmutableCast::class, $dateTimeImmutableCast); + } + + public function testShouldThrowExceptionWhenGivenInvalidCastToBeResolved(): void + { + // Expectations + $this->expectException(InvalidCastException::class); + $this->expectExceptionMessage('Invalid cast attribute: invalid. Use a valid one like datetime,immutable_datetime'); + + // Actions + CastResolver::resolve('invalid'); + } +} diff --git a/tests/Unit/Model/Casts/DateTime/BaseDateTimeCastTest.php b/tests/Unit/Model/Casts/DateTime/BaseDateTimeCastTest.php index 9b4f0855..b4069162 100644 --- a/tests/Unit/Model/Casts/DateTime/BaseDateTimeCastTest.php +++ b/tests/Unit/Model/Casts/DateTime/BaseDateTimeCastTest.php @@ -25,17 +25,4 @@ public function testShouldSet(): void $this->assertInstanceOf(UTCDateTime::class, $restored_at); $this->assertNull($nulled_at); } - - public function testShouldResolve(): void - { - // Actions - $dateTimeCast = BaseDateTimeCast::resolve('datetime'); - $dateTimeImmutableCast = BaseDateTimeCast::resolve('immutable_datetime'); - $invalidCast = BaseDateTimeCast::resolve('invalid'); - - // Assertions - $this->assertInstanceOf(DateTimeCast::class, $dateTimeCast); - $this->assertInstanceOf(DateTimeImmutableCast::class, $dateTimeImmutableCast); - $this->assertNull($invalidCast); - } }