Switch removable attributes

This commit is contained in:
Jake Barnby 2025-08-18 19:52:55 +12:00
parent 34cf5a7c2f
commit ea9cbd2f2c
No known key found for this signature in database
GPG key ID: C437A8CC85B96E9C
6 changed files with 45 additions and 23 deletions

View file

@ -25,6 +25,14 @@ class Action extends UtopiaAction
'subQueryVariables', // Sites
];
/**
* Attributes to remove from relationship path documents per API
* Default is empty - APIs should set their specific attributes
*
* @var array
*/
protected array $removableAttributes = [];
/**
* Foreach Document
* Call provided callback for each document in the collection

View file

@ -4,12 +4,15 @@ namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Documen
use Appwrite\Event\Event;
use Appwrite\Extend\Exception;
use Appwrite\Platform\Action as AppwriteAction;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
use Utopia\Platform\Action as UtopiaAction;
abstract class Action extends UtopiaAction
use const Appwrite\Platform\Modules\Databases\DOCUMENTS;
use const Appwrite\Platform\Modules\Databases\ROWS;
abstract class Action extends AppwriteAction
{
/**
* @var string|null The current context (either 'row' or 'document')
@ -21,10 +24,15 @@ abstract class Action extends UtopiaAction
*/
abstract protected function getResponseModel(): string;
public function setHttpPath(string $path): UtopiaAction
public function setHttpPath(string $path): AppwriteAction
{
if (str_contains($path, '/tablesdb/')) {
$this->context = ROWS;
// Set removable attributes for TablesDB API
$this->removableAttributes = ['$databaseId', '$tableId'];
} else {
// Set removable attributes for Collections API
$this->removableAttributes = ['$databaseId', '$collectionId'];
}
return parent::setHttpPath($path);
@ -192,6 +200,17 @@ abstract class Action extends UtopiaAction
return $this->isCollectionsAPI() ? 'collection' : 'table';
}
/**
* Remove configured removable attributes from a document.
* Used for relationship path handling to remove API-specific attributes.
*/
protected function removeReadonlyAttributes(Document $document): void
{
foreach ($this->removableAttributes as $attribute) {
$document->removeAttribute($attribute);
}
}
/**
* Resolves relationships in a document and attaches metadata.
*/

View file

@ -318,8 +318,7 @@ class Create extends Action
$relation['$id'] = ID::unique();
}
} else {
$relation->removeAttribute('$collectionId');
$relation->removeAttribute('$databaseId');
$this->removeReadonlyAttributes($relation);
$relation->setAttribute('$collection', $relatedCollection->getId());
$type = Database::PERMISSION_UPDATE;
}

View file

@ -209,8 +209,7 @@ class Update extends Action
'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(),
$relation->getId()
));
$relation->removeAttribute('$collectionId');
$relation->removeAttribute('$databaseId');
$this->removeReadonlyAttributes($relation);
// Attribute $collection is required for Utopia.
$relation->setAttribute(
'$collection',

View file

@ -213,8 +213,7 @@ class Upsert extends Action
'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(),
$relation->getId()
));
$relation->removeAttribute('$collectionId');
$relation->removeAttribute('$databaseId');
$this->removeReadonlyAttributes($relation);
// Attribute $collection is required for Utopia.
$relation->setAttribute(
'$collection',

View file

@ -167,11 +167,10 @@ class XList extends Action
return $result || ($query->getMethod() === Query::TYPE_SELECT);
}, false);
// Check if the SELECT query includes $databaseId and $collectionId
// Check if the SELECT query includes the removable attributes
$hasWildcard = false;
$hasDatabaseId = false;
$hasCollectionId = false;
$hasSelectQueries = !empty($selectQueries);
$requestedAttributes = [];
if ($hasSelectQueries) {
foreach ($selectQueries as $query) {
@ -185,22 +184,21 @@ class XList extends Action
break;
}
if (\in_array('$databaseId', $values, true)) {
$hasDatabaseId = true;
}
if (\in_array('$collectionId', $values, true)) {
$hasCollectionId = true;
// Check which removable attributes are explicitly requested
foreach ($this->removableAttributes as $attribute) {
if (\in_array($attribute, $values, true)) {
$requestedAttributes[$attribute] = true;
}
}
}
if (!$hasWildcard) {
foreach ($documents as $document) {
if (!$hasDatabaseId) {
$document->removeAttribute('$databaseId');
}
if (!$hasCollectionId) {
$document->removeAttribute('$collectionId');
// Remove attributes that are not explicitly requested
foreach ($this->removableAttributes as $attribute) {
if (!isset($requestedAttributes[$attribute])) {
$document->removeAttribute($attribute);
}
}
}
}