-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Make shipped apps updatable via appstore #8808
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
2bcfd8e
c8636ca
020255b
c6dc9ae
c8a8c7e
eea501b
19129b3
56a8010
2c00ab1
724d027
00b7f36
6aab50f
fad3bd7
0fe8f77
498aa66
a110973
1ab9bdc
5d4f3ba
6bf0689
602404c
5e9fa64
0890ce4
c378e76
65028c4
86f546f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,8 +3,13 @@ | |
| * ownCloud | ||
| * | ||
| * @author Frank Karlitschek | ||
| * @copyright 2012 Frank Karlitschek <[email protected]> | ||
| * | ||
| * @author Jakob Sack | ||
| * @copyright 2012 Frank Karlitschek [email protected] | ||
| * @copyright 2012 Jakob Sack <[email protected]> | ||
| * | ||
| * @author Georg Ehrke | ||
| * @copyright 2014 Georg Ehrke <[email protected]> | ||
| * | ||
| * This library is free software; you can redistribute it and/or | ||
| * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE | ||
|
|
@@ -211,48 +216,45 @@ public static function isEnabled( $app ) { | |
| */ | ||
| public static function enable( $app ) { | ||
| self::$enabledAppsCache = array(); // flush | ||
| if(!OC_Installer::isInstalled($app)) { | ||
| // 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)) { | ||
| $app = OC_Installer::installShippedApp($app); | ||
| }else{ | ||
| $appdata=OC_OCSClient::getApplication($app); | ||
| $download=OC_OCSClient::getApplicationDownload($app, 1); | ||
| if(isset($download['downloadlink']) and $download['downloadlink']!='') { | ||
| // Replace spaces in download link without encoding entire URL | ||
| $download['downloadlink'] = str_replace(' ', '%20', $download['downloadlink']); | ||
| $info = array('source'=>'http', 'href'=>$download['downloadlink'], 'appdata'=>$appdata); | ||
| $app=OC_Installer::installApp($info); | ||
| } | ||
| } | ||
| if (!OC_Installer::isInstalled($app)) { | ||
| $app = self::installApp($app); | ||
| } | ||
| $l = OC_L10N::get('core'); | ||
| if($app!==false) { | ||
| // check if the app is compatible with this version of ownCloud | ||
| $info=OC_App::getAppInfo($app); | ||
| $version=OC_Util::getVersion(); | ||
| if(!self::isAppCompatible($version, $info)) { | ||
| throw new \Exception( | ||
| $l->t("App \"%s\" can't be installed because it is not compatible with this version of ownCloud.", | ||
| array($info['name']) | ||
| ) | ||
| ); | ||
| }else{ | ||
| OC_Appconfig::setValue( $app, 'enabled', 'yes' ); | ||
| if(isset($appdata['id'])) { | ||
| OC_Appconfig::setValue( $app, 'ocsid', $appdata['id'] ); | ||
| } | ||
| \OC_Hook::emit('OC_App', 'post_enable', array('app' => $app)); | ||
| } | ||
| }else{ | ||
| throw new \Exception($l->t("No app name specified")); | ||
|
|
||
| OC_Appconfig::setValue( $app, 'enabled', 'yes' ); | ||
| } | ||
|
|
||
| /** | ||
| * @param string $app | ||
| * @return int | ||
| */ | ||
| public static function downloadApp($app) { | ||
| $appdata=OC_OCSClient::getApplication($app); | ||
| $download=OC_OCSClient::getApplicationDownload($app, 1); | ||
| if(isset($download['downloadlink']) and $download['downloadlink']!='') { | ||
| // Replace spaces in download link without encoding entire URL | ||
| $download['downloadlink'] = str_replace(' ', '%20', $download['downloadlink']); | ||
| $info = array('source'=>'http', 'href'=>$download['downloadlink'], 'appdata'=>$appdata); | ||
| $app=OC_Installer::installApp($info); | ||
| } | ||
| return $app; | ||
| } | ||
|
|
||
| /** | ||
| * @param string $app | ||
| * @return bool | ||
| */ | ||
| public static function removeApp($app) { | ||
| if (self::isShipped($app)) { | ||
| return false; | ||
| } | ||
|
|
||
| return OC_Installer::removeApp($app); | ||
| } | ||
|
|
||
| /** | ||
| * disables an app | ||
| * @param string $app app | ||
| * @return boolean|null | ||
| * @return null | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. drop the return statement, because there is no return inside of this function |
||
| * | ||
| * This function set an app as disabled in appconfig. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Merge this line with the line above |
||
| */ | ||
|
|
@@ -261,11 +263,6 @@ public static function disable( $app ) { | |
| // check if app is a shipped app or not. if not delete | ||
| \OC_Hook::emit('OC_App', 'pre_disable', array('app' => $app)); | ||
| OC_Appconfig::setValue( $app, 'enabled', 'no' ); | ||
|
|
||
| // check if app is a shipped app or not. if not delete | ||
| if(!OC_App::isShipped( $app )) { | ||
| OC_Installer::removeApp( $app ); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -446,18 +443,50 @@ public static function getInstallPath() { | |
| } | ||
|
|
||
|
|
||
| protected static function findAppInDirectories($appid) { | ||
| /** | ||
| * search for an app in all app-directories | ||
| * @param $appId | ||
| * @return mixed (bool|string) | ||
| */ | ||
| protected static function findAppInDirectories($appId) { | ||
| static $app_dir = array(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. static should be in the object instead of the method?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. works both, didn't write this piece of code. This is how it is in master |
||
| if (isset($app_dir[$appid])) { | ||
| return $app_dir[$appid]; | ||
|
|
||
| if (isset($app_dir[$appId])) { | ||
| return $app_dir[$appId]; | ||
| } | ||
|
|
||
| $possibleApps = array(); | ||
| foreach(OC::$APPSROOTS as $dir) { | ||
| if(file_exists($dir['path'].'/'.$appid)) { | ||
| return $app_dir[$appid]=$dir; | ||
| if(file_exists($dir['path'].'/'.$appId)) { | ||
| $possibleApps[] = $dir; | ||
| } | ||
| } | ||
| return false; | ||
|
|
||
| if (count($possibleApps) === 0) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| return false; | ||
| } elseif(count($possibleApps) === 1) { | ||
| reset($possibleApps); | ||
| $dir = current($possibleApps); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or even better, just |
||
| $app_dir[$appId] = $dir; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this line,
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| return $dir; | ||
| } else { | ||
| $versionToLoad = array(); | ||
| foreach($possibleApps as $possibleApp) { | ||
| $version = self::getAppVersionByPath($possibleApp['path']); | ||
| if (empty($versionToLoad) || version_compare($version, $versionToLoad['version'], '>')) { | ||
| $versionToLoad = array( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but we want to load the newest version, that's why we need to check all
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should load the "running" version, not the newest one?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can't run multiple app versions that use the same appid, that's why we search for the app with the highest version num
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah okay, is that the same way the core finds the classes of apps?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| 'dir' => $possibleApp, | ||
| 'version' => $version, | ||
| ); | ||
| } | ||
| } | ||
| $app_dir[$appId] = $versionToLoad['dir']; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useless assignment
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. invalid (it's a static variable of the method) |
||
| return $versionToLoad['dir']; | ||
| //TODO - write test | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. too many new lines |
||
| /** | ||
| * Get the directory for the given app. | ||
| * If the app is defined in multiple directories, the first one is taken. (false if not found) | ||
|
|
@@ -471,6 +500,18 @@ public static function getAppPath($appid) { | |
| return false; | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * check if an app's directory is writable | ||
| * @param $appid | ||
| * @return bool | ||
| */ | ||
| public static function isAppDirWritable($appid) { | ||
| $path = self::getAppPath($appid); | ||
| return is_writable($path); | ||
| } | ||
|
|
||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. too many new lines |
||
| /** | ||
| * Get the path for the given app on the access | ||
| * If the app is defined in multiple directories, the first one is taken. (false if not found) | ||
|
|
@@ -490,15 +531,28 @@ public static function getAppWebPath($appid) { | |
| * @return string | ||
| */ | ||
| public static function getAppVersion($appid) { | ||
| $file= self::getAppPath($appid).'/appinfo/version'; | ||
| if(is_file($file) && $version = trim(file_get_contents($file))) { | ||
| $file = self::getAppPath($appid); | ||
| return self::getAppVersionByPath($file); | ||
| } | ||
|
|
||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. too many new lines |
||
| /** | ||
| * get app's version based on it's path | ||
| * @param string $path | ||
| * @return string | ||
| */ | ||
| public static function getAppVersionByPath($path) { | ||
| $versionFile = $path . '/appinfo/version'; | ||
| $infoFile = $path . '/appinfo/info.xml'; | ||
| if(is_file($versionFile) && $version = trim(file_get_contents($versionFile))) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't use inline assignments, just do |
||
| return $version; | ||
| }else{ | ||
| $appData=self::getAppInfo($appid); | ||
| $appData=self::getAppInfo($infoFile, true); | ||
| return isset($appData['version'])? $appData['version'] : ''; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Read all app metadata from the info.xml file | ||
| * @param string $appid id of the app or the path of the info.xml file | ||
|
|
@@ -513,7 +567,7 @@ public static function getAppInfo($appid, $path=false) { | |
| if(isset(self::$appInfo[$appid])) { | ||
| return self::$appInfo[$appid]; | ||
| } | ||
| $file= self::getAppPath($appid).'/appinfo/info.xml'; | ||
| $file = self::getAppPath($appid) . '/appinfo/info.xml'; | ||
| } | ||
| $data=array(); | ||
| $content=@file_get_contents($file); | ||
|
|
@@ -602,7 +656,6 @@ public static function getCurrentApp() { | |
| } | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * get the forms for either settings, admin or personal | ||
| */ | ||
|
|
@@ -726,20 +779,22 @@ public static function listAllApps() { | |
| $info['internal']=true; | ||
| $info['internallabel']='Internal App'; | ||
| $info['internalclass']=''; | ||
| $info['update']=false; | ||
| $info['removable'] = false; | ||
| } else { | ||
| $info['internal']=false; | ||
| $info['internallabel']='3rd Party'; | ||
| $info['internalclass']='externalapp'; | ||
| $info['update']=OC_Installer::isUpdateAvailable($app); | ||
| $info['removable'] = true; | ||
| } | ||
|
|
||
| $info['update'] = OC_Installer::isUpdateAvailable($app); | ||
|
|
||
| $info['preview'] = OC_Helper::imagePath('settings', 'trans.png'); | ||
| $info['version'] = OC_App::getAppVersion($app); | ||
| $appList[] = $info; | ||
| } | ||
| } | ||
| $remoteApps = OC_App::getAppstoreApps(); | ||
| $remoteApps = self::getAppstoreApps(); | ||
| if ( $remoteApps ) { | ||
| // Remove duplicates | ||
| foreach ( $appList as $app ) { | ||
|
|
@@ -818,6 +873,7 @@ public static function getAppstoreApps( $filter = 'approved' ) { | |
| $app1[$i]['ocs_id'] = $app['id']; | ||
| $app1[$i]['internal'] = $app1[$i]['active'] = 0; | ||
| $app1[$i]['update'] = false; | ||
| $app1[$i]['removable'] = false; | ||
| if($app['label']=='recommended') { | ||
| $app1[$i]['internallabel'] = 'Recommended'; | ||
| $app1[$i]['internalclass'] = 'recommendedapp'; | ||
|
|
@@ -828,17 +884,29 @@ public static function getAppstoreApps( $filter = 'approved' ) { | |
|
|
||
|
|
||
| // rating img | ||
| if($app['score']>=0 and $app['score']<5) $img=OC_Helper::imagePath( "core", "rating/s1.png" ); | ||
| elseif($app['score']>=5 and $app['score']<15) $img=OC_Helper::imagePath( "core", "rating/s2.png" ); | ||
| elseif($app['score']>=15 and $app['score']<25) $img=OC_Helper::imagePath( "core", "rating/s3.png" ); | ||
| elseif($app['score']>=25 and $app['score']<35) $img=OC_Helper::imagePath( "core", "rating/s4.png" ); | ||
| elseif($app['score']>=35 and $app['score']<45) $img=OC_Helper::imagePath( "core", "rating/s5.png" ); | ||
| elseif($app['score']>=45 and $app['score']<55) $img=OC_Helper::imagePath( "core", "rating/s6.png" ); | ||
| elseif($app['score']>=55 and $app['score']<65) $img=OC_Helper::imagePath( "core", "rating/s7.png" ); | ||
| elseif($app['score']>=65 and $app['score']<75) $img=OC_Helper::imagePath( "core", "rating/s8.png" ); | ||
| elseif($app['score']>=75 and $app['score']<85) $img=OC_Helper::imagePath( "core", "rating/s9.png" ); | ||
| elseif($app['score']>=85 and $app['score']<95) $img=OC_Helper::imagePath( "core", "rating/s10.png" ); | ||
| elseif($app['score']>=95 and $app['score']<100) $img=OC_Helper::imagePath( "core", "rating/s11.png" ); | ||
| if ($app['score'] >= 0 && $app['score'] < 5) { | ||
| $img = OC_Helper::imagePath( "core", "rating/s1.png" ); | ||
| } elseif ($app['score'] >= 5 && $app['score'] < 15) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove all |
||
| $img = OC_Helper::imagePath( "core", "rating/s2.png" ); | ||
| } elseif($app['score'] >= 15 && $app['score'] < 25) { | ||
| $img = OC_Helper::imagePath( "core", "rating/s3.png" ); | ||
| } elseif($app['score'] >= 25 && $app['score'] < 35) { | ||
| $img = OC_Helper::imagePath( "core", "rating/s4.png" ); | ||
| } elseif($app['score'] >= 35 && $app['score'] < 45) { | ||
| $img = OC_Helper::imagePath( "core", "rating/s5.png" ); | ||
| } elseif($app['score'] >= 45 && $app['score'] < 55) { | ||
| $img = OC_Helper::imagePath( "core", "rating/s6.png" ); | ||
| } elseif($app['score'] >= 55 && $app['score'] < 65) { | ||
| $img = OC_Helper::imagePath( "core", "rating/s7.png" ); | ||
| } elseif($app['score'] >= 65 && $app['score'] < 75) { | ||
| $img = OC_Helper::imagePath( "core", "rating/s8.png" ); | ||
| } elseif($app['score'] >= 75 && $app['score'] < 85) { | ||
| $img = OC_Helper::imagePath( "core", "rating/s9.png" ); | ||
| } elseif($app['score'] >= 85 && $app['score'] < 95) { | ||
| $img = OC_Helper::imagePath( "core", "rating/s10.png" ); | ||
| } elseif($app['score'] >= 95 && $app['score'] < 100) { | ||
| $img = OC_Helper::imagePath( "core", "rating/s11.png" ); | ||
| } | ||
|
|
||
| $app1[$i]['score'] = '<img src="'.$img.'"> Score: '.$app['score'].'%'; | ||
| $i++; | ||
|
|
@@ -1007,9 +1075,55 @@ public static function getAppVersions() { | |
| return $versions; | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * @param mixed $app | ||
| * @return bool | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just @throws \Exception or is it supposed to have a description in which certain cases an exception is thrown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the case would be great |
||
| */ | ||
| public static function installApp($app) { | ||
| $l = OC_L10N::get('core'); | ||
| $appdata=OC_OCSClient::getApplication($app); | ||
|
|
||
| // 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{ | ||
| $app = self::downloadApp($app); | ||
| } | ||
|
|
||
| if($app!==false) { | ||
| // check if the app is compatible with this version of ownCloud | ||
| $info = self::getAppInfo($app); | ||
| $version=OC_Util::getVersion(); | ||
| if(!self::isAppCompatible($version, $info)) { | ||
| throw new \Exception( | ||
| $l->t("App \"%s\" can't be installed because it is not compatible with this version of ownCloud.", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use single quotes, so you dont need to escape the double quotes: |
||
| array($info['name']) | ||
| ) | ||
| ); | ||
| }else{ | ||
| OC_Appconfig::setValue( $app, 'enabled', 'yes' ); | ||
| if(isset($appdata['id'])) { | ||
| OC_Appconfig::setValue( $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; | ||
| } | ||
|
|
||
| /** | ||
| * update the database for the app and call the update script | ||
| * @param string $appid | ||
| * @return bool | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't comment on the line bellow: In line 1166 there is just a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed with 6bf0689 |
||
| */ | ||
| public static function updateApp($appid) { | ||
| if(file_exists(self::getAppPath($appid).'/appinfo/preupdate.php')) { | ||
|
|
@@ -1020,7 +1134,7 @@ public static function updateApp($appid) { | |
| OC_DB::updateDbFromStructure(self::getAppPath($appid).'/appinfo/database.xml'); | ||
| } | ||
| if(!self::isEnabled($appid)) { | ||
| return; | ||
| return false; | ||
| } | ||
| if(file_exists(self::getAppPath($appid).'/appinfo/update.php')) { | ||
| self::loadApp($appid); | ||
|
|
@@ -1037,6 +1151,8 @@ public static function updateApp($appid) { | |
| } | ||
|
|
||
| self::setAppTypes($appid); | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| /** | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure there aren't any other special characters in the download links?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just from moved this code here from another place (https://github.com/owncloud/core/pull/8808/files#diff-4828f39ae4935d14b1dc1a6ffe323725L232)
works in current versions, so apparently it's just fine to escape spaces