FilesService::formatNodeData()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 8
dl 0
loc 12
rs 9.9666
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
 * Nextcloud - Gallery
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Olivier Paroz <[email protected]>
9
 *
10
 * @copyright Olivier Paroz 2017
11
 */
12
13
namespace OCA\Gallery\Service;
14
15
use OCP\Files\File;
0 ignored issues
show
Bug introduced by
The type OCP\Files\File was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use OCP\Files\Folder;
0 ignored issues
show
Bug introduced by
The type OCP\Files\Folder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use OCP\Files\Node;
0 ignored issues
show
Bug introduced by
The type OCP\Files\Node was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use OCP\Files\StorageNotAvailableException;
0 ignored issues
show
Bug introduced by
The type OCP\Files\StorageNotAvailableException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
20
/**
21
 * Contains various methods to retrieve information from the filesystem
22
 *
23
 * @package OCA\Gallery\Service
24
 */
25
abstract class FilesService extends Service {
26
27
	/** @var int */
28
	protected $virtualRootLevel = null;
29
	/** @var string[] */
30
	protected $features;
31
	/** @var string[] */
32
	protected $ignoreAlbumStrings = ['.nomedia', '.noimage'];
33
34
	/**
35
	 * Retrieves all files and sub-folders contained in a folder
36
	 *
37
	 * If we can't find anything in the current folder, we throw an exception as there is no point
38
	 * in doing any more work, but if we're looking at a sub-folder, we return an empty array so
39
	 * that it can be simply ignored
40
	 *
41
	 * @param Folder $folder
42
	 * @param int $subDepth
43
	 *
44
	 * @return array
45
	 */
46
	protected function getNodes($folder, $subDepth) {
47
		try {
48
			$nodes = $folder->getDirectoryListing();
49
		} catch (\Exception $exception) {
50
			$nodes = $this->recoverFromGetNodesError($subDepth, $exception);
51
		}
52
53
		return $nodes;
54
	}
55
56
	/**
57
	 * Determines if the files are hosted locally (shared or not) and can be used by the preview
58
	 * system
59
	 *
60
	 * isMounted() doesn't include externally hosted shares, so we need to exclude those from the
61
	 * non-mounted nodes
62
	 *
63
	 * @param Node $node
64
	 *
65
	 * @return bool
66
	 */
67
	protected function isAllowedAndAvailable($node) {
68
		try {
69
			return $node && $this->isAllowed($node) && $this->isAvailable($node);
70
		} catch (\Exception $exception) {
71
			$message = 'The folder is not available: ' . $exception->getMessage();
72
			$this->logger->error($message);
73
74
			return false;
75
		}
76
	}
77
78
	/**
79
	 * Returns the node type, either 'dir' or 'file'
80
	 *
81
	 * If there is a problem, we return an empty string so that the node can be ignored
82
	 *
83
	 * @param Node $node
84
	 *
85
	 * @return string
86
	 */
87
	protected function getNodeType($node) {
88
		try {
89
			$nodeType = $node->getType();
90
		} catch (\Exception $exception) {
91
			return '';
92
		}
93
94
		return $nodeType;
95
	}
96
97
	/**
98
	 * Returns various information about a node
99
	 *
100
	 * @param Node|File|Folder $node
101
	 *
102
	 * @return array<string,int|string|bool|array<string,int|string>>
103
	 */
104
	protected function getNodeData($node) {
105
		$imagePath = $this->environment->getPathFromVirtualRoot($node);
106
		$nodeId = $node->getId();
107
		$mTime = $node->getMTime();
108
		$etag = $node->getEtag();
109
		$size = $node->getSize();
110
		$sharedWithUser = $node->isShared();
111
		$ownerData = $this->getOwnerData($node);
112
		$permissions = $node->getPermissions();
113
114
		//$this->logger->debug("Image path : {var1}", ['var1' => $imagePath]);
115
116
		return $this->formatNodeData(
117
			$imagePath, $nodeId, $mTime, $etag, $size, $sharedWithUser, $ownerData, $permissions
118
		);
119
	}
120
121
	/**
122
	 * Returns various information about a folder
123
	 *
124
	 * @param Folder $node
125
	 *
126
	 * @return array<string,int|string|bool|array<string,int|string>>
127
	 */
128
	protected function getFolderData($node) {
129
		$folderData = $this->getNodeData($node);
130
		$folderData['freespace'] = $node->getFreeSpace();
131
132
		return $folderData;
133
	}
134
135
	/**
136
	 * Returns the node if it's a folder we have access to
137
	 *
138
	 * @param Folder $node
139
	 * @param string $nodeType
140
	 *
141
	 * @return array|Folder
142
	 */
143
	protected function getAllowedSubFolder($node, $nodeType) {
144
		if ($nodeType === 'dir') {
145
			/** @var Folder $node */
146
			try {
147
				foreach ($this->ignoreAlbumStrings as $ignoreAlbum) {
148
					if ($node->nodeExists($ignoreAlbum)) {
149
						return [];
150
					}
151
				}
152
				return [$node];
153
			} catch (StorageNotAvailableException $e) {
154
				return [];
155
			}
156
		}
157
158
		return [];
159
	}
160
161
	/**
162
	 * Determines if we've reached the root folder
163
	 *
164
	 * @param Folder $folder
165
	 * @param int $level
166
	 *
167
	 * @return bool
168
	 */
169
	protected function isRootFolder($folder, $level) {
170
		$isRootFolder = false;
171
		$rootFolder = $this->environment->getVirtualRootFolder();
172
		if (rtrim($folder->getPath(), '/') === rtrim($rootFolder->getPath(), '/')) {
173
			$isRootFolder = true;
174
		}
175
		$virtualRootFolder = $this->environment->getPathFromVirtualRoot($folder);
176
		if (empty($virtualRootFolder)) {
177
			$this->virtualRootLevel = $level;
178
		}
179
180
		return $isRootFolder;
181
	}
182
183
	/**
184
	 * Throws an exception if this problem occurs in the current folder, otherwise just ignores the
185
	 * sub-folder
186
	 *
187
	 * @param int $subDepth
188
	 * @param \Exception $exception
189
	 *
190
	 * @return array
191
	 * @throws NotFoundServiceException
192
	 */
193
	private function recoverFromGetNodesError($subDepth, $exception) {
194
		if ($subDepth === 0) {
195
			throw new NotFoundServiceException($exception->getMessage());
196
		}
197
198
		return [];
199
	}
200
201
	/**
202
	 * Determines if we can consider the node mounted locally or if it's been authorised to be
203
	 * scanned
204
	 *
205
	 * @param Node $node
206
	 *
207
	 * @return bool
208
	 */
209
	private function isAllowed($node) {
210
		$allowed = true;
211
		if ($this->isExternalShare($node)) {
212
			$allowed = $this->isExternalShareAllowed();
213
		}
214
215
		if ($node->isMounted()) {
216
			$mount = $node->getMountPoint();
217
			$allowed = $mount && $mount->getOption('previews', true);
218
		}
219
220
		return $allowed;
221
	}
222
223
	/**
224
	 * Determines if the node is available, as in readable
225
	 *
226
	 * @todo Test to see by how much using file_exists slows things down
227
	 *
228
	 * @param Node $node
229
	 *
230
	 * @return bool
231
	 */
232
	private function isAvailable($node) {
233
		return $node->isReadable();
234
	}
235
236
	/**
237
	 * Determines if the user has allowed the use of external shares
238
	 *
239
	 * @return bool
240
	 */
241
	private function isExternalShareAllowed() {
242
		$rootFolder = $this->environment->getVirtualRootFolder();
243
244
		return ($this->isExternalShare($rootFolder)
245
				|| in_array('external_shares', $this->features));
246
	}
247
248
	/**
249
	 * Determines if the node is a share which is hosted externally
250
	 *
251
	 *
252
	 * @param Node $node
253
	 *
254
	 * @return bool
255
	 */
256
	private function isExternalShare($node) {
257
		$sid = explode(
258
			':',
259
			$node->getStorage()
260
				 ->getId()
261
		);
262
263
		return ($sid[0] === 'shared' && $sid[2][0] !== '/');
264
	}
265
266
	/**
267
	 * Returns what we known about the owner of a node
268
	 *
269
	 * @param Node $node
270
	 *
271
	 * @return null|array<string,int|string>
272
	 */
273
	private function getOwnerData($node) {
274
		$owner = $node->getOwner();
275
		$ownerData = [];
276
		if ($owner) {
277
			$ownerData = [
278
				'uid'         => $owner->getUID(),
279
				'displayname' => $owner->getDisplayName()
280
			];
281
		}
282
283
		return $ownerData;
284
	}
285
286
	/**
287
	 * Returns an array containing information about a node
288
	 *
289
	 * @param string $imagePath
290
	 * @param int $nodeId
291
	 * @param int $mTime
292
	 * @param string $etag
293
	 * @param int $size
294
	 * @param bool $sharedWithUser
295
	 * @param array <string,int|string> $ownerData
0 ignored issues
show
Documentation Bug introduced by
The doc comment <string,int|string> at position 0 could not be parsed: Unknown type name '<' at position 0 in <string,int|string>.
Loading history...
296
	 * @param int $permissions
297
	 *
298
	 * @return array
299
	 */
300
	private function formatNodeData(
301
		$imagePath, $nodeId, $mTime, $etag, $size, $sharedWithUser, $ownerData, $permissions
302
	) {
303
		return [
304
			'path'           => $imagePath,
305
			'nodeid'         => $nodeId,
306
			'mtime'          => $mTime,
307
			'etag'           => $etag,
308
			'size'           => $size,
309
			'sharedwithuser' => $sharedWithUser,
310
			'owner'          => $ownerData,
311
			'permissions'    => $permissions
312
		];
313
	}
314
315
}
316