Passed
Push — master ( 5cdc85...37718d )
by Morris
38:53 queued 21:57
created

OC_Helper   F

Complexity

Total Complexity 112

Size/Duplication

Total Lines 573
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 264
dl 0
loc 573
rs 2
c 1
b 0
f 0
wmc 112

20 Methods

Rating   Name   Duplication   Size   Complexity  
A uploadLimit() 0 10 5
A findBinaryPath() 0 14 3
A computerFileSize() 0 31 4
A mb_array_change_key_case() 0 7 3
B rmdirr() 0 30 9
A is_function_enabled() 0 16 6
A freeSpace() 0 7 3
B canExecute() 0 27 8
A getGlobalStorageInfo() 0 23 5
B buildNotExistingFileNameForView() 0 38 7
A maxUploadFilesize() 0 5 3
B copyr() 0 13 8
A recursiveArraySearch() 0 13 6
A getFileTemplateManager() 0 5 2
A buildNotExistingFileName() 0 3 1
B humanFileSize() 0 26 7
F getStorageInfo() 0 78 18
A isReadOnlyConfigEnabled() 0 2 1
B streamCopy() 0 24 8
A phpFileSize() 0 17 5

How to fix   Complexity   

Complex Class

Complex classes like OC_Helper 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 OC_Helper, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Ardinis <[email protected]>
6
 * @author Arthur Schiwon <[email protected]>
7
 * @author Bart Visscher <[email protected]>
8
 * @author Björn Schießle <[email protected]>
9
 * @author Christopher Schäpers <[email protected]>
10
 * @author Clark Tomlinson <[email protected]>
11
 * @author Fabian Henze <[email protected]>
12
 * @author Felix Moeller <[email protected]>
13
 * @author Jakob Sack <[email protected]>
14
 * @author Jan-Christoph Borchardt <[email protected]>
15
 * @author Joas Schilling <[email protected]>
16
 * @author Jörn Friedrich Dreyer <[email protected]>
17
 * @author Lukas Reschke <[email protected]>
18
 * @author Michael Gapczynski <[email protected]>
19
 * @author Morris Jobke <[email protected]>
20
 * @author Olivier Paroz <[email protected]>
21
 * @author Pellaeon Lin <[email protected]>
22
 * @author RealRancor <[email protected]>
23
 * @author Robin Appelman <[email protected]>
24
 * @author Robin McCorkell <[email protected]>
25
 * @author Roeland Jago Douma <[email protected]>
26
 * @author Simon Könnecke <[email protected]>
27
 * @author Thomas Müller <[email protected]>
28
 * @author Thomas Tanghus <[email protected]>
29
 * @author Vincent Petry <[email protected]>
30
 *
31
 * @license AGPL-3.0
32
 *
33
 * This code is free software: you can redistribute it and/or modify
34
 * it under the terms of the GNU Affero General Public License, version 3,
35
 * as published by the Free Software Foundation.
36
 *
37
 * This program is distributed in the hope that it will be useful,
38
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40
 * GNU Affero General Public License for more details.
41
 *
42
 * You should have received a copy of the GNU Affero General Public License, version 3,
43
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
44
 *
45
 */
46
use Symfony\Component\Process\ExecutableFinder;
47
48
/**
49
 * Collection of useful functions
50
 */
51
class OC_Helper {
52
	private static $templateManager;
53
54
	/**
55
	 * Make a human file size
56
	 * @param int $bytes file size in bytes
57
	 * @return string a human readable file size
58
	 *
59
	 * Makes 2048 to 2 kB.
60
	 */
61
	public static function humanFileSize($bytes) {
62
		if ($bytes < 0) {
63
			return "?";
64
		}
65
		if ($bytes < 1024) {
66
			return "$bytes B";
67
		}
68
		$bytes = round($bytes / 1024, 0);
69
		if ($bytes < 1024) {
70
			return "$bytes KB";
71
		}
72
		$bytes = round($bytes / 1024, 1);
73
		if ($bytes < 1024) {
74
			return "$bytes MB";
75
		}
76
		$bytes = round($bytes / 1024, 1);
77
		if ($bytes < 1024) {
78
			return "$bytes GB";
79
		}
80
		$bytes = round($bytes / 1024, 1);
81
		if ($bytes < 1024) {
82
			return "$bytes TB";
83
		}
84
85
		$bytes = round($bytes / 1024, 1);
86
		return "$bytes PB";
87
	}
88
89
	/**
90
	 * Make a php file size
91
	 * @param int $bytes file size in bytes
92
	 * @return string a php parseable file size
93
	 *
94
	 * Makes 2048 to 2k and 2^41 to 2048G
95
	 */
96
	public static function phpFileSize($bytes) {
97
		if ($bytes < 0) {
98
			return "?";
99
		}
100
		if ($bytes < 1024) {
101
			return $bytes . "B";
102
		}
103
		$bytes = round($bytes / 1024, 1);
104
		if ($bytes < 1024) {
105
			return $bytes . "K";
106
		}
107
		$bytes = round($bytes / 1024, 1);
108
		if ($bytes < 1024) {
109
			return $bytes . "M";
110
		}
111
		$bytes = round($bytes / 1024, 1);
112
		return $bytes . "G";
113
	}
114
115
	/**
116
	 * Make a computer file size
117
	 * @param string $str file size in human readable format
118
	 * @return float|bool a file size in bytes
119
	 *
120
	 * Makes 2kB to 2048.
121
	 *
122
	 * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418
123
	 */
124
	public static function computerFileSize($str) {
125
		$str = strtolower($str);
126
		if (is_numeric($str)) {
127
			return (float)$str;
128
		}
129
130
		$bytes_array = array(
131
			'b' => 1,
132
			'k' => 1024,
133
			'kb' => 1024,
134
			'mb' => 1024 * 1024,
135
			'm' => 1024 * 1024,
136
			'gb' => 1024 * 1024 * 1024,
137
			'g' => 1024 * 1024 * 1024,
138
			'tb' => 1024 * 1024 * 1024 * 1024,
139
			't' => 1024 * 1024 * 1024 * 1024,
140
			'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
141
			'p' => 1024 * 1024 * 1024 * 1024 * 1024,
142
		);
143
144
		$bytes = (float)$str;
145
146
		if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) {
147
			$bytes *= $bytes_array[$matches[1]];
148
		} else {
149
			return false;
150
		}
151
152
		$bytes = round($bytes);
153
154
		return $bytes;
155
	}
156
157
	/**
158
	 * Recursive copying of folders
159
	 * @param string $src source folder
160
	 * @param string $dest target folder
161
	 *
162
	 */
163
	static function copyr($src, $dest) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
164
		if (is_dir($src)) {
165
			if (!is_dir($dest)) {
166
				mkdir($dest);
167
			}
168
			$files = scandir($src);
169
			foreach ($files as $file) {
170
				if ($file != "." && $file != "..") {
171
					self::copyr("$src/$file", "$dest/$file");
172
				}
173
			}
174
		} elseif (file_exists($src) && !\OC\Files\Filesystem::isFileBlacklisted($src)) {
175
			copy($src, $dest);
176
		}
177
	}
178
179
	/**
180
	 * Recursive deletion of folders
181
	 * @param string $dir path to the folder
182
	 * @param bool $deleteSelf if set to false only the content of the folder will be deleted
183
	 * @return bool
184
	 */
185
	static function rmdirr($dir, $deleteSelf = true) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
186
		if (is_dir($dir)) {
187
			$files = new RecursiveIteratorIterator(
188
				new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
189
				RecursiveIteratorIterator::CHILD_FIRST
190
			);
191
192
			foreach ($files as $fileInfo) {
193
				/** @var SplFileInfo $fileInfo */
194
				if ($fileInfo->isLink()) {
195
					unlink($fileInfo->getPathname());
196
				} else if ($fileInfo->isDir()) {
197
					rmdir($fileInfo->getRealPath());
198
				} else {
199
					unlink($fileInfo->getRealPath());
200
				}
201
			}
202
			if ($deleteSelf) {
203
				rmdir($dir);
204
			}
205
		} elseif (file_exists($dir)) {
206
			if ($deleteSelf) {
207
				unlink($dir);
208
			}
209
		}
210
		if (!$deleteSelf) {
211
			return true;
212
		}
213
214
		return !file_exists($dir);
215
	}
216
217
	/**
218
	 * @return \OC\Files\Type\TemplateManager
219
	 */
220
	static public function getFileTemplateManager() {
221
		if (!self::$templateManager) {
222
			self::$templateManager = new \OC\Files\Type\TemplateManager();
223
		}
224
		return self::$templateManager;
225
	}
226
227
	/**
228
	 * detect if a given program is found in the search PATH
229
	 *
230
	 * @param string $name
231
	 * @param bool $path
232
	 * @internal param string $program name
233
	 * @internal param string $optional search path, defaults to $PATH
234
	 * @return bool    true if executable program found in path
235
	 */
236
	public static function canExecute($name, $path = false) {
237
		// path defaults to PATH from environment if not set
238
		if ($path === false) {
239
			$path = getenv("PATH");
240
		}
241
		// we look for an executable file of that name
242
		$exts = [""];
243
		$check_fn = "is_executable";
244
		// Default check will be done with $path directories :
245
		$dirs = explode(PATH_SEPARATOR, $path);
0 ignored issues
show
Bug introduced by
It seems like $path can also be of type true; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

245
		$dirs = explode(PATH_SEPARATOR, /** @scrutinizer ignore-type */ $path);
Loading history...
246
		// WARNING : We have to check if open_basedir is enabled :
247
		$obd = OC::$server->getIniWrapper()->getString('open_basedir');
248
		if ($obd != "none") {
249
			$obd_values = explode(PATH_SEPARATOR, $obd);
250
			if (count($obd_values) > 0 and $obd_values[0]) {
251
				// open_basedir is in effect !
252
				// We need to check if the program is in one of these dirs :
253
				$dirs = $obd_values;
254
			}
255
		}
256
		foreach ($dirs as $dir) {
257
			foreach ($exts as $ext) {
258
				if ($check_fn("$dir/$name" . $ext))
259
					return true;
260
			}
261
		}
262
		return false;
263
	}
264
265
	/**
266
	 * copy the contents of one stream to another
267
	 *
268
	 * @param resource $source
269
	 * @param resource $target
270
	 * @return array the number of bytes copied and result
271
	 */
272
	public static function streamCopy($source, $target) {
273
		if (!$source or !$target) {
0 ignored issues
show
introduced by
$source is of type resource, thus it always evaluated to false.
Loading history...
274
			return array(0, false);
275
		}
276
		$bufSize = 8192;
277
		$result = true;
278
		$count = 0;
279
		while (!feof($source)) {
280
			$buf = fread($source, $bufSize);
281
			$bytesWritten = fwrite($target, $buf);
282
			if ($bytesWritten !== false) {
283
				$count += $bytesWritten;
284
			}
285
			// note: strlen is expensive so only use it when necessary,
286
			// on the last block
287
			if ($bytesWritten === false
288
				|| ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
289
			) {
290
				// write error, could be disk full ?
291
				$result = false;
292
				break;
293
			}
294
		}
295
		return array($count, $result);
296
	}
297
298
	/**
299
	 * Adds a suffix to the name in case the file exists
300
	 *
301
	 * @param string $path
302
	 * @param string $filename
303
	 * @return string
304
	 */
305
	public static function buildNotExistingFileName($path, $filename) {
306
		$view = \OC\Files\Filesystem::getView();
307
		return self::buildNotExistingFileNameForView($path, $filename, $view);
308
	}
309
310
	/**
311
	 * Adds a suffix to the name in case the file exists
312
	 *
313
	 * @param string $path
314
	 * @param string $filename
315
	 * @return string
316
	 */
317
	public static function buildNotExistingFileNameForView($path, $filename, \OC\Files\View $view) {
318
		if ($path === '/') {
319
			$path = '';
320
		}
321
		if ($pos = strrpos($filename, '.')) {
322
			$name = substr($filename, 0, $pos);
323
			$ext = substr($filename, $pos);
324
		} else {
325
			$name = $filename;
326
			$ext = '';
327
		}
328
329
		$newpath = $path . '/' . $filename;
330
		if ($view->file_exists($newpath)) {
331
			if (preg_match_all('/\((\d+)\)/', $name, $matches, PREG_OFFSET_CAPTURE)) {
332
				//Replace the last "(number)" with "(number+1)"
333
				$last_match = count($matches[0]) - 1;
334
				$counter = $matches[1][$last_match][0] + 1;
335
				$offset = $matches[0][$last_match][1];
336
				$match_length = strlen($matches[0][$last_match][0]);
337
			} else {
338
				$counter = 2;
339
				$match_length = 0;
340
				$offset = false;
341
			}
342
			do {
343
				if ($offset) {
344
					//Replace the last "(number)" with "(number+1)"
345
					$newname = substr_replace($name, '(' . $counter . ')', $offset, $match_length);
346
				} else {
347
					$newname = $name . ' (' . $counter . ')';
348
				}
349
				$newpath = $path . '/' . $newname . $ext;
350
				$counter++;
351
			} while ($view->file_exists($newpath));
352
		}
353
354
		return $newpath;
355
	}
356
357
	/**
358
	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
359
	 *
360
	 * @param array $input The array to work on
361
	 * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default)
362
	 * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8
363
	 * @return array
364
	 *
365
	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
366
	 * based on http://www.php.net/manual/en/function.array-change-key-case.php#107715
367
	 *
368
	 */
369
	public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
370
		$case = ($case != MB_CASE_UPPER) ? MB_CASE_LOWER : MB_CASE_UPPER;
371
		$ret = array();
372
		foreach ($input as $k => $v) {
373
			$ret[mb_convert_case($k, $case, $encoding)] = $v;
374
		}
375
		return $ret;
376
	}
377
378
	/**
379
	 * performs a search in a nested array
380
	 * @param array $haystack the array to be searched
381
	 * @param string $needle the search string
382
	 * @param mixed $index optional, only search this key name
383
	 * @return mixed the key of the matching field, otherwise false
384
	 *
385
	 * performs a search in a nested array
386
	 *
387
	 * taken from http://www.php.net/manual/en/function.array-search.php#97645
388
	 */
389
	public static function recursiveArraySearch($haystack, $needle, $index = null) {
390
		$aIt = new RecursiveArrayIterator($haystack);
391
		$it = new RecursiveIteratorIterator($aIt);
392
393
		while ($it->valid()) {
394
			if (((isset($index) AND ($it->key() == $index)) OR !isset($index)) AND ($it->current() == $needle)) {
395
				return $aIt->key();
396
			}
397
398
			$it->next();
399
		}
400
401
		return false;
402
	}
403
404
	/**
405
	 * calculates the maximum upload size respecting system settings, free space and user quota
406
	 *
407
	 * @param string $dir the current folder where the user currently operates
408
	 * @param int $freeSpace the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly
409
	 * @return int number of bytes representing
410
	 */
411
	public static function maxUploadFilesize($dir, $freeSpace = null) {
412
		if (is_null($freeSpace) || $freeSpace < 0){
413
			$freeSpace = self::freeSpace($dir);
414
		}
415
		return min($freeSpace, self::uploadLimit());
416
	}
417
418
	/**
419
	 * Calculate free space left within user quota
420
	 *
421
	 * @param string $dir the current folder where the user currently operates
422
	 * @return int number of bytes representing
423
	 */
424
	public static function freeSpace($dir) {
425
		$freeSpace = \OC\Files\Filesystem::free_space($dir);
426
		if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
427
			$freeSpace = max($freeSpace, 0);
428
			return $freeSpace;
429
		} else {
430
			return (INF > 0)? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
431
		}
432
	}
433
434
	/**
435
	 * Calculate PHP upload limit
436
	 *
437
	 * @return int PHP upload file size limit
438
	 */
439
	public static function uploadLimit() {
440
		$ini = \OC::$server->getIniWrapper();
441
		$upload_max_filesize = OCP\Util::computerFileSize($ini->get('upload_max_filesize'));
442
		$post_max_size = OCP\Util::computerFileSize($ini->get('post_max_size'));
443
		if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) {
444
			return INF;
445
		} elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) {
446
			return max($upload_max_filesize, $post_max_size); //only the non 0 value counts
447
		} else {
448
			return min($upload_max_filesize, $post_max_size);
449
		}
450
	}
451
452
	/**
453
	 * Checks if a function is available
454
	 *
455
	 * @param string $function_name
456
	 * @return bool
457
	 */
458
	public static function is_function_enabled($function_name) {
459
		if (!function_exists($function_name)) {
460
			return false;
461
		}
462
		$ini = \OC::$server->getIniWrapper();
463
		$disabled = explode(',', $ini->get('disable_functions') ?: '');
464
		$disabled = array_map('trim', $disabled);
465
		if (in_array($function_name, $disabled)) {
466
			return false;
467
		}
468
		$disabled = explode(',', $ini->get('suhosin.executor.func.blacklist') ?: '');
469
		$disabled = array_map('trim', $disabled);
470
		if (in_array($function_name, $disabled)) {
471
			return false;
472
		}
473
		return true;
474
	}
475
476
	/**
477
	 * Try to find a program
478
	 *
479
	 * @param string $program
480
	 * @return null|string
481
	 */
482
	public static function findBinaryPath($program) {
483
		$memcache = \OC::$server->getMemCacheFactory()->createDistributed('findBinaryPath');
484
		if ($memcache->hasKey($program)) {
0 ignored issues
show
Deprecated Code introduced by
The function OCP\ICache::hasKey() has been deprecated: 9.1.0 Directly read from GET to prevent race conditions ( Ignorable by Annotation )

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

484
		if (/** @scrutinizer ignore-deprecated */ $memcache->hasKey($program)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
485
			return $memcache->get($program);
486
		}
487
		$result = null;
488
		if (self::is_function_enabled('exec')) {
489
			$exeSniffer = new ExecutableFinder();
490
			// Returns null if nothing is found
491
			$result = $exeSniffer->find($program, null, ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/opt/bin']);
492
		}
493
		// store the value for 5 minutes
494
		$memcache->set($program, $result, 300);
495
		return $result;
496
	}
497
498
	/**
499
	 * Calculate the disc space for the given path
500
	 *
501
	 * @param string $path
502
	 * @param \OCP\Files\FileInfo $rootInfo (optional)
503
	 * @return array
504
	 * @throws \OCP\Files\NotFoundException
505
	 */
506
	public static function getStorageInfo($path, $rootInfo = null) {
507
		// return storage info without adding mount points
508
		$includeExtStorage = \OC::$server->getSystemConfig()->getValue('quota_include_external_storage', false);
509
510
		if (!$rootInfo) {
511
			$rootInfo = \OC\Files\Filesystem::getFileInfo($path, $includeExtStorage ? 'ext' : false);
0 ignored issues
show
Bug introduced by
It seems like $includeExtStorage ? 'ext' : false can also be of type string; however, parameter $includeMountPoints of OC\Files\Filesystem::getFileInfo() does only seem to accept boolean, maybe add an additional type check? ( Ignorable by Annotation )

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

511
			$rootInfo = \OC\Files\Filesystem::getFileInfo($path, /** @scrutinizer ignore-type */ $includeExtStorage ? 'ext' : false);
Loading history...
512
		}
513
		if (!$rootInfo instanceof \OCP\Files\FileInfo) {
514
			throw new \OCP\Files\NotFoundException();
515
		}
516
		$used = $rootInfo->getSize();
517
		if ($used < 0) {
518
			$used = 0;
519
		}
520
		$quota = \OCP\Files\FileInfo::SPACE_UNLIMITED;
521
		$storage = $rootInfo->getStorage();
522
		$sourceStorage = $storage;
523
		if ($storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) {
524
			$includeExtStorage = false;
525
			$sourceStorage = $storage->getSourceStorage();
0 ignored issues
show
Bug introduced by
The method getSourceStorage() does not exist on OC\Files\Storage\Storage. It seems like you code against a sub-type of OC\Files\Storage\Storage such as OC\Files\Storage\Wrapper\Wrapper. ( Ignorable by Annotation )

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

525
			/** @scrutinizer ignore-call */ 
526
   $sourceStorage = $storage->getSourceStorage();
Loading history...
Bug introduced by
The method getSourceStorage() does not exist on OCP\Files\Storage. It seems like you code against a sub-type of OCP\Files\Storage such as OC\Files\Storage\Wrapper\Wrapper. ( Ignorable by Annotation )

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

525
			/** @scrutinizer ignore-call */ 
526
   $sourceStorage = $storage->getSourceStorage();
Loading history...
526
		}
527
		if ($includeExtStorage) {
528
			if ($storage->instanceOfStorage('\OC\Files\Storage\Home')
529
				|| $storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage')
530
			) {
531
				/** @var \OC\Files\Storage\Home $storage */
532
				$userInstance = $storage->getUser();
533
				$user = ($userInstance === null) ? null : $userInstance->getUID();
534
			} else {
535
				$user = \OC::$server->getUserSession()->getUser()->getUID();
536
			}
537
			if ($user) {
538
				$quota = OC_Util::getUserQuota($user);
539
			} else {
540
				$quota = \OCP\Files\FileInfo::SPACE_UNLIMITED;
541
			}
542
			if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
543
				// always get free space / total space from root + mount points
544
				return self::getGlobalStorageInfo();
545
			}
546
		}
547
548
		// TODO: need a better way to get total space from storage
549
		if ($sourceStorage->instanceOfStorage('\OC\Files\Storage\Wrapper\Quota')) {
550
			/** @var \OC\Files\Storage\Wrapper\Quota $storage */
551
			$quota = $sourceStorage->getQuota();
552
		}
553
		$free = $sourceStorage->free_space($rootInfo->getInternalPath());
554
		if ($free >= 0) {
555
			$total = $free + $used;
556
		} else {
557
			$total = $free; //either unknown or unlimited
558
		}
559
		if ($total > 0) {
560
			if ($quota > 0 && $total > $quota) {
561
				$total = $quota;
562
			}
563
			// prevent division by zero or error codes (negative values)
564
			$relative = round(($used / $total) * 10000) / 100;
565
		} else {
566
			$relative = 0;
567
		}
568
569
		$ownerId = $storage->getOwner($path);
570
		$ownerDisplayName = '';
571
		$owner = \OC::$server->getUserManager()->get($ownerId);
572
		if($owner) {
573
			$ownerDisplayName = $owner->getDisplayName();
574
		}
575
576
		return [
577
			'free' => $free,
578
			'used' => $used,
579
			'quota' => $quota,
580
			'total' => $total,
581
			'relative' => $relative,
582
			'owner' => $ownerId,
583
			'ownerDisplayName' => $ownerDisplayName,
584
		];
585
	}
586
587
	/**
588
	 * Get storage info including all mount points and quota
589
	 *
590
	 * @return array
591
	 */
592
	private static function getGlobalStorageInfo() {
593
		$quota = OC_Util::getUserQuota(\OCP\User::getUser());
0 ignored issues
show
Deprecated Code introduced by
The function OCP\User::getUser() has been deprecated: 8.0.0 Use \OC::$server->getUserSession()->getUser()->getUID() ( Ignorable by Annotation )

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

593
		$quota = OC_Util::getUserQuota(/** @scrutinizer ignore-deprecated */ \OCP\User::getUser());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
594
595
		$rootInfo = \OC\Files\Filesystem::getFileInfo('', 'ext');
0 ignored issues
show
Bug introduced by
'ext' of type string is incompatible with the type boolean expected by parameter $includeMountPoints of OC\Files\Filesystem::getFileInfo(). ( Ignorable by Annotation )

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

595
		$rootInfo = \OC\Files\Filesystem::getFileInfo('', /** @scrutinizer ignore-type */ 'ext');
Loading history...
596
		$used = $rootInfo['size'];
597
		if ($used < 0) {
598
			$used = 0;
599
		}
600
601
		$total = $quota;
602
		$free = $quota - $used;
603
604
		if ($total > 0) {
605
			if ($quota > 0 && $total > $quota) {
606
				$total = $quota;
607
			}
608
			// prevent division by zero or error codes (negative values)
609
			$relative = round(($used / $total) * 10000) / 100;
610
		} else {
611
			$relative = 0;
612
		}
613
614
		return array('free' => $free, 'used' => $used, 'total' => $total, 'relative' => $relative);
615
616
	}
617
618
	/**
619
	 * Returns whether the config file is set manually to read-only
620
	 * @return bool
621
	 */
622
	public static function isReadOnlyConfigEnabled() {
623
		return \OC::$server->getConfig()->getSystemValue('config_is_read_only', false);
624
	}
625
}
626