public function testGetApplicationEmptyXml() { $this->config->expects($this->at(0))->method('getSystemValue')->with('appstoreenabled', true)->will($this->returnValue(true)); $this->config->expects($this->at(1))->method('getSystemValue')->with('appstoreurl', 'https://api.owncloud.com/v1')->will($this->returnValue('https://api.owncloud.com/v1')); $response = $this->getMock('\\OCP\\Http\\Client\\IResponse'); $response->expects($this->once())->method('getBody')->will($this->returnValue('<?xml version="1.0"?> <ocs> <meta> <status>ok</status> <statuscode>100</statuscode> <message></message> </meta> </ocs> ')); $client = $this->getMock('\\OCP\\Http\\Client\\IClient'); $client->expects($this->once())->method('get')->with('https://api.owncloud.com/v1/content/data/MyId', ['timeout' => 5, 'query' => ['version' => '8x1x0x7']])->will($this->returnValue($response)); $this->clientService->expects($this->once())->method('newClient')->will($this->returnValue($client)); $this->assertSame(null, $this->ocsClient->getApplication('MyId', [8, 1, 0, 7])); }
/** * Get all available apps in a category * * @param string $category * @param bool $includeUpdateInfo Should we check whether there is an update * in the app store? * @return array */ public function listApps($category = '', $includeUpdateInfo = true) { $category = $this->getCategory($category); $cacheName = 'listApps-' . $category . '-' . (int) $includeUpdateInfo; if (!is_null($this->cache->get($cacheName))) { $apps = $this->cache->get($cacheName); } else { switch ($category) { // installed apps case 0: $apps = $this->getInstalledApps($includeUpdateInfo); usort($apps, function ($a, $b) { $a = (string) $a['name']; $b = (string) $b['name']; if ($a === $b) { return 0; } return $a < $b ? -1 : 1; }); $version = \OCP\Util::getVersion(); foreach ($apps as $key => $app) { if (!array_key_exists('level', $app) && array_key_exists('ocsid', $app)) { $remoteAppEntry = $this->ocsClient->getApplication($app['ocsid'], $version); if (is_array($remoteAppEntry) && array_key_exists('level', $remoteAppEntry)) { $apps[$key]['level'] = $remoteAppEntry['level']; } } } break; // not-installed apps // not-installed apps case 1: $apps = \OC_App::listAllApps(true, $includeUpdateInfo, $this->ocsClient); $apps = array_filter($apps, function ($app) { return !$app['active']; }); $version = \OCP\Util::getVersion(); foreach ($apps as $key => $app) { if (!array_key_exists('level', $app) && array_key_exists('ocsid', $app)) { $remoteAppEntry = $this->ocsClient->getApplication($app['ocsid'], $version); if (is_array($remoteAppEntry) && array_key_exists('level', $remoteAppEntry)) { $apps[$key]['level'] = $remoteAppEntry['level']; } } } usort($apps, function ($a, $b) { $a = (string) $a['name']; $b = (string) $b['name']; if ($a === $b) { return 0; } return $a < $b ? -1 : 1; }); break; default: $filter = $this->config->getSystemValue('appstore.experimental.enabled', false) ? 'all' : 'approved'; $apps = \OC_App::getAppstoreApps($filter, $category, $this->ocsClient); if (!$apps) { $apps = array(); } else { // don't list installed apps $installedApps = $this->getInstalledApps(false); $installedApps = array_map(function ($app) { if (isset($app['ocsid'])) { return $app['ocsid']; } return $app['id']; }, $installedApps); $apps = array_filter($apps, function ($app) use($installedApps) { return !in_array($app['id'], $installedApps); }); // show tooltip if app is downloaded from remote server $inactiveApps = $this->getInactiveApps(); foreach ($apps as &$app) { $app['needsDownload'] = !in_array($app['id'], $inactiveApps); } } // sort by score usort($apps, function ($a, $b) { $a = (int) $a['score']; $b = (int) $b['score']; if ($a === $b) { return 0; } return $a > $b ? -1 : 1; }); break; } } // fix groups to be an array $dependencyAnalyzer = new DependencyAnalyzer(new Platform($this->config), $this->l10n); $apps = array_map(function ($app) use($dependencyAnalyzer) { // fix groups $groups = array(); if (is_string($app['groups'])) { $groups = json_decode($app['groups']); } $app['groups'] = $groups; $app['canUnInstall'] = !$app['active'] && $app['removable']; // fix licence vs license if (isset($app['license']) && !isset($app['licence'])) { $app['licence'] = $app['license']; } // analyse dependencies $missing = $dependencyAnalyzer->analyze($app); $app['canInstall'] = empty($missing); $app['missingDependencies'] = $missing; $app['missingMinOwnCloudVersion'] = !isset($app['dependencies']['owncloud']['@attributes']['min-version']); $app['missingMaxOwnCloudVersion'] = !isset($app['dependencies']['owncloud']['@attributes']['max-version']); return $app; }, $apps); $this->cache->set($cacheName, $apps, 300); return ['apps' => $apps, 'status' => 'success']; }
/** * @param string $app * @return bool * @throws Exception if app is not compatible with this version of ownCloud * @throws Exception if no app-name was specified */ public static function installApp($app) { $l = \OC::$server->getL10N('core'); $config = \OC::$server->getConfig(); $ocsClient = new OCSClient(\OC::$server->getHTTPClientService(), $config, \OC::$server->getLogger()); $appData = $ocsClient->getApplication($app, \OCP\Util::getVersion()); // check if app is a shipped app or not. OCS apps have an integer as id, shipped apps use a string if (!is_numeric($app)) { $shippedVersion = self::getAppVersion($app); if ($appData && version_compare($shippedVersion, $appData['version'], '<')) { $app = self::downloadApp($app); } else { $app = OC_Installer::installShippedApp($app); } } else { // Maybe the app is already installed - compare the version in this // case and use the local already installed one. // FIXME: This is a horrible hack. I feel sad. The god of code cleanness may forgive me. $internalAppId = self::getInternalAppIdByOcs($app); if ($internalAppId !== false) { if ($appData && version_compare(\OC_App::getAppVersion($internalAppId), $appData['version'], '<')) { $app = self::downloadApp($app); } else { self::enable($internalAppId); $app = $internalAppId; } } else { $app = self::downloadApp($app); } } if ($app !== false) { // check if the app is compatible with this version of ownCloud $info = self::getAppInfo($app); $version = \OCP\Util::getVersion(); if (!self::isAppCompatible($version, $info)) { throw new \Exception($l->t('App "%s" cannot be installed because it is not compatible with this version of ownCloud.', array($info['name']))); } // check for required dependencies $dependencyAnalyzer = new DependencyAnalyzer(new Platform($config), $l); $missing = $dependencyAnalyzer->analyze($info); if (!empty($missing)) { $missingMsg = join(PHP_EOL, $missing); throw new \Exception($l->t('App "%s" cannot be installed because the following dependencies are not fulfilled: %s', array($info['name'], $missingMsg))); } $config->setAppValue($app, 'enabled', 'yes'); if (isset($appData['id'])) { $config->setAppValue($app, 'ocsid', $appData['id']); } \OC_Hook::emit('OC_App', 'post_enable', array('app' => $app)); } else { throw new \Exception($l->t("No app name specified")); } return $app; }
/** * Check if an update for the app is available * @param string $app * @return string|false false or the version number of the update * * The function will check if an update for a version is available */ public static function isUpdateAvailable($app) { static $isInstanceReadyForUpdates = null; if ($isInstanceReadyForUpdates === null) { $installPath = OC_App::getInstallPath(); if ($installPath === false || $installPath === null) { $isInstanceReadyForUpdates = false; } else { $isInstanceReadyForUpdates = true; } } if ($isInstanceReadyForUpdates === false) { return false; } $ocsid = \OC::$server->getAppConfig()->getValue($app, 'ocsid', ''); if ($ocsid != '') { $ocsClient = new OCSClient(\OC::$server->getHTTPClientService(), \OC::$server->getConfig(), \OC::$server->getLogger()); $ocsdata = $ocsClient->getApplication($ocsid, \OCP\Util::getVersion()); $ocsversion = (string) $ocsdata['version']; $currentversion = OC_App::getAppVersion($app); if (version_compare($ocsversion, $currentversion, '>')) { return $ocsversion; } else { return false; } } else { return false; } }
public function testGetApplicationSuccessful() { $this->config->expects($this->at(0))->method('getSystemValue')->with('appstoreenabled', true)->will($this->returnValue(true)); $this->config->expects($this->at(1))->method('getSystemValue')->with('appstoreurl', 'https://api.owncloud.com/v1')->will($this->returnValue('https://api.owncloud.com/v1')); $response = $this->getMock('\\OCP\\Http\\Client\\IResponse'); $response->expects($this->once())->method('getBody')->will($this->returnValue('<?xml version="1.0"?> <ocs> <meta> <status>ok</status> <statuscode>100</statuscode> <message></message> </meta> <data> <content details="full"> <id>166053</id> <name>Versioning</name> <version>0.0.1</version> <label>recommended</label> <typeid>925</typeid> <typename>ownCloud other</typename> <language></language> <personid>owncloud</personid> <profilepage>http://opendesktop.org/usermanager/search.php?username=owncloud</profilepage> <created>2014-07-07T16:34:40+02:00</created> <changed>2014-07-07T16:34:40+02:00</changed> <downloads>140</downloads> <score>50</score> <description>Placeholder for future updates</description> <summary></summary> <feedbackurl></feedbackurl> <changelog></changelog> <homepage></homepage> <homepagetype></homepagetype> <homepage2></homepage2> <homepagetype2></homepagetype2> <homepage3></homepage3> <homepagetype3></homepagetype3> <homepage4></homepage4> <homepagetype4></homepagetype4> <homepage5></homepage5> <homepagetype5></homepagetype5> <homepage6></homepage6> <homepagetype6></homepagetype6> <homepage7></homepage7> <homepagetype7></homepagetype7> <homepage8></homepage8> <homepagetype8></homepagetype8> <homepage9></homepage9> <homepagetype9></homepagetype9> <homepage10></homepage10> <homepagetype10></homepagetype10> <licensetype>16</licensetype> <license>AGPL</license> <donationpage></donationpage> <comments>0</comments> <commentspage>http://apps.owncloud.com/content/show.php?content=166053</commentspage> <fans>0</fans> <fanspage>http://apps.owncloud.com/content/show.php?action=fan&content=166053</fanspage> <knowledgebaseentries>0</knowledgebaseentries> <knowledgebasepage>http://apps.owncloud.com/content/show.php?action=knowledgebase&content=166053</knowledgebasepage> <depend>ownCloud 7</depend> <preview1></preview1> <preview2></preview2> <preview3></preview3> <previewpic1></previewpic1> <previewpic2></previewpic2> <previewpic3></previewpic3> <picsmall1></picsmall1> <picsmall2></picsmall2> <picsmall3></picsmall3> <detailpage>https://apps.owncloud.com/content/show.php?content=166053</detailpage> <downloadtype1></downloadtype1> <downloadprice1>0</downloadprice1> <downloadlink1>http://apps.owncloud.com/content/download.php?content=166053&id=1</downloadlink1> <downloadname1></downloadname1> <downloadgpgfingerprint1></downloadgpgfingerprint1> <downloadgpgsignature1></downloadgpgsignature1> <downloadpackagename1></downloadpackagename1> <downloadrepository1></downloadrepository1> <downloadsize1>1</downloadsize1> </content> </data> </ocs> ')); $client = $this->getMock('\\OCP\\Http\\Client\\IClient'); $client->expects($this->once())->method('get')->with('https://api.owncloud.com/v1/content/data/MyId', ['timeout' => 5])->will($this->returnValue($response)); $this->clientService->expects($this->once())->method('newClient')->will($this->returnValue($client)); $expected = ['id' => 166053, 'name' => 'Versioning', 'version' => '0.0.1', 'type' => '925', 'label' => 'recommended', 'typename' => 'ownCloud other', 'personid' => 'owncloud', 'profilepage' => 'http://opendesktop.org/usermanager/search.php?username=owncloud', 'detailpage' => 'https://apps.owncloud.com/content/show.php?content=166053', 'preview1' => '', 'preview2' => '', 'preview3' => '', 'changed' => 1404743680, 'description' => 'Placeholder for future updates', 'score' => 50]; $this->assertSame($expected, $this->ocsClient->getApplication('MyId')); }