diff options
author | Lukas Reschke <lukas@statuscode.ch> | 2016-11-24 14:29:57 +0100 |
---|---|---|
committer | Lukas Reschke <lukas@statuscode.ch> | 2016-11-24 14:29:57 +0100 |
commit | 6a4c0cf237d2c738bb20403a2cbcccd1964c6136 (patch) | |
tree | c03c062df15e5bdd09038d59a2ee2f7f273b25ce /lib/private/App | |
parent | e3489d92fd820c1a94251d007e0189c8588eaee2 (diff) | |
download | nextcloud-server-6a4c0cf237d2c738bb20403a2cbcccd1964c6136.tar.gz nextcloud-server-6a4c0cf237d2c738bb20403a2cbcccd1964c6136.zip |
Loop for newest version in appstore response
The current implementation when fetching apps from the appstore is to assume that the first element is the newest version, this is now always applicable and leads to the fact that for some apps (e.g. nextant) the newest version is not delivered. This can be easily tested by comparing the version of the downloaded Nextant version.
This change will loop over all releases delivered by the appstore and chooses the newest compatible one. While not the cleanest solution, it does its job.
Most of the code are actually unit tests. Whereas I have copied the whole original response from the appstore and also have performed the transformation. So that's why the diff looks so huge.
Signed-off-by: Lukas Reschke <lukas@statuscode.ch>
Diffstat (limited to 'lib/private/App')
-rw-r--r-- | lib/private/App/AppStore/Fetcher/AppFetcher.php | 67 | ||||
-rw-r--r-- | lib/private/App/AppStore/Fetcher/Fetcher.php | 26 |
2 files changed, 85 insertions, 8 deletions
diff --git a/lib/private/App/AppStore/Fetcher/AppFetcher.php b/lib/private/App/AppStore/Fetcher/AppFetcher.php index 19e61d416a0..32c207e3ac0 100644 --- a/lib/private/App/AppStore/Fetcher/AppFetcher.php +++ b/lib/private/App/AppStore/Fetcher/AppFetcher.php @@ -21,12 +21,16 @@ namespace OC\App\AppStore\Fetcher; +use OC\App\AppStore\Version\VersionParser; use OCP\AppFramework\Utility\ITimeFactory; use OCP\Files\IAppData; use OCP\Http\Client\IClientService; use OCP\IConfig; class AppFetcher extends Fetcher { + /** @var IConfig */ + private $config; + /** * @param IAppData $appData * @param IClientService $clientService @@ -44,6 +48,7 @@ class AppFetcher extends Fetcher { ); $this->fileName = 'apps.json'; + $this->config = $config; $versionArray = \OC_Util::getVersion(); $this->endpointUrl = sprintf( @@ -53,4 +58,66 @@ class AppFetcher extends Fetcher { $versionArray[2] ); } + + /** + * Only returns the latest compatible app release in the releases array + * + * @return array + */ + protected function fetch() { + $client = $this->clientService->newClient(); + $response = $client->get($this->endpointUrl); + $responseJson = []; + $responseJson['data'] = json_decode($response->getBody(), true); + $responseJson['timestamp'] = $this->timeFactory->getTime(); + $response = $responseJson; + + $ncVersion = $this->config->getSystemValue('version'); + $ncMajorVersion = explode('.', $ncVersion)[0]; + foreach($response['data'] as $dataKey => $app) { + $releases = []; + + // Filter all compatible releases + foreach($app['releases'] as $release) { + // Exclude all nightly releases + if($release['isNightly'] === false) { + // Exclude all versions not compatible with the current version + $versionParser = new VersionParser(); + $version = $versionParser->getVersion($release['rawPlatformVersionSpec']); + + if( + // Major version is bigger or equals to the minimum version of the app + version_compare($ncMajorVersion, $version->getMinimumVersion(), '>=') + // Major version is smaller or equals to the maximum version of the app + && version_compare($ncMajorVersion, $version->getMaximumVersion(), '<=')) { + $releases[] = $release; + } + } + } + + // Get the highest version + $versions = []; + foreach($releases as $release) { + $versions[] = $release['version']; + } + usort($versions, 'version_compare'); + $versions = array_reverse($versions); + $compatible = false; + if(isset($versions[0])) { + $highestVersion = $versions[0]; + foreach ($releases as $release) { + if ((string)$release['version'] === (string)$highestVersion) { + $compatible = true; + $response['data'][$dataKey]['releases'] = [$release]; + break; + } + } + } + if(!$compatible) { + unset($response['data'][$dataKey]); + } + } + + return $response; + } } diff --git a/lib/private/App/AppStore/Fetcher/Fetcher.php b/lib/private/App/AppStore/Fetcher/Fetcher.php index cffff9176e2..f82e1a253f6 100644 --- a/lib/private/App/AppStore/Fetcher/Fetcher.php +++ b/lib/private/App/AppStore/Fetcher/Fetcher.php @@ -30,11 +30,11 @@ abstract class Fetcher { const INVALIDATE_AFTER_SECONDS = 300; /** @var IAppData */ - private $appData; + protected $appData; /** @var IClientService */ - private $clientService; + protected $clientService; /** @var ITimeFactory */ - private $timeFactory; + protected $timeFactory; /** @var string */ protected $fileName; /** @var string */ @@ -54,6 +54,20 @@ abstract class Fetcher { } /** + * Fetches the response from the server + * + * @return array + */ + protected function fetch() { + $client = $this->clientService->newClient(); + $response = $client->get($this->endpointUrl); + $responseJson = []; + $responseJson['data'] = json_decode($response->getBody(), true); + $responseJson['timestamp'] = $this->timeFactory->getTime(); + return $responseJson; + } + + /** * Returns the array with the categories on the appstore server * * @return array @@ -77,12 +91,8 @@ abstract class Fetcher { } // Refresh the file content - $client = $this->clientService->newClient(); try { - $response = $client->get($this->endpointUrl); - $responseJson = []; - $responseJson['data'] = json_decode($response->getBody(), true); - $responseJson['timestamp'] = $this->timeFactory->getTime(); + $responseJson = $this->fetch(); $file->putContent(json_encode($responseJson)); return json_decode($file->getContent(), true)['data']; } catch (\Exception $e) { |