diff --git a/composer.json b/composer.json index a52b23a9..6bd64041 100644 --- a/composer.json +++ b/composer.json @@ -22,10 +22,11 @@ "check": "./vendor/bin/phpstan analyse --level 3 src tests --memory-limit 2G" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "ext-curl": "*", "ext-openssl": "*", - "appwrite/appwrite": "19.*", + + "appwrite/appwrite": "23.*", "utopia-php/database": "5.*", "utopia-php/storage": "2.*", "utopia-php/dsn": "0.2.*", @@ -38,9 +39,6 @@ "laravel/pint": "1.*", "phpstan/phpstan": "1.*" }, - "platform": { - "php": "8.1" - }, "config": { "allow-plugins": { "php-http/discovery": true, diff --git a/composer.lock b/composer.lock index 15882491..ab0a68c7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,29 +4,29 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "38981f8df096cfbc9dd34487643b7ed6", + "content-hash": "44746ecb1183e23d963fc90b1481541a", "packages": [ { "name": "appwrite/appwrite", - "version": "19.1.0", + "version": "23.1.0", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-for-php.git", - "reference": "8738e812062f899c85b2598eef43d6a247f08a56" + "reference": "2f275921f10ceb7cff99f2d463f7328b296234fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/8738e812062f899c85b2598eef43d6a247f08a56", - "reference": "8738e812062f899c85b2598eef43d6a247f08a56", + "url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/2f275921f10ceb7cff99f2d463f7328b296234fa", + "reference": "2f275921f10ceb7cff99f2d463f7328b296234fa", "shasum": "" }, "require": { "ext-curl": "*", "ext-json": "*", - "php": ">=7.1.0" + "php": ">=8.2.0" }, "require-dev": { - "mockery/mockery": "^1.6.12", + "mockery/mockery": "1.6.12", "phpunit/phpunit": "^10" }, "type": "library", @@ -39,14 +39,14 @@ "license": [ "BSD-3-Clause" ], - "description": "Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API", + "description": "Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API", "support": { "email": "team@appwrite.io", "issues": "https://github.com/appwrite/sdk-for-php/issues", - "source": "https://github.com/appwrite/sdk-for-php/tree/19.1.0", + "source": "https://github.com/appwrite/sdk-for-php/tree/23.1.0", "url": "https://appwrite.io/support" }, - "time": "2025-12-18T08:07:43+00:00" + "time": "2026-05-08T13:44:58+00:00" }, { "name": "brick/math", @@ -1420,16 +1420,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v3.6.0", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", - "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/50f59d1f3ca46d41ac911f97a78626b6756af35b", + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b", "shasum": "" }, "require": { @@ -1442,7 +1442,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.6-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -1467,7 +1467,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.0" }, "funding": [ { @@ -1478,12 +1478,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-25T14:21:43+00:00" + "time": "2026-04-13T15:52:40+00:00" }, { "name": "symfony/http-client", @@ -1588,16 +1592,16 @@ }, { "name": "symfony/http-client-contracts", - "version": "v3.6.0", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "75d7043853a42837e68111812f4d964b01e5101c" + "reference": "4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/75d7043853a42837e68111812f4d964b01e5101c", - "reference": "75d7043853a42837e68111812f4d964b01e5101c", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d", + "reference": "4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d", "shasum": "" }, "require": { @@ -1610,7 +1614,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.6-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -1646,7 +1650,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.6.0" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.7.0" }, "funding": [ { @@ -1657,12 +1661,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-04-29T11:18:49+00:00" + "time": "2026-03-06T13:17:50+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1991,16 +1999,16 @@ }, { "name": "symfony/service-contracts", - "version": "v3.6.1", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", - "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d25d82433a80eba6aa0e6c24b61d7370d99e444a", + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a", "shasum": "" }, "require": { @@ -2018,7 +2026,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.6-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -2054,7 +2062,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.7.0" }, "funding": [ { @@ -2074,7 +2082,7 @@ "type": "tidelift" } ], - "time": "2025-07-15T11:30:57+00:00" + "time": "2026-03-28T09:44:51+00:00" }, { "name": "tbachert/spi", @@ -2130,16 +2138,16 @@ }, { "name": "utopia-php/cache", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/utopia-php/cache.git", - "reference": "05ceba981436a4022553f7aaa2a05fa049d0f71c" + "reference": "d36f9050c39c02e09a7763389c9e71258e74af1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/cache/zipball/05ceba981436a4022553f7aaa2a05fa049d0f71c", - "reference": "05ceba981436a4022553f7aaa2a05fa049d0f71c", + "url": "https://api.github.com/repos/utopia-php/cache/zipball/d36f9050c39c02e09a7763389c9e71258e74af1f", + "reference": "d36f9050c39c02e09a7763389c9e71258e74af1f", "shasum": "" }, "require": { @@ -2176,9 +2184,9 @@ ], "support": { "issues": "https://github.com/utopia-php/cache/issues", - "source": "https://github.com/utopia-php/cache/tree/1.0.1" + "source": "https://github.com/utopia-php/cache/tree/1.0.2" }, - "time": "2026-03-12T03:39:09+00:00" + "time": "2026-05-08T11:40:20+00:00" }, { "name": "utopia-php/console", @@ -4956,7 +4964,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=8.1", + "php": ">=8.2", "ext-curl": "*", "ext-openssl": "*" }, diff --git a/src/Migration/Destinations/Appwrite.php b/src/Migration/Destinations/Appwrite.php index 312f7e3f..71ab9da8 100644 --- a/src/Migration/Destinations/Appwrite.php +++ b/src/Migration/Destinations/Appwrite.php @@ -1999,7 +1999,7 @@ public function importFileResource(Resource $resource): Resource $resource->getTransformations() ); - $resource->setId($response['$id']); + $resource->setId($response->id); } $resource->setStatus(Resource::STATUS_SUCCESS); @@ -2151,11 +2151,11 @@ public function importAuthResource(Resource $resource): Resource /** * @param User $user - * @return array|null + * @return \Appwrite\Models\User|null * @throws AppwriteException * @throws \Exception */ - public function importPasswordUser(User $user): ?array + public function importPasswordUser(User $user): ?\Appwrite\Models\User { $hash = $user->getPasswordHash(); $result = null; @@ -2277,9 +2277,6 @@ public function importFunctionResource(Resource $resource): Resource 'dart-2.17' => Runtime::DART217(), 'dart-2.18' => Runtime::DART218(), 'dart-2.19' => Runtime::DART219(), - 'deno-1.21' => Runtime::DENO121(), - 'deno-1.24' => Runtime::DENO124(), - 'deno-1.35' => Runtime::DENO135(), 'deno-1.40' => Runtime::DENO140(), 'deno-1.46' => Runtime::DENO146(), 'deno-2.0' => Runtime::DENO20(), @@ -2310,27 +2307,29 @@ public function importFunctionResource(Resource $resource): Resource }; $this->functions->create( - $resource->getId(), - $resource->getFunctionName(), - $runtime, - $resource->getExecute(), - $resource->getEvents(), - $resource->getSchedule(), - $resource->getTimeout(), - $resource->getEnabled(), - $resource->getLogging(), - $resource->getEntrypoint(), - $resource->getCommands(), - $resource->getScopes(), - specification: $resource->getSpecification() ?: null, + functionId: $resource->getId(), + name: $resource->getFunctionName(), + runtime: $runtime, + execute: $resource->getExecute(), + events: $resource->getEvents(), + schedule: $resource->getSchedule(), + timeout: $resource->getTimeout(), + enabled: $resource->getEnabled(), + logging: $resource->getLogging(), + entrypoint: $resource->getEntrypoint(), + commands: $resource->getCommands(), + scopes: $resource->getScopes(), + buildSpecification: $resource->getSpecification() ?: null, + runtimeSpecification: $resource->getSpecification() ?: null, ); break; case Resource::TYPE_ENVIRONMENT_VARIABLE: /** @var EnvVar $resource */ $this->functions->createVariable( - $resource->getFunc()->getId(), - $resource->getKey(), - $resource->getValue() + functionId: $resource->getFunc()->getId(), + variableId: $resource->getId(), + key: $resource->getKey(), + value: $resource->getValue(), ); break; case Resource::TYPE_DEPLOYMENT: @@ -2498,9 +2497,6 @@ public function importSiteResource(Resource $resource): Resource 'dart-2.17' => BuildRuntime::DART217(), 'dart-2.18' => BuildRuntime::DART218(), 'dart-2.19' => BuildRuntime::DART219(), - 'deno-1.21' => BuildRuntime::DENO121(), - 'deno-1.24' => BuildRuntime::DENO124(), - 'deno-1.35' => BuildRuntime::DENO135(), 'deno-1.40' => BuildRuntime::DENO140(), 'deno-1.46' => BuildRuntime::DENO146(), 'deno-2.0' => BuildRuntime::DENO20(), @@ -2561,27 +2557,29 @@ public function importSiteResource(Resource $resource): Resource }; $this->sites->create( - $resource->getId(), - $resource->getSiteName(), - $framework, - $buildRuntime, - $resource->getEnabled(), - $resource->getLogging(), - $resource->getTimeout(), - $resource->getInstallCommand(), - $resource->getBuildCommand(), - $resource->getOutputDirectory(), - $adapter, + siteId: $resource->getId(), + name: $resource->getSiteName(), + framework: $framework, + buildRuntime: $buildRuntime, + enabled: $resource->getEnabled(), + logging: $resource->getLogging(), + timeout: $resource->getTimeout(), + installCommand: $resource->getInstallCommand(), + buildCommand: $resource->getBuildCommand(), + outputDirectory: $resource->getOutputDirectory(), + adapter: $adapter, fallbackFile: $resource->getFallbackFile(), - specification: $resource->getSpecification(), + buildSpecification: $resource->getSpecification() ?: null, + runtimeSpecification: $resource->getSpecification() ?: null, ); break; case Resource::TYPE_SITE_VARIABLE: /** @var SiteEnvVar $resource */ $this->sites->createVariable( - $resource->getSite()->getId(), - $resource->getKey(), - $resource->getValue() + siteId: $resource->getSite()->getId(), + variableId: $resource->getId(), + key: $resource->getKey(), + value: $resource->getValue(), ); break; case Resource::TYPE_SITE_DEPLOYMENT: diff --git a/src/Migration/Sources/Appwrite.php b/src/Migration/Sources/Appwrite.php index 48dc03d9..94368e5e 100644 --- a/src/Migration/Sources/Appwrite.php +++ b/src/Migration/Sources/Appwrite.php @@ -288,7 +288,7 @@ private function reportAuth(array $resources, array &$report, array $resourceIds limit: 1 ); $userList = $this->users->list($userQueries); - $report[Resource::TYPE_USER] = $userList['total']; + $report[Resource::TYPE_USER] = $userList->total; } if ($needTeams) { @@ -304,11 +304,11 @@ private function reportAuth(array $resources, array &$report, array $resourceIds ); $teamList = $this->teams->list($params); - $totalTeams = $teamList['total']; - $currentTeams = $teamList['teams']; + $totalTeams = $teamList->total; + $currentTeams = $teamList->teams; $allTeams = array_merge($allTeams, $currentTeams); - $lastTeam = $currentTeams[count($currentTeams) - 1]['$id'] ?? null; + $lastTeam = empty($currentTeams) ? null : end($currentTeams)->id; if (count($currentTeams) < self::DEFAULT_PAGE_LIMIT) { break; @@ -322,7 +322,7 @@ private function reportAuth(array $resources, array &$report, array $resourceIds limit: 1 ); $teamList = $this->teams->list($params); - $teams = ['total' => $teamList['total'], 'teams' => []]; + $teams = ['total' => $teamList->total, 'teams' => []]; } } @@ -334,9 +334,9 @@ private function reportAuth(array $resources, array &$report, array $resourceIds $report[Resource::TYPE_MEMBERSHIP] = 0; foreach ($teams['teams'] as $team) { $report[Resource::TYPE_MEMBERSHIP] += $this->teams->listMemberships( - $team['$id'], + $team->id, [Query::limit(1)] - )['total']; + )->total; } } } @@ -364,7 +364,7 @@ private function reportStorage(array $resources, array &$report, array $resource resourceIds: $resourceIds, limit: 1 ); - $report[Resource::TYPE_BUCKET] = $this->storage->listBuckets($bucketQueries)['total']; + $report[Resource::TYPE_BUCKET] = $this->storage->listBuckets($bucketQueries)->total; } if (\in_array(Resource::TYPE_FILE, $resources)) { @@ -379,10 +379,10 @@ private function reportStorage(array $resources, array &$report, array $resource resourceIds: $resourceIds, cursor: $lastBucket, ); - $currentBuckets = $this->storage->listBuckets($queries)['buckets']; + $currentBuckets = $this->storage->listBuckets($queries)->buckets; $buckets = array_merge($buckets, $currentBuckets); - $lastBucket = $buckets[count($buckets) - 1]['$id'] ?? null; + $lastBucket = $buckets[count($buckets) - 1]->id ?? null; if (count($currentBuckets) < self::DEFAULT_PAGE_LIMIT) { break; @@ -391,12 +391,12 @@ private function reportStorage(array $resources, array &$report, array $resource foreach ($buckets as $bucket) { $filesResponse = $this->storage->listFiles( - $bucket['$id'], + $bucket->id, [Query::limit(1)] ); - $report['size'] += $bucket['totalSize'] ?? 0; - $report[Resource::TYPE_FILE] += $filesResponse['total']; + $report['size'] += $bucket->totalSize ?? 0; + $report[Resource::TYPE_FILE] += $filesResponse->total; } $report['size'] = $report['size'] / 1000 / 1000; // MB @@ -419,7 +419,7 @@ private function reportFunctions(array $resources, array &$report, array $resour resourceIds: $resourceIds, limit: 1 ); - $report[Resource::TYPE_FUNCTION] = $this->functions->list($functionQueries)['total']; + $report[Resource::TYPE_FUNCTION] = $this->functions->list($functionQueries)->total; return; } @@ -433,11 +433,11 @@ private function reportFunctions(array $resources, array &$report, array $resour ); $funcList = $this->functions->list($params); - $totalFunctions = $funcList['total']; - $currentFunctions = $funcList['functions']; + $totalFunctions = $funcList->total; + $currentFunctions = $funcList->functions; $functions = array_merge($functions, $currentFunctions); - $lastFunction = $currentFunctions[count($currentFunctions) - 1]['$id'] ?? null; + $lastFunction = $currentFunctions[count($currentFunctions) - 1]->id ?? null; if (count($currentFunctions) < self::DEFAULT_PAGE_LIMIT) { break; } @@ -451,7 +451,7 @@ private function reportFunctions(array $resources, array &$report, array $resour if (\in_array(Resource::TYPE_DEPLOYMENT, $resources)) { $report[Resource::TYPE_DEPLOYMENT] = 0; foreach ($functions as $function) { - if (!empty($function['deploymentId'])) { + if (!empty($function->deploymentId)) { $report[Resource::TYPE_DEPLOYMENT] += 1; } } @@ -461,7 +461,7 @@ private function reportFunctions(array $resources, array &$report, array $resour $report[Resource::TYPE_ENVIRONMENT_VARIABLE] = 0; foreach ($functions as $function) { // function model contains `vars`, we don't need to fetch the list again. - $report[Resource::TYPE_ENVIRONMENT_VARIABLE] += count($function['vars'] ?? []); + $report[Resource::TYPE_ENVIRONMENT_VARIABLE] += count($function->vars ?? []); } } } @@ -482,7 +482,7 @@ private function reportSites(array $resources, array &$report, array $resourceId resourceIds: $resourceIds, limit: 1 ); - $report[Resource::TYPE_SITE] = $this->sites->list($siteQueries)['total']; + $report[Resource::TYPE_SITE] = $this->sites->list($siteQueries)->total; return; } @@ -496,15 +496,15 @@ private function reportSites(array $resources, array &$report, array $resourceId ); $siteList = $this->sites->list($params); - $totalSites = $siteList['total']; - $currentSites = $siteList['sites']; + $totalSites = $siteList->total; + $currentSites = $siteList->sites; $sites = array_merge($sites, $currentSites); if (count($currentSites) === 0 || count($currentSites) < self::DEFAULT_PAGE_LIMIT) { break; } - $lastSite = $currentSites[count($currentSites) - 1]['$id']; + $lastSite = $currentSites[count($currentSites) - 1]->id; } } @@ -515,7 +515,7 @@ private function reportSites(array $resources, array &$report, array $resourceId if (\in_array(Resource::TYPE_SITE_DEPLOYMENT, $resources)) { $report[Resource::TYPE_SITE_DEPLOYMENT] = 0; foreach ($sites as $site) { - if (!empty($site['deploymentId'])) { + if (!empty($site->deploymentId)) { $report[Resource::TYPE_SITE_DEPLOYMENT] += 1; } } @@ -524,8 +524,8 @@ private function reportSites(array $resources, array &$report, array $resourceId if (\in_array(Resource::TYPE_SITE_VARIABLE, $resources)) { $report[Resource::TYPE_SITE_VARIABLE] = 0; foreach ($sites as $site) { - $variables = $this->sites->listVariables($site['$id']); - $report[Resource::TYPE_SITE_VARIABLE] += $variables['total'] ?? 0; + $variables = $this->sites->listVariables($site->id); + $report[Resource::TYPE_SITE_VARIABLE] += $variables->total ?? 0; } } } @@ -603,27 +603,27 @@ private function exportUsers(int $batchSize): void } $response = $this->users->list($queries); - if ($response['total'] == 0) { + if ($response->total == 0) { break; } - foreach ($response['users'] as $user) { + foreach ($response->users as $user) { $users[] = new User( - $user['$id'], - empty($user['email']) ? null : $user['email'], - empty($user['name']) ? null : $user['name'], - $user['password'] ? new Hash($user['password'], algorithm: $user['hash']) : null, - empty($user['phone']) ? null : $user['phone'], - $user['labels'] ?? [], + $user->id, + empty($user->email) ? null : $user->email, + empty($user->name) ? null : $user->name, + $user->password ? new Hash($user->password, algorithm: $user->hash) : null, + empty($user->phone) ? null : $user->phone, + $user->labels ?? [], '', - $user['emailVerification'] ?? false, - $user['phoneVerification'] ?? false, - !$user['status'], - $user['prefs'] ?? [], - $user['targets'] ?? [], + $user->emailVerification ?? false, + $user->phoneVerification ?? false, + !$user->status, + $user->prefs->data ?? [], + \array_map(fn ($target) => $target->toArray(), $user->targets ?? []), ); - $lastDocument = $user['$id']; + $lastDocument = $user->id; } $this->callback($users); @@ -657,18 +657,18 @@ private function exportTeams(int $batchSize): void } $response = $this->teams->list($queries); - if ($response['total'] == 0) { + if ($response->total == 0) { break; } - foreach ($response['teams'] as $team) { + foreach ($response->teams as $team) { $teams[] = new Team( - $team['$id'], - $team['name'], - $team['prefs'], + $team->id, + $team->name, + $team->prefs->data, ); - $lastDocument = $team['$id']; + $lastDocument = $team->id; } $this->callback($teams); @@ -709,25 +709,25 @@ private function exportMemberships(int $batchSize): void $response = $this->teams->listMemberships($team->getId(), $queries); - if ($response['total'] == 0) { + if ($response->total == 0) { break; } - foreach ($response['memberships'] as $membership) { - $user = $cacheUsers[$membership['userId']] ?? null; + foreach ($response->memberships as $membership) { + $user = $cacheUsers[$membership->userId] ?? null; if ($user === null) { throw new \Exception('User not found', Exception::CODE_NOT_FOUND); } $memberships[] = new Membership( - $membership['$id'], + $membership->id, $team, $user, - $membership['roles'], - $membership['confirm'] + $membership->roles, + $membership->confirm ); - $lastDocument = $membership['$id']; + $lastDocument = $membership->id; } $this->callback($memberships); @@ -1245,20 +1245,20 @@ private function exportBuckets(int $batchSize): void $convertedBuckets = []; - foreach ($buckets['buckets'] as $bucket) { + foreach ($buckets->buckets as $bucket) { $bucket = new Bucket( - $bucket['$id'], - $bucket['name'], - $bucket['$permissions'], - $bucket['fileSecurity'], - $bucket['enabled'], - $bucket['maximumFileSize'], - $bucket['allowedFileExtensions'], - $bucket['compression'], - $bucket['encryption'], - $bucket['antivirus'], + $bucket->id, + $bucket->name, + $bucket->permissions, + $bucket->fileSecurity, + $bucket->enabled, + $bucket->maximumFileSize, + $bucket->allowedFileExtensions, + $bucket->compression, + $bucket->encryption, + $bucket->antivirus, false, - $bucket['transformations'] ?? false, + $bucket->transformations ?? false, ); $convertedBuckets[] = $bucket; } @@ -1293,31 +1293,31 @@ private function exportFiles(int $batchSize): void $queries ); - foreach ($response['files'] as $file) { + foreach ($response->files as $file) { try { $this->exportFileData(new File( - $file['$id'], + $file->id, $bucket, - $file['name'], - $file['signature'], - $file['mimeType'], - $file['$permissions'], - $file['sizeOriginal'], + $file->name, + $file->signature, + $file->mimeType, + $file->permissions, + $file->sizeOriginal, )); } catch (\Throwable $e) { $this->addError(new Exception( resourceName: Resource::TYPE_FILE, resourceGroup: Transfer::GROUP_STORAGE, - resourceId: $file['$id'], + resourceId: $file->id, message: $e->getMessage(), code: $e->getCode() )); } - $lastDocument = $file['$id']; + $lastDocument = $file->id; } - if (count($response['files']) < $batchSize) { + if (count($response->files) < $batchSize) { break; } } @@ -1463,40 +1463,40 @@ private function exportFunctions(int $batchSize): void $response = $this->functions->list($queries); - if ($response['total'] === 0) { + if ($response->total === 0) { return; } $functions = []; $convertedResources = []; - foreach ($response['functions'] as $function) { + foreach ($response->functions as $function) { $convertedFunc = new Func( - $function['$id'], - $function['name'], - $function['runtime'], - $function['execute'], - $function['enabled'], - $function['events'], - $function['schedule'], - $function['timeout'], - $function['deploymentId'] ?? '', - $function['entrypoint'], - $function['commands'] ?? '', - $function['logging'] ?? true, - $function['scopes'] ?? [], - $function['specification'] ?? '', + $function->id, + $function->name, + $function->runtime, + $function->execute, + $function->enabled, + $function->events, + $function->schedule, + $function->timeout, + $function->deploymentId ?? '', + $function->entrypoint, + $function->commands ?? '', + $function->logging ?? true, + $function->scopes ?? [], + $function->runtimeSpecification ?: $function->buildSpecification ?: '', ); $functions[] = $convertedFunc; $convertedResources[] = $convertedFunc; - foreach ($function['vars'] as $var) { + foreach ($function->vars as $var) { $convertedResources[] = new EnvVar( - $var['$id'], + $var->id, $convertedFunc, - $var['key'], - $var['value'], + $var->key, + $var->value, ); } } @@ -1551,17 +1551,17 @@ private function exportDeployments(int $batchSize, bool $exportOnlyActive = fals $queries ); - foreach ($response['deployments'] as $deployment) { + foreach ($response->deployments as $deployment) { try { $this->exportDeploymentData($func, $deployment); } catch (\Throwable $e) { $func->setStatus(Resource::STATUS_ERROR, $e->getMessage()); } - $lastDocument = $deployment['$id']; + $lastDocument = $deployment->id; } - if (count($response['deployments']) < $batchSize) { + if (count($response->deployments) < $batchSize) { break; } } @@ -1571,7 +1571,7 @@ private function exportDeployments(int $batchSize, bool $exportOnlyActive = fals /** * @throws \Exception */ - private function exportDeploymentData(Func $func, array $deployment): void + private function exportDeploymentData(Func $func, \Appwrite\Models\Deployment $deployment): void { // Set the chunk size (5MB) $start = 0; @@ -1582,7 +1582,7 @@ private function exportDeploymentData(Func $func, array $deployment): void $this->call( 'HEAD', - "/functions/{$func->getId()}/deployments/{$deployment['$id']}/download", + "/functions/{$func->getId()}/deployments/{$deployment->id}/download", [], [], $responseHeaders @@ -1592,7 +1592,7 @@ private function exportDeploymentData(Func $func, array $deployment): void if (!array_key_exists('content-length', $responseHeaders)) { $file = $this->call( 'GET', - "/functions/{$func->getId()}/deployments/{$deployment['$id']}/download", + "/functions/{$func->getId()}/deployments/{$deployment->id}/download", [], [], $responseHeaders @@ -1605,14 +1605,14 @@ private function exportDeploymentData(Func $func, array $deployment): void } $deployment = new Deployment( - $deployment['$id'], + $deployment->id, $func, $size, - $deployment['entrypoint'], + $deployment->entrypoint, $start, $end, $file, - $deployment['activate'] + $deployment->activate ); $deployment->setSequence($deployment->getId()); @@ -1628,14 +1628,14 @@ private function exportDeploymentData(Func $func, array $deployment): void } $deployment = new Deployment( - $deployment['$id'], + $deployment->id, $func, $fileSize, - $deployment['entrypoint'], + $deployment->entrypoint, $start, $end, '', - $deployment['activate'] + $deployment->activate ); $deployment->setSequence($deployment->getId()); @@ -1680,7 +1680,7 @@ private function reportMessaging(array $resources, array &$report, array $resour resourceIds: $resourceIds, limit: 1 ); - $report[Resource::TYPE_PROVIDER] = $this->messaging->listProviders($providerQueries)['total']; + $report[Resource::TYPE_PROVIDER] = $this->messaging->listProviders($providerQueries)->total; } if (\in_array(Resource::TYPE_TOPIC, $resources)) { @@ -1689,7 +1689,7 @@ private function reportMessaging(array $resources, array &$report, array $resour resourceIds: $resourceIds, limit: 1 ); - $report[Resource::TYPE_TOPIC] = $this->messaging->listTopics($topicQueries)['total']; + $report[Resource::TYPE_TOPIC] = $this->messaging->listTopics($topicQueries)->total; } if (\in_array(Resource::TYPE_SUBSCRIBER, $resources)) { @@ -1703,16 +1703,16 @@ private function reportMessaging(array $resources, array &$report, array $resour } $topicResponse = $this->messaging->listTopics($topicQueries); - if ($topicResponse['total'] == 0 || empty($topicResponse['topics'])) { + if ($topicResponse->total == 0 || empty($topicResponse->topics)) { break; } - foreach ($topicResponse['topics'] as $topic) { - $subscriberTotal += $this->messaging->listSubscribers($topic['$id'], [Query::limit(1)])['total']; - $lastTopic = $topic['$id']; + foreach ($topicResponse->topics as $topic) { + $subscriberTotal += $this->messaging->listSubscribers($topic->id, [Query::limit(1)])->total; + $lastTopic = $topic->id; } - if (\count($topicResponse['topics']) < self::DEFAULT_PAGE_LIMIT) { + if (\count($topicResponse->topics) < self::DEFAULT_PAGE_LIMIT) { break; } } @@ -1726,7 +1726,7 @@ private function reportMessaging(array $resources, array &$report, array $resour resourceIds: $resourceIds, limit: 1 ); - $report[Resource::TYPE_MESSAGE] = $this->messaging->listMessages($messageQueries)['total']; + $report[Resource::TYPE_MESSAGE] = $this->messaging->listMessages($messageQueries)->total; } } @@ -1812,24 +1812,24 @@ private function exportProviders(int $batchSize): void $response = $this->messaging->listProviders($queries); - if ($response['total'] == 0) { + if ($response->total == 0) { break; } - foreach ($response['providers'] as $provider) { + foreach ($response->providers as $provider) { $providers[] = new Provider( - $provider['$id'], - $provider['name'], - $provider['provider'], - $provider['type'], - $provider['enabled'], - $provider['credentials'] ?? [], - $provider['options'] ?? [], - $provider['$createdAt'] ?? '', - $provider['$updatedAt'] ?? '', + $provider->id, + $provider->name, + $provider->provider, + $provider->type, + $provider->enabled, + $provider->credentials ?? [], + $provider->options ?? [], + $provider->createdAt ?? '', + $provider->updatedAt ?? '', ); - $lastDocument = $provider['$id']; + $lastDocument = $provider->id; } $this->callback($providers); @@ -1863,20 +1863,20 @@ private function exportTopics(int $batchSize): void $response = $this->messaging->listTopics($queries); - if ($response['total'] == 0) { + if ($response->total == 0) { break; } - foreach ($response['topics'] as $topic) { + foreach ($response->topics as $topic) { $topics[] = new Topic( - $topic['$id'], - $topic['name'], - $topic['subscribe'] ?? [], - $topic['$createdAt'] ?? '', - $topic['$updatedAt'] ?? '', + $topic->id, + $topic->name, + $topic->subscribe ?? [], + $topic->createdAt ?? '', + $topic->updatedAt ?? '', ); - $lastDocument = $topic['$id']; + $lastDocument = $topic->id; } $this->callback($topics); @@ -1909,23 +1909,23 @@ private function exportSubscribers(int $batchSize): void $response = $this->messaging->listSubscribers($topic->getId(), $queries); - if ($response['total'] == 0) { + if ($response->total == 0) { break; } - foreach ($response['subscribers'] as $subscriber) { + foreach ($response->subscribers as $subscriber) { $subscribers[] = new Subscriber( - $subscriber['$id'], - $subscriber['topicId'], - $subscriber['targetId'], - $subscriber['userId'] ?? '', - $subscriber['userName'] ?? '', - $subscriber['providerType'] ?? '', - $subscriber['$createdAt'] ?? '', - $subscriber['$updatedAt'] ?? '', + $subscriber->id, + $subscriber->topicId, + $subscriber->targetId, + $subscriber->userId ?? '', + $subscriber->userName ?? '', + $subscriber->providerType ?? '', + $subscriber->createdAt ?? '', + $subscriber->updatedAt ?? '', ); - $lastDocument = $subscriber['$id']; + $lastDocument = $subscriber->id; } $this->callback($subscribers); @@ -1960,28 +1960,28 @@ private function exportMessages(int $batchSize): void $response = $this->messaging->listMessages($queries); - if ($response['total'] == 0) { + if ($response->total == 0) { break; } - foreach ($response['messages'] as $message) { + foreach ($response->messages as $message) { $messages[] = new Message( - $message['$id'], - $message['providerType'] ?? '', - $message['topics'] ?? [], - $message['users'] ?? [], - $message['targets'] ?? [], - $message['data'] ?? [], - $message['status'] ?? '', - $message['scheduledAt'] ?? '', - $message['deliveredAt'] ?? '', - $message['deliveryErrors'] ?? [], - $message['deliveredTotal'] ?? 0, - $message['$createdAt'] ?? '', - $message['$updatedAt'] ?? '', + $message->id, + $message->providerType ?? '', + $message->topics ?? [], + $message->users ?? [], + $message->targets ?? [], + $message->data ?? [], + (string) $message->status, + $message->scheduledAt ?? '', + $message->deliveredAt ?? '', + $message->deliveryErrors ?? [], + $message->deliveredTotal ?? 0, + $message->createdAt ?? '', + $message->updatedAt ?? '', ); - $lastDocument = $message['$id']; + $lastDocument = $message->id; } $this->callback($messages); @@ -2015,40 +2015,40 @@ private function exportSites(int $batchSize): void $response = $this->sites->list($queries); - if ($response['total'] === 0) { + if ($response->total === 0) { return; } $sites = []; $convertedResources = []; - foreach ($response['sites'] as $site) { + foreach ($response->sites as $site) { $convertedSite = new Site( - $site['$id'], - $site['name'], - $site['framework'], - $site['buildRuntime'], - $site['enabled'], - $site['logging'], - $site['timeout'], - $site['installCommand'] ?? '', - $site['buildCommand'] ?? '', - $site['outputDirectory'] ?? '', - $site['adapter'] ?? 'static', - $site['fallbackFile'] ?? '', - $site['specification'] ?? '', - $site['deploymentId'] ?? '' + $site->id, + $site->name, + $site->framework, + $site->buildRuntime, + $site->enabled, + $site->logging, + $site->timeout, + $site->installCommand ?? '', + $site->buildCommand ?? '', + $site->outputDirectory ?? '', + $site->adapter ?? 'static', + $site->fallbackFile ?? '', + $site->runtimeSpecification ?: $site->buildSpecification ?: '', + $site->deploymentId ?? '' ); $sites[] = $convertedSite; $convertedResources[] = $convertedSite; - $variables = $this->sites->listVariables($site['$id']); - foreach ($variables['variables'] ?? [] as $var) { + $variables = $this->sites->listVariables($site->id); + foreach ($variables->variables ?? [] as $var) { $convertedResources[] = new SiteEnvVar( - $var['$id'], + $var->id, $convertedSite, - $var['key'], - $var['value'] + $var->key, + $var->value ); } } @@ -2104,17 +2104,17 @@ private function exportSiteDeployments(int $batchSize, bool $exportOnlyActive = $queries ); - foreach ($response['deployments'] as $deployment) { + foreach ($response->deployments as $deployment) { try { $this->exportSiteDeploymentData($site, $deployment); } catch (\Throwable $e) { $site->setStatus(Resource::STATUS_ERROR, $e->getMessage()); } - $lastDocument = $deployment['$id']; + $lastDocument = $deployment->id; } - if (count($response['deployments']) < $batchSize) { + if (count($response->deployments) < $batchSize) { break; } } @@ -2124,7 +2124,7 @@ private function exportSiteDeployments(int $batchSize, bool $exportOnlyActive = /** * @throws \Exception */ - private function exportSiteDeploymentData(Site $site, array $deployment): void + private function exportSiteDeploymentData(Site $site, \Appwrite\Models\Deployment $deployment): void { $start = 0; $end = Transfer::STORAGE_MAX_CHUNK_SIZE - 1; @@ -2133,7 +2133,7 @@ private function exportSiteDeploymentData(Site $site, array $deployment): void $this->call( 'HEAD', - "/sites/{$site->getId()}/deployments/{$deployment['$id']}/download", + "/sites/{$site->getId()}/deployments/{$deployment->id}/download", [], [], $responseHeaders @@ -2142,7 +2142,7 @@ private function exportSiteDeploymentData(Site $site, array $deployment): void if (!\array_key_exists('content-length', $responseHeaders)) { $file = $this->call( 'GET', - "/sites/{$site->getId()}/deployments/{$deployment['$id']}/download", + "/sites/{$site->getId()}/deployments/{$deployment->id}/download", [], [], $responseHeaders @@ -2155,13 +2155,13 @@ private function exportSiteDeploymentData(Site $site, array $deployment): void } $siteDeployment = new SiteDeployment( - $deployment['$id'], + $deployment->id, $site, $size, $start, $end, $file, - $deployment['$id'] === $site->getActiveDeployment() + $deployment->id === $site->getActiveDeployment() ); $siteDeployment->setSequence($siteDeployment->getId()); @@ -2177,13 +2177,13 @@ private function exportSiteDeploymentData(Site $site, array $deployment): void } $siteDeployment = new SiteDeployment( - $deployment['$id'], + $deployment->id, $site, $fileSize, $start, $end, '', - $deployment['$id'] === $site->getActiveDeployment() + $deployment->id === $site->getActiveDeployment() ); $siteDeployment->setSequence($siteDeployment->getId()); diff --git a/src/Migration/Sources/Appwrite/Reader/API.php b/src/Migration/Sources/Appwrite/Reader/API.php index 47a52f9d..a187e8c9 100644 --- a/src/Migration/Sources/Appwrite/Reader/API.php +++ b/src/Migration/Sources/Appwrite/Reader/API.php @@ -11,6 +11,10 @@ use Utopia\Migration\Sources\Appwrite\Reader; /** + * Adapts Appwrite SDK typed models to the Reader's plain-array contract so that + * downstream callers can use array-offset syntax interchangeably with the + * Database reader (which returns utopia-php Document objects). + * * @implements Reader */ class API implements Reader @@ -51,10 +55,10 @@ public function report(array $resources, array &$report, array $resourceIds = [] } $databasesResponse = $this->database->list($databaseQueries); - $databases = $databasesResponse['databases']; + $databases = \array_map(fn ($database) => $database->toArray(), $databasesResponse->databases); if (in_array(Resource::TYPE_DATABASE, $resources)) { - $report[Resource::TYPE_DATABASE] = $databasesResponse['total']; + $report[Resource::TYPE_DATABASE] = $databasesResponse->total; } if (count(array_intersect($resources, $relevantResources)) === 1 && @@ -71,12 +75,13 @@ public function report(array $resources, array &$report, array $resourceIds = [] $lastTable = null; while (true) { - $currentTables = $this->database->listTables( + $tablesResponse = $this->database->listTables( $databaseId, $lastTable ? [Query::cursorAfter($lastTable)] : [Query::limit($pageLimit)] - )['tables']; + ); + $currentTables = \array_map(fn ($table) => $table->toArray(), $tablesResponse->tables); $tables = \array_merge($tables, $currentTables); $lastTable = $tables[count($tables) - 1]['$id'] ?? null; @@ -111,7 +116,7 @@ public function report(array $resources, array &$report, array $resourceIds = [] [Query::limit(1)] ); - $report[Resource::TYPE_ROW] += $rowsResponse['total']; + $report[Resource::TYPE_ROW] += $rowsResponse->total; } } } @@ -121,75 +126,79 @@ public function report(array $resources, array &$report, array $resourceIds = [] } /** + * @return array> * @throws AppwriteException */ public function listDatabases(array $queries = []): array { - return $this->database->list($queries)['databases']; + return \array_map( + fn ($database) => $database->toArray(), + $this->database->list($queries)->databases + ); } /** + * @return array> * @throws AppwriteException */ public function listTables(Database $resource, array $queries = []): array { - return $this->database->listTables( - $resource->getId(), - $queries - )['tables']; + return \array_map( + fn ($table) => $table->toArray(), + $this->database->listTables($resource->getId(), $queries)->tables + ); } /** - * @param Table $resource - * @param array $queries - * @return array + * @return array> * @throws AppwriteException */ public function listColumns(Table $resource, array $queries = []): array { - return $this->database->listColumns( - $resource->getDatabase()->getId(), - $resource->getId(), - $queries - )['columns']; + return \array_map( + fn ($column) => $column->toArray(), + $this->database->listColumns( + $resource->getDatabase()->getId(), + $resource->getId(), + $queries + )->columns + ); } /** - * @param Table $resource - * @param array $queries - * @return array + * @return array> * @throws AppwriteException */ public function listIndexes(Table $resource, array $queries = []): array { - return $this->database->listIndexes( - $resource->getDatabase()->getId(), - $resource->getId(), - $queries - )['indexes']; + return \array_map( + fn ($index) => $index->toArray(), + $this->database->listIndexes( + $resource->getDatabase()->getId(), + $resource->getId(), + $queries + )->indexes + ); } - /** - * @param Table $resource - * @param array $queries - * @return array + * @return array> * @throws AppwriteException */ public function listRows(Table $resource, array $queries = []): array { - return $this->database->listRows( - $resource->getDatabase()->getId(), - $resource->getId(), - $queries - )['rows']; + return \array_map( + fn ($row) => $row->toArray(), + $this->database->listRows( + $resource->getDatabase()->getId(), + $resource->getId(), + $queries + )->rows + ); } /** - * @param Table $resource - * @param string $rowId - * @param array $queries - * @return array + * @return array * @throws AppwriteException */ public function getRow(Table $resource, string $rowId, array $queries = []): array @@ -199,7 +208,7 @@ public function getRow(Table $resource, string $rowId, array $queries = []): arr $resource->getId(), $rowId, $queries - ); + )->toArray(); } /**