Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/Appwrite/Utopia/Request/Filters/V16.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ public function parse(array $content, string $model): array
{
switch ($model) {
case 'functions.create':
$content['commands'] = $this->getCommands($content['runtime'] ?? '');
break;
case 'functions.update':
$content['commands'] = $this->getCommands($content['runtime'] ?? '');
break;
Expand Down
54 changes: 35 additions & 19 deletions src/Appwrite/Utopia/Request/Filters/V17.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Appwrite\Utopia\Request\Filters;

use Appwrite\Extend\Exception;
use Appwrite\Utopia\Request\Filter;
use Utopia\Database\Query;

Expand Down Expand Up @@ -67,9 +68,9 @@ private function convertOldQueries(array $content): array
foreach ($content['queries'] as $query) {
try {
$query = $this->parseQuery($query);
$parsed[] = json_encode(array_filter($query->toArray()));
$parsed[] = \json_encode(\array_filter($query->toArray()));
} catch (\Throwable $th) {
throw new \Exception("Invalid query: {$query}", previous: $th);
throw new Exception(Exception::GENERAL_QUERY_INVALID, $th->getMessage());
}
}

Expand All @@ -83,6 +84,7 @@ public function parseQuery(string $filter): Query
{
// Init empty vars we fill later
$method = '';
$attribute = null;
$params = [];

// Separate method from filter
Expand All @@ -92,7 +94,7 @@ public function parseQuery(string $filter): Query
throw new \Exception('Invalid query');
}

$method = mb_substr($filter, 0, $paramsStart);
$method = \mb_substr($filter, 0, $paramsStart);

// Separate params from filter
$paramsEnd = \strlen($filter) - 1; // -1 to ignore )
Expand All @@ -103,14 +105,13 @@ public function parseQuery(string $filter): Query
throw new \Exception('Invalid query method');
}

$currentParam = ""; // We build param here before pushing when it's ended
$currentParam = ''; // We build param here before pushing when it's ended
$currentArrayParam = []; // We build array param here before pushing when it's ended

$stack = []; // State for stack of parentheses
$stackCount = 0; // Length of stack array. Kept as variable to improve performance
$stringStackState = null; // State for string support


// Loop thorough all characters
for ($i = $parametersStart; $i < $paramsEnd; $i++) {
$char = $filter[$i];
Expand All @@ -135,20 +136,25 @@ public function parseQuery(string $filter): Query
($filter[$i - 1] !== static::CHAR_BACKSLASH || $filter[$i - 2] === static::CHAR_BACKSLASH) // Must not be escaped;
) {
if ($isStringStack) {
// Dont mix-up string symbols. Only allow the same as on start
// Don't mix up string symbols. Only allow the same as on start
if ($char === $stringStackState) {
// End of string
$stringStackState = null;
}

// Either way, add symbol to builder
static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam);
} else {
// Start of string
$stringStackState = $char;
static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam);
}

// Either way, add symbol to builder
static::appendSymbol(
$isStringStack,
$char,
$i,
$filter,
$currentParam,
);

continue;
}

Expand All @@ -174,12 +180,12 @@ public function parseQuery(string $filter): Query

continue;
} elseif ($char === static::CHAR_COMMA) { // Params separation support
// If in array stack, dont merge yet, just mark it in array param builder
// If in array stack, don't merge yet, just mark it in array param builder
if ($isArrayStack) {
$currentArrayParam[] = $currentParam;
$currentParam = "";
} else {
// Append from parap builder. Either value, or array
// Append from param builder. Either value, or array
if (empty($currentArrayParam)) {
if (strlen($currentParam)) {
$params[] = $currentParam;
Expand All @@ -193,23 +199,28 @@ public function parseQuery(string $filter): Query
}

// Value, not relevant to syntax
static::appendSymbol($isStringStack, $char, $i, $filter, $currentParam);
static::appendSymbol(
$isStringStack,
$char,
$i,
$filter,
$currentParam,
);
}

if (strlen($currentParam)) {
if (\strlen($currentParam)) {
$params[] = $currentParam;
$currentParam = "";
$currentParam = '';
}

$parsedParams = [];

foreach ($params as $param) {
// If array, parse each child separatelly
// If array, parse each child separately
if (\is_array($param)) {
foreach ($param as $element) {
$arr[] = self::parseValue($element);
}

$parsedParams[] = $arr ?? [];
} else {
$parsedParams[] = self::parseValue($param);
Expand Down Expand Up @@ -295,8 +306,13 @@ private function parseValue(string $value): mixed
* @param string $currentParam
* @return void
*/
private function appendSymbol(bool $isStringStack, string $char, int $index, string $filter, string &$currentParam): void
{
private function appendSymbol(
bool $isStringStack,
string $char,
int $index,
string $filter,
string &$currentParam
): void {
// Ignore spaces and commas outside of string
$canBeIgnored = false;

Expand Down
35 changes: 24 additions & 11 deletions src/Appwrite/Utopia/Request/Filters/V20.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

namespace Appwrite\Utopia\Request\Filters;

use Appwrite\Extend\Exception;
use Appwrite\Utopia\Request\Filter;
use Utopia\Database\Database;
use Utopia\Database\Exception\NotFound;
use Utopia\Database\Exception\Query as QueryException;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
Expand Down Expand Up @@ -54,8 +56,8 @@ protected function manageSelectQueries(array $content): array

try {
$parsed = Query::parseQueries($content['queries']);
} catch (QueryException) {
return $content;
} catch (QueryException $e) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}

$selections = Query::groupByType($parsed)['selections'] ?? [];
Expand Down Expand Up @@ -136,17 +138,28 @@ private function getRelatedCollectionKeys(
return [];
}

$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
return [];
try {
$database = Authorization::skip(fn () => $dbForProject->getDocument(
'databases',
$databaseId
));
if ($database->isEmpty()) {
return [];
}
} catch (NotFound) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}

$collection = Authorization::skip(fn () => $dbForProject->getDocument(
'database_' . $database->getSequence(),
$collectionId
));
if ($collection->isEmpty()) {
return [];
try {
$collection = Authorization::skip(fn () => $dbForProject->getDocument(
'database_' . $database->getSequence(),
$collectionId
));
if ($collection->isEmpty()) {
return [];
}
} catch (NotFound) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}

$attributes = $collection->getAttribute('attributes', []);
Expand Down