Passed
Push — master ( bfe2c1...5d2edc )
by Morris
19:21 queued 09:32
created

ViewController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 10
dl 0
loc 22
rs 9.9
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
 *
5
 * @author Christoph Wurst <[email protected]>
6
 * @author Joas Schilling <[email protected]>
7
 * @author Lukas Reschke <[email protected]>
8
 * @author Roeland Jago Douma <[email protected]>
9
 * @author Thomas Müller <[email protected]>
10
 * @author Vincent Petry <[email protected]>
11
 * @author Felix Nüsse <[email protected]>
12
 *
13
 * @license AGPL-3.0
14
 *
15
 * This code is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License, version 3,
17
 * as published by the Free Software Foundation.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public License, version 3,
25
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
26
 *
27
 */
28
29
namespace OCA\Files\Controller;
30
31
use OCA\Files\Activity\Helper;
32
use OCP\AppFramework\Controller;
33
use OCP\AppFramework\Http\ContentSecurityPolicy;
34
use OCP\AppFramework\Http\RedirectResponse;
35
use OCP\AppFramework\Http\Response;
36
use OCP\AppFramework\Http\TemplateResponse;
37
use OCP\App\IAppManager;
38
use OCP\Files\Folder;
39
use OCP\Files\IRootFolder;
40
use OCP\Files\NotFoundException;
41
use OCP\IConfig;
42
use OCP\IL10N;
43
use OCP\IRequest;
44
use OCP\IURLGenerator;
45
use OCP\IUserSession;
46
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
47
use Symfony\Component\EventDispatcher\GenericEvent;
48
49
/**
50
 * Class ViewController
51
 *
52
 * @package OCA\Files\Controller
53
 */
54
class ViewController extends Controller {
55
	/** @var string */
56
	protected $appName;
57
	/** @var IRequest */
58
	protected $request;
59
	/** @var IURLGenerator */
60
	protected $urlGenerator;
61
	/** @var IL10N */
62
	protected $l10n;
63
	/** @var IConfig */
64
	protected $config;
65
	/** @var EventDispatcherInterface */
66
	protected $eventDispatcher;
67
	/** @var IUserSession */
68
	protected $userSession;
69
	/** @var IAppManager */
70
	protected $appManager;
71
	/** @var IRootFolder */
72
	protected $rootFolder;
73
	/** @var Helper */
74
	protected $activityHelper;
75
76
	public function __construct(string $appName,
77
		IRequest $request,
78
		IURLGenerator $urlGenerator,
79
		IL10N $l10n,
80
		IConfig $config,
81
		EventDispatcherInterface $eventDispatcherInterface,
82
		IUserSession $userSession,
83
		IAppManager $appManager,
84
		IRootFolder $rootFolder,
85
		Helper $activityHelper
86
	) {
87
		parent::__construct($appName, $request);
88
		$this->appName         = $appName;
89
		$this->request         = $request;
90
		$this->urlGenerator    = $urlGenerator;
91
		$this->l10n            = $l10n;
92
		$this->config          = $config;
93
		$this->eventDispatcher = $eventDispatcherInterface;
94
		$this->userSession     = $userSession;
95
		$this->appManager      = $appManager;
96
		$this->rootFolder      = $rootFolder;
97
		$this->activityHelper  = $activityHelper;
98
	}
99
100
	/**
101
	 * @param string $appName
102
	 * @param string $scriptName
103
	 * @return string
104
	 */
105
	protected function renderScript($appName, $scriptName) {
106
		$content    = '';
107
		$appPath    = \OC_App::getAppPath($appName);
108
		$scriptPath = $appPath . '/' . $scriptName;
0 ignored issues
show
Bug introduced by
Are you sure $appPath of type false|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

108
		$scriptPath = /** @scrutinizer ignore-type */ $appPath . '/' . $scriptName;
Loading history...
109
		if (file_exists($scriptPath)) {
110
			// TODO: sanitize path / script name ?
111
			ob_start();
112
			include $scriptPath;
113
			$content = ob_get_contents();
114
			@ob_end_clean();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for ob_end_clean(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

114
			/** @scrutinizer ignore-unhandled */ @ob_end_clean();

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
115
		}
116
117
		return $content;
118
	}
119
120
	/**
121
	 * FIXME: Replace with non static code
122
	 *
123
	 * @return array
124
	 * @throws \OCP\Files\NotFoundException
125
	 */
126
	protected function getStorageInfo() {
127
		$dirInfo = \OC\Files\Filesystem::getFileInfo('/', false);
128
129
		return \OC_Helper::getStorageInfo('/', $dirInfo);
130
	}
131
132
	/**
133
	 * @NoCSRFRequired
134
	 * @NoAdminRequired
135
	 *
136
	 * @param string $fileid
137
	 * @return TemplateResponse|RedirectResponse
138
	 */
139
	public function showFile(string $fileid = null): Response {
140
		// This is the entry point from the `/f/{fileid}` URL which is hardcoded in the server.
141
		return $this->redirectToFile($fileid);
142
	}
143
144
	/**
145
	 * @NoCSRFRequired
146
	 * @NoAdminRequired
147
	 *
148
	 * @param string $dir
149
	 * @param string $view
150
	 * @param string $fileid
151
	 * @return TemplateResponse|RedirectResponse
152
	 */
153
	public function index($dir = '', $view = '', $fileid = null, $fileNotFound = false) {
0 ignored issues
show
Unused Code introduced by
The parameter $view is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

153
	public function index($dir = '', /** @scrutinizer ignore-unused */ $view = '', $fileid = null, $fileNotFound = false) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $dir is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

153
	public function index(/** @scrutinizer ignore-unused */ $dir = '', $view = '', $fileid = null, $fileNotFound = false) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
154
		if ($fileid !== null) {
155
			try {
156
				return $this->redirectToFile($fileid);
157
			} catch (NotFoundException $e) {
158
				return new RedirectResponse($this->urlGenerator->linkToRoute('files.view.index', ['fileNotFound' => true]));
159
			}
160
		}
161
162
		$nav = new \OCP\Template('files', 'appnavigation', '');
163
164
		// Load the files we need
165
		\OCP\Util::addStyle('files', 'merged');
166
		\OCP\Util::addScript('files', 'merged-index');
167
168
		// mostly for the home storage's free space
169
		// FIXME: Make non static
170
		$storageInfo = $this->getStorageInfo();
171
172
		$user = $this->userSession->getUser()->getUID();
173
174
		// Get all the user favorites to create a submenu
175
		try {
176
			$favElements = $this->activityHelper->getFavoriteFilePaths($this->userSession->getUser()->getUID());
177
		} catch (\RuntimeException $e) {
178
			$favElements['folders'] = [];
179
		}
180
181
		$collapseClasses = '';
182
		if (count($favElements['folders']) > 0) {
183
			$collapseClasses = 'collapsible';
184
		}
185
186
		$favoritesSublistArray = Array();
187
188
		$navBarPositionPosition = 6;
189
		$currentCount           = 0;
190
		foreach ($favElements['folders'] as $dir) {
191
192
			$link         = $this->urlGenerator->linkToRoute('files.view.index', ['dir' => $dir, 'view' => 'files']);
193
			$sortingValue = ++$currentCount;
194
			$element      = [
195
				'id'                 => str_replace('/', '-', $dir),
196
				'view'               => 'files',
197
				'href'               => $link,
198
				'dir'                => $dir,
199
				'order'              => $navBarPositionPosition,
200
				'folderPosition'     => $sortingValue,
201
				'name'               => basename($dir),
202
				'icon'               => 'files',
203
				'quickaccesselement' => 'true'
204
			];
205
206
			array_push($favoritesSublistArray, $element);
207
			$navBarPositionPosition++;
208
		}
209
210
		$navItems = \OCA\Files\App::getNavigationManager()->getAll();
211
212
		// add the favorites entry in menu
213
		$navItems['favorites']['sublist'] = $favoritesSublistArray;
214
		$navItems['favorites']['classes'] = $collapseClasses;
215
216
		// parse every menu and add the expandedState user value
217
		foreach ($navItems as $key => $item) {
218
			if (isset($item['expandedState'])) {
219
				$navItems[$key]['defaultExpandedState'] = $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', $item['expandedState'], '0') === '1';
220
			}
221
		}
222
223
		$nav->assign('navigationItems', $navItems);
224
225
		$nav->assign('usage', \OC_Helper::humanFileSize($storageInfo['used']));
226
		if ($storageInfo['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED) {
227
			$totalSpace = $this->l10n->t('Unlimited');
228
		} else {
229
			$totalSpace = \OC_Helper::humanFileSize($storageInfo['total']);
230
		}
231
		$nav->assign('total_space', $totalSpace);
232
		$nav->assign('quota', $storageInfo['quota']);
233
		$nav->assign('usage_relative', $storageInfo['relative']);
234
235
		$contentItems = [];
236
237
		// render the container content for every navigation item
238
		foreach ($navItems as $item) {
239
			$content = '';
240
			if (isset($item['script'])) {
241
				$content = $this->renderScript($item['appname'], $item['script']);
242
			}
243
			// parse submenus
244
			if (isset($item['sublist'])) {
245
				foreach ($item['sublist'] as $subitem) {
246
					$subcontent = '';
247
					if (isset($subitem['script'])) {
248
						$subcontent = $this->renderScript($subitem['appname'], $subitem['script']);
249
					}
250
					$contentItems[$subitem['id']] = [
251
						'id'      => $subitem['id'],
252
						'content' => $subcontent
253
					];
254
				}
255
			}
256
			$contentItems[$item['id']] = [
257
				'id'      => $item['id'],
258
				'content' => $content
259
			];
260
		}
261
262
		$event = new GenericEvent(null, ['hiddenFields' => []]);
263
		$this->eventDispatcher->dispatch('OCA\Files::loadAdditionalScripts', $event);
264
265
		$params                                = [];
266
		$params['usedSpacePercent']            = (int) $storageInfo['relative'];
267
		$params['owner']                       = $storageInfo['owner'];
268
		$params['ownerDisplayName']            = $storageInfo['ownerDisplayName'];
269
		$params['isPublic']                    = false;
270
		$params['allowShareWithLink']          = $this->config->getAppValue('core', 'shareapi_allow_links', 'yes');
271
		$params['defaultFileSorting']          = $this->config->getUserValue($user, 'files', 'file_sorting', 'name');
272
		$params['defaultFileSortingDirection'] = $this->config->getUserValue($user, 'files', 'file_sorting_direction', 'asc');
273
		$params['showgridview']				   = $this->config->getUserValue($user, 'files', 'show_grid', false);
274
		$params['isIE']						   = \OCP\Util::isIE();
275
		$showHidden                            = (bool) $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', 'show_hidden', false);
276
		$params['showHiddenFiles']             = $showHidden ? 1 : 0;
277
		$params['fileNotFound']                = $fileNotFound ? 1 : 0;
278
		$params['appNavigation']               = $nav;
279
		$params['appContents']                 = $contentItems;
280
		$params['hiddenFields']                = $event->getArgument('hiddenFields');
281
282
		$response = new TemplateResponse(
283
			$this->appName,
284
			'index',
285
			$params
286
		);
287
		$policy = new ContentSecurityPolicy();
288
		$policy->addAllowedFrameDomain('\'self\'');
289
		$response->setContentSecurityPolicy($policy);
290
291
		return $response;
292
	}
293
294
	/**
295
	 * Redirects to the file list and highlight the given file id
296
	 *
297
	 * @param string $fileId file id to show
298
	 * @return RedirectResponse redirect response or not found response
299
	 * @throws \OCP\Files\NotFoundException
300
	 */
301
	private function redirectToFile($fileId) {
302
		$uid        = $this->userSession->getUser()->getUID();
303
		$baseFolder = $this->rootFolder->getUserFolder($uid);
304
		$files      = $baseFolder->getById($fileId);
0 ignored issues
show
Bug introduced by
$fileId of type string is incompatible with the type integer expected by parameter $id of OCP\Files\Folder::getById(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

304
		$files      = $baseFolder->getById(/** @scrutinizer ignore-type */ $fileId);
Loading history...
305
		$params     = [];
306
307
		if (empty($files) && $this->appManager->isEnabledForUser('files_trashbin')) {
308
			$baseFolder     = $this->rootFolder->get($uid . '/files_trashbin/files/');
309
			$files          = $baseFolder->getById($fileId);
0 ignored issues
show
Bug introduced by
The method getById() does not exist on OCP\Files\Node. Did you maybe mean getId()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

309
			/** @scrutinizer ignore-call */ 
310
   $files          = $baseFolder->getById($fileId);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
310
			$params['view'] = 'trashbin';
311
		}
312
313
		if (!empty($files)) {
314
			$file = current($files);
315
			if ($file instanceof Folder) {
316
				// set the full path to enter the folder
317
				$params['dir'] = $baseFolder->getRelativePath($file->getPath());
0 ignored issues
show
Bug introduced by
The method getRelativePath() does not exist on OCP\Files\Node. It seems like you code against a sub-type of OCP\Files\Node such as OCP\Files\Folder or OC\Files\Node\Folder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

317
				/** @scrutinizer ignore-call */ 
318
    $params['dir'] = $baseFolder->getRelativePath($file->getPath());
Loading history...
318
			} else {
319
				// set parent path as dir
320
				$params['dir'] = $baseFolder->getRelativePath($file->getParent()->getPath());
321
				// and scroll to the entry
322
				$params['scrollto'] = $file->getName();
323
			}
324
325
			return new RedirectResponse($this->urlGenerator->linkToRoute('files.view.index', $params));
326
		}
327
		throw new \OCP\Files\NotFoundException();
328
	}
329
}
330