diff --git a/lib/Application.php b/lib/Application.php index 58b4882f..20b8c66f 100644 --- a/lib/Application.php +++ b/lib/Application.php @@ -44,7 +44,15 @@ public function __construct(array $urlParams = array()) { IRepairStep::class . '::upgradeAppStoreApp', function ($event) use ($listener) { if ($event instanceof GenericEvent) { - $listener->upgradeAppStoreApp($event->getSubject()); + try { + $isMajorUpdate = $event->getArgument('isMajorUpdate'); + } catch (\InvalidArgumentException $e) { + $isMajorUpdate = false; + } + $listener->upgradeAppStoreApp( + $event->getSubject(), + $isMajorUpdate + ); } } ); diff --git a/lib/Listener.php b/lib/Listener.php index d1c06cab..9fc72342 100644 --- a/lib/Listener.php +++ b/lib/Listener.php @@ -32,10 +32,13 @@ public function __construct(MarketService $marketService) { $this->marketService = $marketService; } - public function upgradeAppStoreApp($app){ - $updateVersion = $this->marketService->getAvailableUpdateVersion($app); + public function upgradeAppStoreApp($app, $isMajorUpdate) { + $updateVersion = $this->marketService->getAvailableUpdateVersion( + $app, + $isMajorUpdate + ); if ($updateVersion !== false) { - $this->marketService->updateApp($app); + $this->marketService->updateApp($app, $isMajorUpdate); } else { throw new AppUpdateNotFoundException(); } diff --git a/lib/MarketService.php b/lib/MarketService.php index aa4fb3bb..3b66bad0 100644 --- a/lib/MarketService.php +++ b/lib/MarketService.php @@ -116,7 +116,7 @@ public function installApp($appId, $skipMigrations = false) { } // download package - $package = $this->downloadPackage($appId); + $package = $this->downloadPackage($appId, true); $this->installPackage($package, $skipMigrations); $this->appManager->enableApp($appId); } @@ -140,7 +140,7 @@ public function readAppPackage($path){ return $this->appManager->readAppPackage($path); } - private function downloadPackage($appId) { + private function downloadPackage($appId, $isMajor, $currentVersion = '0.0.0.0') { $this->checkInternetConnection(); $data = $this->getAppInfo($appId); if (empty($data)) { @@ -148,7 +148,14 @@ private function downloadPackage($appId) { } $version = $this->getPlatformVersion(); - $release = array_filter($data['releases'], function($element) use ($version) { + $release = array_filter($data['releases'], function($element) use ($version, $isMajor, $currentVersion) { + if ($isMajor === false) { + $marketVersionMajor = $this->getMajorVersion($element['version']); + $currentVersionMajor = $this->getMajorVersion($currentVersion); + if ($marketVersionMajor > $currentVersionMajor) { + return false; + } + } $platformMin = $element['platformMin']; $platformMax = $element['platformMax']; $tooSmall = $this->compare($version, $platformMin, '<'); @@ -187,11 +194,12 @@ public function isAppInstalled($appId) { * Returns the version for the app if an update is available * * @param string $appId + * @param bool $isMajorUpdate are major app updates allowed * @return bool|string * @throws AppNotFoundException * @throws AppNotInstalledException */ - public function getAvailableUpdateVersion($appId) { + public function getAvailableUpdateVersion($appId, $isMajorUpdate = false) { $info = $this->getInstalledAppInfo($appId); if (is_null($info)) { throw new AppNotInstalledException($this->l10n->t('App (%s) is not installed', $appId)); @@ -202,8 +210,15 @@ public function getAvailableUpdateVersion($appId) { } $releases = $marketInfo['releases']; $currentVersion = (string) $info['version']; - $releases = array_filter($releases, function($r) use ($currentVersion) { + $releases = array_filter($releases, function($r) use ($currentVersion, $isMajorUpdate) { $marketVersion = $r['version']; + $marketVersionMajor = $this->getMajorVersion($marketVersion); + $currentVersionMajor = $this->getMajorVersion($currentVersion); + if ($isMajorUpdate === false + && $marketVersionMajor > $currentVersionMajor + ) { + return false; + } return version_compare($marketVersion, $currentVersion, '>'); }); usort($releases, function ($a, $b) { @@ -215,6 +230,12 @@ public function getAvailableUpdateVersion($appId) { return false; } + public function getMajorVersion($version) { + $versionArray = \explode('.', $version); + return $versionArray[0]; + } + + public function getAppInfo($appId) { $data = $this->getApps(); $data = array_filter($data, function($element) use ($appId) { @@ -249,7 +270,7 @@ public function getInstalledAppInfo($appId) { * @throws AppManagerException * @throws AppNotInstalledException */ - public function updateApp($appId) { + public function updateApp($appId, $isMajorUpdate = false) { if (!$this->canInstall()) { throw new \Exception("Installing apps is not supported because the app folder is not writable."); } @@ -260,7 +281,7 @@ public function updateApp($appId) { } // download package - $package = $this->downloadPackage($appId); + $package = $this->downloadPackage($appId, $isMajorUpdate, $info['version']); $this->updatePackage($package); }