Skip to content
Prev Previous commit
Next Next commit
allow modification of created at and updated at in update document an…
…d update documents
  • Loading branch information
ArnabChatterjee20k committed Jul 30, 2025
commit d63dcbd67b7f605dcdf3a3fd2afa1265a7251b87
23 changes: 13 additions & 10 deletions src/Database/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -4119,10 +4119,11 @@ public function updateDocument(string $collection, string $id, Document $documen

$skipPermissionsUpdate = ($originalPermissions === $currentPermissions);
}
$createdAt = $document->getCreatedAt();

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

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

if ($shouldUpdate) {
$updatedAt = $document->getUpdatedAt();
$document->setAttribute('$updatedAt', empty($updatedAt) || !$this->preserveDates ? $time : $updatedAt);
$document->setAttribute('$updatedAt', ($updatedAt === null || !$this->preserveDates) ? $time : $updatedAt);
}

// Check if document was updated after the request timestamp
Expand Down Expand Up @@ -4365,29 +4366,31 @@ public function updateDocuments(
if (!empty($cursor) && $cursor->getCollection() !== $collection->getId()) {
throw new DatabaseException("Cursor document must be from the same Collection.");
}

$attributesToCheckForRequiredValidation = ['$updatedAt'];
unset($updates['$id']);
unset($updates['$createdAt']);
unset($updates['$tenant']);

if (($updates->getCreatedAt() === null || !$this->preserveDates)) {
unset($updates['$createdAt']);
} else {
$updates['$createdAt'] = $updates->getCreatedAt();
$attributesToCheckForRequiredValidation[] = '$createdAt';
}
if ($this->adapter->getSharedTables()) {
$updates['$tenant'] = $this->adapter->getTenant();
}

if (!$this->preserveDates) {
$updates['$updatedAt'] = DateTime::now();
}
$updatedAt = $updates->getUpdatedAt();
$updates['$updatedAt'] = ($updatedAt === null || !$this->preserveDates) ? DateTime::now() : $updatedAt;

$updates = $this->encode($collection, $updates);

// Check new document structure
$validator = new PartialStructure(
$collection,
$this->adapter->getMinDateTime(),
$this->adapter->getMaxDateTime(),
);

if (!$validator->isValid($updates)) {
if (!$validator->isValid($updates, $attributesToCheckForRequiredValidation)) {
throw new StructureException($validator->getDescription());
}

Expand Down
12 changes: 11 additions & 1 deletion src/Database/Validator/PartialStructure.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ class PartialStructure extends Structure
* Returns true if valid or false if not.
*
* @param mixed $document
* @param array<string, string> $requiredAttributes optional list of required attributes to check
*
* @return bool
*/
public function isValid($document): bool
public function isValid($document, array $requiredAttributes = []): bool
{
if (!$document instanceof Document) {
$this->message = 'Value must be an instance of Document';
Expand All @@ -36,7 +37,16 @@ public function isValid($document): bool
$name = $attribute['$id'] ?? '';
$keys[$name] = $attribute;
}
$requiredAttributesMap = [];
foreach ($this->attributes as $attribute) {
if ($attribute['required'] === true && in_array($attribute['$id'], $requiredAttributes)) {
$requiredAttributesMap[] = $attribute;
}
}

if (!$this->checkForAllRequiredValues($structure, $requiredAttributesMap, $keys)) {
return false;
}
if (!$this->checkForUnknownAttributes($structure, $keys)) {
return false;
}
Expand Down
Loading
Loading