LazyFolder   F
last analyzed

Complexity

Total Complexity 74

Size/Duplication

Total Lines 489
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 90
dl 0
loc 489
rs 2.48
c 0
b 0
f 0
wmc 74

64 Methods

Rating   Name   Duplication   Size   Complexity  
A removeListener() 0 2 1
A getInternalPath() 0 2 1
A getRelativePath() 0 2 1
A search() 0 2 1
A rename() 0 2 1
A __construct() 0 3 1
A getRecent() 0 2 1
A getById() 0 2 1
A getSize() 0 2 1
A getExtension() 0 2 1
A isEncrypted() 0 2 1
A getPermissions() 0 5 2
A getEtag() 0 2 1
A emit() 0 2 1
A getStorage() 0 2 1
A copy() 0 2 1
A delete() 0 2 1
A listen() 0 2 1
A unlock() 0 2 1
A getType() 0 5 2
A getId() 0 2 1
A unMount() 0 2 1
A getOwner() 0 2 1
A isReadable() 0 5 2
A lock() 0 2 1
A isShareable() 0 5 2
A newFolder() 0 2 1
A getMimetype() 0 5 2
A getMountsIn() 0 2 1
A isSubNode() 0 2 1
A getPath() 0 5 2
A isUpdateable() 0 5 2
A getMountByNumericStorageId() 0 2 1
A getMount() 0 2 1
A getNonExistingName() 0 2 1
A isMounted() 0 2 1
A newFile() 0 2 1
A getMountPoint() 0 2 1
A get() 0 2 1
A isShared() 0 2 1
A getDirectoryListing() 0 2 1
A getMimePart() 0 6 2
A nodeExists() 0 2 1
A getChecksum() 0 2 1
A getCreationTime() 0 2 1
A searchByMime() 0 2 1
A __call() 0 6 2
A searchByTag() 0 2 1
A mount() 0 2 1
A getFreeSpace() 0 2 1
A getUploadTime() 0 2 1
A isCreatable() 0 2 1
A getMTime() 0 2 1
A getMountByStorageId() 0 2 1
A move() 0 2 1
A getName() 0 2 1
A changeLock() 0 2 1
A getParent() 0 2 1
A getUser() 0 2 1
A touch() 0 2 1
A getUserFolder() 0 2 1
A stat() 0 2 1
A getFullPath() 0 2 1
A isDeletable() 0 5 2

How to fix   Complexity   

Complex Class

Complex classes like LazyFolder often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use LazyFolder, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @copyright Copyright (c) 2020 Robin Appelman <[email protected]>
7
 *
8
 * @author Robin Appelman <[email protected]>
9
 *
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OC\Files\Node;
28
29
use OC\Files\Utils\PathHelper;
30
use OCP\Files\Folder;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, OC\Files\Node\Folder. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
31
use OCP\Constants;
32
33
/**
34
 * Class LazyFolder
35
 *
36
 * This is a lazy wrapper around a folder. So only
37
 * once it is needed this will get initialized.
38
 *
39
 * @package OC\Files\Node
40
 */
41
class LazyFolder implements Folder {
42
	/** @var \Closure(): Folder */
43
	private $folderClosure;
44
45
	/** @var LazyFolder | null */
46
	protected $folder = null;
47
48
	protected array $data;
49
50
	/**
51
	 * LazyFolder constructor.
52
	 *
53
	 * @param \Closure(): Folder $folderClosure
54
	 */
55
	public function __construct(\Closure $folderClosure, array $data = []) {
56
		$this->folderClosure = $folderClosure;
57
		$this->data = $data;
58
	}
59
60
	/**
61
	 * Magic method to first get the real rootFolder and then
62
	 * call $method with $args on it
63
	 *
64
	 * @param $method
65
	 * @param $args
66
	 * @return mixed
67
	 */
68
	public function __call($method, $args) {
69
		if ($this->folder === null) {
70
			$this->folder = call_user_func($this->folderClosure);
71
		}
72
73
		return call_user_func_array([$this->folder, $method], $args);
74
	}
75
76
	/**
77
	 * @inheritDoc
78
	 */
79
	public function getUser() {
80
		return $this->__call(__FUNCTION__, func_get_args());
81
	}
82
83
	/**
84
	 * @inheritDoc
85
	 */
86
	public function listen($scope, $method, callable $callback) {
87
		$this->__call(__FUNCTION__, func_get_args());
88
	}
89
90
	/**
91
	 * @inheritDoc
92
	 */
93
	public function removeListener($scope = null, $method = null, callable $callback = null) {
94
		$this->__call(__FUNCTION__, func_get_args());
95
	}
96
97
	/**
98
	 * @inheritDoc
99
	 */
100
	public function emit($scope, $method, $arguments = []) {
101
		$this->__call(__FUNCTION__, func_get_args());
102
	}
103
104
	/**
105
	 * @inheritDoc
106
	 */
107
	public function mount($storage, $mountPoint, $arguments = []) {
108
		$this->__call(__FUNCTION__, func_get_args());
109
	}
110
111
	/**
112
	 * @inheritDoc
113
	 */
114
	public function getMount($mountPoint) {
115
		return $this->__call(__FUNCTION__, func_get_args());
116
	}
117
118
	/**
119
	 * @inheritDoc
120
	 */
121
	public function getMountsIn($mountPoint) {
122
		return $this->__call(__FUNCTION__, func_get_args());
123
	}
124
125
	/**
126
	 * @inheritDoc
127
	 */
128
	public function getMountByStorageId($storageId) {
129
		return $this->__call(__FUNCTION__, func_get_args());
130
	}
131
132
	/**
133
	 * @inheritDoc
134
	 */
135
	public function getMountByNumericStorageId($numericId) {
136
		return $this->__call(__FUNCTION__, func_get_args());
137
	}
138
139
	/**
140
	 * @inheritDoc
141
	 */
142
	public function unMount($mount) {
143
		$this->__call(__FUNCTION__, func_get_args());
144
	}
145
146
	/**
147
	 * @inheritDoc
148
	 */
149
	public function get($path) {
150
		return $this->__call(__FUNCTION__, func_get_args());
151
	}
152
153
	/**
154
	 * @inheritDoc
155
	 */
156
	public function rename($targetPath) {
157
		return $this->__call(__FUNCTION__, func_get_args());
158
	}
159
160
	/**
161
	 * @inheritDoc
162
	 */
163
	public function delete() {
164
		return $this->__call(__FUNCTION__, func_get_args());
165
	}
166
167
	/**
168
	 * @inheritDoc
169
	 */
170
	public function copy($targetPath) {
171
		return $this->__call(__FUNCTION__, func_get_args());
172
	}
173
174
	/**
175
	 * @inheritDoc
176
	 */
177
	public function touch($mtime = null) {
178
		$this->__call(__FUNCTION__, func_get_args());
179
	}
180
181
	/**
182
	 * @inheritDoc
183
	 */
184
	public function getStorage() {
185
		return $this->__call(__FUNCTION__, func_get_args());
186
	}
187
188
	/**
189
	 * @inheritDoc
190
	 */
191
	public function getPath() {
192
		if (isset($this->data['path'])) {
193
			return $this->data['path'];
194
		}
195
		return $this->__call(__FUNCTION__, func_get_args());
196
	}
197
198
	/**
199
	 * @inheritDoc
200
	 */
201
	public function getInternalPath() {
202
		return $this->__call(__FUNCTION__, func_get_args());
203
	}
204
205
	/**
206
	 * @inheritDoc
207
	 */
208
	public function getId() {
209
		return $this->__call(__FUNCTION__, func_get_args());
210
	}
211
212
	/**
213
	 * @inheritDoc
214
	 */
215
	public function stat() {
216
		return $this->__call(__FUNCTION__, func_get_args());
217
	}
218
219
	/**
220
	 * @inheritDoc
221
	 */
222
	public function getMTime() {
223
		return $this->__call(__FUNCTION__, func_get_args());
224
	}
225
226
	/**
227
	 * @inheritDoc
228
	 */
229
	public function getSize($includeMounts = true): int|float {
230
		return $this->__call(__FUNCTION__, func_get_args());
231
	}
232
233
	/**
234
	 * @inheritDoc
235
	 */
236
	public function getEtag() {
237
		return $this->__call(__FUNCTION__, func_get_args());
238
	}
239
240
	/**
241
	 * @inheritDoc
242
	 */
243
	public function getPermissions() {
244
		if (isset($this->data['permissions'])) {
245
			return $this->data['permissions'];
246
		}
247
		return $this->__call(__FUNCTION__, func_get_args());
248
	}
249
250
	/**
251
	 * @inheritDoc
252
	 */
253
	public function isReadable() {
254
		if (isset($this->data['permissions'])) {
255
			return ($this->data['permissions'] & Constants::PERMISSION_READ) == Constants::PERMISSION_READ;
256
		}
257
		return $this->__call(__FUNCTION__, func_get_args());
258
	}
259
260
	/**
261
	 * @inheritDoc
262
	 */
263
	public function isUpdateable() {
264
		if (isset($this->data['permissions'])) {
265
			return ($this->data['permissions'] & Constants::PERMISSION_UPDATE) == Constants::PERMISSION_UPDATE;
266
		}
267
		return $this->__call(__FUNCTION__, func_get_args());
268
	}
269
270
	/**
271
	 * @inheritDoc
272
	 */
273
	public function isDeletable() {
274
		if (isset($this->data['permissions'])) {
275
			return ($this->data['permissions'] & Constants::PERMISSION_DELETE) == Constants::PERMISSION_DELETE;
276
		}
277
		return $this->__call(__FUNCTION__, func_get_args());
278
	}
279
280
	/**
281
	 * @inheritDoc
282
	 */
283
	public function isShareable() {
284
		if (isset($this->data['permissions'])) {
285
			return ($this->data['permissions'] & Constants::PERMISSION_SHARE) == Constants::PERMISSION_SHARE;
286
		}
287
		return $this->__call(__FUNCTION__, func_get_args());
288
	}
289
290
	/**
291
	 * @inheritDoc
292
	 */
293
	public function getParent() {
294
		return $this->__call(__FUNCTION__, func_get_args());
295
	}
296
297
	/**
298
	 * @inheritDoc
299
	 */
300
	public function getName() {
301
		return $this->__call(__FUNCTION__, func_get_args());
302
	}
303
304
	/**
305
	 * @inheritDoc
306
	 */
307
	public function getUserFolder($userId) {
308
		return $this->__call(__FUNCTION__, func_get_args());
309
	}
310
311
	/**
312
	 * @inheritDoc
313
	 */
314
	public function getMimetype() {
315
		if (isset($this->data['mimetype'])) {
316
			return $this->data['mimetype'];
317
		}
318
		return $this->__call(__FUNCTION__, func_get_args());
319
	}
320
321
	/**
322
	 * @inheritDoc
323
	 */
324
	public function getMimePart() {
325
		if (isset($this->data['mimetype'])) {
326
			[$part,] = explode('/', $this->data['mimetype']);
327
			return $part;
328
		}
329
		return $this->__call(__FUNCTION__, func_get_args());
330
	}
331
332
	/**
333
	 * @inheritDoc
334
	 */
335
	public function isEncrypted() {
336
		return $this->__call(__FUNCTION__, func_get_args());
337
	}
338
339
	/**
340
	 * @inheritDoc
341
	 */
342
	public function getType() {
343
		if (isset($this->data['type'])) {
344
			return $this->data['type'];
345
		}
346
		return $this->__call(__FUNCTION__, func_get_args());
347
	}
348
349
	/**
350
	 * @inheritDoc
351
	 */
352
	public function isShared() {
353
		return $this->__call(__FUNCTION__, func_get_args());
354
	}
355
356
	/**
357
	 * @inheritDoc
358
	 */
359
	public function isMounted() {
360
		return $this->__call(__FUNCTION__, func_get_args());
361
	}
362
363
	/**
364
	 * @inheritDoc
365
	 */
366
	public function getMountPoint() {
367
		return $this->__call(__FUNCTION__, func_get_args());
368
	}
369
370
	/**
371
	 * @inheritDoc
372
	 */
373
	public function getOwner() {
374
		return $this->__call(__FUNCTION__, func_get_args());
375
	}
376
377
	/**
378
	 * @inheritDoc
379
	 */
380
	public function getChecksum() {
381
		return $this->__call(__FUNCTION__, func_get_args());
382
	}
383
384
	public function getExtension(): string {
385
		return $this->__call(__FUNCTION__, func_get_args());
386
	}
387
388
	/**
389
	 * @inheritDoc
390
	 */
391
	public function getFullPath($path) {
392
		return $this->__call(__FUNCTION__, func_get_args());
393
	}
394
395
	/**
396
	 * @inheritDoc
397
	 */
398
	public function isSubNode($node) {
399
		return $this->__call(__FUNCTION__, func_get_args());
400
	}
401
402
	/**
403
	 * @inheritDoc
404
	 */
405
	public function getDirectoryListing() {
406
		return $this->__call(__FUNCTION__, func_get_args());
407
	}
408
409
	/**
410
	 * @inheritDoc
411
	 */
412
	public function nodeExists($path) {
413
		return $this->__call(__FUNCTION__, func_get_args());
414
	}
415
416
	/**
417
	 * @inheritDoc
418
	 */
419
	public function newFolder($path) {
420
		return $this->__call(__FUNCTION__, func_get_args());
421
	}
422
423
	/**
424
	 * @inheritDoc
425
	 */
426
	public function newFile($path, $content = null) {
427
		return $this->__call(__FUNCTION__, func_get_args());
428
	}
429
430
	/**
431
	 * @inheritDoc
432
	 */
433
	public function search($query) {
434
		return $this->__call(__FUNCTION__, func_get_args());
435
	}
436
437
	/**
438
	 * @inheritDoc
439
	 */
440
	public function searchByMime($mimetype) {
441
		return $this->__call(__FUNCTION__, func_get_args());
442
	}
443
444
	/**
445
	 * @inheritDoc
446
	 */
447
	public function searchByTag($tag, $userId) {
448
		return $this->__call(__FUNCTION__, func_get_args());
449
	}
450
451
	/**
452
	 * @inheritDoc
453
	 */
454
	public function getById($id) {
455
		return $this->__call(__FUNCTION__, func_get_args());
456
	}
457
458
	/**
459
	 * @inheritDoc
460
	 */
461
	public function getFreeSpace() {
462
		return $this->__call(__FUNCTION__, func_get_args());
463
	}
464
465
	/**
466
	 * @inheritDoc
467
	 */
468
	public function isCreatable() {
469
		return $this->__call(__FUNCTION__, func_get_args());
470
	}
471
472
	/**
473
	 * @inheritDoc
474
	 */
475
	public function getNonExistingName($name) {
476
		return $this->__call(__FUNCTION__, func_get_args());
477
	}
478
479
	/**
480
	 * @inheritDoc
481
	 */
482
	public function move($targetPath) {
483
		return $this->__call(__FUNCTION__, func_get_args());
484
	}
485
486
	/**
487
	 * @inheritDoc
488
	 */
489
	public function lock($type) {
490
		return $this->__call(__FUNCTION__, func_get_args());
491
	}
492
493
	/**
494
	 * @inheritDoc
495
	 */
496
	public function changeLock($targetType) {
497
		return $this->__call(__FUNCTION__, func_get_args());
498
	}
499
500
	/**
501
	 * @inheritDoc
502
	 */
503
	public function unlock($type) {
504
		return $this->__call(__FUNCTION__, func_get_args());
505
	}
506
507
	/**
508
	 * @inheritDoc
509
	 */
510
	public function getRecent($limit, $offset = 0) {
511
		return $this->__call(__FUNCTION__, func_get_args());
512
	}
513
514
	/**
515
	 * @inheritDoc
516
	 */
517
	public function getCreationTime(): int {
518
		return $this->__call(__FUNCTION__, func_get_args());
519
	}
520
521
	/**
522
	 * @inheritDoc
523
	 */
524
	public function getUploadTime(): int {
525
		return $this->__call(__FUNCTION__, func_get_args());
526
	}
527
528
	public function getRelativePath($path) {
529
		return PathHelper::getRelativePath($this->getPath(), $path);
530
	}
531
}
532