Fix readonly attr stripping on write

This commit is contained in:
Jake Barnby
2025-08-29 19:30:59 +12:00
parent 7f59872673
commit f0c10acbb4
7 changed files with 90 additions and 17 deletions
@@ -27,9 +27,8 @@ abstract class Action extends AppwriteAction
$this->context = ROWS;
}
// Use the same helper method to ensure consistency
$contextId = '$' . $this->getCollectionsEventsContext() . 'Id';
$this->removableAttributes = ['$databaseId', $contextId, '$sequence'];
$this->removableAttributes = ['$sequence', '$databaseId', $contextId];
return parent::setHttpPath($path);
}
@@ -200,11 +199,13 @@ abstract class Action extends AppwriteAction
* Remove configured removable attributes from a document.
* Used for relationship path handling to remove API-specific attributes.
*/
protected function removeReadonlyAttributes(Document $document): void
protected function removeReadonlyAttributes(Document|array $document): Document|array
{
foreach ($this->removableAttributes as $attribute) {
$document->removeAttribute($attribute);
\var_dump('Removing attribute: ' . $attribute);
unset($document[$attribute]);
}
return $document;
}
/**
@@ -127,8 +127,7 @@ class Update extends Action
}
}
// Remove sequence if set
unset($document['$sequence']);
$data = $this->removeReadonlyAttributes($data);
$documents = [];
@@ -100,6 +100,7 @@ class Upsert extends Action
}
foreach ($documents as $key => $document) {
$document = $this->removeReadonlyAttributes($document);
$documents[$key] = new Document($document);
}
@@ -298,6 +298,8 @@ class Create extends Action
);
foreach ($relations as &$relation) {
$relation = $this->removeReadonlyAttributes($relation);
if (
\is_array($relation)
&& \array_values($relation) !== $relation
@@ -318,7 +320,6 @@ class Create extends Action
$relation['$id'] = ID::unique();
}
} else {
$this->removeReadonlyAttributes($relation);
$relation->setAttribute('$collection', $relatedCollection->getId());
$type = Database::PERMISSION_UPDATE;
}
@@ -351,9 +352,6 @@ class Create extends Action
}
}
// Remove sequence if set
unset($document['$sequence']);
// Assign a unique ID if needed, otherwise use the provided ID.
$document['$id'] = $sourceId === 'unique()' ? ID::unique() : $sourceId;
@@ -368,10 +366,11 @@ class Create extends Action
}
}
$document = $this->removeReadonlyAttributes($document);
$document = new Document($document);
$setPermissions($document, $permissions);
$checkPermissions($collection, $document, Database::PERMISSION_CREATE);
return $document;
}, $documents);
@@ -159,17 +159,14 @@ class Update extends Action
$permissions = $document->getPermissions() ?? [];
}
// Remove sequence if set
unset($document['$sequence']);
$data['$id'] = $documentId;
$data['$permissions'] = $permissions;
$data = $this->removeReadonlyAttributes($data);
$newDocument = new Document($data);
$operations = 0;
$setCollection = (function (Document $collection, Document $document) use (&$setCollection, $dbForProject, $database, &$operations) {
$operations++;
$relationships = \array_filter(
@@ -198,6 +195,8 @@ class Update extends Action
);
foreach ($relations as &$relation) {
$relation = $this->removeReadonlyAttributes($relation);
// If the relation is an array it can be either update or create a child document.
if (
\is_array($relation)
@@ -212,7 +211,7 @@ class Update extends Action
'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(),
$relation->getId()
));
$this->removeReadonlyAttributes($relation);
// Attribute $collection is required for Utopia.
$relation->setAttribute(
'$collection',
@@ -242,6 +241,8 @@ class Update extends Action
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, max($operations, 1))
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), $operations);
\var_dump($newDocument);
try {
$document = $dbForProject->withRequestTimestamp(
$requestTimestamp,
@@ -170,6 +170,7 @@ class Upsert extends Action
$data['$id'] = $documentId;
$data['$permissions'] = $permissions ?? [];
$data = $this->removeReadonlyAttributes($data);
$newDocument = new Document($data);
$operations = 0;
@@ -203,6 +204,8 @@ class Upsert extends Action
);
foreach ($relations as &$relation) {
$relation = $this->removeReadonlyAttributes($relation);
// If the relation is an array it can be either update or create a child document.
if (
\is_array($relation)
@@ -217,7 +220,7 @@ class Upsert extends Action
'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(),
$relation->getId()
));
$this->removeReadonlyAttributes($relation);
// Attribute $collection is required for Utopia.
$relation->setAttribute(
'$collection',