Skip to content

Commit 45cf27f

Browse files
authored
Merge pull request #642 from utopia-php/dat-588
Allow modifying createdAt and updatedAt
2 parents 68545df + e15bf27 commit 45cf27f

File tree

7 files changed

+787
-25
lines changed

7 files changed

+787
-25
lines changed

src/Database/Adapter/SQL.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,10 @@ public function updateDocuments(string $collection, Document $updates, array $do
422422
$attributes['_updatedAt'] = $updates->getUpdatedAt();
423423
}
424424

425+
if (!empty($updates->getCreatedAt())) {
426+
$attributes['_createdAt'] = $updates->getCreatedAt();
427+
}
428+
425429
if (!empty($updates->getPermissions())) {
426430
$attributes['_permissions'] = json_encode($updates->getPermissions());
427431
}

src/Database/Database.php

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3604,8 +3604,8 @@ public function createDocument(string $collection, Document $document): Document
36043604
$document
36053605
->setAttribute('$id', empty($document->getId()) ? ID::unique() : $document->getId())
36063606
->setAttribute('$collection', $collection->getId())
3607-
->setAttribute('$createdAt', empty($createdAt) || !$this->preserveDates ? $time : $createdAt)
3608-
->setAttribute('$updatedAt', empty($updatedAt) || !$this->preserveDates ? $time : $updatedAt);
3607+
->setAttribute('$createdAt', ($createdAt === null || !$this->preserveDates) ? $time : $createdAt)
3608+
->setAttribute('$updatedAt', ($updatedAt === null || !$this->preserveDates) ? $time : $updatedAt);
36093609

36103610
if ($this->adapter->getSharedTables()) {
36113611
if ($this->adapter->getTenantPerDocument()) {
@@ -3703,8 +3703,8 @@ public function createDocuments(
37033703
$document
37043704
->setAttribute('$id', empty($document->getId()) ? ID::unique() : $document->getId())
37053705
->setAttribute('$collection', $collection->getId())
3706-
->setAttribute('$createdAt', empty($createdAt) || !$this->preserveDates ? $time : $createdAt)
3707-
->setAttribute('$updatedAt', empty($updatedAt) || !$this->preserveDates ? $time : $updatedAt);
3706+
->setAttribute('$createdAt', ($createdAt === null || !$this->preserveDates) ? $time : $createdAt)
3707+
->setAttribute('$updatedAt', ($updatedAt === null || !$this->preserveDates) ? $time : $updatedAt);
37083708

37093709
if ($this->adapter->getSharedTables()) {
37103710
if ($this->adapter->getTenantPerDocument()) {
@@ -4119,10 +4119,11 @@ public function updateDocument(string $collection, string $id, Document $documen
41194119

41204120
$skipPermissionsUpdate = ($originalPermissions === $currentPermissions);
41214121
}
4122+
$createdAt = $document->getCreatedAt();
41224123

41234124
$document = \array_merge($old->getArrayCopy(), $document->getArrayCopy());
41244125
$document['$collection'] = $old->getAttribute('$collection'); // Make sure user doesn't switch collection ID
4125-
$document['$createdAt'] = $old->getCreatedAt(); // Make sure user doesn't switch createdAt
4126+
$document['$createdAt'] = ($createdAt === null || !$this->preserveDates) ? $old->getCreatedAt() : $createdAt;
41264127

41274128
if ($this->adapter->getSharedTables()) {
41284129
$document['$tenant'] = $old->getTenant(); // Make sure user doesn't switch tenant
@@ -4251,7 +4252,7 @@ public function updateDocument(string $collection, string $id, Document $documen
42514252

42524253
if ($shouldUpdate) {
42534254
$updatedAt = $document->getUpdatedAt();
4254-
$document->setAttribute('$updatedAt', empty($updatedAt) || !$this->preserveDates ? $time : $updatedAt);
4255+
$document->setAttribute('$updatedAt', ($updatedAt === null || !$this->preserveDates) ? $time : $updatedAt);
42554256
}
42564257

42574258
// Check if document was updated after the request timestamp
@@ -4365,21 +4366,21 @@ public function updateDocuments(
43654366
if (!empty($cursor) && $cursor->getCollection() !== $collection->getId()) {
43664367
throw new DatabaseException("Cursor document must be from the same Collection.");
43674368
}
4368-
43694369
unset($updates['$id']);
4370-
unset($updates['$createdAt']);
43714370
unset($updates['$tenant']);
4372-
4371+
if (($updates->getCreatedAt() === null || !$this->preserveDates)) {
4372+
unset($updates['$createdAt']);
4373+
} else {
4374+
$updates['$createdAt'] = $updates->getCreatedAt();
4375+
}
43734376
if ($this->adapter->getSharedTables()) {
43744377
$updates['$tenant'] = $this->adapter->getTenant();
43754378
}
43764379

4377-
if (!$this->preserveDates) {
4378-
$updates['$updatedAt'] = DateTime::now();
4379-
}
4380+
$updatedAt = $updates->getUpdatedAt();
4381+
$updates['$updatedAt'] = ($updatedAt === null || !$this->preserveDates) ? DateTime::now() : $updatedAt;
43804382

43814383
$updates = $this->encode($collection, $updates);
4382-
43834384
// Check new document structure
43844385
$validator = new PartialStructure(
43854386
$collection,
@@ -4990,14 +4991,14 @@ public function createOrUpdateDocumentsWithIncrease(
49904991
$document
49914992
->setAttribute('$id', empty($document->getId()) ? ID::unique() : $document->getId())
49924993
->setAttribute('$collection', $collection->getId())
4993-
->setAttribute('$updatedAt', empty($updatedAt) || !$this->preserveDates ? $time : $updatedAt)
4994+
->setAttribute('$updatedAt', ($updatedAt === null || !$this->preserveDates) ? $time : $updatedAt)
49944995
->removeAttribute('$sequence');
49954996

4996-
if ($old->isEmpty()) {
4997-
$createdAt = $document->getCreatedAt();
4998-
$document->setAttribute('$createdAt', empty($createdAt) || !$this->preserveDates ? $time : $createdAt);
4997+
$createdAt = $document->getCreatedAt();
4998+
if ($createdAt === null || !$this->preserveDates) {
4999+
$document->setAttribute('$createdAt', $old->isEmpty() ? $time : $old->getCreatedAt());
49995000
} else {
5000-
$document['$createdAt'] = $old->getCreatedAt();
5001+
$document->setAttribute('$createdAt', $createdAt);
50015002
}
50025003

50035004
// Force matching optional parameter sets
@@ -6312,7 +6313,7 @@ public static function addFilter(string $name, callable $encode, callable $decod
63126313
public function encode(Document $collection, Document $document): Document
63136314
{
63146315
$attributes = $collection->getAttribute('attributes', []);
6315-
6316+
$internalDateAttributes = ['$createdAt','$updatedAt'];
63166317
foreach ($this->getInternalAttributes() as $attribute) {
63176318
$attributes[] = $attribute;
63186319
}
@@ -6324,6 +6325,11 @@ public function encode(Document $collection, Document $document): Document
63246325
$filters = $attribute['filters'] ?? [];
63256326
$value = $document->getAttribute($key);
63266327

6328+
if (in_array($key, $internalDateAttributes) && is_string($value) && empty($value)) {
6329+
$document->setAttribute($key, null);
6330+
continue;
6331+
}
6332+
63276333
if ($key === '$permissions') {
63286334
if (empty($value)) {
63296335
$document->setAttribute('$permissions', []); // set default value
@@ -6356,7 +6362,6 @@ public function encode(Document $collection, Document $document): Document
63566362
if (!$array) {
63576363
$value = $value[0];
63586364
}
6359-
63606365
$document->setAttribute($key, $value);
63616366
}
63626367

src/Database/Validator/PartialStructure.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,19 @@ public function isValid($document): bool
3636
$name = $attribute['$id'] ?? '';
3737
$keys[$name] = $attribute;
3838
}
39+
/**
40+
* @var array<string, mixed> $requiredAttributes
41+
*/
42+
$requiredAttributes = [];
43+
foreach ($this->attributes as $attribute) {
44+
if ($attribute['required'] === true && $document->offsetExists($attribute['$id'])) {
45+
$requiredAttributes[] = $attribute;
46+
}
47+
}
3948

49+
if (!$this->checkForAllRequiredValues($structure, $requiredAttributes, $keys)) {
50+
return false;
51+
}
4052
if (!$this->checkForUnknownAttributes($structure, $keys)) {
4153
return false;
4254
}

src/Database/Validator/Structure.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class Structure extends Validator
7171
'$id' => '$createdAt',
7272
'type' => Database::VAR_DATETIME,
7373
'size' => 0,
74-
'required' => false,
74+
'required' => true,
7575
'signed' => false,
7676
'array' => false,
7777
'filters' => [],
@@ -80,7 +80,7 @@ class Structure extends Validator
8080
'$id' => '$updatedAt',
8181
'type' => Database::VAR_DATETIME,
8282
'size' => 0,
83-
'required' => false,
83+
'required' => true,
8484
'signed' => false,
8585
'array' => false,
8686
'filters' => [],

0 commit comments

Comments
 (0)