''], root: '')] #[FrontpageRoute(verb: 'GET', url: '/settings/apps/{category}/{id}', defaults: ['category' => '', 'id' => ''], root: '')] public function viewApps(): TemplateResponse { $this->navigationManager->setActiveEntry('core_apps'); $this->initialState->provideInitialState('appstoreEnabled', $this->config->getSystemValueBool('appstoreenabled', true)); $this->initialState->provideInitialState('appstoreBundles', $this->getBundles()); $this->initialState->provideInitialState('appstoreDeveloperDocs', $this->urlGenerator->linkToDocs('developer-manual')); $this->initialState->provideInitialState('appstoreUpdateCount', count($this->getAppsWithUpdates())); if ($this->appManager->isEnabledForAnyone('app_api')) { try { /** * @psalm-suppress UndefinedClass AppAPI is shipped since 30.0.1 */ Server::get(ExAppsPageService::class)->provideAppApiState($this->initialState); } catch (\Psr\Container\NotFoundExceptionInterface|\Psr\Container\ContainerExceptionInterface) { // nop } } $policy = new ContentSecurityPolicy(); $policy->addAllowedImageDomain('https://usercontent.apps.nextcloud.com'); $templateResponse = new TemplateResponse(Application::APP_ID, 'empty', ['pageTitle' => $this->l10n->t('App store')]); $templateResponse->setContentSecurityPolicy($policy); Util::addStyle(Application::APP_ID, 'main'); Util::addScript(Application::APP_ID, 'main'); return $templateResponse; } private function getAppsWithUpdates(): array { $appClass = new \OC_App(); $apps = $appClass->listAllApps(); /** @var array{id: string, ...} $app */ foreach ($apps as $key => $app) { $newVersion = $this->installer->isUpdateAvailable($app['id']); if ($newVersion === false) { unset($apps[$key]); } } return $apps; } /** * @return list}> */ private function getBundles(): array { $result = []; $bundles = $this->bundleFetcher->getBundles(); foreach ($bundles as $bundle) { $result[] = [ 'name' => $bundle->getName(), 'id' => $bundle->getIdentifier(), 'appIdentifiers' => $bundle->getAppIdentifiers() ]; } return $result; } }