You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
6.7 KiB

  1. <?php
  2. /**
  3. * @author Joas Schilling <nickvergessen@owncloud.com>
  4. * @author Lukas Reschke <lukas@owncloud.com>
  5. * @author Morris Jobke <hey@morrisjobke.de>
  6. * @author Thomas Müller <thomas.mueller@tmit.eu>
  7. *
  8. * @copyright Copyright (c) 2015, ownCloud, Inc.
  9. * @license AGPL-3.0
  10. *
  11. * This code is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Affero General Public License, version 3,
  13. * as published by the Free Software Foundation.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Affero General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Affero General Public License, version 3,
  21. * along with this program. If not, see <http://www.gnu.org/licenses/>
  22. *
  23. */
  24. namespace OC\Settings\Controller;
  25. use OC\App\DependencyAnalyzer;
  26. use OC\App\Platform;
  27. use OC\OCSClient;
  28. use OCP\App\IAppManager;
  29. use \OCP\AppFramework\Controller;
  30. use OCP\AppFramework\Http\ContentSecurityPolicy;
  31. use OCP\AppFramework\Http\DataResponse;
  32. use OCP\AppFramework\Http\TemplateResponse;
  33. use OCP\ICacheFactory;
  34. use OCP\INavigationManager;
  35. use OCP\IRequest;
  36. use OCP\IL10N;
  37. use OCP\IConfig;
  38. /**
  39. * @package OC\Settings\Controller
  40. */
  41. class AppSettingsController extends Controller {
  42. /** @var \OCP\IL10N */
  43. private $l10n;
  44. /** @var IConfig */
  45. private $config;
  46. /** @var \OCP\ICache */
  47. private $cache;
  48. /** @var INavigationManager */
  49. private $navigationManager;
  50. /** @var IAppManager */
  51. private $appManager;
  52. /** @var OCSClient */
  53. private $ocsClient;
  54. /**
  55. * @param string $appName
  56. * @param IRequest $request
  57. * @param IL10N $l10n
  58. * @param IConfig $config
  59. * @param ICacheFactory $cache
  60. * @param INavigationManager $navigationManager
  61. * @param IAppManager $appManager
  62. * @param OCSClient $ocsClient
  63. */
  64. public function __construct($appName,
  65. IRequest $request,
  66. IL10N $l10n,
  67. IConfig $config,
  68. ICacheFactory $cache,
  69. INavigationManager $navigationManager,
  70. IAppManager $appManager,
  71. OCSClient $ocsClient) {
  72. parent::__construct($appName, $request);
  73. $this->l10n = $l10n;
  74. $this->config = $config;
  75. $this->cache = $cache->create($appName);
  76. $this->navigationManager = $navigationManager;
  77. $this->appManager = $appManager;
  78. $this->ocsClient = $ocsClient;
  79. }
  80. /**
  81. * Enables or disables the display of experimental apps
  82. * @param bool $state
  83. * @return DataResponse
  84. */
  85. public function changeExperimentalConfigState($state) {
  86. $this->config->setSystemValue('appstore.experimental.enabled', $state);
  87. $this->appManager->clearAppsCache();
  88. return new DataResponse();
  89. }
  90. /**
  91. * @NoCSRFRequired
  92. * @return TemplateResponse
  93. */
  94. public function viewApps() {
  95. $params = [];
  96. $params['experimentalEnabled'] = $this->config->getSystemValue('appstore.experimental.enabled', false);
  97. $this->navigationManager->setActiveEntry('core_apps');
  98. $templateResponse = new TemplateResponse($this->appName, 'apps', $params, 'user');
  99. $policy = new ContentSecurityPolicy();
  100. $policy->addAllowedImageDomain('https://apps.owncloud.com');
  101. $templateResponse->setContentSecurityPolicy($policy);
  102. return $templateResponse;
  103. }
  104. /**
  105. * Get all available categories
  106. * @return array
  107. */
  108. public function listCategories() {
  109. if(!is_null($this->cache->get('listCategories'))) {
  110. return $this->cache->get('listCategories');
  111. }
  112. $categories = [
  113. ['id' => 0, 'displayName' => (string)$this->l10n->t('Enabled')],
  114. ['id' => 1, 'displayName' => (string)$this->l10n->t('Not enabled')],
  115. ];
  116. if($this->ocsClient->isAppStoreEnabled()) {
  117. // apps from external repo via OCS
  118. $ocs = $this->ocsClient->getCategories();
  119. if ($ocs) {
  120. foreach($ocs as $k => $v) {
  121. $categories[] = [
  122. 'id' => $k,
  123. 'displayName' => str_replace('ownCloud ', '', $v)
  124. ];
  125. }
  126. }
  127. }
  128. $this->cache->set('listCategories', $categories, 3600);
  129. return $categories;
  130. }
  131. /**
  132. * Get all available apps in a category
  133. *
  134. * @param int $category
  135. * @return array
  136. */
  137. public function listApps($category = 0) {
  138. if(!is_null($this->cache->get('listApps-'.$category))) {
  139. $apps = $this->cache->get('listApps-'.$category);
  140. } else {
  141. switch ($category) {
  142. // installed apps
  143. case 0:
  144. $apps = $this->getInstalledApps();
  145. usort($apps, function ($a, $b) {
  146. $a = (string)$a['name'];
  147. $b = (string)$b['name'];
  148. if ($a === $b) {
  149. return 0;
  150. }
  151. return ($a < $b) ? -1 : 1;
  152. });
  153. break;
  154. // not-installed apps
  155. case 1:
  156. $apps = \OC_App::listAllApps(true);
  157. $apps = array_filter($apps, function ($app) {
  158. return !$app['active'];
  159. });
  160. usort($apps, function ($a, $b) {
  161. $a = (string)$a['name'];
  162. $b = (string)$b['name'];
  163. if ($a === $b) {
  164. return 0;
  165. }
  166. return ($a < $b) ? -1 : 1;
  167. });
  168. break;
  169. default:
  170. $filter = $this->config->getSystemValue('appstore.experimental.enabled', false) ? 'all' : 'approved';
  171. $apps = \OC_App::getAppstoreApps($filter, $category);
  172. if (!$apps) {
  173. $apps = array();
  174. } else {
  175. // don't list installed apps
  176. $installedApps = $this->getInstalledApps();
  177. $installedApps = array_map(function ($app) {
  178. if (isset($app['ocsid'])) {
  179. return $app['ocsid'];
  180. }
  181. return $app['id'];
  182. }, $installedApps);
  183. $apps = array_filter($apps, function ($app) use ($installedApps) {
  184. return !in_array($app['id'], $installedApps);
  185. });
  186. }
  187. // sort by score
  188. usort($apps, function ($a, $b) {
  189. $a = (int)$a['score'];
  190. $b = (int)$b['score'];
  191. if ($a === $b) {
  192. return 0;
  193. }
  194. return ($a > $b) ? -1 : 1;
  195. });
  196. break;
  197. }
  198. }
  199. // fix groups to be an array
  200. $dependencyAnalyzer = new DependencyAnalyzer(new Platform($this->config), $this->l10n);
  201. $apps = array_map(function($app) use ($dependencyAnalyzer) {
  202. // fix groups
  203. $groups = array();
  204. if (is_string($app['groups'])) {
  205. $groups = json_decode($app['groups']);
  206. }
  207. $app['groups'] = $groups;
  208. $app['canUnInstall'] = !$app['active'] && $app['removable'];
  209. // fix licence vs license
  210. if (isset($app['license']) && !isset($app['licence'])) {
  211. $app['licence'] = $app['license'];
  212. }
  213. // analyse dependencies
  214. $missing = $dependencyAnalyzer->analyze($app);
  215. $app['canInstall'] = empty($missing);
  216. $app['missingDependencies'] = $missing;
  217. return $app;
  218. }, $apps);
  219. $this->cache->set('listApps-'.$category, $apps, 300);
  220. return ['apps' => $apps, 'status' => 'success'];
  221. }
  222. /**
  223. * @return array
  224. */
  225. private function getInstalledApps() {
  226. $apps = \OC_App::listAllApps(true);
  227. $apps = array_filter($apps, function ($app) {
  228. return $app['active'];
  229. });
  230. return $apps;
  231. }
  232. }