Completed
Push — master ( 281937...5a0dc1 )
by Blizzz
34s
created

OC_Helper::rmdirr()   D

Complexity

Conditions 9
Paths 10

Size

Total Lines 31
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 9
eloc 20
c 3
b 0
f 0
nc 10
nop 2
dl 0
loc 31
rs 4.909
1
<?php
2
/**
3
 * @author Arthur Schiwon <[email protected]>
4
 * @author Bart Visscher <[email protected]>
5
 * @author Björn Schießle <[email protected]>
6
 * @author Christopher Schäpers <[email protected]>
7
 * @author Clark Tomlinson <[email protected]>
8
 * @author Fabian Henze <[email protected]>
9
 * @author Felix Moeller <[email protected]>
10
 * @author Georg Ehrke <[email protected]>
11
 * @author Jakob Sack <[email protected]>
12
 * @author Jan-Christoph Borchardt <[email protected]>
13
 * @author Joas Schilling <[email protected]>
14
 * @author Jörn Friedrich Dreyer <[email protected]>
15
 * @author Lukas Reschke <[email protected]>
16
 * @author Michael Gapczynski <[email protected]>
17
 * @author Morris Jobke <[email protected]>
18
 * @author Olivier Paroz <[email protected]>
19
 * @author Pellaeon Lin <[email protected]>
20
 * @author Robin Appelman <[email protected]>
21
 * @author Robin McCorkell <[email protected]>
22
 * @author Roeland Jago Douma <[email protected]>
23
 * @author Simon Könnecke <[email protected]>
24
 * @author Thomas Müller <[email protected]>
25
 * @author Thomas Tanghus <[email protected]>
26
 * @author Vincent Petry <[email protected]>
27
 *
28
 * @copyright Copyright (c) 2016, ownCloud, Inc.
29
 * @license AGPL-3.0
30
 *
31
 * This code is free software: you can redistribute it and/or modify
32
 * it under the terms of the GNU Affero General Public License, version 3,
33
 * as published by the Free Software Foundation.
34
 *
35
 * This program is distributed in the hope that it will be useful,
36
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38
 * GNU Affero General Public License for more details.
39
 *
40
 * You should have received a copy of the GNU Affero General Public License, version 3,
41
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
42
 *
43
 */
44
use Symfony\Component\Process\ExecutableFinder;
45
46
/**
47
 * Collection of useful functions
48
 */
49
class OC_Helper {
50
	private static $templateManager;
51
52
	/**
53
	 * Creates an absolute url for public use
54
	 * @param string $service id
55
	 * @param bool $add_slash
56
	 * @return string the url
57
	 *
58
	 * Returns a absolute url to the given service.
59
	 */
60
	public static function linkToPublic($service, $add_slash = false) {
61
		if ($service === 'files') {
62
			$url = OC::$server->getURLGenerator()->getAbsoluteURL('/s');
63
		} else {
64
			$url = OC::$server->getURLGenerator()->getAbsoluteURL(OC::$server->getURLGenerator()->linkTo('', 'public.php').'?service='.$service);
65
		}
66
		return $url . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : '');
67
	}
68
69
	/**
70
	 * Make a human file size
71
	 * @param int $bytes file size in bytes
72
	 * @return string a human readable file size
73
	 *
74
	 * Makes 2048 to 2 kB.
75
	 */
76
	public static function humanFileSize($bytes) {
77
		if ($bytes < 0) {
78
			return "?";
79
		}
80
		if ($bytes < 1024) {
81
			return "$bytes B";
82
		}
83
		$bytes = round($bytes / 1024, 0);
84
		if ($bytes < 1024) {
85
			return "$bytes KB";
86
		}
87
		$bytes = round($bytes / 1024, 1);
88
		if ($bytes < 1024) {
89
			return "$bytes MB";
90
		}
91
		$bytes = round($bytes / 1024, 1);
92
		if ($bytes < 1024) {
93
			return "$bytes GB";
94
		}
95
		$bytes = round($bytes / 1024, 1);
96
		if ($bytes < 1024) {
97
			return "$bytes TB";
98
		}
99
100
		$bytes = round($bytes / 1024, 1);
101
		return "$bytes PB";
102
	}
103
104
	/**
105
	 * Make a php file size
106
	 * @param int $bytes file size in bytes
107
	 * @return string a php parseable file size
108
	 *
109
	 * Makes 2048 to 2k and 2^41 to 2048G
110
	 */
111
	public static function phpFileSize($bytes) {
112
		if ($bytes < 0) {
113
			return "?";
114
		}
115
		if ($bytes < 1024) {
116
			return $bytes . "B";
117
		}
118
		$bytes = round($bytes / 1024, 1);
119
		if ($bytes < 1024) {
120
			return $bytes . "K";
121
		}
122
		$bytes = round($bytes / 1024, 1);
123
		if ($bytes < 1024) {
124
			return $bytes . "M";
125
		}
126
		$bytes = round($bytes / 1024, 1);
127
		return $bytes . "G";
128
	}
129
130
	/**
131
	 * Make a computer file size
132
	 * @param string $str file size in human readable format
133
	 * @return float a file size in bytes
134
	 *
135
	 * Makes 2kB to 2048.
136
	 *
137
	 * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418
138
	 */
139
	public static function computerFileSize($str) {
140
		$str = strtolower($str);
141
		if (is_numeric($str)) {
142
			return floatval($str);
143
		}
144
145
		$bytes_array = array(
146
			'b' => 1,
147
			'k' => 1024,
148
			'kb' => 1024,
149
			'mb' => 1024 * 1024,
150
			'm' => 1024 * 1024,
151
			'gb' => 1024 * 1024 * 1024,
152
			'g' => 1024 * 1024 * 1024,
153
			'tb' => 1024 * 1024 * 1024 * 1024,
154
			't' => 1024 * 1024 * 1024 * 1024,
155
			'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
156
			'p' => 1024 * 1024 * 1024 * 1024 * 1024,
157
		);
158
159
		$bytes = floatval($str);
160
161
		if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) {
162
			$bytes *= $bytes_array[$matches[1]];
163
		} else {
164
			return false;
165
		}
166
167
		$bytes = round($bytes);
168
169
		return $bytes;
170
	}
171
172
	/**
173
	 * Recursive copying of folders
174
	 * @param string $src source folder
175
	 * @param string $dest target folder
176
	 *
177
	 */
178
	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...
179
		if (is_dir($src)) {
180
			if (!is_dir($dest)) {
181
				mkdir($dest);
182
			}
183
			$files = scandir($src);
184
			foreach ($files as $file) {
185
				if ($file != "." && $file != "..") {
186
					self::copyr("$src/$file", "$dest/$file");
187
				}
188
			}
189
		} elseif (file_exists($src) && !\OC\Files\Filesystem::isFileBlacklisted($src)) {
190
			copy($src, $dest);
191
		}
192
	}
193
194
	/**
195
	 * Recursive deletion of folders
196
	 * @param string $dir path to the folder
197
	 * @param bool $deleteSelf if set to false only the content of the folder will be deleted
198
	 * @return bool
199
	 */
200
	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...
201
		if (is_dir($dir)) {
202
			$files = new RecursiveIteratorIterator(
203
				new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
204
				RecursiveIteratorIterator::CHILD_FIRST
205
			);
206
207
			foreach ($files as $fileInfo) {
208
				/** @var SplFileInfo $fileInfo */
209
				if ($fileInfo->isLink()) {
210
					unlink($fileInfo->getPathname());
211
				} else if ($fileInfo->isDir()) {
212
					rmdir($fileInfo->getRealPath());
213
				} else {
214
					unlink($fileInfo->getRealPath());
215
				}
216
			}
217
			if ($deleteSelf) {
218
				rmdir($dir);
219
			}
220
		} elseif (file_exists($dir)) {
221
			if ($deleteSelf) {
222
				unlink($dir);
223
			}
224
		}
225
		if (!$deleteSelf) {
226
			return true;
227
		}
228
229
		return !file_exists($dir);
230
	}
231
232
	/**
233
	 * @return \OC\Files\Type\TemplateManager
234
	 */
235
	static public function getFileTemplateManager() {
236
		if (!self::$templateManager) {
237
			self::$templateManager = new \OC\Files\Type\TemplateManager();
238
		}
239
		return self::$templateManager;
240
	}
241
242
	/**
243
	 * detect if a given program is found in the search PATH
244
	 *
245
	 * @param string $name
246
	 * @param bool $path
247
	 * @internal param string $program name
248
	 * @internal param string $optional search path, defaults to $PATH
249
	 * @return bool    true if executable program found in path
250
	 */
251
	public static function canExecute($name, $path = false) {
252
		// path defaults to PATH from environment if not set
253
		if ($path === false) {
254
			$path = getenv("PATH");
255
		}
256
		// check method depends on operating system
257
		if (!strncmp(PHP_OS, "WIN", 3)) {
258
			// on Windows an appropriate COM or EXE file needs to exist
259
			$exts = array(".exe", ".com");
260
			$check_fn = "file_exists";
261
		} else {
262
			// anywhere else we look for an executable file of that name
263
			$exts = array("");
264
			$check_fn = "is_executable";
265
		}
266
		// Default check will be done with $path directories :
267
		$dirs = explode(PATH_SEPARATOR, $path);
268
		// WARNING : We have to check if open_basedir is enabled :
269
		$obd = OC::$server->getIniWrapper()->getString('open_basedir');
270
		if ($obd != "none") {
271
			$obd_values = explode(PATH_SEPARATOR, $obd);
272
			if (count($obd_values) > 0 and $obd_values[0]) {
273
				// open_basedir is in effect !
274
				// We need to check if the program is in one of these dirs :
275
				$dirs = $obd_values;
276
			}
277
		}
278
		foreach ($dirs as $dir) {
279
			foreach ($exts as $ext) {
280
				if ($check_fn("$dir/$name" . $ext))
281
					return true;
282
			}
283
		}
284
		return false;
285
	}
286
287
	/**
288
	 * copy the contents of one stream to another
289
	 *
290
	 * @param resource $source
291
	 * @param resource $target
292
	 * @return array the number of bytes copied and result
293
	 */
294
	public static function streamCopy($source, $target) {
295
		if (!$source or !$target) {
296
			return array(0, false);
297
		}
298
		$bufSize = 8192;
299
		$result = true;
300
		$count = 0;
301
		while (!feof($source)) {
302
			$buf = fread($source, $bufSize);
303
			$bytesWritten = fwrite($target, $buf);
304
			if ($bytesWritten !== false) {
305
				$count += $bytesWritten;
306
			}
307
			// note: strlen is expensive so only use it when necessary,
308
			// on the last block
309
			if ($bytesWritten === false
310
				|| ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
311
			) {
312
				// write error, could be disk full ?
313
				$result = false;
314
				break;
315
			}
316
		}
317
		return array($count, $result);
318
	}
319
320
	/**
321
	 * Adds a suffix to the name in case the file exists
322
	 *
323
	 * @param string $path
324
	 * @param string $filename
325
	 * @return string
326
	 */
327
	public static function buildNotExistingFileName($path, $filename) {
328
		$view = \OC\Files\Filesystem::getView();
329
		return self::buildNotExistingFileNameForView($path, $filename, $view);
330
	}
331
332
	/**
333
	 * Adds a suffix to the name in case the file exists
334
	 *
335
	 * @param string $path
336
	 * @param string $filename
337
	 * @return string
338
	 */
339
	public static function buildNotExistingFileNameForView($path, $filename, \OC\Files\View $view) {
340
		if ($path === '/') {
341
			$path = '';
342
		}
343
		if ($pos = strrpos($filename, '.')) {
344
			$name = substr($filename, 0, $pos);
345
			$ext = substr($filename, $pos);
346
		} else {
347
			$name = $filename;
348
			$ext = '';
349
		}
350
351
		$newpath = $path . '/' . $filename;
352
		if ($view->file_exists($newpath)) {
353
			if (preg_match_all('/\((\d+)\)/', $name, $matches, PREG_OFFSET_CAPTURE)) {
354
				//Replace the last "(number)" with "(number+1)"
355
				$last_match = count($matches[0]) - 1;
356
				$counter = $matches[1][$last_match][0] + 1;
357
				$offset = $matches[0][$last_match][1];
358
				$match_length = strlen($matches[0][$last_match][0]);
359
			} else {
360
				$counter = 2;
361
				$match_length = 0;
362
				$offset = false;
363
			}
364
			do {
365
				if ($offset) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $offset 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...
366
					//Replace the last "(number)" with "(number+1)"
367
					$newname = substr_replace($name, '(' . $counter . ')', $offset, $match_length);
368
				} else {
369
					$newname = $name . ' (' . $counter . ')';
370
				}
371
				$newpath = $path . '/' . $newname . $ext;
372
				$counter++;
373
			} while ($view->file_exists($newpath));
374
		}
375
376
		return $newpath;
377
	}
378
379
	/**
380
	 * Checks if $sub is a subdirectory of $parent
381
	 *
382
	 * @param string $sub
383
	 * @param string $parent
384
	 * @return bool
385
	 */
386
	public static function isSubDirectory($sub, $parent) {
387
		$realpathSub = realpath($sub);
388
		$realpathParent = realpath($parent);
389
390
		// realpath() may return false in case the directory does not exist
391
		// since we can not be sure how different PHP versions may behave here
392
		// we do an additional check whether realpath returned false
393
		if($realpathSub === false ||  $realpathParent === false) {
394
			return false;
395
		}
396
397
		// Check whether $sub is a subdirectory of $parent
398
		if (strpos($realpathSub, $realpathParent) === 0) {
399
			return true;
400
		}
401
402
		return false;
403
	}
404
405
	/**
406
	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
407
	 *
408
	 * @param array $input The array to work on
409
	 * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default)
410
	 * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8
411
	 * @return array
412
	 *
413
	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
414
	 * based on http://www.php.net/manual/en/function.array-change-key-case.php#107715
415
	 *
416
	 */
417
	public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
418
		$case = ($case != MB_CASE_UPPER) ? MB_CASE_LOWER : MB_CASE_UPPER;
419
		$ret = array();
420
		foreach ($input as $k => $v) {
421
			$ret[mb_convert_case($k, $case, $encoding)] = $v;
422
		}
423
		return $ret;
424
	}
425
426
	/**
427
	 * performs a search in a nested array
428
	 * @param array $haystack the array to be searched
429
	 * @param string $needle the search string
430
	 * @param string $index optional, only search this key name
431
	 * @return mixed the key of the matching field, otherwise false
432
	 *
433
	 * performs a search in a nested array
434
	 *
435
	 * taken from http://www.php.net/manual/en/function.array-search.php#97645
436
	 */
437
	public static function recursiveArraySearch($haystack, $needle, $index = null) {
438
		$aIt = new RecursiveArrayIterator($haystack);
439
		$it = new RecursiveIteratorIterator($aIt);
440
441
		while ($it->valid()) {
442
			if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) {
443
				return $aIt->key();
444
			}
445
446
			$it->next();
447
		}
448
449
		return false;
450
	}
451
452
	/**
453
	 * calculates the maximum upload size respecting system settings, free space and user quota
454
	 *
455
	 * @param string $dir the current folder where the user currently operates
456
	 * @param int $freeSpace the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly
457
	 * @return int number of bytes representing
458
	 */
459
	public static function maxUploadFilesize($dir, $freeSpace = null) {
460
		if (is_null($freeSpace) || $freeSpace < 0){
461
			$freeSpace = self::freeSpace($dir);
462
		}
463
		return min($freeSpace, self::uploadLimit());
464
	}
465
466
	/**
467
	 * Calculate free space left within user quota
468
	 *
469
	 * @param string $dir the current folder where the user currently operates
470
	 * @return int number of bytes representing
471
	 */
472
	public static function freeSpace($dir) {
473
		$freeSpace = \OC\Files\Filesystem::free_space($dir);
474 View Code Duplication
		if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
475
			$freeSpace = max($freeSpace, 0);
476
			return $freeSpace;
477
		} else {
478
			return (INF > 0)? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
479
		}
480
	}
481
482
	/**
483
	 * Calculate PHP upload limit
484
	 *
485
	 * @return int PHP upload file size limit
486
	 */
487
	public static function uploadLimit() {
488
		$ini = \OC::$server->getIniWrapper();
489
		$upload_max_filesize = OCP\Util::computerFileSize($ini->get('upload_max_filesize'));
490
		$post_max_size = OCP\Util::computerFileSize($ini->get('post_max_size'));
491
		if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) {
492
			return INF;
493
		} elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) {
494
			return max($upload_max_filesize, $post_max_size); //only the non 0 value counts
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression max($upload_max_filesize, $post_max_size); of type double|false adds false to the return on line 494 which is incompatible with the return type documented by OC_Helper::uploadLimit of type integer. It seems like you forgot to handle an error condition.
Loading history...
495
		} else {
496
			return min($upload_max_filesize, $post_max_size);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression min($upload_max_filesize, $post_max_size); of type double|false adds false to the return on line 496 which is incompatible with the return type documented by OC_Helper::uploadLimit of type integer. It seems like you forgot to handle an error condition.
Loading history...
497
		}
498
	}
499
500
	/**
501
	 * Checks if a function is available
502
	 *
503
	 * @param string $function_name
504
	 * @return bool
505
	 */
506
	public static function is_function_enabled($function_name) {
507
		if (!function_exists($function_name)) {
508
			return false;
509
		}
510
		$ini = \OC::$server->getIniWrapper();
511
		$disabled = explode(',', $ini->get('disable_functions'));
512
		$disabled = array_map('trim', $disabled);
513
		if (in_array($function_name, $disabled)) {
514
			return false;
515
		}
516
		$disabled = explode(',', $ini->get('suhosin.executor.func.blacklist'));
517
		$disabled = array_map('trim', $disabled);
518
		if (in_array($function_name, $disabled)) {
519
			return false;
520
		}
521
		return true;
522
	}
523
524
	/**
525
	 * Try to find a program
526
	 * Note: currently windows is not supported
527
	 *
528
	 * @param string $program
529
	 * @return null|string
530
	 */
531
	public static function findBinaryPath($program) {
532
		$memcache = \OC::$server->getMemCacheFactory()->create('findBinaryPath');
533
		if ($memcache->hasKey($program)) {
0 ignored issues
show
Deprecated Code introduced by
The method OCP\ICache::hasKey() has been deprecated with message: 9.1.0 Directly read from GET to prevent race conditions

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

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

Loading history...
534
			return $memcache->get($program);
535
		}
536
		$result = null;
537
		if (!\OC_Util::runningOnWindows() && self::is_function_enabled('exec')) {
538
			$exeSniffer = new ExecutableFinder();
539
			// Returns null if nothing is found
540
			$result = $exeSniffer->find($program);
541
			if (empty($result)) {
542
				$paths = getenv('PATH');
543
				if (empty($paths)) {
544
					$paths = '/usr/local/bin /usr/bin /opt/bin /bin';
545
				} else {
546
					$paths = str_replace(':',' ',getenv('PATH'));
547
				}
548
				$command = 'find ' . $paths . ' -name ' . escapeshellarg($program) . ' 2> /dev/null';
549
				exec($command, $output, $returnCode);
550
				if (count($output) > 0) {
551
					$result = escapeshellcmd($output[0]);
552
				}
553
			}
554
		}
555
		// store the value for 5 minutes
556
		$memcache->set($program, $result, 300);
557
		return $result;
558
	}
559
560
	/**
561
	 * Calculate the disc space for the given path
562
	 *
563
	 * @param string $path
564
	 * @param \OCP\Files\FileInfo $rootInfo (optional)
565
	 * @return array
566
	 * @throws \OCP\Files\NotFoundException
567
	 */
568
	public static function getStorageInfo($path, $rootInfo = null) {
569
		// return storage info without adding mount points
570
		$includeExtStorage = \OC::$server->getSystemConfig()->getValue('quota_include_external_storage', false);
571
572
		if (!$rootInfo) {
573
			$rootInfo = \OC\Files\Filesystem::getFileInfo($path, false);
574
		}
575
		if (!$rootInfo instanceof \OCP\Files\FileInfo) {
576
			throw new \OCP\Files\NotFoundException();
577
		}
578
		$used = $rootInfo->getSize();
579
		if ($used < 0) {
580
			$used = 0;
581
		}
582
		$quota = \OCP\Files\FileInfo::SPACE_UNLIMITED;
583
		$storage = $rootInfo->getStorage();
584
		$sourceStorage = $storage;
585
		if ($storage->instanceOfStorage('\OC\Files\Storage\Shared')) {
586
			$includeExtStorage = false;
587
			$sourceStorage = $storage->getSourceStorage();
588
		}
589
		if ($includeExtStorage) {
590
			$quota = OC_Util::getUserQuota(\OCP\User::getUser());
0 ignored issues
show
Deprecated Code introduced by
The method OCP\User::getUser() has been deprecated with message: 8.0.0 Use \OC::$server->getUserSession()->getUser()->getUID()

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

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

Loading history...
591
			if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
592
				// always get free space / total space from root + mount points
593
				return self::getGlobalStorageInfo();
594
			}
595
		}
596
597
		// TODO: need a better way to get total space from storage
598
		if ($sourceStorage->instanceOfStorage('\OC\Files\Storage\Wrapper\Quota')) {
599
			/** @var \OC\Files\Storage\Wrapper\Quota $storage */
600
			$quota = $sourceStorage->getQuota();
601
		}
602
		$free = $sourceStorage->free_space('');
603
		if ($free >= 0) {
604
			$total = $free + $used;
605
		} else {
606
			$total = $free; //either unknown or unlimited
607
		}
608 View Code Duplication
		if ($total > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
609
			if ($quota > 0 && $total > $quota) {
610
				$total = $quota;
611
			}
612
			// prevent division by zero or error codes (negative values)
613
			$relative = round(($used / $total) * 10000) / 100;
614
		} else {
615
			$relative = 0;
616
		}
617
618
		$ownerId = $storage->getOwner($path);
619
		$ownerDisplayName = '';
620
		$owner = \OC::$server->getUserManager()->get($ownerId);
621
		if($owner) {
622
			$ownerDisplayName = $owner->getDisplayName();
623
		}
624
625
		return [
626
			'free' => $free,
627
			'used' => $used,
628
			'quota' => $quota,
629
			'total' => $total,
630
			'relative' => $relative,
631
			'owner' => $ownerId,
632
			'ownerDisplayName' => $ownerDisplayName,
633
		];
634
	}
635
636
	/**
637
	 * Get storage info including all mount points and quota
638
	 *
639
	 * @return array
640
	 */
641
	private static function getGlobalStorageInfo() {
642
		$quota = OC_Util::getUserQuota(\OCP\User::getUser());
0 ignored issues
show
Deprecated Code introduced by
The method OCP\User::getUser() has been deprecated with message: 8.0.0 Use \OC::$server->getUserSession()->getUser()->getUID()

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

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

Loading history...
643
644
		$rootInfo = \OC\Files\Filesystem::getFileInfo('', 'ext');
0 ignored issues
show
Documentation introduced by
'ext' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
645
		$used = $rootInfo['size'];
646
		if ($used < 0) {
647
			$used = 0;
648
		}
649
650
		$total = $quota;
651
		$free = $quota - $used;
652
653 View Code Duplication
		if ($total > 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
654
			if ($quota > 0 && $total > $quota) {
655
				$total = $quota;
656
			}
657
			// prevent division by zero or error codes (negative values)
658
			$relative = round(($used / $total) * 10000) / 100;
659
		} else {
660
			$relative = 0;
661
		}
662
663
		return array('free' => $free, 'used' => $used, 'total' => $total, 'relative' => $relative);
664
665
	}
666
667
	/**
668
	 * Returns whether the config file is set manually to read-only
669
	 * @return bool
670
	 */
671
	public static function isReadOnlyConfigEnabled() {
672
		return \OC::$server->getConfig()->getSystemValue('config_is_read_only', false);
673
	}
674
}
675