Skip to content

Commit 1951a23

Browse files
authored
Add nullable parameter to the updatedAt behavior (#23)
1 parent a8f0f92 commit 1951a23

File tree

4 files changed

+47
-9
lines changed

4 files changed

+47
-9
lines changed

src/Listener/UpdatedAt.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66

77
use Cycle\ORM\Command\StoreCommandInterface;
88
use Cycle\ORM\Entity\Behavior\Attribute\Listen;
9+
use Cycle\ORM\Entity\Behavior\Event\Mapper\Command\OnCreate;
910
use Cycle\ORM\Entity\Behavior\Event\Mapper\Command\OnUpdate;
1011

1112
final class UpdatedAt
1213
{
1314
public function __construct(
14-
private string $field = 'updatedAt'
15+
private string $field = 'updatedAt',
16+
private bool $nullable = false
1517
) {
1618
}
1719

@@ -22,4 +24,12 @@ public function __invoke(OnUpdate $event): void
2224
$event->command->registerAppendix($this->field, $event->timestamp);
2325
}
2426
}
27+
28+
#[Listen(OnCreate::class)]
29+
public function onCreate(OnCreate $event): void
30+
{
31+
if (!$this->nullable) {
32+
$event->state->register($this->field, $event->timestamp);
33+
}
34+
}
2535
}

src/UpdatedAt.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
use Doctrine\Common\Annotations\Annotation\Target;
1515

1616
/**
17-
* UpdatedAt behavior will automate adding an updating date to your entity. The behavior has two parameters:
17+
* UpdatedAt behavior will automate adding an updating date to your entity. The behavior has three parameters:
1818
* - field - is a property in the entity
19-
* - column - is a column in the database.
19+
* - column - is a column in the database
20+
* - nullable - if this parameter is set to false, will be set initial value when an entity is creating
2021
* Behavior requires a field with the DateTime type.
2122
* A property in an entity and a field in the database can be added in several ways:
2223
* - Can be added by a behavior automatically.
@@ -29,7 +30,8 @@
2930
* @Target({"CLASS"})
3031
* @Attributes({
3132
* @Attribute("field", type="string"),
32-
* @Attribute("column", type="string")
33+
* @Attribute("column", type="string"),
34+
* @Attribute("nullable", type="boolean")
3335
* })
3436
*/
3537
#[\Attribute(\Attribute::TARGET_CLASS), NamedArgumentConstructor]
@@ -39,7 +41,8 @@ final class UpdatedAt extends BaseModifier
3941

4042
public function __construct(
4143
private string $field = 'updatedAt',
42-
?string $column = null
44+
?string $column = null,
45+
private bool $nullable = false
4346
) {
4447
$this->column = $column;
4548
}
@@ -52,7 +55,8 @@ protected function getListenerClass(): string
5255
protected function getListenerArgs(): array
5356
{
5457
return [
55-
'field' => $this->field
58+
'field' => $this->field,
59+
'nullable' => $this->nullable
5660
];
5761
}
5862

tests/Behavior/Fixtures/UpdatedAt/Post.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ class Post
1919
#[Column(type: 'datetime', nullable: true)]
2020
public ?\DateTimeImmutable $updatedAt = null;
2121
public ?\DateTimeImmutable $customUpdatedAt = null;
22+
public \DateTimeImmutable $notNullableUpdatedAt;
2223
public ?string $content = null;
2324
}

tests/Behavior/Functional/Driver/Common/UpdatedAt/ListenerTest.php

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public function setUp(): void
2727
'id' => 'primary',
2828
'updated_at' => 'datetime,nullable',
2929
'custom_updated_at' => 'datetime,nullable',
30+
'not_nullable_updated_at' => 'datetime',
3031
'content' => 'string,nullable'
3132
]
3233
);
@@ -41,19 +42,28 @@ public function setUp(): void
4142
'id' => 'id',
4243
'updatedAt' => 'updated_at',
4344
'customUpdatedAt' => 'custom_updated_at',
45+
'notNullableUpdatedAt' => 'not_nullable_updated_at',
4446
'content' => 'content'
4547
],
4648
SchemaInterface::LISTENERS => [
47-
UpdatedAt::class,
4849
[
4950
UpdatedAt::class,
50-
['field' => 'customUpdatedAt']
51+
['nullable' => true]
52+
],
53+
[
54+
UpdatedAt::class,
55+
['field' => 'customUpdatedAt', 'nullable' => true]
56+
],
57+
[
58+
UpdatedAt::class,
59+
['field' => 'notNullableUpdatedAt', 'nullable' => false]
5160
]
5261
],
5362
SchemaInterface::TYPECAST => [
5463
'id' => 'int',
5564
'updatedAt' => 'datetime',
56-
'customUpdatedAt' => 'datetime'
65+
'customUpdatedAt' => 'datetime',
66+
'notNullableUpdatedAt' => 'datetime'
5767
],
5868
SchemaInterface::SCHEMA => [],
5969
SchemaInterface::RELATIONS => [],
@@ -73,6 +83,19 @@ public function testCreate(): void
7383
$this->assertNull($data->customUpdatedAt);
7484
}
7585

86+
public function testCreateNotNullable(): void
87+
{
88+
$post = new Post();
89+
90+
$this->save($post);
91+
92+
$this->orm->getHeap()->clean();
93+
$select = new Select($this->orm, Post::class);
94+
$data = $select->fetchOne();
95+
96+
$this->assertInstanceOf(\DateTimeImmutable::class, $data->notNullableUpdatedAt);
97+
}
98+
7699
public function testUpdate(): void
77100
{
78101
$post = new Post();

0 commit comments

Comments
 (0)