diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php index 7778393b3b3..6f1377a3b53 100644 --- a/lib/private/App/AppManager.php +++ b/lib/private/App/AppManager.php @@ -10,10 +10,12 @@ namespace OC\App; use OC\AppConfig; use OC\AppFramework\Bootstrap\Coordinator; use OC\Config\ConfigManager; +use OC\DB\MigrationService; use OCP\Activity\IManager as IActivityManager; use OCP\App\AppPathNotFoundException; use OCP\App\Events\AppDisableEvent; use OCP\App\Events\AppEnableEvent; +use OCP\App\Events\AppUpdateEvent; use OCP\App\IAppManager; use OCP\App\ManagerEvent; use OCP\Collaboration\AutoComplete\IManager as IAutoCompleteManager; @@ -677,8 +679,8 @@ class AppManager implements IAppManager { * * @throws AppPathNotFoundException if app folder can't be found */ - public function getAppPath(string $appId): string { - $appPath = \OC_App::getAppPath($appId); + public function getAppPath(string $appId, bool $ignoreCache = false): string { + $appPath = \OC_App::getAppPath($appId, $ignoreCache); if ($appPath === false) { throw new AppPathNotFoundException('Could not find path for ' . $appId); } @@ -949,4 +951,75 @@ class AppManager implements IAppManager { /* Only lowercase alphanumeric is allowed */ return preg_replace('/(^[0-9_]|[^a-z0-9_]+|_$)/', '', $app); } + + /** + * Run upgrade tasks for an app after the code has already been updated + * + * @throws AppPathNotFoundException if app folder can't be found + */ + public function upgradeApp(string $appId): bool { + // for apps distributed with core, we refresh app path in case the downloaded version + // have been installed in custom apps and not in the default path + $appPath = $this->getAppPath($appId, true); + + $this->clearAppsCache(); + $l = \OC::$server->getL10N('core'); + $appData = $this->getAppInfo($appId, false, $l->getLanguageCode()); + if ($appData === null) { + throw new AppPathNotFoundException('Could not find ' . $appId); + } + + $ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []); + $ignoreMax = in_array($appId, $ignoreMaxApps, true); + \OC_App::checkAppDependencies( + $this->config, + $l, + $appData, + $ignoreMax + ); + + \OC_App::registerAutoloading($appId, $appPath, true); + \OC_App::executeRepairSteps($appId, $appData['repair-steps']['pre-migration']); + + $ms = new MigrationService($appId, \OCP\Server::get(\OC\DB\Connection::class)); + $ms->migrate(); + + \OC_App::executeRepairSteps($appId, $appData['repair-steps']['post-migration']); + \OC_App::setupLiveMigrations($appId, $appData['repair-steps']['live-migration']); + + // update appversion in app manager + $this->clearAppsCache(); + $this->getAppVersion($appId, false); + + \OC_App::setupBackgroundJobs($appData['background-jobs']); + + //set remote/public handlers + if (array_key_exists('ocsid', $appData)) { + $this->config->setAppValue($appId, 'ocsid', $appData['ocsid']); + } elseif ($this->config->getAppValue($appId, 'ocsid') !== '') { + $this->config->deleteAppValue($appId, 'ocsid'); + } + foreach ($appData['remote'] as $name => $path) { + $this->config->setAppValue('core', 'remote_' . $name, $appId . '/' . $path); + } + foreach ($appData['public'] as $name => $path) { + $this->config->setAppValue('core', 'public_' . $name, $appId . '/' . $path); + } + + \OC_App::setAppTypes($appId); + + $version = $this->getAppVersion($appId); + $this->config->setAppValue($appId, 'installed_version', $version); + + // migrate eventual new config keys in the process + /** @psalm-suppress InternalMethod */ + $this->configManager->migrateConfigLexiconKeys($appId); + + $this->dispatcher->dispatchTyped(new AppUpdateEvent($appId)); + $this->dispatcher->dispatch(ManagerEvent::EVENT_APP_UPDATE, new ManagerEvent( + ManagerEvent::EVENT_APP_UPDATE, $appId + )); + + return true; + } } diff --git a/lib/private/Installer.php b/lib/private/Installer.php index fd737d286ad..1f22224964d 100644 --- a/lib/private/Installer.php +++ b/lib/private/Installer.php @@ -600,7 +600,7 @@ class Installer { //run appinfo/install.php self::includeAppScript("$appPath/appinfo/install.php"); - $info = \OCP\Server::get(IAppManager::class)->getAppInfo($app); + $info = $appManager->getAppInfo($app); if (is_null($info)) { return false; } @@ -611,7 +611,7 @@ class Installer { OC_App::executeRepairSteps($app, $info['repair-steps']['install']); - $config->setAppValue($app, 'installed_version', \OCP\Server::get(IAppManager::class)->getAppVersion($app)); + $config->setAppValue($app, 'installed_version', $appManager->getAppVersion($app)); if (array_key_exists('ocsid', $info)) { $config->setAppValue($app, 'ocsid', $info['ocsid']); } diff --git a/lib/private/Updater.php b/lib/private/Updater.php index 17b740a0b65..d0f9c35f078 100644 --- a/lib/private/Updater.php +++ b/lib/private/Updater.php @@ -321,7 +321,7 @@ class Updater extends BasicEmitter { foreach ($stack as $appId) { if (\OC_App::shouldUpgrade($appId)) { $this->emit('\OC\Updater', 'appUpgradeStarted', [$appId, $this->appManager->getAppVersion($appId)]); - \OC_App::updateApp($appId); + $this->appManager->upgradeApp($appId); $this->emit('\OC\Updater', 'appUpgrade', [$appId, $this->appManager->getAppVersion($appId)]); } if ($type !== $pseudoOtherType) { diff --git a/lib/private/legacy/OC_App.php b/lib/private/legacy/OC_App.php index 6dbef42594b..dccfb961d25 100644 --- a/lib/private/legacy/OC_App.php +++ b/lib/private/legacy/OC_App.php @@ -9,14 +9,10 @@ declare(strict_types=1); use OC\App\DependencyAnalyzer; use OC\App\Platform; use OC\AppFramework\Bootstrap\Coordinator; -use OC\Config\ConfigManager; -use OC\DB\MigrationService; use OC\Installer; use OC\Repair; use OC\Repair\Events\RepairErrorEvent; -use OCP\App\Events\AppUpdateEvent; use OCP\App\IAppManager; -use OCP\App\ManagerEvent; use OCP\Authentication\IAlternativeLogin; use OCP\EventDispatcher\IEventDispatcher; use OCP\IAppConfig; @@ -639,77 +635,14 @@ class OC_App { /** * update the database for the app and call the update script * - * @param string $appId - * @return bool + * @deprecated 32.0.0 Use IAppManager::upgradeApp instead */ public static function updateApp(string $appId): bool { - // for apps distributed with core, we refresh app path in case the downloaded version - // have been installed in custom apps and not in the default path - $appPath = self::getAppPath($appId, true); - if ($appPath === false) { + try { + return Server::get(\OC\App\AppManager::class)->upgradeApp($appId); + } catch (\OCP\App\AppPathNotFoundException $e) { return false; } - - if (is_file($appPath . '/appinfo/database.xml')) { - Server::get(LoggerInterface::class)->error('The appinfo/database.xml file is not longer supported. Used in ' . $appId); - return false; - } - - \OC::$server->getAppManager()->clearAppsCache(); - $l = \OC::$server->getL10N('core'); - $appData = Server::get(\OCP\App\IAppManager::class)->getAppInfo($appId, false, $l->getLanguageCode()); - - $ignoreMaxApps = \OC::$server->getConfig()->getSystemValue('app_install_overwrite', []); - $ignoreMax = in_array($appId, $ignoreMaxApps, true); - \OC_App::checkAppDependencies( - \OC::$server->getConfig(), - $l, - $appData, - $ignoreMax - ); - - self::registerAutoloading($appId, $appPath, true); - self::executeRepairSteps($appId, $appData['repair-steps']['pre-migration']); - - $ms = new MigrationService($appId, \OC::$server->get(\OC\DB\Connection::class)); - $ms->migrate(); - - self::executeRepairSteps($appId, $appData['repair-steps']['post-migration']); - self::setupLiveMigrations($appId, $appData['repair-steps']['live-migration']); - // update appversion in app manager - \OC::$server->getAppManager()->clearAppsCache(); - \OC::$server->getAppManager()->getAppVersion($appId, false); - - self::setupBackgroundJobs($appData['background-jobs']); - - //set remote/public handlers - if (array_key_exists('ocsid', $appData)) { - \OC::$server->getConfig()->setAppValue($appId, 'ocsid', $appData['ocsid']); - } elseif (\OC::$server->getConfig()->getAppValue($appId, 'ocsid') !== '') { - \OC::$server->getConfig()->deleteAppValue($appId, 'ocsid'); - } - foreach ($appData['remote'] as $name => $path) { - \OC::$server->getConfig()->setAppValue('core', 'remote_' . $name, $appId . '/' . $path); - } - foreach ($appData['public'] as $name => $path) { - \OC::$server->getConfig()->setAppValue('core', 'public_' . $name, $appId . '/' . $path); - } - - self::setAppTypes($appId); - - $version = Server::get(\OCP\App\IAppManager::class)->getAppVersion($appId); - \OC::$server->getConfig()->setAppValue($appId, 'installed_version', $version); - - // migrate eventual new config keys in the process - /** @psalm-suppress InternalMethod */ - Server::get(ConfigManager::class)->migrateConfigLexiconKeys($appId); - - \OC::$server->get(IEventDispatcher::class)->dispatchTyped(new AppUpdateEvent($appId)); - \OC::$server->get(IEventDispatcher::class)->dispatch(ManagerEvent::EVENT_APP_UPDATE, new ManagerEvent( - ManagerEvent::EVENT_APP_UPDATE, $appId - )); - - return true; } /** diff --git a/lib/public/App/IAppManager.php b/lib/public/App/IAppManager.php index 20019ce1ffd..788d810ff22 100644 --- a/lib/public/App/IAppManager.php +++ b/lib/public/App/IAppManager.php @@ -166,9 +166,10 @@ interface IAppManager { * Get the directory for the given app. * * @since 11.0.0 + * @since 32.0.0 Added param $ignoreCache to ignore cache * @throws AppPathNotFoundException */ - public function getAppPath(string $appId): string; + public function getAppPath(string $appId, bool $ignoreCache = false): string; /** * Get the web path for the given app. @@ -340,4 +341,12 @@ interface IAppManager { * @since 31.0.0 */ public function getAllAppsInAppsFolders(): array; + + /** + * Run upgrade tasks for an app after the code has already been updated + * + * @throws AppPathNotFoundException if app folder can't be found + * @since 32.0.0 + */ + public function upgradeApp(string $appId): bool; }