Completed
Push — master ( 988917...cb69ac )
by Blizzz
13:42 queued 05:46
created

AppSettingsController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
nc 1
nop 9
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 * @copyright Copyright (c) 2016, Lukas Reschke <[email protected]>
5
 *
6
 * @author Christoph Wurst <[email protected]>
7
 * @author Joas Schilling <[email protected]>
8
 * @author Lukas Reschke <[email protected]>
9
 * @author Morris Jobke <[email protected]>
10
 * @author Thomas Müller <[email protected]>
11
 *
12
 * @license AGPL-3.0
13
 *
14
 * This code is free software: you can redistribute it and/or modify
15
 * it under the terms of the GNU Affero General Public License, version 3,
16
 * as published by the Free Software Foundation.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
 * GNU Affero General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU Affero General Public License, version 3,
24
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
25
 *
26
 */
27
28
namespace OC\Settings\Controller;
29
30
use OC\App\AppStore\Fetcher\AppFetcher;
31
use OC\App\AppStore\Fetcher\CategoryFetcher;
32
use OC\App\AppStore\Version\VersionParser;
33
use OC\App\DependencyAnalyzer;
34
use OC\App\Platform;
35
use OCP\App\IAppManager;
36
use \OCP\AppFramework\Controller;
37
use OCP\AppFramework\Http\ContentSecurityPolicy;
38
use OCP\AppFramework\Http\JSONResponse;
39
use OCP\AppFramework\Http\TemplateResponse;
40
use OCP\INavigationManager;
41
use OCP\IRequest;
42
use OCP\IL10N;
43
use OCP\IConfig;
44
use OCP\L10N\IFactory;
45
46
/**
47
 * @package OC\Settings\Controller
48
 */
49
class AppSettingsController extends Controller {
50
	const CAT_ENABLED = 0;
51
	const CAT_DISABLED = 1;
52
53
	/** @var \OCP\IL10N */
54
	private $l10n;
55
	/** @var IConfig */
56
	private $config;
57
	/** @var INavigationManager */
58
	private $navigationManager;
59
	/** @var IAppManager */
60
	private $appManager;
61
	/** @var CategoryFetcher */
62
	private $categoryFetcher;
63
	/** @var AppFetcher */
64
	private $appFetcher;
65
	/** @var IFactory */
66
	private $l10nFactory;
67
68
	/**
69
	 * @param string $appName
70
	 * @param IRequest $request
71
	 * @param IL10N $l10n
72
	 * @param IConfig $config
73
	 * @param INavigationManager $navigationManager
74
	 * @param IAppManager $appManager
75
	 * @param CategoryFetcher $categoryFetcher
76
	 * @param AppFetcher $appFetcher
77
	 * @param IFactory $l10nFactory
78
	 */
79
	public function __construct($appName,
80
								IRequest $request,
81
								IL10N $l10n,
82
								IConfig $config,
83
								INavigationManager $navigationManager,
84
								IAppManager $appManager,
85
								CategoryFetcher $categoryFetcher,
86
								AppFetcher $appFetcher,
87
								IFactory $l10nFactory) {
88
		parent::__construct($appName, $request);
89
		$this->l10n = $l10n;
90
		$this->config = $config;
91
		$this->navigationManager = $navigationManager;
92
		$this->appManager = $appManager;
93
		$this->categoryFetcher = $categoryFetcher;
94
		$this->appFetcher = $appFetcher;
95
		$this->l10nFactory = $l10nFactory;
96
	}
97
98
	/**
99
	 * @NoCSRFRequired
100
	 *
101
	 * @param string $category
102
	 * @return TemplateResponse
103
	 */
104
	public function viewApps($category = '') {
105
		if ($category === '') {
106
			$category = 'enabled';
107
		}
108
109
		$params = [];
110
		$params['category'] = $category;
111
		$params['appstoreEnabled'] = $this->config->getSystemValue('appstoreenabled', true) === true;
112
		$this->navigationManager->setActiveEntry('core_apps');
113
114
		$templateResponse = new TemplateResponse($this->appName, 'apps', $params, 'user');
115
		$policy = new ContentSecurityPolicy();
116
		$policy->addAllowedImageDomain('https://usercontent.apps.nextcloud.com');
117
		$templateResponse->setContentSecurityPolicy($policy);
118
119
		return $templateResponse;
120
	}
121
122
	/**
123
	 * Get all available categories
124
	 *
125
	 * @return JSONResponse
126
	 */
127
	public function listCategories() {
128
		$currentLanguage = substr($this->l10nFactory->findLanguage(), 0, 2);
129
130
		$formattedCategories = [
131
			['id' => self::CAT_ENABLED, 'ident' => 'enabled', 'displayName' => (string)$this->l10n->t('Enabled')],
132
			['id' => self::CAT_DISABLED, 'ident' => 'disabled', 'displayName' => (string)$this->l10n->t('Not enabled')],
133
		];
134
		$categories = $this->categoryFetcher->get();
135
		foreach($categories as $category) {
136
			$formattedCategories[] = [
137
				'id' => $category['id'],
138
				'ident' => $category['id'],
139
				'displayName' => isset($category['translations'][$currentLanguage]['name']) ? $category['translations'][$currentLanguage]['name'] : $category['translations']['en']['name'],
140
			];
141
		}
142
143
		return new JSONResponse($formattedCategories);
144
	}
145
146
	/**
147
	 * Get all apps for a category
148
	 *
149
	 * @param string $requestedCategory
150
	 * @return array
151
	 */
152
	private function getAppsForCategory($requestedCategory) {
153
		$versionParser = new VersionParser();
154
		$formattedApps = [];
155
		$apps = $this->appFetcher->get();
156
		foreach($apps as $app) {
157
			if (isset($app['isFeatured'])) {
158
				$app['featured'] = $app['isFeatured'];
159
			}
160
161
			// Skip all apps not in the requested category
162
			$isInCategory = false;
163
			foreach($app['categories'] as $category) {
164
				if($category === $requestedCategory) {
165
					$isInCategory = true;
166
				}
167
			}
168
			if(!$isInCategory) {
169
				continue;
170
			}
171
172
			$nextCloudVersion = $versionParser->getVersion($app['releases'][0]['rawPlatformVersionSpec']);
173
			$nextCloudVersionDependencies = [];
174
			if($nextCloudVersion->getMinimumVersion() !== '') {
175
				$nextCloudVersionDependencies['nextcloud']['@attributes']['min-version'] = $nextCloudVersion->getMinimumVersion();
176
			}
177
			if($nextCloudVersion->getMaximumVersion() !== '') {
178
				$nextCloudVersionDependencies['nextcloud']['@attributes']['max-version'] = $nextCloudVersion->getMaximumVersion();
179
			}
180
			$phpVersion = $versionParser->getVersion($app['releases'][0]['rawPhpVersionSpec']);
181
			$existsLocally = (\OC_App::getAppPath($app['id']) !== false) ? true : false;
182
			$phpDependencies = [];
183
			if($phpVersion->getMinimumVersion() !== '') {
184
				$phpDependencies['php']['@attributes']['min-version'] = $phpVersion->getMinimumVersion();
185
			}
186
			if($phpVersion->getMaximumVersion() !== '') {
187
				$phpDependencies['php']['@attributes']['max-version'] = $phpVersion->getMaximumVersion();
188
			}
189
			if(isset($app['releases'][0]['minIntSize'])) {
190
				$phpDependencies['php']['@attributes']['min-int-size'] = $app['releases'][0]['minIntSize'];
191
			}
192
			$authors = '';
193
			foreach($app['authors'] as $key => $author) {
194
				$authors .= $author['name'];
195
				if($key !== count($app['authors']) - 1) {
196
					$authors .= ', ';
197
				}
198
			}
199
200
			$currentLanguage = substr(\OC::$server->getL10NFactory()->findLanguage(), 0, 2);
201
			$enabledValue = $this->config->getAppValue($app['id'], 'enabled', 'no');
202
			$groups = null;
203
			if($enabledValue !== 'no' && $enabledValue !== 'yes') {
204
				$groups = $enabledValue;
205
			}
206
207
			$currentVersion = '';
208
			if($this->appManager->isInstalled($app['id'])) {
209
				$currentVersion = \OC_App::getAppVersion($app['id']);
210
			} else {
211
				$currentLanguage = $app['releases'][0]['version'];
212
			}
213
214
			$formattedApps[] = [
215
				'id' => $app['id'],
216
				'name' => isset($app['translations'][$currentLanguage]['name']) ? $app['translations'][$currentLanguage]['name'] : $app['translations']['en']['name'],
217
				'description' => isset($app['translations'][$currentLanguage]['description']) ? $app['translations'][$currentLanguage]['description'] : $app['translations']['en']['description'],
218
				'license' => $app['releases'][0]['licenses'],
219
				'author' => $authors,
220
				'shipped' => false,
221
				'version' => $currentVersion,
222
				'default_enable' => '',
223
				'types' => [],
224
				'documentation' => [
225
					'admin' => $app['adminDocs'],
226
					'user' => $app['userDocs'],
227
					'developer' => $app['developerDocs']
228
				],
229
				'website' => $app['website'],
230
				'bugs' => $app['issueTracker'],
231
				'detailpage' => $app['website'],
232
				'dependencies' => array_merge(
233
					$nextCloudVersionDependencies,
234
					$phpDependencies
235
				),
236
				'level' => ($app['featured'] === true) ? 200 : 100,
237
				'missingMaxOwnCloudVersion' => false,
238
				'missingMinOwnCloudVersion' => false,
239
				'canInstall' => true,
240
				'preview' => isset($app['screenshots'][0]['url']) ? 'https://usercontent.apps.nextcloud.com/'.base64_encode($app['screenshots'][0]['url']) : '',
241
				'score' => $app['ratingOverall'],
242
				'removable' => $existsLocally,
243
				'active' => $this->appManager->isEnabledForUser($app['id']),
244
				'needsDownload' => !$existsLocally,
245
				'groups' => $groups,
246
				'fromAppStore' => true,
247
			];
248
249
250
			$appFetcher = \OC::$server->getAppFetcher();
251
			$newVersion = \OC\Installer::isUpdateAvailable($app['id'], $appFetcher);
252
			if($newVersion && $this->appManager->isInstalled($app['id'])) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $newVersion of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
253
				$formattedApps[count($formattedApps)-1]['update'] = $newVersion;
254
			}
255
		}
256
257
		return $formattedApps;
258
	}
259
260
	/**
261
	 * Get all available apps in a category
262
	 *
263
	 * @param string $category
264
	 * @return JSONResponse
265
	 */
266
	public function listApps($category = '') {
267
		$appClass = new \OC_App();
268
269
		switch ($category) {
270
			// installed apps
271
			case 'enabled':
272
				$apps = $appClass->listAllApps();
273
				$apps = array_filter($apps, function ($app) {
274
					return $app['active'];
275
				});
276
277
				foreach($apps as $key => $app) {
278
					$newVersion = \OC\Installer::isUpdateAvailable($app['id'], $this->appFetcher);
279
					$apps[$key]['update'] = $newVersion;
280
				}
281
282
				usort($apps, function ($a, $b) {
283
					$a = (string)$a['name'];
284
					$b = (string)$b['name'];
285
					if ($a === $b) {
286
						return 0;
287
					}
288
					return ($a < $b) ? -1 : 1;
289
				});
290
				break;
291
			// disabled  apps
292
			case 'disabled':
293
				$apps = $appClass->listAllApps();
294
				$apps = array_filter($apps, function ($app) {
295
					return !$app['active'];
296
				});
297
				usort($apps, function ($a, $b) {
298
					$a = (string)$a['name'];
299
					$b = (string)$b['name'];
300
					if ($a === $b) {
301
						return 0;
302
					}
303
					return ($a < $b) ? -1 : 1;
304
				});
305
				break;
306
			default:
307
				$apps = $this->getAppsForCategory($category);
308
309
				// sort by score
310
				usort($apps, function ($a, $b) {
311
					$a = (int)$a['score'];
312
					$b = (int)$b['score'];
313
					if ($a === $b) {
314
						return 0;
315
					}
316
					return ($a > $b) ? -1 : 1;
317
				});
318
				break;
319
		}
320
321
		// fix groups to be an array
322
		$dependencyAnalyzer = new DependencyAnalyzer(new Platform($this->config), $this->l10n);
323
		$apps = array_map(function($app) use ($dependencyAnalyzer) {
324
325
			// fix groups
326
			$groups = array();
327
			if (is_string($app['groups'])) {
328
				$groups = json_decode($app['groups']);
329
			}
330
			$app['groups'] = $groups;
331
			$app['canUnInstall'] = !$app['active'] && $app['removable'];
332
333
			// fix licence vs license
334
			if (isset($app['license']) && !isset($app['licence'])) {
335
				$app['licence'] = $app['license'];
336
			}
337
338
			// analyse dependencies
339
			$missing = $dependencyAnalyzer->analyze($app);
340
			$app['canInstall'] = empty($missing);
341
			$app['missingDependencies'] = $missing;
342
343
			$app['missingMinOwnCloudVersion'] = !isset($app['dependencies']['nextcloud']['@attributes']['min-version']);
344
			$app['missingMaxOwnCloudVersion'] = !isset($app['dependencies']['nextcloud']['@attributes']['max-version']);
345
346
			return $app;
347
		}, $apps);
348
349
		return new JSONResponse(['apps' => $apps, 'status' => 'success']);
350
	}
351
}
352