Skip to content

Commit

Permalink
chore: split datetimecast into multiple classes
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielgomes94 committed Oct 16, 2023
1 parent 5f782da commit a5e6a07
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 96 deletions.
36 changes: 36 additions & 0 deletions src/Model/Casts/Caster.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Mongolid\Model\Casts;

use MongoDB\BSON\UTCDateTime;
use Mongolid\Model\Casts\DateTime\BaseDateTimeCast;
use Mongolid\Model\Casts\DateTime\DateTimeCast;
use Mongolid\Model\Casts\DateTime\DateTimeImmutableCast;

class Caster
{
public static function castToDateTime(
string $cast,
mixed $value
)
{
if (!$value instanceof UTCDateTime) {
return null;
}

if ($cast === 'datetime') {
return DateTimeCast::castToDateTime($value);
}

if ($cast === 'immutable_datetime') {
return DateTimeImmutableCast::castToDateTime($value);
}

return null;
}

public static function castToMongoUTCDateTime(mixed $value): ?UTCDateTime
{
return BaseDateTimeCast::castToMongoUTCDateTime($value);
}
}
25 changes: 25 additions & 0 deletions src/Model/Casts/DateTime/BaseDateTimeCast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Mongolid\Model\Casts\DateTime;

use DateTimeInterface;
use MongoDB\BSON\UTCDateTime;

abstract class BaseDateTimeCast
{
public static array $validCasts = [
'datetime',
'immutable_datetime',
];

abstract public static function castToDateTime(?UTCDateTime $value): ?DateTimeInterface;

public static function castToMongoUTCDateTime(?DateTimeInterface $value): ?UTCDateTime
{
if (is_null($value)) {
return null;
}

return new UTCDateTime($value);
}
}
19 changes: 19 additions & 0 deletions src/Model/Casts/DateTime/DateTimeCast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Mongolid\Model\Casts\DateTime;

use DateTime;
use MongoDB\BSON\UTCDateTime;
use Mongolid\Util\LocalDateTime;

class DateTimeCast extends BaseDateTimeCast
{
public static function castToDateTime(?UTCDateTime $value): ?DateTime
{
if (is_null($value)) {
return null;
}

return LocalDateTime::get($value);
}
}
25 changes: 25 additions & 0 deletions src/Model/Casts/DateTime/DateTimeImmutableCast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Mongolid\Model\Casts\DateTime;

use DateTimeImmutable;
use MongoDB\BSON\UTCDateTime;
use Mongolid\Util\LocalDateTime;

class DateTimeImmutableCast extends BaseDateTimeCast
{
/**
* @param UTCDateTime|null $value
* @return DateTimeImmutable|null
*/
public static function castToDateTime(?UTCDateTime $value): ?DateTimeImmutable
{
if (is_null($value)) {
return null;
}

return DateTimeImmutable::createFromMutable(
LocalDateTime::get($value)
);
}
}
65 changes: 0 additions & 65 deletions src/Model/Casts/DateTimeCast.php

This file was deleted.

31 changes: 18 additions & 13 deletions src/Model/HasAttributesTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
use DateTimeInterface;
use Exception;
use Illuminate\Support\Str;
use MongoDB\BSON\UTCDateTime;
use Mongolid\Container\Container;
use Mongolid\Model\Casts\DateTimeCast;
use Mongolid\Model\Casts\Caster;
use Mongolid\Model\Casts\DateTime\BaseDateTimeCast;
use Mongolid\Model\Casts\DateTime\DateTimeCast;
use stdClass;

/**
Expand Down Expand Up @@ -133,15 +136,8 @@ public function &getDocumentAttribute(string $key)
return $this->mutableCache[$key];
}

if (
$this->shouldCastDateTime($key)
&& !$this->attributes[$key] instanceof DateTimeInterface
) {
$this->attributes[$key] = DateTimeCast::castToDateTime(
$key,
$this->casts,
$this->attributes[$key]
);
if ($this->shouldCastDateTime($key)) {
$this->attributes[$key] = Caster::castToDateTime($this->casts[$key], $this->attributes[$key]);

return $this->attributes[$key];
}
Expand Down Expand Up @@ -194,8 +190,8 @@ public function setDocumentAttribute(string $key, $value)
$value = $this->{$this->buildMutatorMethod($key, 'set')}($value);
}

if ($this->shouldCastDateTime($key)) {
$this->attributes[$key] = DateTimeCast::castToMongoUTCDateTime($value);
if ($this->shouldCastUTCDateTime($key, $value)) {
$this->attributes[$key] = Caster::castToMongoUTCDateTime($value);

return $this->attributes[$key];
}
Expand Down Expand Up @@ -268,6 +264,15 @@ protected function buildMutatorMethod(string $key, string $prefix): string
private function shouldCastDateTime(string $key): bool
{
return array_key_exists($key, $this->casts)
&& in_array($this->casts[$key], DateTimeCast::$validCasts);
&& in_array($this->casts[$key], BaseDateTimeCast::$validCasts)
&& !$this->attributes[$key] instanceof DateTimeInterface;
}


private function shouldCastUTCDateTime(string $key, mixed $value): bool
{
return array_key_exists($key, $this->casts)
&& in_array($this->casts[$key], BaseDateTimeCast::$validCasts)
&& !$value instanceof UTCDateTime;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,25 @@
use DateTime;
use DateTimeImmutable;
use MongoDB\BSON\UTCDateTime;
use Mongolid\TestCase;
use Mongolid\Model\Casts\DateTime\DateTimeCast;
use PHPUnit\Framework\TestCase;

class DateTimeCastTest extends TestCase
class CasterTest extends TestCase
{
public function testCastToDateTime(): void
{
// Set
$casts = [
'expires_at' => 'datetime',
'birthdate' => 'immutable_datetime',
'validated_at' => 'datetime',
'created_at' => 'immutable_datetime',
'deleted_at' => 'invalid',
];
$timestamp = new UTCDateTime(
DateTime::createFromFormat('d/m/Y H:i:s', '08/10/2025 12:30:45')
);

// Actions
$revoked_at = DateTimeCast::castToDateTime('revoked_at', $casts, new DateTime());
$birthdate = DateTimeCast::castToDateTime('birthdate', $casts, $timestamp);
$expires_at = DateTimeCast::castToDateTime('expires_at', $casts, $timestamp);
$deleted_at = DateTimeCast::castToDateTime('deleted_at', $casts, $timestamp);
$validated_at = DateTimeCast::castToDateTime('validated_at', $casts, $timestamp);
$created_at = DateTimeCast::castToDateTime('created_at', $casts, $timestamp);
$revoked_at = Caster::castToDateTime('datetime', new DateTime());
$birthdate = Caster::castToDateTime('immutable_datetime', $timestamp);
$expires_at = Caster::castToDateTime('datetime', $timestamp);
$deleted_at = Caster::castToDateTime('invalid', $timestamp);
$validated_at = Caster::castToDateTime('datetime', $timestamp);
$created_at = Caster::castToDateTime('immutable_datetime', $timestamp);

// Assertions
$this->assertNull($revoked_at);
Expand All @@ -44,15 +38,12 @@ public function testCastToMongoUTCDateTime(): void
{
// Set
$dateInDateTime = DateTime::createFromFormat('d/m/Y H:i:s', '08/10/2025 12:30:45');
$dateInUTC = new UTCDateTime($dateInDateTime);

// Actions
$revoked_at = DateTimeCast::castToMongoUTCDateTime($dateInUTC);
$expires_at = DateTimeCast::castToMongoUTCDateTime($dateInDateTime);
$nulled_at = DateTimeCast::castToMongoUTCDateTime(null);

// Assertions
$this->assertInstanceOf(UTCDateTime::class, $revoked_at);
$this->assertInstanceOf(UTCDateTime::class, $expires_at);
$this->assertNull($nulled_at);
}
Expand Down
23 changes: 23 additions & 0 deletions tests/Unit/Model/Casts/DateTime/BaseDateTimeCast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Mongolid\Model\Casts\DateTime;

use MongoDB\BSON\UTCDateTime;
use Mongolid\TestCase;

class BaseDateTimeCast extends TestCase
{
public function testCastToMongoUTCDateTime(): void
{
// Set
$dateInDateTime = DateTime::createFromFormat('d/m/Y H:i:s', '08/10/2025 12:30:45');

// Actions
$expires_at = DateTimeCast::castToMongoUTCDateTime($dateInDateTime);
$nulled_at = DateTimeCast::castToMongoUTCDateTime(null);

// Assertions
$this->assertInstanceOf(UTCDateTime::class, $expires_at);
$this->assertNull($nulled_at);
}
}
28 changes: 28 additions & 0 deletions tests/Unit/Model/Casts/DateTime/DateTimeCastTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Mongolid\Model\Casts\DateTime;

use DateTime;
use MongoDB\BSON\UTCDateTime;
use Mongolid\TestCase;

class DateTimeCastTest extends TestCase
{
public function testCastToDateTime(): void
{
// Set
$timestamp = new UTCDateTime(
DateTime::createFromFormat('d/m/Y H:i:s', '08/10/2025 12:30:45')
);

// Actions
$revoked_at = DateTimeCast::castToDateTime(null);
$expires_at = DateTimeCast::castToDateTime($timestamp);
$validated_at = DateTimeCast::castToDateTime($timestamp);

// Assertions
$this->assertNull($revoked_at);
$this->assertInstanceOf(DateTime::class, $expires_at);
$this->assertInstanceOf(DateTime::class, $validated_at);
}
}
28 changes: 28 additions & 0 deletions tests/Unit/Model/Casts/DateTime/DateTimeImmutableCastTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Mongolid\Model\Casts\DateTime;

use DateTimeImmutable;
use MongoDB\BSON\UTCDateTime;
use Mongolid\TestCase;

class DateTimeImmutableCastTest extends TestCase
{
public function testCastToDateTime(): void
{
// Set
$timestamp = new UTCDateTime(
DateTimeImmutable::createFromFormat('d/m/Y H:i:s', '08/10/2025 12:30:45')
);

// Actions
$revoked_at = DateTimeImmutableCast::castToDateTime(null);
$birthdate = DateTimeImmutableCast::castToDateTime($timestamp);
$created_at = DateTimeImmutableCast::castToDateTime($timestamp);

// Assertions
$this->assertNull($revoked_at);
$this->assertInstanceOf(DateTimeImmutable::class, $birthdate);
$this->assertInstanceOf(DateTimeImmutable::class, $created_at);
}
}

0 comments on commit a5e6a07

Please sign in to comment.