Merge branch '1.8.x' of github.com:appwrite/appwrite into feat-mongodb-pulls

This commit is contained in:
shimon
2025-08-12 17:54:55 +03:00
11 changed files with 1416 additions and 35 deletions
+2 -1
View File
@@ -55,7 +55,8 @@ return [
'$id' => ID::custom('type'),
'type' => Database::VAR_STRING,
'size' => 128,
'required' => true,
'required' => false,
'default' => 'grids',
'signed' => true,
'array' => false,
'filters' => [],
+2 -2
View File
@@ -473,13 +473,13 @@ return [
'frameworks' => [
getFramework('FLUTTER', [
'providerRootDirectory' => './',
'buildCommand' => 'bash build.sh',
'buildCommand' => 'bash prepare-env.sh && flutter build web',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'starter-for-flutter',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'providerVersion' => '0.2.*',
'variables' => [
[
'name' => 'APPWRITE_PUBLIC_ENDPOINT',
+14 -9
View File
@@ -643,15 +643,20 @@ App::get('/v1/users')
$cursor->setValue($cursorDocument);
}
$filterQueries = Query::groupByType($queries)['filters'];
try {
$users = $dbForProject->find('users', $queries);
$total = $dbForProject->count('users', $filterQueries, APP_LIMIT_COUNT);
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
} catch (QueryException $e) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$users = [];
$total = 0;
$dbForProject->skipFilters(function () use ($dbForProject, $queries, &$users, &$total) {
try {
$users = $dbForProject->find('users', $queries);
$total = $dbForProject->count('users', $queries, APP_LIMIT_COUNT);
} catch (OrderException $e) {
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
} catch (QueryException $e) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
}, ['subQueryAuthenticators', 'subQuerySessions', 'subQueryTokens', 'subQueryChallenges', 'subQueryMemberships']);
$response->dynamic(new Document([
'users' => $users,
'total' => $total,
Generated
+63
View File
@@ -6362,15 +6362,19 @@
{
"name": "phpunit/phpunit",
"version": "9.6.24",
"version": "9.6.24",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "ea49afa29aeea25ea7bf9de9fdd7cab163cc0701"
"reference": "ea49afa29aeea25ea7bf9de9fdd7cab163cc0701"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ea49afa29aeea25ea7bf9de9fdd7cab163cc0701",
"reference": "ea49afa29aeea25ea7bf9de9fdd7cab163cc0701",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ea49afa29aeea25ea7bf9de9fdd7cab163cc0701",
"reference": "ea49afa29aeea25ea7bf9de9fdd7cab163cc0701",
"shasum": ""
},
"require": {
@@ -6382,6 +6386,7 @@
"ext-xml": "*",
"ext-xmlwriter": "*",
"myclabs/deep-copy": "^1.13.4",
"myclabs/deep-copy": "^1.13.4",
"phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1",
"php": ">=7.3",
@@ -6393,10 +6398,12 @@
"sebastian/cli-parser": "^1.0.2",
"sebastian/code-unit": "^1.0.8",
"sebastian/comparator": "^4.0.9",
"sebastian/comparator": "^4.0.9",
"sebastian/diff": "^4.0.6",
"sebastian/environment": "^5.1.5",
"sebastian/exporter": "^4.0.6",
"sebastian/global-state": "^5.0.8",
"sebastian/global-state": "^5.0.8",
"sebastian/object-enumerator": "^4.0.4",
"sebastian/resource-operations": "^3.0.4",
"sebastian/type": "^3.2.1",
@@ -6445,6 +6452,7 @@
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.24"
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.24"
},
"funding": [
{
@@ -6469,6 +6477,7 @@
}
],
"time": "2025-08-10T08:32:42+00:00"
"time": "2025-08-10T08:32:42+00:00"
},
{
"name": "psr/cache",
@@ -6689,15 +6698,19 @@
{
"name": "sebastian/comparator",
"version": "4.0.9",
"version": "4.0.9",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5"
"reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/67a2df3a62639eab2cc5906065e9805d4fd5dfc5",
"reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/67a2df3a62639eab2cc5906065e9805d4fd5dfc5",
"reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5",
"shasum": ""
},
"require": {
@@ -6751,6 +6764,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
"source": "https://github.com/sebastianbergmann/comparator/tree/4.0.9"
"source": "https://github.com/sebastianbergmann/comparator/tree/4.0.9"
},
"funding": [
{
@@ -6765,12 +6779,25 @@
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/comparator",
"type": "tidelift"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/comparator",
"type": "tidelift"
}
],
"time": "2025-08-10T06:51:50+00:00"
"time": "2025-08-10T06:51:50+00:00"
},
{
"name": "sebastian/complexity",
@@ -7038,15 +7065,19 @@
{
"name": "sebastian/global-state",
"version": "5.0.8",
"version": "5.0.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
"reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6"
"reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6",
"reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6",
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6",
"reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6",
"shasum": ""
},
"require": {
@@ -7090,6 +7121,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
"source": "https://github.com/sebastianbergmann/global-state/tree/5.0.8"
"source": "https://github.com/sebastianbergmann/global-state/tree/5.0.8"
},
"funding": [
{
@@ -7104,12 +7136,25 @@
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/global-state",
"type": "tidelift"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/global-state",
"type": "tidelift"
}
],
"time": "2025-08-10T07:10:35+00:00"
"time": "2025-08-10T07:10:35+00:00"
},
{
"name": "sebastian/lines-of-code",
@@ -7283,15 +7328,19 @@
{
"name": "sebastian/recursion-context",
"version": "4.0.6",
"version": "4.0.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
"reference": "539c6691e0623af6dc6f9c20384c120f963465a0"
"reference": "539c6691e0623af6dc6f9c20384c120f963465a0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0",
"reference": "539c6691e0623af6dc6f9c20384c120f963465a0",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0",
"reference": "539c6691e0623af6dc6f9c20384c120f963465a0",
"shasum": ""
},
"require": {
@@ -7334,6 +7383,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/recursion-context/issues",
"source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.6"
"source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.6"
},
"funding": [
{
@@ -7348,12 +7398,25 @@
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context",
"type": "tidelift"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context",
"type": "tidelift"
}
],
"time": "2025-08-10T06:57:39+00:00"
"time": "2025-08-10T06:57:39+00:00"
},
{
"name": "sebastian/resource-operations",
+1 -1
View File
@@ -219,7 +219,7 @@ services:
appwrite-console:
<<: *x-logging
container_name: appwrite-console
image: appwrite/console:6.2.0
image: appwrite/console:7.0.0-qa.8
restart: unless-stopped
networks:
- appwrite
@@ -225,9 +225,11 @@ class Databases extends Action
if (! $relatedCollection->isEmpty()) {
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $relatedCollection->getId());
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence());
}
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $collectionId);
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
}
}
@@ -383,9 +385,11 @@ class Databases extends Action
}
} finally {
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $collectionId);
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
if (! $relatedCollection->isEmpty()) {
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $relatedCollection->getId());
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence());
}
}
}
@@ -444,6 +448,7 @@ class Databases extends Action
} finally {
$this->trigger($database, $collection, $project, $event, $queueForRealtime, null, $index);
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $collectionId);
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
}
}
@@ -500,6 +505,7 @@ class Databases extends Action
} finally {
$this->trigger($database, $collection, $project, $event, $queueForRealtime, null, $index);
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $collection->getId());
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
}
}
+12
View File
@@ -6,6 +6,7 @@ use Appwrite\Template\Template;
use Exception;
use PHPMailer\PHPMailer\PHPMailer;
use Swoole\Runtime;
use Utopia\CLI\Console;
use Utopia\Logger\Log;
use Utopia\Platform\Action;
use Utopia\Queue\Message;
@@ -148,6 +149,17 @@ class Mails extends Action
$mail->AltBody = \strip_tags($mail->AltBody);
$mail->AltBody = \trim($mail->AltBody);
if (\str_contains($mail->Body, 'buttonText') || \str_contains($mail->AltBody, 'buttonText')) {
Console::warning('Email might contain placeholder. Logs relevant to verify and isolate the issue:');
var_dump($mail->Body);
var_dump($mail->AltBody);
\var_dump($message->getPayload());
\var_dump($message->getPid());
\var_dump($message->getQueue());
\var_dump($message->getTimestamp());
Console::warning('End of placeholder detection report.');
}
$replyTo = System::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
$replyToName = \urldecode(System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'));
@@ -43,8 +43,8 @@ class Database extends Model
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Database type.',
'default' => 'grids',
'example' => 'grids',
'default' => 'legacy',
'example' => 'legacy',
])
;
}
File diff suppressed because it is too large Load Diff
@@ -1382,8 +1382,7 @@ trait DatabasesBase
'attributes' => ['actors'],
]);
// Indexes on array attributes are disabled due to MySQL bug
$this->assertEquals(400, $actorsArray['headers']['status-code']);
$this->assertEquals(202, $actorsArray['headers']['status-code']);
$twoLevelsArray = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/indexes', array_merge([
'content-type' => 'application/json',
@@ -1396,8 +1395,7 @@ trait DatabasesBase
'orders' => ['DESC', 'DESC'],
]);
// Indexes on array attributes are disabled due to MySQL bug
$this->assertEquals(400, $twoLevelsArray['headers']['status-code']);
$this->assertEquals(202, $twoLevelsArray['headers']['status-code']);
$unknown = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/indexes', array_merge([
'content-type' => 'application/json',
@@ -1423,8 +1421,7 @@ trait DatabasesBase
'orders' => ['DESC'], // Check order is removed in API
]);
// Indexes on array attributes are disabled due to MySQL bug
$this->assertEquals(400, $index1['headers']['status-code']);
$this->assertEquals(202, $index1['headers']['status-code']);
$index2 = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/indexes', array_merge([
'content-type' => 'application/json',
@@ -1436,8 +1433,7 @@ trait DatabasesBase
'attributes' => ['integers'], // array attribute
]);
// Indexes on array attributes are disabled due to MySQL bug
$this->assertEquals(400, $index2['headers']['status-code']);
$this->assertEquals(202, $index2['headers']['status-code']);
/**
* Create Indexes by worker
@@ -1451,7 +1447,7 @@ trait DatabasesBase
]), []);
$this->assertIsArray($movies['body']['indexes']);
$this->assertCount(4, $movies['body']['indexes']);
$this->assertCount(8, $movies['body']['indexes']);
$this->assertEquals($titleIndex['body']['key'], $movies['body']['indexes'][0]['key']);
$this->assertEquals($releaseYearIndex['body']['key'], $movies['body']['indexes'][1]['key']);
$this->assertEquals($releaseWithDate1['body']['key'], $movies['body']['indexes'][2]['key']);
@@ -1049,7 +1049,6 @@ trait MigrationsBase
$this->assertEquals('Appwrite', $migration['body']['destination']);
$this->assertContains(Resource::TYPE_ROW, $migration['body']['resources']);
$this->assertEmpty($migration['body']['statusCounters']);
$errorJson = $migration['body']['errors'][0];
$errorData = json_decode($errorJson, true);
@@ -1082,7 +1081,6 @@ trait MigrationsBase
$this->assertEquals('Appwrite', $migration['body']['destination']);
$this->assertContains(Resource::TYPE_ROW, $migration['body']['resources']);
$this->assertEmpty($migration['body']['statusCounters']);
$errorJson = $migration['body']['errors'][0];
$errorData = json_decode($errorJson, true);