diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 682c18f85f..aa6dbe2bc3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -451,10 +451,6 @@ jobs: _APP_BROWSER_HOST: http://invalid-browser/v1 _APP_DATABASE_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'database_db_main' || '' }} _APP_DATABASE_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'database_db_main' || '' }} - _APP_DATABASE_DOCUMENTSDB_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'documentsdb_db_main' || '' }} - _APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'documentsdb_db_main' || '' }} - _APP_DATABASE_VECTORSDB_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'vectorsdb_db_main' || '' }} - _APP_DATABASE_VECTORSDB_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'vectorsdb_db_main' || '' }} run: | docker load --input /tmp/${{ env.IMAGE }}.tar docker compose pull --quiet --ignore-buildable @@ -529,10 +525,6 @@ jobs: _APP_OPTIONS_ABUSE: enabled _APP_DATABASE_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'database_db_main' || '' }} _APP_DATABASE_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'database_db_main' || '' }} - _APP_DATABASE_DOCUMENTSDB_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'documentsdb_db_main' || '' }} - _APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'documentsdb_db_main' || '' }} - _APP_DATABASE_VECTORSDB_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'vectorsdb_db_main' || '' }} - _APP_DATABASE_VECTORSDB_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'vectorsdb_db_main' || '' }} run: | docker load --input /tmp/${{ env.IMAGE }}.tar docker compose pull --quiet --ignore-buildable @@ -590,10 +582,6 @@ jobs: env: _APP_DATABASE_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'database_db_main' || '' }} _APP_DATABASE_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'database_db_main' || '' }} - _APP_DATABASE_DOCUMENTSDB_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'documentsdb_db_main' || '' }} - _APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'documentsdb_db_main' || '' }} - _APP_DATABASE_VECTORSDB_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'vectorsdb_db_main' || '' }} - _APP_DATABASE_VECTORSDB_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'vectorsdb_db_main' || '' }} run: | docker load --input /tmp/${{ env.IMAGE }}.tar docker compose pull --quiet --ignore-buildable diff --git a/app/controllers/api/migrations.php b/app/controllers/api/migrations.php index 5a87293b49..45a663fb56 100644 --- a/app/controllers/api/migrations.php +++ b/app/controllers/api/migrations.php @@ -29,6 +29,7 @@ use Utopia\Migration\Resource; use Utopia\Migration\Sources\Appwrite; use Utopia\Migration\Sources\CSV; use Utopia\Migration\Sources\Firebase; +use Utopia\Migration\Sources\JSON; use Utopia\Migration\Sources\NHost; use Utopia\Migration\Sources\Supabase; use Utopia\Migration\Transfer; @@ -53,6 +54,15 @@ function getDatabaseTransferResourceServices(string $databaseType) }; } +function getDatabaseResourceType(string $databaseType): string +{ + return match($databaseType) { + DATABASE_TYPE_VECTORSDB => Resource::TYPE_DATABASE_VECTORSDB, + DATABASE_TYPE_DOCUMENTSDB => Resource::TYPE_DATABASE_DOCUMENTSDB, + default => Resource::TYPE_DATABASE, + }; +} + Http::post('/v1/migrations/appwrite') ->groups(['api', 'migrations']) ->desc('Create Appwrite migration') @@ -447,6 +457,7 @@ Http::post('/v1/migrations/csv/imports') } $fileSize = $deviceForMigrations->getFileSize($newPath); $resources = Transfer::extractServices([getDatabaseTransferResourceServices($databaseType)]); + $resourceType = getDatabaseResourceType($databaseType); $migration = $dbForProject->createDocument('migrations', new Document([ '$id' => $migrationId, @@ -456,7 +467,7 @@ Http::post('/v1/migrations/csv/imports') 'destination' => Appwrite::getName(), 'resources' => $resources, 'resourceId' => $resourceId, - 'resourceType' => Resource::TYPE_DATABASE, + 'resourceType' => $resourceType, 'statusCounters' => '{}', 'resourceData' => '{}', 'errors' => [], @@ -565,16 +576,6 @@ Http::post('/v1/migrations/csv/exports') throw new Exception(Exception::COLLECTION_NOT_FOUND); } - $validator = new Documents( - attributes: $collection->getAttribute('attributes', []), - indexes: $collection->getAttribute('indexes', []), - idAttributeType: $dbForProject->getAdapter()->getIdAttributeType(), - ); - - if (!$validator->isValid($parsedQueries)) { - throw new Exception(Exception::GENERAL_QUERY_INVALID, $validator->getDescription()); - } - // getting databasetype $resources = explode(':', $resourceId); $databaseId = $resources[0]; @@ -583,7 +584,23 @@ Http::post('/v1/migrations/csv/exports') if (!in_array($databaseType, CSV_ALLOWED_DATABASE_TYPES)) { throw new Exception(Exception::MIGRATION_DATABASE_TYPE_UNSUPPORTED, 'Database type not supported for csv'); } + + // Schemaless databases (DocumentsDB, VectorsDB) allow queries on dynamic fields + $isSchemaless = in_array($databaseType, [DATABASE_TYPE_DOCUMENTSDB, DATABASE_TYPE_VECTORSDB]); + + $validator = new Documents( + attributes: $collection->getAttribute('attributes', []), + indexes: $collection->getAttribute('indexes', []), + idAttributeType: $dbForProject->getAdapter()->getIdAttributeType(), + supportForAttributes: !$isSchemaless, + ); + + if (!$validator->isValid($parsedQueries)) { + throw new Exception(Exception::GENERAL_QUERY_INVALID, $validator->getDescription()); + } + $resources = Transfer::extractServices([getDatabaseTransferResourceServices($databaseType)]); + $resourceType = getDatabaseResourceType($databaseType); $migration = $dbForProject->createDocument('migrations', new Document([ '$id' => ID::unique(), @@ -593,7 +610,7 @@ Http::post('/v1/migrations/csv/exports') 'destination' => CSV::getName(), 'resources' => $resources, 'resourceId' => $resourceId, - 'resourceType' => Resource::TYPE_DATABASE, + 'resourceType' => $resourceType, 'statusCounters' => '{}', 'resourceData' => '{}', 'errors' => [], @@ -624,6 +641,291 @@ Http::post('/v1/migrations/csv/exports') ->dynamic($migration, Response::MODEL_MIGRATION); }); +Http::post('/v1/migrations/json/imports') + ->groups(['api', 'migrations']) + ->desc('Import documents from a JSON') + ->label('scope', 'migrations.write') + ->label('event', 'migrations.[migrationId].create') + ->label('audits.event', 'migration.create') + ->label('sdk', new Method( + namespace: 'migrations', + group: null, + name: 'createJSONImport', + description: '/docs/references/migrations/migration-json-import.md', + auth: [AuthType::ADMIN], + responses: [ + new SDKResponse( + code: Response::STATUS_CODE_ACCEPTED, + model: Response::MODEL_MIGRATION, + ) + ] + )) + ->param('bucketId', '', new UID(), 'Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).') + ->param('fileId', '', new UID(), 'File ID.') + ->param('resourceId', null, new CompoundUID(), 'Composite ID in the format {databaseId:collectionId}, identifying a collection within a database.') + ->param('internalFile', false, new Boolean(), 'Is the file stored in an internal bucket?', true) + ->inject('response') + ->inject('dbForProject') + ->inject('dbForPlatform') + ->inject('authorization') + ->inject('project') + ->inject('platform') + ->inject('deviceForFiles') + ->inject('deviceForMigrations') + ->inject('queueForEvents') + ->inject('queueForMigrations') + ->action(function ( + string $bucketId, + string $fileId, + string $resourceId, + bool $internalFile, + Response $response, + Database $dbForProject, + Database $dbForPlatform, + Authorization $authorization, + Document $project, + array $platform, + Device $deviceForFiles, + Device $deviceForMigrations, + Event $queueForEvents, + Migration $queueForMigrations + ) { + $bucket = $authorization->skip(function () use ($internalFile, $dbForPlatform, $dbForProject, $bucketId) { + if ($internalFile) { + return $dbForPlatform->getDocument('buckets', 'default'); + } + return $dbForProject->getDocument('buckets', $bucketId); + }); + + if ($bucket->isEmpty()) { + throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); + } + + $file = $authorization->skip(fn () => $internalFile ? $dbForPlatform->getDocument('bucket_' . $bucket->getSequence(), $fileId) : $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId)); + if ($file->isEmpty()) { + throw new Exception(Exception::STORAGE_FILE_NOT_FOUND); + } + + $path = $file->getAttribute('path', ''); + if (!$deviceForFiles->exists($path)) { + throw new Exception(Exception::STORAGE_FILE_NOT_FOUND, 'File not found in ' . $path); + } + + // No encryption or compression on files above 20MB. + $hasEncryption = !empty($file->getAttribute('openSSLCipher')); + $compression = $file->getAttribute('algorithm', Compression::NONE); + $hasCompression = $compression !== Compression::NONE; + + $migrationId = ID::unique(); + $newPath = $deviceForMigrations->getPath($migrationId . '_' . $fileId . '.json'); + + if ($hasEncryption || $hasCompression) { + $source = $deviceForFiles->read($path); + + if ($hasEncryption) { + $source = OpenSSL::decrypt( + $source, + $file->getAttribute('openSSLCipher'), + System::getEnv('_APP_OPENSSL_KEY_V' . $file->getAttribute('openSSLVersion')), + 0, + hex2bin($file->getAttribute('openSSLIV')), + hex2bin($file->getAttribute('openSSLTag')) + ); + } + + if ($hasCompression) { + switch ($compression) { + case Compression::ZSTD: + $source = (new Zstd())->decompress($source); + break; + case Compression::GZIP: + $source = (new GZIP())->decompress($source); + break; + } + } + + // Manual write after decryption and/or decompression + if (!$deviceForMigrations->write($newPath, $source, 'application/json')) { + throw new \Exception('Unable to copy file'); + } + } elseif (!$deviceForFiles->transfer($path, $newPath, $deviceForMigrations)) { + throw new \Exception('Unable to copy file'); + } + + $fileSize = $deviceForMigrations->getFileSize($newPath); + + [$databaseId] = \explode(':', $resourceId, 2); + $database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + if ($database->isEmpty()) { + throw new Exception(Exception::DATABASE_NOT_FOUND); + } + $databaseType = $database->getAttribute('type'); + $resources = Transfer::extractServices([getDatabaseTransferResourceServices($databaseType)]); + $resourceType = getDatabaseResourceType($databaseType); + + $migration = $dbForProject->createDocument('migrations', new Document([ + '$id' => $migrationId, + 'status' => 'pending', + 'stage' => 'init', + 'source' => JSON::getName(), + 'destination' => Appwrite::getName(), + 'resources' => $resources, + 'resourceId' => $resourceId, + 'resourceType' => $resourceType, + 'statusCounters' => '{}', + 'resourceData' => '{}', + 'errors' => [], + 'options' => [ + 'path' => $newPath, + 'size' => $fileSize, + ], + ])); + + $queueForEvents->setParam('migrationId', $migration->getId()); + + $queueForMigrations + ->setMigration($migration) + ->setProject($project) + ->setPlatform($platform) + ->trigger(); + + $response + ->setStatusCode(Response::STATUS_CODE_ACCEPTED) + ->dynamic($migration, Response::MODEL_MIGRATION); + }); + +Http::post('/v1/migrations/json/exports') + ->groups(['api', 'migrations']) + ->desc('Export documents to JSON') + ->label('scope', 'migrations.write') + ->label('event', 'migrations.[migrationId].create') + ->label('audits.event', 'migration.create') + ->label('sdk', new Method( + namespace: 'migrations', + group: null, + name: 'createJSONExport', + description: '/docs/references/migrations/migration-json-export.md', + auth: [AuthType::ADMIN], + responses: [ + new SDKResponse( + code: Response::STATUS_CODE_ACCEPTED, + model: Response::MODEL_MIGRATION, + ) + ] + )) + ->param('resourceId', null, new CompoundUID(), 'Composite ID in the format {databaseId:collectionId}, identifying a collection within a database to export.') + ->param('filename', '', new Text(255), 'The name of the file to be created for the export, excluding the .json extension.') + ->param('columns', [], new ArrayList(new Text(Database::LENGTH_KEY)), 'List of attributes to export. If empty, all attributes will be exported. You can use the `*` wildcard to export all attributes from the collection.', true) + ->param('queries', [], new ArrayList(new Text(0)), 'Array of query strings generated using the Query class provided by the SDK to filter documents to export. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) + ->param('notify', true, new Boolean(), 'Set to true to receive an email when the export is complete. Default is true.', true) + ->inject('user') + ->inject('response') + ->inject('dbForProject') + ->inject('dbForPlatform') + ->inject('authorization') + ->inject('project') + ->inject('platform') + ->inject('queueForEvents') + ->inject('queueForMigrations') + ->action(function ( + string $resourceId, + string $filename, + array $columns, + array $queries, + bool $notify, + Document $user, + Response $response, + Database $dbForProject, + Database $dbForPlatform, + Authorization $authorization, + Document $project, + array $platform, + Event $queueForEvents, + Migration $queueForMigrations + ) { + try { + $parsedQueries = Query::parseQueries($queries); + } catch (QueryException $e) { + throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage()); + } + + $bucket = $authorization->skip(fn () => $dbForPlatform->getDocument('buckets', 'default')); + if ($bucket->isEmpty()) { + throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); + } + + [$databaseId, $collectionId] = \explode(':', $resourceId, 2); + if (empty($databaseId)) { + throw new Exception(Exception::DATABASE_NOT_FOUND); + } + if (empty($collectionId)) { + throw new Exception(Exception::COLLECTION_NOT_FOUND); + } + + $database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + if ($database->isEmpty()) { + throw new Exception(Exception::DATABASE_NOT_FOUND); + } + + $collection = $authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId)); + if ($collection->isEmpty()) { + throw new Exception(Exception::COLLECTION_NOT_FOUND); + } + + $databaseType = $database->getAttribute('type'); + + // Schemaless databases (DocumentsDB, VectorsDB) allow queries on dynamic fields + $isSchemaless = in_array($databaseType, [DATABASE_TYPE_DOCUMENTSDB, DATABASE_TYPE_VECTORSDB]); + + $validator = new Documents( + attributes: $collection->getAttribute('attributes', []), + indexes: $collection->getAttribute('indexes', []), + idAttributeType: $dbForProject->getAdapter()->getIdAttributeType(), + supportForAttributes: !$isSchemaless, + ); + + if (!$validator->isValid($parsedQueries)) { + throw new Exception(Exception::GENERAL_QUERY_INVALID, $validator->getDescription()); + } + + $resources = Transfer::extractServices([getDatabaseTransferResourceServices($databaseType)]); + $resourceType = getDatabaseResourceType($databaseType); + + $migration = $dbForProject->createDocument('migrations', new Document([ + '$id' => ID::unique(), + 'status' => 'pending', + 'stage' => 'init', + 'source' => Appwrite::getName(), + 'destination' => JSON::getName(), + 'resources' => $resources, + 'resourceId' => $resourceId, + 'resourceType' => $resourceType, + 'statusCounters' => '{}', + 'resourceData' => '{}', + 'errors' => [], + 'options' => [ + 'bucketId' => 'default', // Always use internal bucket + 'filename' => $filename, + 'columns' => $columns, + 'queries' => $queries, + 'notify' => $notify, + 'userInternalId' => $user->getSequence(), + ], + ])); + + $queueForEvents->setParam('migrationId', $migration->getId()); + + $queueForMigrations + ->setMigration($migration) + ->setProject($project) + ->setPlatform($platform) + ->trigger(); + + $response + ->setStatusCode(Response::STATUS_CODE_ACCEPTED) + ->dynamic($migration, Response::MODEL_MIGRATION); + }); + Http::get('/v1/migrations') ->groups(['api', 'migrations']) ->desc('List migrations') diff --git a/app/init/resources.php b/app/init/resources.php index 9f5b02fb91..ddfbb5c348 100644 --- a/app/init/resources.php +++ b/app/init/resources.php @@ -888,9 +888,8 @@ Http::setResource('dbForPlatform', function (Group $pools, Cache $cache, Authori }, ['pools', 'cache', 'authorization']); Http::setResource('getDatabasesDB', function (Group $pools, Cache $cache, Document $project, Request $request, UsageContext $usage, Authorization $authorization) { - $initializedPools = []; - return function (Document $database) use ($pools, $cache, $project, $request, $usage, $authorization, &$initializedPools): Database { + return function (Document $database) use ($pools, $cache, $project, $request, $usage, $authorization): Database { $databaseDSN = $database->getAttribute('database', $project->getAttribute('database', '')); $databaseType = $database->getAttribute('type', ''); @@ -908,12 +907,11 @@ Http::setResource('getDatabasesDB', function (Group $pools, Cache $cache, Docume $dsn = new DSN('mysql://' . $project->getAttribute('database')); } - $databaseHost = $databaseDSN->getHost(); - $pool = $pools->get($databaseHost); + $pool = $pools->get($databaseDSN->getHost()); $adapter = new DatabasePool($pool); $database = new Database($adapter, $cache); - $sharedTables = \array_filter(\explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''))); + $sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', '')); $database ->setDatabase(APP_DATABASE) @@ -924,27 +922,7 @@ Http::setResource('getDatabasesDB', function (Group $pools, Cache $cache, Docume ->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES); // inside pools authorization needs to be set first $database->getAdapter()->setSupportForAttributes($databaseType !== DOCUMENTSDB); - - // When the database uses a separate pool (e.g. vectorsdb on PostgreSQL), - // always use dedicated mode with namespace isolation. Shared tables mode - // can't be used across different engines (e.g. MongoDB UUID tenants are - // incompatible with PostgreSQL's integer _tenant column). - if ($databaseHost !== $dsn->getHost()) { - $database - ->setSharedTables(false) - ->setTenant(null) - ->setNamespace('_' . $project->getSequence()); - - $poolKey = $databaseHost . ':' . $database->getNamespace(); - if (!isset($initializedPools[$poolKey])) { - try { - $database->create(); - } catch (\Utopia\Database\Exception\Duplicate) { - // Schema already exists - } - $initializedPools[$poolKey] = true; - } - } elseif (\in_array($dsn->getHost(), $sharedTables)) { + if (\in_array($dsn->getHost(), $sharedTables)) { $database ->setSharedTables(true) ->setTenant($project->getSequence()) diff --git a/app/worker.php b/app/worker.php index e54819e729..e5aa32938f 100644 --- a/app/worker.php +++ b/app/worker.php @@ -221,9 +221,7 @@ Server::setResource('getLogsDB', function (Group $pools, Cache $cache, Authoriza }, ['pools', 'cache', 'authorization']); Server::setResource('getDatabasesDB', function (Cache $cache, Registry $register, Document $project, Authorization $authorization) { - $initializedPools = []; - - return function (Document $database, ?Document $projectDocument = null) use ($cache, $register, $project, $authorization, &$initializedPools): Database { + return function (Document $database, ?Document $projectDocument = null) use ($cache, $register, $project, $authorization): Database { $projectDocument ??= $project; $databaseDSN = $database->getAttribute('database', $project->getAttribute('database', '')); $databaseType = $database->getAttribute('type', ''); @@ -248,8 +246,7 @@ Server::setResource('getDatabasesDB', function (Cache $cache, Registry $register } $pools = $register->get('pools'); - $databaseHost = $databaseDSN->getHost(); - $pool = $pools->get($databaseHost); + $pool = $pools->get($databaseDSN->getHost()); $adapter = new DatabasePool($pool); $database = new Database($adapter, $cache); @@ -258,27 +255,9 @@ Server::setResource('getDatabasesDB', function (Cache $cache, Registry $register ->setAuthorization($authorization); $database->getAdapter()->setSupportForAttributes($databaseType !== DOCUMENTSDB); - $sharedTables = \array_filter(\explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''))); + $sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', '')); - // When using a separate pool, always use dedicated mode with namespace isolation. - // Shared tables mode can't be used across different engines (e.g. MongoDB UUID - // tenants are incompatible with PostgreSQL's integer _tenant column). - if ($databaseHost !== $dsn->getHost()) { - $database - ->setSharedTables(false) - ->setTenant(null) - ->setNamespace('_' . $projectDocument->getSequence()); - - $poolKey = $databaseHost . ':' . $database->getNamespace(); - if (!isset($initializedPools[$poolKey])) { - try { - $database->create(); - } catch (\Utopia\Database\Exception\Duplicate) { - // Schema already exists - } - $initializedPools[$poolKey] = true; - } - } elseif (\in_array($dsn->getHost(), $sharedTables, true)) { + if (\in_array($dsn->getHost(), $sharedTables, true)) { $database ->setSharedTables(true) ->setTenant($projectDocument->getSequence()) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 37e2579644..816ff0e5f5 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -186,108 +186,6 @@ parameters: count: 3 path: app/worker.php - - - message: '#^PHPDoc tag @return with type string is incompatible with native type int\.$#' - identifier: return.phpDocType - count: 1 - path: src/Appwrite/Auth/OAuth2.php - - - - message: '#^PHPDoc tag @param references unknown parameter\: \$token$#' - identifier: parameter.notFound - count: 1 - path: src/Appwrite/Auth/OAuth2/Disqus.php - - - - message: '#^PHPDoc tag @param references unknown parameter\: \$value$#' - identifier: parameter.notFound - count: 1 - path: src/Appwrite/Auth/Validator/PersonalData.php - - - - message: '#^PHPDoc tag @param has invalid value \(DeviceDetector\)\: Unexpected token "\\n ", expected variable at offset 32 on line 2$#' - identifier: phpDoc.parseError - count: 1 - path: src/Appwrite/Detector/Detector.php - - - - message: '#^PHPDoc tag @param has invalid value \(string\)\: Unexpected token "\\n ", expected variable at offset 24 on line 2$#' - identifier: phpDoc.parseError - count: 1 - path: src/Appwrite/Detector/Detector.php - - - - message: '#^PHPDoc tag @var above a method has no effect\.$#' - identifier: varTag.misplaced - count: 1 - path: src/Appwrite/Docker/Compose.php - - - - message: '#^PHPDoc tag @var above a method has no effect\.$#' - identifier: varTag.misplaced - count: 1 - path: src/Appwrite/Docker/Compose/Service.php - - - - message: '#^PHPDoc tag @var above a method has no effect\.$#' - identifier: varTag.misplaced - count: 1 - path: src/Appwrite/Docker/Env.php - - - - message: '#^PHPDoc tag @param has invalid value \(int port\)\: Unexpected token "port", expected variable at offset 50 on line 4$#' - identifier: phpDoc.parseError - count: 1 - path: src/Appwrite/Event/Mail.php - - - - message: '#^PHPDoc tag @param references unknown parameter\: \$password$#' - identifier: parameter.notFound - count: 1 - path: src/Appwrite/Event/Mail.php - - - - message: '#^PHPDoc tag @return with type string is incompatible with native type Appwrite\\Event\\Mail\.$#' - identifier: return.phpDocType - count: 1 - path: src/Appwrite/Event/Mail.php - - - - message: '#^Method Appwrite\\Event\\Message\\Usage\:\:fromArray\(\) should return static\(Appwrite\\Event\\Message\\Usage\) but returns Appwrite\\Event\\Message\\Usage\.$#' - identifier: return.type - count: 1 - path: src/Appwrite/Event/Message/Usage.php - - - - message: '#^PHPDoc tag @param references unknown parameter\: \$message$#' - identifier: parameter.notFound - count: 1 - path: src/Appwrite/Event/Messaging.php - - - - message: '#^PHPDoc tag @return with type string is incompatible with native type Utopia\\Database\\Document\.$#' - identifier: return.phpDocType - count: 1 - path: src/Appwrite/Event/Messaging.php - - - - message: '#^Method Appwrite\\Functions\\EventProcessor\:\:getFunctionsEvents\(\) should return array\ but returns array\\>\.$#' - identifier: return.type - count: 1 - path: src/Appwrite/Functions/EventProcessor.php - - - - message: '#^Method Appwrite\\Functions\\EventProcessor\:\:getWebhooksEvents\(\) should return array\ but returns array\\>\.$#' - identifier: return.type - count: 1 - path: src/Appwrite/Functions/EventProcessor.php - - - - message: '#^Variable \$hostname on left side of \?\? always exists and is not nullable\.$#' - identifier: nullCoalesce.variable - count: 1 - path: src/Appwrite/Functions/EventProcessor.php - - message: '#^Anonymous function has an unused use \$context\.$#' identifier: closure.unusedUse @@ -360,30 +258,6 @@ parameters: count: 1 path: src/Appwrite/GraphQL/Types/Mapper.php - - - message: '#^Unsafe access to private property Appwrite\\GraphQL\\Types\\Mapper\:\:\$models through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 3 - path: src/Appwrite/GraphQL/Types/Mapper.php - - - - message: '#^Unsafe call to private method Appwrite\\GraphQL\\Types\\Mapper\:\:getColumnImplementation\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 2 - path: src/Appwrite/GraphQL/Types/Mapper.php - - - - message: '#^Unsafe call to private method Appwrite\\GraphQL\\Types\\Mapper\:\:getHashOptionsImplementation\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 1 - path: src/Appwrite/GraphQL/Types/Mapper.php - - - - message: '#^Unsafe call to private method Appwrite\\GraphQL\\Types\\Mapper\:\:getUnionImplementation\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 1 - path: src/Appwrite/GraphQL/Types/Mapper.php - - message: '#^Call to an undefined method Appwrite\\Migration\\Version\\V15\:\:documentsIterator\(\)\.$#' identifier: method.notFound @@ -450,12 +324,6 @@ parameters: count: 1 path: src/Appwrite/OpenSSL/OpenSSL.php - - - message: '#^PHPDoc tag @param references unknown parameter\: \$projectId$#' - identifier: parameter.notFound - count: 1 - path: src/Appwrite/Platform/Action.php - - message: '#^Variable \$output in empty\(\) always exists and is not falsy\.$#' identifier: empty.variable @@ -1152,12 +1020,6 @@ parameters: count: 1 path: src/Appwrite/SDK/Specification/Format/Swagger2.php - - - message: '#^PHPDoc tag @var above a method has no effect\.$#' - identifier: varTag.misplaced - count: 2 - path: src/Appwrite/Template/Template.php - - message: '#^PHPDoc tag @param has invalid value \(Document \$this\)\: Unexpected token "\$this", expected variable at offset 69 on line 4$#' identifier: phpDoc.parseError @@ -1170,35 +1032,6 @@ parameters: count: 1 path: src/Appwrite/Utopia/Database/Documents/User.php - - - message: '#^Unsafe call to private method Appwrite\\Utopia\\Request\\Filters\\V17\:\:appendSymbol\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 4 - path: src/Appwrite/Utopia/Request/Filters/V17.php - - - - message: '#^Unsafe call to private method Appwrite\\Utopia\\Request\\Filters\\V17\:\:isSpecialChar\(\) through static\:\:\.$#' - identifier: staticClassAccess.privateMethod - count: 1 - path: src/Appwrite/Utopia/Request/Filters/V17.php - - - - message: '#^PHPDoc tag @param has invalid value \(callable The callback to show sensitive information for\)\: Unexpected token "The", expected variable at offset 91 on line 4$#' - identifier: phpDoc.parseError - count: 1 - path: src/Appwrite/Utopia/Response.php - - - - message: '#^PHPDoc tag @return with type Appwrite\\Utopia\\Response\\Filter is incompatible with native type array\.$#' - identifier: return.phpDocType - count: 1 - path: src/Appwrite/Utopia/Response.php - - - - message: '#^PHPDoc tag @return with type string is incompatible with native type Utopia\\Database\\Document\.$#' - identifier: return.phpDocType - count: 1 - path: src/Appwrite/Utopia/Response/Model/User.php - message: '#^Unsafe access to private property Tests\\E2E\\Services\\Databases\\Legacy\\DatabasesStringTypesTest\:\:\$setupCache through static\:\:\.$#' identifier: staticClassAccess.privateProperty @@ -1234,108 +1067,12 @@ parameters: count: 8 path: tests/e2e/Services/Functions/FunctionsCustomServerTest.php - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\FunctionsClientTest\:\:\$cachedDeployment through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 3 - path: tests/e2e/Services/GraphQL/FunctionsClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\FunctionsClientTest\:\:\$cachedExecution through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/FunctionsClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\FunctionsClientTest\:\:\$cachedFunction through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 3 - path: tests/e2e/Services/GraphQL/FunctionsClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\FunctionsServerTest\:\:\$cachedDeployment through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/FunctionsServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\FunctionsServerTest\:\:\$cachedExecution through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/FunctionsServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\FunctionsServerTest\:\:\$cachedFunction through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/FunctionsServerTest.php - - message: '#^Binary operation "\+" between string and 1 results in an error\.$#' identifier: binaryOp.invalid count: 1 path: tests/e2e/Services/GraphQL/Legacy/AbuseTest.php - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\Legacy\\DatabaseClientTest\:\:\$bulkData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/Legacy/DatabaseClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\Legacy\\DatabaseClientTest\:\:\$collection through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/Legacy/DatabaseClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\Legacy\\DatabaseClientTest\:\:\$database through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/Legacy/DatabaseClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\Legacy\\DatabaseClientTest\:\:\$document through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/Legacy/DatabaseClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\MessagingTest\:\:\$cachedEmail through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 2 - path: tests/e2e/Services/GraphQL/MessagingTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\MessagingTest\:\:\$cachedProviders through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 8 - path: tests/e2e/Services/GraphQL/MessagingTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\MessagingTest\:\:\$cachedPush through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/MessagingTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\MessagingTest\:\:\$cachedSms through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/MessagingTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\MessagingTest\:\:\$cachedSubscriber through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/MessagingTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\MessagingTest\:\:\$cachedTopic through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 9 - path: tests/e2e/Services/GraphQL/MessagingTest.php - - message: '#^Variable \$from in empty\(\) is never defined\.$#' identifier: empty.variable @@ -1348,174 +1085,18 @@ parameters: count: 1 path: tests/e2e/Services/GraphQL/StorageClientTest.php - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\StorageClientTest\:\:\$cachedBucket through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 3 - path: tests/e2e/Services/GraphQL/StorageClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\StorageClientTest\:\:\$cachedFile through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/StorageClientTest.php - - message: '#^Method Tests\\E2E\\Services\\GraphQL\\StorageServerTest\:\:testGetFileDownload\(\) should return array but return statement is missing\.$#' identifier: return.missing count: 1 path: tests/e2e/Services/GraphQL/StorageServerTest.php - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\StorageServerTest\:\:\$cachedBucket through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/StorageServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\StorageServerTest\:\:\$cachedFile through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 6 - path: tests/e2e/Services/GraphQL/StorageServerTest.php - - message: '#^Binary operation "\+" between string and 1 results in an error\.$#' identifier: binaryOp.invalid count: 1 path: tests/e2e/Services/GraphQL/TablesDB/AbuseTest.php - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedBooleanColumnData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedBulkData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedDatabase through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedDatetimeColumnData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedEmailColumnData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedEnumColumnData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedFloatColumnData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedIPColumnData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedIndexData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 7 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedIntegerColumnData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedRelationshipColumnData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedRowData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedStringColumnData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedTableData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TablesDB\\DatabaseServerTest\:\:\$cachedURLColumnData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TeamsClientTest\:\:\$cachedMembership through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/TeamsClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TeamsClientTest\:\:\$cachedTeam through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 3 - path: tests/e2e/Services/GraphQL/TeamsClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TeamsServerTest\:\:\$cachedMembership through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/GraphQL/TeamsServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TeamsServerTest\:\:\$cachedTeam through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 3 - path: tests/e2e/Services/GraphQL/TeamsServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\TeamsServerTest\:\:\$cachedTeamWithPrefs through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 3 - path: tests/e2e/Services/GraphQL/TeamsServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\UsersTest\:\:\$cachedUser through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 3 - path: tests/e2e/Services/GraphQL/UsersTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\GraphQL\\UsersTest\:\:\$cachedUserTarget through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 5 - path: tests/e2e/Services/GraphQL/UsersTest.php - - message: '#^Variable \$from in empty\(\) is never defined\.$#' identifier: empty.variable @@ -1587,36 +1168,6 @@ parameters: identifier: method.notFound count: 1 path: tests/e2e/Services/TablesDB/Permissions/TablesDBPermissionsTeamTest.php - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\Tokens\\TokensConsoleClientTest\:\:\$bucketAndFileData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/Tokens/TokensConsoleClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\Tokens\\TokensConsoleClientTest\:\:\$tokenData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/Tokens/TokensConsoleClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\Tokens\\TokensCustomClientTest\:\:\$bucketAndFileData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/Tokens/TokensCustomClientTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\Tokens\\TokensCustomServerTest\:\:\$bucketAndFileData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/Tokens/TokensCustomServerTest.php - - - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\Tokens\\TokensCustomServerTest\:\:\$tokenData through static\:\:\.$#' - identifier: staticClassAccess.privateProperty - count: 4 - path: tests/e2e/Services/Tokens/TokensCustomServerTest.php - - message: '#^Unsafe access to private property Tests\\E2E\\Services\\Users\\UsersCustomServerTest\:\:\$cachedHashedPasswordUsers through static\:\:\.$#' identifier: staticClassAccess.privateProperty @@ -1676,75 +1227,3 @@ parameters: identifier: method.notFound count: 1 path: tests/unit/Event/EventTest.php - - - - message: '#^Call to method parse\(\) on an unknown class Tests\\Unit\\Utopia\\Response\\Filters\\Filter\.$#' - identifier: class.notFound - count: 6 - path: tests/unit/Utopia/Response/Filters/V16Test.php - - - - message: '#^Property Tests\\Unit\\Utopia\\Response\\Filters\\V16Test\:\:\$filter \(Tests\\Unit\\Utopia\\Response\\Filters\\Filter\) does not accept Appwrite\\Utopia\\Response\\Filters\\V16\.$#' - identifier: assign.propertyType - count: 1 - path: tests/unit/Utopia/Response/Filters/V16Test.php - - - - message: '#^Property Tests\\Unit\\Utopia\\Response\\Filters\\V16Test\:\:\$filter has unknown class Tests\\Unit\\Utopia\\Response\\Filters\\Filter as its type\.$#' - identifier: class.notFound - count: 1 - path: tests/unit/Utopia/Response/Filters/V16Test.php - - - - message: '#^Call to method parse\(\) on an unknown class Tests\\Unit\\Utopia\\Response\\Filters\\Filter\.$#' - identifier: class.notFound - count: 5 - path: tests/unit/Utopia/Response/Filters/V17Test.php - - - - message: '#^Property Tests\\Unit\\Utopia\\Response\\Filters\\V17Test\:\:\$filter \(Tests\\Unit\\Utopia\\Response\\Filters\\Filter\) does not accept Appwrite\\Utopia\\Response\\Filters\\V17\.$#' - identifier: assign.propertyType - count: 1 - path: tests/unit/Utopia/Response/Filters/V17Test.php - - - - message: '#^Property Tests\\Unit\\Utopia\\Response\\Filters\\V17Test\:\:\$filter has unknown class Tests\\Unit\\Utopia\\Response\\Filters\\Filter as its type\.$#' - identifier: class.notFound - count: 1 - path: tests/unit/Utopia/Response/Filters/V17Test.php - - - - message: '#^Call to method parse\(\) on an unknown class Tests\\Unit\\Utopia\\Response\\Filters\\Filter\.$#' - identifier: class.notFound - count: 4 - path: tests/unit/Utopia/Response/Filters/V18Test.php - - - - message: '#^Property Tests\\Unit\\Utopia\\Response\\Filters\\V18Test\:\:\$filter \(Tests\\Unit\\Utopia\\Response\\Filters\\Filter\) does not accept Appwrite\\Utopia\\Response\\Filters\\V18\.$#' - identifier: assign.propertyType - count: 1 - path: tests/unit/Utopia/Response/Filters/V18Test.php - - - - message: '#^Property Tests\\Unit\\Utopia\\Response\\Filters\\V18Test\:\:\$filter has unknown class Tests\\Unit\\Utopia\\Response\\Filters\\Filter as its type\.$#' - identifier: class.notFound - count: 1 - path: tests/unit/Utopia/Response/Filters/V18Test.php - - - - message: '#^Call to method parse\(\) on an unknown class Tests\\Unit\\Utopia\\Response\\Filters\\Filter\.$#' - identifier: class.notFound - count: 11 - path: tests/unit/Utopia/Response/Filters/V19Test.php - - - - message: '#^Property Tests\\Unit\\Utopia\\Response\\Filters\\V19Test\:\:\$filter \(Tests\\Unit\\Utopia\\Response\\Filters\\Filter\) does not accept Appwrite\\Utopia\\Response\\Filters\\V19\.$#' - identifier: assign.propertyType - count: 1 - path: tests/unit/Utopia/Response/Filters/V19Test.php - - - - message: '#^Property Tests\\Unit\\Utopia\\Response\\Filters\\V19Test\:\:\$filter has unknown class Tests\\Unit\\Utopia\\Response\\Filters\\Filter as its type\.$#' - identifier: class.notFound - count: 1 - path: tests/unit/Utopia/Response/Filters/V19Test.php diff --git a/src/Appwrite/Auth/OAuth2.php b/src/Appwrite/Auth/OAuth2.php index 9358c89547..a8a2d175b5 100644 --- a/src/Appwrite/Auth/OAuth2.php +++ b/src/Appwrite/Auth/OAuth2.php @@ -155,7 +155,7 @@ abstract class OAuth2 /** * @param string $code * - * @return string + * @return int */ public function getAccessTokenExpiry(string $code): int { diff --git a/src/Appwrite/Auth/OAuth2/Disqus.php b/src/Appwrite/Auth/OAuth2/Disqus.php index 58b7f48914..738c6d503e 100644 --- a/src/Appwrite/Auth/OAuth2/Disqus.php +++ b/src/Appwrite/Auth/OAuth2/Disqus.php @@ -108,7 +108,7 @@ class Disqus extends OAuth2 } /** - * @param string $token + * @param string $accessToken * * @return string */ diff --git a/src/Appwrite/Auth/Validator/PersonalData.php b/src/Appwrite/Auth/Validator/PersonalData.php index 8eaae002f6..3b09839bd1 100644 --- a/src/Appwrite/Auth/Validator/PersonalData.php +++ b/src/Appwrite/Auth/Validator/PersonalData.php @@ -33,7 +33,7 @@ class PersonalData extends Password /** * Is valid. * - * @param mixed $value + * @param mixed $password * * @return bool */ diff --git a/src/Appwrite/Detector/Detector.php b/src/Appwrite/Detector/Detector.php index 61286835f5..73259673dd 100644 --- a/src/Appwrite/Detector/Detector.php +++ b/src/Appwrite/Detector/Detector.php @@ -6,14 +6,8 @@ use DeviceDetector\DeviceDetector; class Detector { - /** - * @param string - */ protected $userAgent = ''; - /** - * @param DeviceDetector - */ protected $detctor; /** diff --git a/src/Appwrite/Docker/Compose.php b/src/Appwrite/Docker/Compose.php index 241e281ed8..9ea6420d2d 100644 --- a/src/Appwrite/Docker/Compose.php +++ b/src/Appwrite/Docker/Compose.php @@ -12,9 +12,6 @@ class Compose */ protected $compose = []; - /** - * @var string $data - */ public function __construct(string $data) { $this->compose = yaml_parse($data); diff --git a/src/Appwrite/Docker/Compose/Service.php b/src/Appwrite/Docker/Compose/Service.php index a3f9c91253..87699aaeba 100644 --- a/src/Appwrite/Docker/Compose/Service.php +++ b/src/Appwrite/Docker/Compose/Service.php @@ -11,9 +11,6 @@ class Service */ protected $service = []; - /** - * @var string $path - */ public function __construct(array $service) { $this->service = $service; diff --git a/src/Appwrite/Docker/Env.php b/src/Appwrite/Docker/Env.php index 3bf6fb2d50..af5e4f11e2 100644 --- a/src/Appwrite/Docker/Env.php +++ b/src/Appwrite/Docker/Env.php @@ -9,9 +9,6 @@ class Env */ protected $vars = []; - /** - * @var string $data - */ public function __construct(string $data) { $data = explode("\n", $data); diff --git a/src/Appwrite/Event/Mail.php b/src/Appwrite/Event/Mail.php index 2d12aa542c..38d7a27c11 100644 --- a/src/Appwrite/Event/Mail.php +++ b/src/Appwrite/Event/Mail.php @@ -101,7 +101,8 @@ class Mail extends Event /** * Sets preview for the mail event. * - * @return string + * @param string $preview + * @return self */ public function setPreview(string $preview): self { @@ -115,7 +116,7 @@ class Mail extends Event * * @return string */ - public function getPreview(string $preview): string + public function getPreview(): string { return $this->preview; } @@ -181,7 +182,7 @@ class Mail extends Event /** * Set SMTP port * - * @param int port + * @param int $port * @return self */ public function setSmtpPort(int $port): self @@ -217,7 +218,7 @@ class Mail extends Event /** * Set SMTP secure * - * @param string $password + * @param string $secure * @return self */ public function setSmtpSecure(string $secure): self diff --git a/src/Appwrite/Event/Message/Usage.php b/src/Appwrite/Event/Message/Usage.php index 776188d5b5..eb40f6dfea 100644 --- a/src/Appwrite/Event/Message/Usage.php +++ b/src/Appwrite/Event/Message/Usage.php @@ -4,7 +4,7 @@ namespace Appwrite\Event\Message; use Utopia\Database\Document; -class Usage extends Base +final class Usage extends Base { /** * @param Document $project @@ -40,7 +40,7 @@ class Usage extends Base */ public static function fromArray(array $data): static { - return new self( + return new static( project: new Document($data['project'] ?? []), metrics: $data['metrics'] ?? [], reduce: array_map(fn (array $doc) => new Document($doc), $data['reduce'] ?? []), diff --git a/src/Appwrite/Event/Messaging.php b/src/Appwrite/Event/Messaging.php index 8c13185e0b..9895d52ec2 100644 --- a/src/Appwrite/Event/Messaging.php +++ b/src/Appwrite/Event/Messaging.php @@ -86,7 +86,7 @@ class Messaging extends Event /** * Returns message document for the messaging event. * - * @return string + * @return Document */ public function getMessage(): Document { @@ -96,7 +96,7 @@ class Messaging extends Event /** * Sets message ID for the messaging event. * - * @param string $message + * @param string $messageId * @return self */ public function setMessageId(string $messageId): self diff --git a/src/Appwrite/Functions/EventProcessor.php b/src/Appwrite/Functions/EventProcessor.php index e9c3b7241a..d41ee56c5d 100644 --- a/src/Appwrite/Functions/EventProcessor.php +++ b/src/Appwrite/Functions/EventProcessor.php @@ -8,6 +8,18 @@ use Utopia\Database\Query; class EventProcessor { + /** + * @param array $events + * @return array + */ + private function getEventMap(array $events): array + { + return \array_fill_keys( + \array_map('strval', \array_unique($events)), + true + ); + } + /** * Get function events for a project, using Redis cache * @param Document|null $project @@ -26,7 +38,7 @@ class EventProcessor $cacheKey = \sprintf( '%s-cache-%s:%s:%s:project:%s:functions:events', $dbForProject->getCacheName(), - $hostname ?? '', + $hostname, $dbForProject->getNamespace(), $dbForProject->getTenant(), $project->getId() @@ -36,7 +48,9 @@ class EventProcessor $cachedFunctionEvents = $dbForProject->getCache()->load($cacheKey, $ttl); if ($cachedFunctionEvents !== false) { - return \json_decode($cachedFunctionEvents, true) ?? []; + $decoded = \json_decode($cachedFunctionEvents, true); + + return \is_array($decoded) ? $this->getEventMap(\array_keys($decoded)) : []; } $events = []; @@ -63,7 +77,7 @@ class EventProcessor } } - $uniqueEvents = \array_flip(\array_unique($events)); + $uniqueEvents = $this->getEventMap($events); $dbForProject->getCache()->save($cacheKey, \json_encode($uniqueEvents)); return $uniqueEvents; @@ -97,6 +111,6 @@ class EventProcessor } } - return \array_flip(\array_unique($events)); + return $this->getEventMap($events); } } diff --git a/src/Appwrite/GraphQL/Types/Mapper.php b/src/Appwrite/GraphQL/Types/Mapper.php index 037f80bcf7..de4913cec4 100644 --- a/src/Appwrite/GraphQL/Types/Mapper.php +++ b/src/Appwrite/GraphQL/Types/Mapper.php @@ -101,16 +101,16 @@ class Mapper if (\is_array($modelName)) { foreach ($modelName as $name) { - $models[] = static::$models[$name]; + $models[] = self::$models[$name]; } } else { - $models[] = static::$models[$modelName]; + $models[] = self::$models[$modelName]; } } } else { // If single response, get its model and wrap in array $modelName = $responses->getModel(); - $models = [static::$models[$modelName]]; + $models = [self::$models[$modelName]]; } foreach ($models as $model) { @@ -425,7 +425,7 @@ class Mapper 'name' => $unionName, 'types' => $types, 'resolveType' => static function ($object) use ($unionName) { - return static::getUnionImplementation($unionName, $object); + return self::getUnionImplementation($unionName, $object); }, ]); @@ -440,11 +440,11 @@ class Mapper switch ($name) { case 'Attributes': - return static::getColumnImplementation($object); + return self::getColumnImplementation($object); case 'Columns': - return static::getColumnImplementation($object, true); + return self::getColumnImplementation($object, true); case 'HashOptions': - return static::getHashOptionsImplementation($object); + return self::getHashOptionsImplementation($object); } throw new Exception('Unknown union type: ' . $name); diff --git a/src/Appwrite/Platform/Action.php b/src/Appwrite/Platform/Action.php index 01ac92a45c..0aa0da7149 100644 --- a/src/Appwrite/Platform/Action.php +++ b/src/Appwrite/Platform/Action.php @@ -37,7 +37,7 @@ class Action extends UtopiaAction * Foreach Document * Call provided callback for each document in the collection * - * @param string $projectId + * @param Database $database * @param string $collection * @param array $queries * @param callable $callback diff --git a/src/Appwrite/Template/Template.php b/src/Appwrite/Template/Template.php index c8744c87bb..695e925e52 100644 --- a/src/Appwrite/Template/Template.php +++ b/src/Appwrite/Template/Template.php @@ -149,7 +149,7 @@ class Template extends View /** * From Camel Case * - * @var string $input + * @param string $input * * @return string */ @@ -167,7 +167,7 @@ class Template extends View /** * From Camel Case to Dash Case * - * @var string $input + * @param string $input * * @return string */ diff --git a/src/Appwrite/Utopia/Request/Filters/V17.php b/src/Appwrite/Utopia/Request/Filters/V17.php index 2cdf3973b2..0e4f9eceb6 100644 --- a/src/Appwrite/Utopia/Request/Filters/V17.php +++ b/src/Appwrite/Utopia/Request/Filters/V17.php @@ -120,11 +120,11 @@ class V17 extends Filter $isArrayStack = !$isStringStack && $stackCount > 0; if ($char === static::CHAR_BACKSLASH) { - if (!(static::isSpecialChar($filter[$i + 1]))) { - static::appendSymbol($isStringStack, $filter[$i], $i, $filter, $currentParam); + if (!(self::isSpecialChar($filter[$i + 1]))) { + self::appendSymbol($isStringStack, $filter[$i], $i, $filter, $currentParam); } - static::appendSymbol($isStringStack, $filter[$i + 1], $i, $filter, $currentParam); + self::appendSymbol($isStringStack, $filter[$i + 1], $i, $filter, $currentParam); $i++; continue; @@ -147,7 +147,7 @@ class V17 extends Filter } // Either way, add symbol to builder - static::appendSymbol( + self::appendSymbol( $isStringStack, $char, $i, @@ -199,7 +199,7 @@ class V17 extends Filter } // Value, not relevant to syntax - static::appendSymbol( + self::appendSymbol( $isStringStack, $char, $i, diff --git a/src/Appwrite/Utopia/Response.php b/src/Appwrite/Utopia/Response.php index 99170a58c9..e01dc58bf6 100644 --- a/src/Appwrite/Utopia/Response.php +++ b/src/Appwrite/Utopia/Response.php @@ -629,9 +629,9 @@ class Response extends SwooleResponse } /** - * Return the currently set filter + * Return the currently set filters * - * @return Filter + * @return array */ public function getFilters(): array { @@ -661,7 +661,7 @@ class Response extends SwooleResponse /** * Static wrapper to show sensitive data in response * - * @param callable The callback to show sensitive information for + * @param callable(): array $callback The callback to show sensitive information for * @return array */ public static function showSensitive(callable $callback): array diff --git a/src/Appwrite/Utopia/Response/Model/User.php b/src/Appwrite/Utopia/Response/Model/User.php index 476778e68b..01447ccfc2 100644 --- a/src/Appwrite/Utopia/Response/Model/User.php +++ b/src/Appwrite/Utopia/Response/Model/User.php @@ -157,9 +157,9 @@ class User extends Model } /** - * Get Collection + * Filter user document attributes for response output. * - * @return string + * @return Document */ public function filter(Document $document): Document { diff --git a/tests/e2e/Services/GraphQL/FunctionsClientTest.php b/tests/e2e/Services/GraphQL/FunctionsClientTest.php index 234d8fa71b..8dc2fe337f 100644 --- a/tests/e2e/Services/GraphQL/FunctionsClientTest.php +++ b/tests/e2e/Services/GraphQL/FunctionsClientTest.php @@ -24,8 +24,8 @@ class FunctionsClientTest extends Scope protected function setupFunction(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedFunction[$key])) { - return static::$cachedFunction[$key]; + if (!empty(self::$cachedFunction[$key])) { + return self::$cachedFunction[$key]; } $projectId = $this->getProject()['$id']; @@ -79,15 +79,15 @@ class FunctionsClientTest extends Scope $this->assertIsArray($variables['body']['data']); $this->assertArrayNotHasKey('errors', $variables['body']); - static::$cachedFunction[$key] = $function; + self::$cachedFunction[$key] = $function; return $function; } protected function setupDeployment(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedDeployment[$key])) { - return static::$cachedDeployment[$key]; + if (!empty(self::$cachedDeployment[$key])) { + return self::$cachedDeployment[$key]; } $function = $this->setupFunction(); @@ -146,15 +146,15 @@ class FunctionsClientTest extends Scope $this->assertEquals('ready', $deployment['status']); }, 60000); - static::$cachedDeployment[$key] = $deployment; + self::$cachedDeployment[$key] = $deployment; return $deployment; } protected function setupExecution(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedExecution[$key])) { - return static::$cachedExecution[$key]; + if (!empty(self::$cachedExecution[$key])) { + return self::$cachedExecution[$key]; } $function = $this->setupFunction(); @@ -177,8 +177,8 @@ class FunctionsClientTest extends Scope $this->assertIsArray($execution['body']['data']); $this->assertArrayNotHasKey('errors', $execution['body']); - static::$cachedExecution[$key] = $execution['body']['data']['functionsCreateExecution']; - return static::$cachedExecution[$key]; + self::$cachedExecution[$key] = $execution['body']['data']['functionsCreateExecution']; + return self::$cachedExecution[$key]; } public function testCreateFunction(): void diff --git a/tests/e2e/Services/GraphQL/FunctionsServerTest.php b/tests/e2e/Services/GraphQL/FunctionsServerTest.php index a66789d646..8e1c7ac7e7 100644 --- a/tests/e2e/Services/GraphQL/FunctionsServerTest.php +++ b/tests/e2e/Services/GraphQL/FunctionsServerTest.php @@ -25,8 +25,8 @@ class FunctionsServerTest extends Scope protected function setupFunction(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedFunction[$key])) { - return static::$cachedFunction[$key]; + if (!empty(self::$cachedFunction[$key])) { + return self::$cachedFunction[$key]; } $projectId = $this->getProject()['$id']; @@ -79,15 +79,15 @@ class FunctionsServerTest extends Scope $this->assertIsArray($variables['body']['data']); $this->assertArrayNotHasKey('errors', $variables['body']); - static::$cachedFunction[$key] = $function; + self::$cachedFunction[$key] = $function; return $function; } protected function setupDeployment(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedDeployment[$key])) { - return static::$cachedDeployment[$key]; + if (!empty(self::$cachedDeployment[$key])) { + return self::$cachedDeployment[$key]; } $function = $this->setupFunction(); @@ -149,15 +149,15 @@ class FunctionsServerTest extends Scope $this->assertEquals('ready', $deployment['status']); }, 120000); - static::$cachedDeployment[$key] = $deployment; + self::$cachedDeployment[$key] = $deployment; return $deployment; } protected function setupExecution(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedExecution[$key])) { - return static::$cachedExecution[$key]; + if (!empty(self::$cachedExecution[$key])) { + return self::$cachedExecution[$key]; } $deployment = $this->setupDeployment(); @@ -179,8 +179,8 @@ class FunctionsServerTest extends Scope $this->assertIsArray($execution['body']['data']); $this->assertArrayNotHasKey('errors', $execution['body']); - static::$cachedExecution[$key] = $execution['body']['data']['functionsCreateExecution']; - return static::$cachedExecution[$key]; + self::$cachedExecution[$key] = $execution['body']['data']['functionsCreateExecution']; + return self::$cachedExecution[$key]; } public function testCreateFunction(): void @@ -496,8 +496,8 @@ class FunctionsServerTest extends Scope // Clear cache after deletion $key = $this->getProject()['$id']; - static::$cachedDeployment[$key] = []; - static::$cachedExecution[$key] = []; + self::$cachedDeployment[$key] = []; + self::$cachedExecution[$key] = []; } /** @@ -529,6 +529,6 @@ class FunctionsServerTest extends Scope // Clear cache after deletion $key = $this->getProject()['$id']; - static::$cachedFunction[$key] = []; + self::$cachedFunction[$key] = []; } } diff --git a/tests/e2e/Services/GraphQL/Legacy/DatabaseClientTest.php b/tests/e2e/Services/GraphQL/Legacy/DatabaseClientTest.php index 4d34dc6b23..a4987c4078 100644 --- a/tests/e2e/Services/GraphQL/Legacy/DatabaseClientTest.php +++ b/tests/e2e/Services/GraphQL/Legacy/DatabaseClientTest.php @@ -43,8 +43,8 @@ class DatabaseClientTest extends Scope protected function setupDatabase(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$database[$cacheKey])) { - return static::$database[$cacheKey]; + if (!empty(self::$database[$cacheKey])) { + return self::$database[$cacheKey]; } $projectId = $this->getProject()['$id']; @@ -71,9 +71,9 @@ class DatabaseClientTest extends Scope } $this->assertIsArray($database['body']['data']); - static::$database[$cacheKey] = $database['body']['data']['databasesCreate']; + self::$database[$cacheKey] = $database['body']['data']['databasesCreate']; - return static::$database[$cacheKey]; + return self::$database[$cacheKey]; } /** @@ -82,8 +82,8 @@ class DatabaseClientTest extends Scope protected function setupCollection(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$collection[$cacheKey])) { - return static::$collection[$cacheKey]; + if (!empty(self::$collection[$cacheKey])) { + return self::$collection[$cacheKey]; } $database = $this->setupDatabase(); @@ -121,12 +121,12 @@ class DatabaseClientTest extends Scope $this->assertIsArray($collection['body']['data']); - static::$collection[$cacheKey] = [ + self::$collection[$cacheKey] = [ 'database' => $database, 'collection' => $collection['body']['data']['databasesCreateCollection'], ]; - return static::$collection[$cacheKey]; + return self::$collection[$cacheKey]; } /** @@ -206,8 +206,8 @@ class DatabaseClientTest extends Scope protected function setupDocument(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$document[$cacheKey])) { - return static::$document[$cacheKey]; + if (!empty(self::$document[$cacheKey])) { + return self::$document[$cacheKey]; } $data = $this->setupAttributes(); @@ -256,13 +256,13 @@ class DatabaseClientTest extends Scope $this->assertArrayNotHasKey('errors', $document['body']); $this->assertIsArray($document['body']['data']); - static::$document[$cacheKey] = [ + self::$document[$cacheKey] = [ 'database' => $data['database'], 'collection' => $data['collection'], 'document' => $document['body']['data']['databasesCreateDocument'], ]; - return static::$document[$cacheKey]; + return self::$document[$cacheKey]; } /** @@ -271,8 +271,8 @@ class DatabaseClientTest extends Scope protected function setupBulkData(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$bulkData[$cacheKey])) { - return static::$bulkData[$cacheKey]; + if (!empty(self::$bulkData[$cacheKey])) { + return self::$bulkData[$cacheKey]; } $project = $this->getProject(); @@ -352,13 +352,13 @@ class DatabaseClientTest extends Scope $this->assertArrayNotHasKey('errors', $res['body']); $this->assertCount(10, $res['body']['data']['databasesCreateDocuments']['documents']); - static::$bulkData[$cacheKey] = [ + self::$bulkData[$cacheKey] = [ 'databaseId' => $databaseId, 'collectionId' => $collectionId, 'projectId' => $projectId, ]; - return static::$bulkData[$cacheKey]; + return self::$bulkData[$cacheKey]; } /** diff --git a/tests/e2e/Services/GraphQL/MessagingTest.php b/tests/e2e/Services/GraphQL/MessagingTest.php index 322c51c1f7..03e7cc00f6 100644 --- a/tests/e2e/Services/GraphQL/MessagingTest.php +++ b/tests/e2e/Services/GraphQL/MessagingTest.php @@ -26,8 +26,8 @@ class MessagingTest extends Scope protected function setupProviders(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedProviders[$key])) { - return static::$cachedProviders[$key]; + if (!empty(self::$cachedProviders[$key])) { + return self::$cachedProviders[$key]; } $providersParams = [ @@ -128,15 +128,15 @@ class MessagingTest extends Scope $this->assertEquals($providersParams[$providerKey]['name'], $response['body']['data']['messagingCreate' . $providerKey . 'Provider']['name']); } - static::$cachedProviders[$key] = $providers; + self::$cachedProviders[$key] = $providers; return $providers; } protected function setupUpdatedProviders(): array { $key = $this->getProject()['$id'] . '_updated'; - if (!empty(static::$cachedProviders[$key])) { - return static::$cachedProviders[$key]; + if (!empty(self::$cachedProviders[$key])) { + return self::$cachedProviders[$key]; } $providers = $this->setupProviders(); @@ -247,15 +247,15 @@ class MessagingTest extends Scope $this->assertEquals('Mailgun2', $response['body']['data']['messagingUpdateMailgunProvider']['name']); $this->assertEquals(false, $response['body']['data']['messagingUpdateMailgunProvider']['enabled']); - static::$cachedProviders[$key] = $providers; + self::$cachedProviders[$key] = $providers; return $providers; } protected function setupTopic(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedTopic[$key])) { - return static::$cachedTopic[$key]; + if (!empty(self::$cachedTopic[$key])) { + return self::$cachedTopic[$key]; } $query = $this->getQuery(self::CREATE_TOPIC); @@ -275,15 +275,15 @@ class MessagingTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals('topic1', $response['body']['data']['messagingCreateTopic']['name']); - static::$cachedTopic[$key] = $response['body']['data']['messagingCreateTopic']; - return static::$cachedTopic[$key]; + self::$cachedTopic[$key] = $response['body']['data']['messagingCreateTopic']; + return self::$cachedTopic[$key]; } protected function setupUpdatedTopic(): string { $key = $this->getProject()['$id'] . '_updated'; - if (!empty(static::$cachedTopic[$key])) { - return static::$cachedTopic[$key]; + if (!empty(self::$cachedTopic[$key])) { + return self::$cachedTopic[$key]; } $topic = $this->setupTopic(); @@ -306,15 +306,15 @@ class MessagingTest extends Scope $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals('topic2', $response['body']['data']['messagingUpdateTopic']['name']); - static::$cachedTopic[$key] = $topicId; + self::$cachedTopic[$key] = $topicId; return $topicId; } protected function setupSubscriber(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedSubscriber[$key])) { - return static::$cachedSubscriber[$key]; + if (!empty(self::$cachedSubscriber[$key])) { + return self::$cachedSubscriber[$key]; } $topic = $this->setupTopic(); @@ -386,15 +386,15 @@ class MessagingTest extends Scope $this->assertEquals($response['body']['data']['messagingCreateSubscriber']['targetId'], $targetId); $this->assertEquals($response['body']['data']['messagingCreateSubscriber']['target']['userId'], $userId); - static::$cachedSubscriber[$key] = $response['body']['data']['messagingCreateSubscriber']; - return static::$cachedSubscriber[$key]; + self::$cachedSubscriber[$key] = $response['body']['data']['messagingCreateSubscriber']; + return self::$cachedSubscriber[$key]; } protected function setupEmail(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedEmail[$key])) { - return static::$cachedEmail[$key]; + if (!empty(self::$cachedEmail[$key])) { + return self::$cachedEmail[$key]; } if (empty(System::getEnv('_APP_MESSAGE_EMAIL_TEST_DSN'))) { @@ -550,15 +550,15 @@ class MessagingTest extends Scope $this->assertEquals(1, $message['body']['data']['messagingGetMessage']['deliveredTotal']); $this->assertEquals(0, \count($message['body']['data']['messagingGetMessage']['deliveryErrors'])); - static::$cachedEmail[$key] = $message['body']['data']['messagingGetMessage']; - return static::$cachedEmail[$key]; + self::$cachedEmail[$key] = $message['body']['data']['messagingGetMessage']; + return self::$cachedEmail[$key]; } protected function setupSms(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedSms[$key])) { - return static::$cachedSms[$key]; + if (!empty(self::$cachedSms[$key])) { + return self::$cachedSms[$key]; } if (empty(System::getEnv('_APP_MESSAGE_SMS_TEST_DSN'))) { @@ -709,15 +709,15 @@ class MessagingTest extends Scope $this->assertEquals(1, $message['body']['data']['messagingGetMessage']['deliveredTotal']); $this->assertEquals(0, \count($message['body']['data']['messagingGetMessage']['deliveryErrors'])); - static::$cachedSms[$key] = $message['body']['data']['messagingGetMessage']; - return static::$cachedSms[$key]; + self::$cachedSms[$key] = $message['body']['data']['messagingGetMessage']; + return self::$cachedSms[$key]; } protected function setupPush(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedPush[$key])) { - return static::$cachedPush[$key]; + if (!empty(self::$cachedPush[$key])) { + return self::$cachedPush[$key]; } if (empty(System::getEnv('_APP_MESSAGE_PUSH_TEST_DSN'))) { @@ -870,8 +870,8 @@ class MessagingTest extends Scope $this->assertEquals(1, $message['body']['data']['messagingGetMessage']['deliveredTotal']); $this->assertEquals(0, \count($message['body']['data']['messagingGetMessage']['deliveryErrors'])); - static::$cachedPush[$key] = $message['body']['data']['messagingGetMessage']; - return static::$cachedPush[$key]; + self::$cachedPush[$key] = $message['body']['data']['messagingGetMessage']; + return self::$cachedPush[$key]; } public function testCreateProviders(): void @@ -945,8 +945,8 @@ class MessagingTest extends Scope // Clear cache after deletion $key = $this->getProject()['$id']; - static::$cachedProviders[$key] = []; - static::$cachedProviders[$key . '_updated'] = []; + self::$cachedProviders[$key] = []; + self::$cachedProviders[$key . '_updated'] = []; } public function testCreateTopic(): void @@ -1081,7 +1081,7 @@ class MessagingTest extends Scope // Clear cache after deletion $key = $this->getProject()['$id']; - static::$cachedSubscriber[$key] = []; + self::$cachedSubscriber[$key] = []; } public function testDeleteTopic() @@ -1105,8 +1105,8 @@ class MessagingTest extends Scope // Clear cache after deletion $key = $this->getProject()['$id']; - static::$cachedTopic[$key] = []; - static::$cachedTopic[$key . '_updated'] = []; + self::$cachedTopic[$key] = []; + self::$cachedTopic[$key . '_updated'] = []; } public function testSendEmail(): void diff --git a/tests/e2e/Services/GraphQL/StorageClientTest.php b/tests/e2e/Services/GraphQL/StorageClientTest.php index 84af910a50..3e02de0585 100644 --- a/tests/e2e/Services/GraphQL/StorageClientTest.php +++ b/tests/e2e/Services/GraphQL/StorageClientTest.php @@ -23,8 +23,8 @@ class StorageClientTest extends Scope protected function setupBucket(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedBucket[$key])) { - return static::$cachedBucket[$key]; + if (!empty(self::$cachedBucket[$key])) { + return self::$cachedBucket[$key]; } $projectId = $this->getProject()['$id']; @@ -55,15 +55,15 @@ class StorageClientTest extends Scope $bucket = $bucket['body']['data']['storageCreateBucket']; $this->assertEquals('Actors', $bucket['name']); - static::$cachedBucket[$key] = $bucket; + self::$cachedBucket[$key] = $bucket; return $bucket; } protected function setupFile(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedFile[$key])) { - return static::$cachedFile[$key]; + if (!empty(self::$cachedFile[$key])) { + return self::$cachedFile[$key]; } $bucket = $this->setupBucket(); @@ -99,8 +99,8 @@ class StorageClientTest extends Scope $this->assertIsArray($file['body']['data']); $this->assertArrayNotHasKey('errors', $file['body']); - static::$cachedFile[$key] = $file['body']['data']['storageCreateFile']; - return static::$cachedFile[$key]; + self::$cachedFile[$key] = $file['body']['data']['storageCreateFile']; + return self::$cachedFile[$key]; } public function testCreateBucket(): void @@ -319,6 +319,6 @@ class StorageClientTest extends Scope // Clear cache after deletion $key = $this->getProject()['$id']; - static::$cachedFile[$key] = []; + self::$cachedFile[$key] = []; } } diff --git a/tests/e2e/Services/GraphQL/StorageServerTest.php b/tests/e2e/Services/GraphQL/StorageServerTest.php index 8a3158a98b..9622582e80 100644 --- a/tests/e2e/Services/GraphQL/StorageServerTest.php +++ b/tests/e2e/Services/GraphQL/StorageServerTest.php @@ -23,8 +23,8 @@ class StorageServerTest extends Scope protected function setupBucket(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedBucket[$key])) { - return static::$cachedBucket[$key]; + if (!empty(self::$cachedBucket[$key])) { + return self::$cachedBucket[$key]; } $projectId = $this->getProject()['$id']; @@ -54,15 +54,15 @@ class StorageServerTest extends Scope $bucket = $bucket['body']['data']['storageCreateBucket']; $this->assertEquals('Actors', $bucket['name']); - static::$cachedBucket[$key] = $bucket; + self::$cachedBucket[$key] = $bucket; return $bucket; } protected function setupFile(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedFile[$key])) { - return static::$cachedFile[$key]; + if (!empty(self::$cachedFile[$key])) { + return self::$cachedFile[$key]; } $bucket = $this->setupBucket(); @@ -98,8 +98,8 @@ class StorageServerTest extends Scope $this->assertIsArray($file['body']['data']); $this->assertArrayNotHasKey('errors', $file['body']); - static::$cachedFile[$key] = $file['body']['data']['storageCreateFile']; - return static::$cachedFile[$key]; + self::$cachedFile[$key] = $file['body']['data']['storageCreateFile']; + return self::$cachedFile[$key]; } public function testCreateBucket(): void @@ -413,7 +413,7 @@ class StorageServerTest extends Scope // Clear cache after deletion $key = $this->getProject()['$id']; - static::$cachedFile[$key] = []; + self::$cachedFile[$key] = []; } /** @@ -443,7 +443,7 @@ class StorageServerTest extends Scope // Clear cache after deletion $key = $this->getProject()['$id']; - static::$cachedBucket[$key] = []; - static::$cachedFile[$key] = []; + self::$cachedBucket[$key] = []; + self::$cachedFile[$key] = []; } } diff --git a/tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php b/tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php index 3078202546..f0b4e4b75c 100644 --- a/tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php +++ b/tests/e2e/Services/GraphQL/TablesDB/DatabaseServerTest.php @@ -39,8 +39,8 @@ class DatabaseServerTest extends Scope protected function setupDatabase(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedDatabase[$cacheKey])) { - return static::$cachedDatabase[$cacheKey]; + if (!empty(self::$cachedDatabase[$cacheKey])) { + return self::$cachedDatabase[$cacheKey]; } $projectId = $this->getProject()['$id']; @@ -62,15 +62,15 @@ class DatabaseServerTest extends Scope $this->assertArrayNotHasKey('errors', $database['body']); - static::$cachedDatabase[$cacheKey] = $database['body']['data']['tablesDBCreate']; - return static::$cachedDatabase[$cacheKey]; + self::$cachedDatabase[$cacheKey] = $database['body']['data']['tablesDBCreate']; + return self::$cachedDatabase[$cacheKey]; } protected function setupTable(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedTableData[$cacheKey])) { - return static::$cachedTableData[$cacheKey]; + if (!empty(self::$cachedTableData[$cacheKey])) { + return self::$cachedTableData[$cacheKey]; } $database = $this->setupDatabase(); @@ -124,20 +124,20 @@ class DatabaseServerTest extends Scope $this->assertArrayNotHasKey('errors', $table2['body']); $table2 = $table2['body']['data']['tablesDBCreateTable']; - static::$cachedTableData[$cacheKey] = [ + self::$cachedTableData[$cacheKey] = [ 'database' => $database, 'table' => $table, 'table2' => $table2, ]; - return static::$cachedTableData[$cacheKey]; + return self::$cachedTableData[$cacheKey]; } protected function setupStringColumn(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedStringColumnData[$cacheKey])) { - return static::$cachedStringColumnData[$cacheKey]; + if (!empty(self::$cachedStringColumnData[$cacheKey])) { + return self::$cachedStringColumnData[$cacheKey]; } $data = $this->setupTable(); @@ -159,8 +159,8 @@ class DatabaseServerTest extends Scope 'x-appwrite-project' => $projectId, ], $this->getHeaders()), $gqlPayload); - static::$cachedStringColumnData[$cacheKey] = $data; - return static::$cachedStringColumnData[$cacheKey]; + self::$cachedStringColumnData[$cacheKey] = $data; + return self::$cachedStringColumnData[$cacheKey]; } protected function setupUpdatedStringColumn(): array @@ -205,8 +205,8 @@ class DatabaseServerTest extends Scope protected function setupIntegerColumn(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedIntegerColumnData[$cacheKey])) { - return static::$cachedIntegerColumnData[$cacheKey]; + if (!empty(self::$cachedIntegerColumnData[$cacheKey])) { + return self::$cachedIntegerColumnData[$cacheKey]; } $data = $this->setupTable(); @@ -229,8 +229,8 @@ class DatabaseServerTest extends Scope 'x-appwrite-project' => $projectId, ], $this->getHeaders()), $gqlPayload); - static::$cachedIntegerColumnData[$cacheKey] = $data; - return static::$cachedIntegerColumnData[$cacheKey]; + self::$cachedIntegerColumnData[$cacheKey] = $data; + return self::$cachedIntegerColumnData[$cacheKey]; } protected function setupUpdatedIntegerColumn(): array @@ -275,8 +275,8 @@ class DatabaseServerTest extends Scope protected function setupBooleanColumn(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedBooleanColumnData[$cacheKey])) { - return static::$cachedBooleanColumnData[$cacheKey]; + if (!empty(self::$cachedBooleanColumnData[$cacheKey])) { + return self::$cachedBooleanColumnData[$cacheKey]; } $data = $this->setupTable(); @@ -297,8 +297,8 @@ class DatabaseServerTest extends Scope 'x-appwrite-project' => $projectId, ], $this->getHeaders()), $gqlPayload); - static::$cachedBooleanColumnData[$cacheKey] = $data; - return static::$cachedBooleanColumnData[$cacheKey]; + self::$cachedBooleanColumnData[$cacheKey] = $data; + return self::$cachedBooleanColumnData[$cacheKey]; } protected function setupUpdatedBooleanColumn(): array @@ -341,8 +341,8 @@ class DatabaseServerTest extends Scope protected function setupFloatColumn(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedFloatColumnData[$cacheKey])) { - return static::$cachedFloatColumnData[$cacheKey]; + if (!empty(self::$cachedFloatColumnData[$cacheKey])) { + return self::$cachedFloatColumnData[$cacheKey]; } $data = $this->setupTable(); @@ -366,8 +366,8 @@ class DatabaseServerTest extends Scope 'x-appwrite-project' => $projectId, ], $this->getHeaders()), $gqlPayload); - static::$cachedFloatColumnData[$cacheKey] = $data; - return static::$cachedFloatColumnData[$cacheKey]; + self::$cachedFloatColumnData[$cacheKey] = $data; + return self::$cachedFloatColumnData[$cacheKey]; } protected function setupUpdatedFloatColumn(): array @@ -412,8 +412,8 @@ class DatabaseServerTest extends Scope protected function setupEmailColumn(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedEmailColumnData[$cacheKey])) { - return static::$cachedEmailColumnData[$cacheKey]; + if (!empty(self::$cachedEmailColumnData[$cacheKey])) { + return self::$cachedEmailColumnData[$cacheKey]; } $data = $this->setupTable(); @@ -434,8 +434,8 @@ class DatabaseServerTest extends Scope 'x-appwrite-project' => $projectId, ], $this->getHeaders()), $gqlPayload); - static::$cachedEmailColumnData[$cacheKey] = $data; - return static::$cachedEmailColumnData[$cacheKey]; + self::$cachedEmailColumnData[$cacheKey] = $data; + return self::$cachedEmailColumnData[$cacheKey]; } protected function setupUpdatedEmailColumn(): array @@ -478,8 +478,8 @@ class DatabaseServerTest extends Scope protected function setupEnumColumn(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedEnumColumnData[$cacheKey])) { - return static::$cachedEnumColumnData[$cacheKey]; + if (!empty(self::$cachedEnumColumnData[$cacheKey])) { + return self::$cachedEnumColumnData[$cacheKey]; } $data = $this->setupTable(); @@ -505,8 +505,8 @@ class DatabaseServerTest extends Scope 'x-appwrite-project' => $projectId, ], $this->getHeaders()), $gqlPayload); - static::$cachedEnumColumnData[$cacheKey] = $data; - return static::$cachedEnumColumnData[$cacheKey]; + self::$cachedEnumColumnData[$cacheKey] = $data; + return self::$cachedEnumColumnData[$cacheKey]; } protected function setupUpdatedEnumColumn(): array @@ -554,8 +554,8 @@ class DatabaseServerTest extends Scope protected function setupDatetimeColumn(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedDatetimeColumnData[$cacheKey])) { - return static::$cachedDatetimeColumnData[$cacheKey]; + if (!empty(self::$cachedDatetimeColumnData[$cacheKey])) { + return self::$cachedDatetimeColumnData[$cacheKey]; } $data = $this->setupTable(); @@ -576,8 +576,8 @@ class DatabaseServerTest extends Scope 'x-appwrite-project' => $projectId, ], $this->getHeaders()), $gqlPayload); - static::$cachedDatetimeColumnData[$cacheKey] = $data; - return static::$cachedDatetimeColumnData[$cacheKey]; + self::$cachedDatetimeColumnData[$cacheKey] = $data; + return self::$cachedDatetimeColumnData[$cacheKey]; } protected function setupUpdatedDatetimeColumn(): array @@ -620,8 +620,8 @@ class DatabaseServerTest extends Scope protected function setupRelationshipColumn(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedRelationshipColumnData[$cacheKey])) { - return static::$cachedRelationshipColumnData[$cacheKey]; + if (!empty(self::$cachedRelationshipColumnData[$cacheKey])) { + return self::$cachedRelationshipColumnData[$cacheKey]; } $data = $this->setupTable(); @@ -645,8 +645,8 @@ class DatabaseServerTest extends Scope 'x-appwrite-project' => $projectId, ], $this->getHeaders()), $gqlPayload); - static::$cachedRelationshipColumnData[$cacheKey] = $data; - return static::$cachedRelationshipColumnData[$cacheKey]; + self::$cachedRelationshipColumnData[$cacheKey] = $data; + return self::$cachedRelationshipColumnData[$cacheKey]; } protected function setupUpdatedRelationshipColumn(): array @@ -688,8 +688,8 @@ class DatabaseServerTest extends Scope protected function setupIPColumn(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedIPColumnData[$cacheKey])) { - return static::$cachedIPColumnData[$cacheKey]; + if (!empty(self::$cachedIPColumnData[$cacheKey])) { + return self::$cachedIPColumnData[$cacheKey]; } $data = $this->setupTable(); @@ -711,8 +711,8 @@ class DatabaseServerTest extends Scope 'x-appwrite-project' => $projectId, ], $this->getHeaders()), $gqlPayload); - static::$cachedIPColumnData[$cacheKey] = $data; - return static::$cachedIPColumnData[$cacheKey]; + self::$cachedIPColumnData[$cacheKey] = $data; + return self::$cachedIPColumnData[$cacheKey]; } protected function setupUpdatedIPColumn(): array @@ -755,8 +755,8 @@ class DatabaseServerTest extends Scope protected function setupURLColumn(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedURLColumnData[$cacheKey])) { - return static::$cachedURLColumnData[$cacheKey]; + if (!empty(self::$cachedURLColumnData[$cacheKey])) { + return self::$cachedURLColumnData[$cacheKey]; } $data = $this->setupTable(); @@ -778,8 +778,8 @@ class DatabaseServerTest extends Scope 'x-appwrite-project' => $projectId, ], $this->getHeaders()), $gqlPayload); - static::$cachedURLColumnData[$cacheKey] = $data; - return static::$cachedURLColumnData[$cacheKey]; + self::$cachedURLColumnData[$cacheKey] = $data; + return self::$cachedURLColumnData[$cacheKey]; } protected function setupUpdatedURLColumn(): array @@ -822,8 +822,8 @@ class DatabaseServerTest extends Scope protected function setupIndex(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedIndexData[$cacheKey])) { - return static::$cachedIndexData[$cacheKey]; + if (!empty(self::$cachedIndexData[$cacheKey])) { + return self::$cachedIndexData[$cacheKey]; } // Need updated string and integer columns first @@ -855,31 +855,31 @@ class DatabaseServerTest extends Scope if (isset($index['body']['errors'])) { $errorMessage = $index['body']['errors'][0]['message'] ?? ''; if (strpos($errorMessage, 'already exists') !== false || strpos($errorMessage, 'Document with the requested ID already exists') !== false) { - static::$cachedIndexData[$cacheKey] = [ + self::$cachedIndexData[$cacheKey] = [ 'database' => $data['database'], 'table' => $data['table'], 'index' => ['key' => 'index'], ]; - return static::$cachedIndexData[$cacheKey]; + return self::$cachedIndexData[$cacheKey]; } } $this->assertArrayNotHasKey('errors', $index['body']); - static::$cachedIndexData[$cacheKey] = [ + self::$cachedIndexData[$cacheKey] = [ 'database' => $data['database'], 'table' => $data['table'], 'index' => $index['body']['data']['tablesDBCreateIndex'], ]; - return static::$cachedIndexData[$cacheKey]; + return self::$cachedIndexData[$cacheKey]; } protected function setupRow(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedRowData[$cacheKey])) { - return static::$cachedRowData[$cacheKey]; + if (!empty(self::$cachedRowData[$cacheKey])) { + return self::$cachedRowData[$cacheKey]; } // Need all columns that the row data references @@ -940,20 +940,20 @@ class DatabaseServerTest extends Scope $this->assertArrayNotHasKey('errors', $row['body']); $row = $row['body']['data']['tablesDBCreateRow']; - static::$cachedRowData[$cacheKey] = [ + self::$cachedRowData[$cacheKey] = [ 'database' => $data['database'], 'table' => $data['table'], 'row' => $row, ]; - return static::$cachedRowData[$cacheKey]; + return self::$cachedRowData[$cacheKey]; } protected function setupBulkData(): array { $cacheKey = $this->getProject()['$id'] ?? 'default'; - if (!empty(static::$cachedBulkData[$cacheKey])) { - return static::$cachedBulkData[$cacheKey]; + if (!empty(self::$cachedBulkData[$cacheKey])) { + return self::$cachedBulkData[$cacheKey]; } $project = $this->getProject(); @@ -1034,9 +1034,9 @@ class DatabaseServerTest extends Scope $this->client->call(Client::METHOD_POST, '/graphql', $headers, $payload); - static::$cachedBulkData[$cacheKey] = compact('databaseId', 'tableId', 'projectId'); + self::$cachedBulkData[$cacheKey] = compact('databaseId', 'tableId', 'projectId'); - return static::$cachedBulkData[$cacheKey]; + return self::$cachedBulkData[$cacheKey]; } public function testCreateDatabase(): void @@ -1088,7 +1088,7 @@ class DatabaseServerTest extends Scope // Store for caching $cacheKey = $this->getProject()['$id'] ?? 'default'; - static::$cachedStringColumnData[$cacheKey] = $data; + self::$cachedStringColumnData[$cacheKey] = $data; } /** @@ -1166,7 +1166,7 @@ class DatabaseServerTest extends Scope // Store for caching $cacheKey = $this->getProject()['$id'] ?? 'default'; - static::$cachedIntegerColumnData[$cacheKey] = $data; + self::$cachedIntegerColumnData[$cacheKey] = $data; } /** @@ -1246,7 +1246,7 @@ class DatabaseServerTest extends Scope // Store for caching $cacheKey = $this->getProject()['$id'] ?? 'default'; - static::$cachedBooleanColumnData[$cacheKey] = $data; + self::$cachedBooleanColumnData[$cacheKey] = $data; } /** @@ -1325,7 +1325,7 @@ class DatabaseServerTest extends Scope // Store for caching $cacheKey = $this->getProject()['$id'] ?? 'default'; - static::$cachedFloatColumnData[$cacheKey] = $data; + self::$cachedFloatColumnData[$cacheKey] = $data; } /** @@ -1405,7 +1405,7 @@ class DatabaseServerTest extends Scope // Store for caching $cacheKey = $this->getProject()['$id'] ?? 'default'; - static::$cachedEmailColumnData[$cacheKey] = $data; + self::$cachedEmailColumnData[$cacheKey] = $data; } /** @@ -1486,7 +1486,7 @@ class DatabaseServerTest extends Scope // Store for caching $cacheKey = $this->getProject()['$id'] ?? 'default'; - static::$cachedEnumColumnData[$cacheKey] = $data; + self::$cachedEnumColumnData[$cacheKey] = $data; } @@ -1570,7 +1570,7 @@ class DatabaseServerTest extends Scope // Store for caching $cacheKey = $this->getProject()['$id'] ?? 'default'; - static::$cachedDatetimeColumnData[$cacheKey] = $data; + self::$cachedDatetimeColumnData[$cacheKey] = $data; } /** @@ -1646,7 +1646,7 @@ class DatabaseServerTest extends Scope // Store for caching $cacheKey = $this->getProject()['$id'] ?? 'default'; - static::$cachedRelationshipColumnData[$cacheKey] = $data; + self::$cachedRelationshipColumnData[$cacheKey] = $data; } public function testUpdateRelationshipColumn(): void @@ -1717,7 +1717,7 @@ class DatabaseServerTest extends Scope // Store for caching $cacheKey = $this->getProject()['$id'] ?? 'default'; - static::$cachedIPColumnData[$cacheKey] = $data; + self::$cachedIPColumnData[$cacheKey] = $data; } /** @@ -1794,7 +1794,7 @@ class DatabaseServerTest extends Scope // Store for caching $cacheKey = $this->getProject()['$id'] ?? 'default'; - static::$cachedURLColumnData[$cacheKey] = $data; + self::$cachedURLColumnData[$cacheKey] = $data; } /** @@ -1877,7 +1877,7 @@ class DatabaseServerTest extends Scope // Store for caching $cacheKey = $this->getProject()['$id'] ?? 'default'; - static::$cachedIndexData[$cacheKey] = [ + self::$cachedIndexData[$cacheKey] = [ 'database' => $data['database'], 'table' => $data['table'], 'index' => $index['body']['data']['tablesDBCreateIndex'], @@ -1952,7 +1952,7 @@ class DatabaseServerTest extends Scope // Store for caching $cacheKey = $this->getProject()['$id'] ?? 'default'; - static::$cachedRowData[$cacheKey] = [ + self::$cachedRowData[$cacheKey] = [ 'database' => $data['database'], 'table' => $data['table'], 'row' => $row, diff --git a/tests/e2e/Services/GraphQL/TeamsClientTest.php b/tests/e2e/Services/GraphQL/TeamsClientTest.php index 44cf3c9d12..e6c27f44f8 100644 --- a/tests/e2e/Services/GraphQL/TeamsClientTest.php +++ b/tests/e2e/Services/GraphQL/TeamsClientTest.php @@ -20,8 +20,8 @@ class TeamsClientTest extends Scope protected function setupTeam(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedTeam[$key])) { - return static::$cachedTeam[$key]; + if (!empty(self::$cachedTeam[$key])) { + return self::$cachedTeam[$key]; } $projectId = $this->getProject()['$id']; @@ -45,15 +45,15 @@ class TeamsClientTest extends Scope $team = $team['body']['data']['teamsCreate']; $this->assertEquals('Team Name', $team['name']); - static::$cachedTeam[$key] = $team; + self::$cachedTeam[$key] = $team; return $team; } protected function setupMembership(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedMembership[$key])) { - return static::$cachedMembership[$key]; + if (!empty(self::$cachedMembership[$key])) { + return self::$cachedMembership[$key]; } $team = $this->setupTeam(); @@ -82,7 +82,7 @@ class TeamsClientTest extends Scope $this->assertEquals($team['_id'], $membership['teamId']); $this->assertEquals(['developer'], $membership['roles']); - static::$cachedMembership[$key] = $membership; + self::$cachedMembership[$key] = $membership; return $membership; } @@ -211,6 +211,6 @@ class TeamsClientTest extends Scope // Clear cache after deletion $key = $this->getProject()['$id']; - static::$cachedMembership[$key] = []; + self::$cachedMembership[$key] = []; } } diff --git a/tests/e2e/Services/GraphQL/TeamsServerTest.php b/tests/e2e/Services/GraphQL/TeamsServerTest.php index bd0939040c..ff6e8e3c6f 100644 --- a/tests/e2e/Services/GraphQL/TeamsServerTest.php +++ b/tests/e2e/Services/GraphQL/TeamsServerTest.php @@ -22,8 +22,8 @@ class TeamsServerTest extends Scope protected function setupTeam(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedTeam[$key])) { - return static::$cachedTeam[$key]; + if (!empty(self::$cachedTeam[$key])) { + return self::$cachedTeam[$key]; } $projectId = $this->getProject()['$id']; @@ -47,15 +47,15 @@ class TeamsServerTest extends Scope $team = $team['body']['data']['teamsCreate']; $this->assertEquals('Team Name', $team['name']); - static::$cachedTeam[$key] = $team; + self::$cachedTeam[$key] = $team; return $team; } protected function setupMembership(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedMembership[$key])) { - return static::$cachedMembership[$key]; + if (!empty(self::$cachedMembership[$key])) { + return self::$cachedMembership[$key]; } $team = $this->setupTeam(); @@ -83,15 +83,15 @@ class TeamsServerTest extends Scope $this->assertEquals($team['_id'], $membership['teamId']); $this->assertEquals(['developer'], $membership['roles']); - static::$cachedMembership[$key] = $membership; + self::$cachedMembership[$key] = $membership; return $membership; } protected function setupTeamWithPrefs(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedTeamWithPrefs[$key])) { - return static::$cachedTeamWithPrefs[$key]; + if (!empty(self::$cachedTeamWithPrefs[$key])) { + return self::$cachedTeamWithPrefs[$key]; } $team = $this->setupTeam(); @@ -137,7 +137,7 @@ class TeamsServerTest extends Scope $this->assertIsArray($prefs['body']['data']['teamsUpdatePrefs']); $this->assertEquals('{"key":"value"}', $prefs['body']['data']['teamsUpdatePrefs']['data']); - static::$cachedTeamWithPrefs[$key] = $fetchedTeam; + self::$cachedTeamWithPrefs[$key] = $fetchedTeam; return $fetchedTeam; } @@ -349,7 +349,7 @@ class TeamsServerTest extends Scope // Clear cache after deletion $key = $this->getProject()['$id']; - static::$cachedMembership[$key] = []; + self::$cachedMembership[$key] = []; } #[Group('cl-ignore')] diff --git a/tests/e2e/Services/GraphQL/UsersTest.php b/tests/e2e/Services/GraphQL/UsersTest.php index da9f761567..efe99531be 100644 --- a/tests/e2e/Services/GraphQL/UsersTest.php +++ b/tests/e2e/Services/GraphQL/UsersTest.php @@ -21,8 +21,8 @@ class UsersTest extends Scope protected function setupUser(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedUser[$key])) { - return static::$cachedUser[$key]; + if (!empty(self::$cachedUser[$key])) { + return self::$cachedUser[$key]; } $projectId = $this->getProject()['$id']; @@ -50,15 +50,15 @@ class UsersTest extends Scope $this->assertEquals('Project User', $user['name']); $this->assertEquals($email, $user['email']); - static::$cachedUser[$key] = $user; + self::$cachedUser[$key] = $user; return $user; } protected function setupUserTarget(): array { $key = $this->getProject()['$id']; - if (!empty(static::$cachedUserTarget[$key])) { - return static::$cachedUserTarget[$key]; + if (!empty(self::$cachedUserTarget[$key])) { + return self::$cachedUserTarget[$key]; } $user = $this->setupUser(); @@ -106,8 +106,8 @@ class UsersTest extends Scope $this->assertEquals(200, $target['headers']['status-code']); $this->assertEquals('random-email@mail.org', $target['body']['data']['usersCreateTarget']['identifier']); - static::$cachedUserTarget[$key] = $target['body']['data']['usersCreateTarget']; - return static::$cachedUserTarget[$key]; + self::$cachedUserTarget[$key] = $target['body']['data']['usersCreateTarget']; + return self::$cachedUserTarget[$key]; } public function testCreateUser(): void @@ -581,7 +581,7 @@ class UsersTest extends Scope // Clear cache after deletion $key = $this->getProject()['$id']; - static::$cachedUserTarget[$key] = []; + self::$cachedUserTarget[$key] = []; } public function testDeleteUser() diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index a2bf23d402..03723bf231 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -3054,6 +3054,10 @@ class RealtimeCustomClientTest extends Scope } $this->assertNotNull($event, 'Timed out waiting for the row update event'); + $this->assertArrayHasKey('type', $event); + $this->assertArrayHasKey('data', $event); + $this->assertEquals('event', $event['type']); + $this->assertNotEmpty($event['data']); $this->assertArrayHasKey('timestamp', $event['data']); $channels = $event['data']['channels']; diff --git a/tests/e2e/Services/Tokens/TokensBase.php b/tests/e2e/Services/Tokens/TokensBase.php index ced6bb5dde..1fcdeb347f 100644 --- a/tests/e2e/Services/Tokens/TokensBase.php +++ b/tests/e2e/Services/Tokens/TokensBase.php @@ -14,8 +14,8 @@ trait TokensBase protected function setupBucketAndFile(): array { - if (!empty(static::$bucketAndFileData)) { - return static::$bucketAndFileData; + if (!empty(self::$bucketAndFileData)) { + return self::$bucketAndFileData; } $bucket = $this->client->call( @@ -61,7 +61,7 @@ trait TokensBase ] ); - static::$bucketAndFileData = [ + self::$bucketAndFileData = [ 'fileId' => $fileId, 'bucketId' => $bucketId, 'token' => $token['body'], @@ -72,7 +72,7 @@ trait TokensBase ], ]; - return static::$bucketAndFileData; + return self::$bucketAndFileData; } public function testCreateBucketAndFile(): void diff --git a/tests/e2e/Services/Tokens/TokensConsoleClientTest.php b/tests/e2e/Services/Tokens/TokensConsoleClientTest.php index b7f188f5b5..601bf1d2d0 100644 --- a/tests/e2e/Services/Tokens/TokensConsoleClientTest.php +++ b/tests/e2e/Services/Tokens/TokensConsoleClientTest.php @@ -25,8 +25,8 @@ class TokensConsoleClientTest extends Scope protected function setupToken(): array { - if (!empty(static::$tokenData)) { - return static::$tokenData; + if (!empty(self::$tokenData)) { + return self::$tokenData; } $bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', array_merge([ @@ -68,13 +68,13 @@ class TokensConsoleClientTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders())); - static::$tokenData = [ + self::$tokenData = [ 'fileId' => $fileId, 'bucketId' => $bucketId, 'tokenId' => $token['body']['$id'], ]; - return static::$tokenData; + return self::$tokenData; } public function testCreateToken(): void diff --git a/tests/e2e/Services/Tokens/TokensCustomServerTest.php b/tests/e2e/Services/Tokens/TokensCustomServerTest.php index ecb9bafc89..3efa0adbe1 100644 --- a/tests/e2e/Services/Tokens/TokensCustomServerTest.php +++ b/tests/e2e/Services/Tokens/TokensCustomServerTest.php @@ -22,8 +22,8 @@ class TokensCustomServerTest extends Scope protected function setupToken(): array { - if (!empty(static::$tokenData)) { - return static::$tokenData; + if (!empty(self::$tokenData)) { + return self::$tokenData; } $bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', [ @@ -66,13 +66,13 @@ class TokensCustomServerTest extends Scope 'x-appwrite-project' => $this->getProject()['$id'] ], $this->getHeaders())); - static::$tokenData = [ + self::$tokenData = [ 'fileId' => $fileId, 'bucketId' => $bucketId, 'tokenId' => $token['body']['$id'], ]; - return static::$tokenData; + return self::$tokenData; } public function testCreateToken(): void diff --git a/tests/unit/Utopia/Response/Filters/V16Test.php b/tests/unit/Utopia/Response/Filters/V16Test.php index e771146e3a..2ba60d35e9 100644 --- a/tests/unit/Utopia/Response/Filters/V16Test.php +++ b/tests/unit/Utopia/Response/Filters/V16Test.php @@ -3,6 +3,7 @@ namespace Tests\Unit\Utopia\Response\Filters; use Appwrite\Utopia\Response; +use Appwrite\Utopia\Response\Filter; use Appwrite\Utopia\Response\Filters\V16; use Cron\CronExpression; use PHPUnit\Framework\Attributes\DataProvider; @@ -11,10 +12,7 @@ use Utopia\Database\DateTime; class V16Test extends TestCase { - /** - * @var Filter - */ - protected $filter = null; + protected Filter $filter; public function setUp(): void { diff --git a/tests/unit/Utopia/Response/Filters/V17Test.php b/tests/unit/Utopia/Response/Filters/V17Test.php index 21d91e1314..0bdc4de53e 100644 --- a/tests/unit/Utopia/Response/Filters/V17Test.php +++ b/tests/unit/Utopia/Response/Filters/V17Test.php @@ -3,16 +3,14 @@ namespace Tests\Unit\Utopia\Response\Filters; use Appwrite\Utopia\Response; +use Appwrite\Utopia\Response\Filter; use Appwrite\Utopia\Response\Filters\V17; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; class V17Test extends TestCase { - /** - * @var Filter - */ - protected $filter = null; + protected Filter $filter; public function setUp(): void { diff --git a/tests/unit/Utopia/Response/Filters/V18Test.php b/tests/unit/Utopia/Response/Filters/V18Test.php index da169a7d0e..2e09b34515 100644 --- a/tests/unit/Utopia/Response/Filters/V18Test.php +++ b/tests/unit/Utopia/Response/Filters/V18Test.php @@ -3,16 +3,14 @@ namespace Tests\Unit\Utopia\Response\Filters; use Appwrite\Utopia\Response; +use Appwrite\Utopia\Response\Filter; use Appwrite\Utopia\Response\Filters\V18; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; class V18Test extends TestCase { - /** - * @var Filter - */ - protected $filter = null; + protected Filter $filter; public function setUp(): void { diff --git a/tests/unit/Utopia/Response/Filters/V19Test.php b/tests/unit/Utopia/Response/Filters/V19Test.php index eaeefba2fc..a53dbfe355 100644 --- a/tests/unit/Utopia/Response/Filters/V19Test.php +++ b/tests/unit/Utopia/Response/Filters/V19Test.php @@ -3,16 +3,14 @@ namespace Tests\Unit\Utopia\Response\Filters; use Appwrite\Utopia\Response; +use Appwrite\Utopia\Response\Filter; use Appwrite\Utopia\Response\Filters\V19; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; class V19Test extends TestCase { - /** - * @var Filter - */ - protected $filter = null; + protected Filter $filter; public function setUp(): void {