Skip to content

Commit 67815dc

Browse files
author
Ivan Vasilkov
committed
Add Date attribute
1 parent 9afb80f commit 67815dc

File tree

4 files changed

+97
-1
lines changed

4 files changed

+97
-1
lines changed

src/Attributes/Date.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Composite\Entity\Attributes;
4+
5+
#[\Attribute(\Attribute::TARGET_PARAMETER | \Attribute::TARGET_PROPERTY)]
6+
class Date
7+
{
8+
}

src/Columns/DateTimeColumn.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Composite\Entity\Columns;
44

5+
use Composite\Entity\Attributes\Date;
56
use Composite\Entity\Helpers\DateTimeHelper;
67

78
class DateTimeColumn extends AbstractColumn
@@ -17,7 +18,8 @@ public function cast(mixed $dbValue): ?\DateTimeInterface
1718
/** @var class-string<\DateTimeInterface> $class */
1819
$class = $this->type;
1920
if (is_string($dbValue)) {
20-
return new $class($dbValue);
21+
$timeValue = $this->isDate() ? substr($dbValue, 0, 10) : $dbValue;
22+
return new $class($timeValue);
2123
} elseif ($dbValue instanceof $class) {
2224
return $dbValue;
2325
} else {
@@ -30,9 +32,17 @@ public function cast(mixed $dbValue): ?\DateTimeInterface
3032
*/
3133
public function uncast(mixed $entityValue): ?string
3234
{
35+
if ($this->isDate()) {
36+
return $entityValue->format(DateTimeHelper::DATE_FORMAT);
37+
}
3338
if ($this->isNullable && DateTimeHelper::isDefault($entityValue)) {
3439
return null;
3540
}
3641
return DateTimeHelper::dateTimeToString($entityValue);
3742
}
43+
44+
private function isDate(): bool
45+
{
46+
return (bool)$this->getFirstAttributeByClass(Date::class);
47+
}
3848
}

src/Helpers/DateTimeHelper.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class DateTimeHelper
99
final public const DEFAULT_DATETIME = '1000-01-01 00:00:00';
1010
final public const DEFAULT_DATETIME_MICRO = '1000-01-01 00:00:00.000000';
1111
final public const DATETIME_FORMAT = 'Y-m-d H:i:s';
12+
final public const DATE_FORMAT = 'Y-m-d';
1213
final public const DATETIME_MICRO_FORMAT = 'Y-m-d H:i:s.u';
1314

1415
public static function getDefaultDateTimeImmutable() : \DateTimeImmutable

tests/Columns/DateTimeColumnTest.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
namespace Composite\Entity\Tests\Columns;
44

55
use Composite\Entity\AbstractEntity;
6+
use Composite\Entity\Attributes\Date;
67
use Composite\Entity\Helpers\DateTimeHelper;
8+
use DateTimeImmutable;
79

810
final class DateTimeColumnTest extends \PHPUnit\Framework\TestCase
911
{
@@ -139,4 +141,79 @@ public function __construct(
139141
$newEntity = $entity::fromArray(['column' => null]);
140142
$this->assertNull($newEntity->column);
141143
}
144+
145+
146+
public static function date_dataProvider(): array
147+
{
148+
return [
149+
[
150+
'value' => '2020-01-02 23:59:59',
151+
'expected' => '2020-01-02',
152+
],
153+
[
154+
'value' => '2000-02-02 00:00:00',
155+
'expected' => '2000-02-02',
156+
],
157+
[
158+
'value' => '1990-07-07',
159+
'expected' => '1990-07-07',
160+
],
161+
[
162+
'value' => 'not valid',
163+
'expected' => null,
164+
],
165+
[
166+
'value' => null,
167+
'expected' => null,
168+
],
169+
[
170+
'value' => false,
171+
'expected' => null,
172+
],
173+
];
174+
}
175+
176+
/**
177+
* @dataProvider date_dataProvider
178+
*/
179+
public function test_dateUncast(mixed $value, ?string $expected): void
180+
{
181+
$class = new class() extends AbstractEntity {
182+
public function __construct(
183+
#[Date]
184+
public ?\DateTimeImmutable $column = null,
185+
) {}
186+
};
187+
188+
$entity = $class::fromArray(['column' => $value]);
189+
$actual = $entity->toArray()['column'];
190+
$this->assertEquals($expected, $actual);
191+
}
192+
193+
public function test_dateCast(): void
194+
{
195+
$date = '2000-01-01';
196+
$dti = new \DateTimeImmutable($date . ' 12:00:00');
197+
$entity = new class($dti) extends AbstractEntity {
198+
public function __construct(
199+
#[Date]
200+
public \DateTimeImmutable $column,
201+
) {}
202+
};
203+
$entity->resetChangedColumns();
204+
205+
$actual = $entity->toArray()['column'];
206+
$this->assertEquals($date, $actual);
207+
$this->assertEmpty($entity->getChangedColumns());
208+
209+
$entity->column = new DateTimeImmutable($date . ' 23:59:59');
210+
$this->assertEmpty($entity->getChangedColumns());
211+
212+
$newDate = '2020-07-07';
213+
$entity->column = new DateTimeImmutable($newDate . ' 07:07:07');
214+
$this->assertEquals(
215+
['column' => $newDate],
216+
$entity->getChangedColumns(),
217+
);
218+
}
142219
}

0 commit comments

Comments
 (0)