Completed
Push — master ( 240d91...1034ef )
by Morris
16:31
created

OC_Helper::isReadOnlyConfigEnabled()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
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
	 * Creates an absolute url for public use
56
	 * @param string $service id
57
	 * @param bool $add_slash
58
	 * @return string the url
59
	 *
60
	 * Returns a absolute url to the given service.
61
	 */
62
	public static function linkToPublic($service, $add_slash = false) {
63
		if ($service === 'files') {
64
			$url = OC::$server->getURLGenerator()->getAbsoluteURL('/s');
65
		} else {
66
			$url = OC::$server->getURLGenerator()->getAbsoluteURL(OC::$server->getURLGenerator()->linkTo('', 'public.php').'?service='.$service);
67
		}
68
		return $url . (($add_slash && $service[strlen($service) - 1] != '/') ? '/' : '');
69
	}
70
71
	/**
72
	 * Make a human file size
73
	 * @param int $bytes file size in bytes
74
	 * @return string a human readable file size
75
	 *
76
	 * Makes 2048 to 2 kB.
77
	 */
78
	public static function humanFileSize($bytes) {
79
		if ($bytes < 0) {
80
			return "?";
81
		}
82
		if ($bytes < 1024) {
83
			return "$bytes B";
84
		}
85
		$bytes = round($bytes / 1024, 0);
86
		if ($bytes < 1024) {
87
			return "$bytes KB";
88
		}
89
		$bytes = round($bytes / 1024, 1);
90
		if ($bytes < 1024) {
91
			return "$bytes MB";
92
		}
93
		$bytes = round($bytes / 1024, 1);
94
		if ($bytes < 1024) {
95
			return "$bytes GB";
96
		}
97
		$bytes = round($bytes / 1024, 1);
98
		if ($bytes < 1024) {
99
			return "$bytes TB";
100
		}
101
102
		$bytes = round($bytes / 1024, 1);
103
		return "$bytes PB";
104
	}
105
106
	/**
107
	 * Make a php file size
108
	 * @param int $bytes file size in bytes
109
	 * @return string a php parseable file size
110
	 *
111
	 * Makes 2048 to 2k and 2^41 to 2048G
112
	 */
113
	public static function phpFileSize($bytes) {
114
		if ($bytes < 0) {
115
			return "?";
116
		}
117
		if ($bytes < 1024) {
118
			return $bytes . "B";
119
		}
120
		$bytes = round($bytes / 1024, 1);
121
		if ($bytes < 1024) {
122
			return $bytes . "K";
123
		}
124
		$bytes = round($bytes / 1024, 1);
125
		if ($bytes < 1024) {
126
			return $bytes . "M";
127
		}
128
		$bytes = round($bytes / 1024, 1);
129
		return $bytes . "G";
130
	}
131
132
	/**
133
	 * Make a computer file size
134
	 * @param string $str file size in human readable format
135
	 * @return float|bool a file size in bytes
136
	 *
137
	 * Makes 2kB to 2048.
138
	 *
139
	 * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418
140
	 */
141
	public static function computerFileSize($str) {
142
		$str = strtolower($str);
143
		if (is_numeric($str)) {
144
			return (float)$str;
145
		}
146
147
		$bytes_array = array(
148
			'b' => 1,
149
			'k' => 1024,
150
			'kb' => 1024,
151
			'mb' => 1024 * 1024,
152
			'm' => 1024 * 1024,
153
			'gb' => 1024 * 1024 * 1024,
154
			'g' => 1024 * 1024 * 1024,
155
			'tb' => 1024 * 1024 * 1024 * 1024,
156
			't' => 1024 * 1024 * 1024 * 1024,
157
			'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
158
			'p' => 1024 * 1024 * 1024 * 1024 * 1024,
159
		);
160
161
		$bytes = (float)$str;
162
163
		if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) {
164
			$bytes *= $bytes_array[$matches[1]];
165
		} else {
166
			return false;
167
		}
168
169
		$bytes = round($bytes);
170
171
		return $bytes;
172
	}
173
174
	/**
175
	 * Recursive copying of folders
176
	 * @param string $src source folder
177
	 * @param string $dest target folder
178
	 *
179
	 */
180
	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...
181
		if (is_dir($src)) {
182
			if (!is_dir($dest)) {
183
				mkdir($dest);
184
			}
185
			$files = scandir($src);
186
			foreach ($files as $file) {
187
				if ($file != "." && $file != "..") {
188
					self::copyr("$src/$file", "$dest/$file");
189
				}
190
			}
191
		} elseif (file_exists($src) && !\OC\Files\Filesystem::isFileBlacklisted($src)) {
192
			copy($src, $dest);
193
		}
194
	}
195
196
	/**
197
	 * Recursive deletion of folders
198
	 * @param string $dir path to the folder
199
	 * @param bool $deleteSelf if set to false only the content of the folder will be deleted
200
	 * @return bool
201
	 */
202
	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...
203
		if (is_dir($dir)) {
204
			$files = new RecursiveIteratorIterator(
205
				new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
206
				RecursiveIteratorIterator::CHILD_FIRST
207
			);
208
209
			foreach ($files as $fileInfo) {
210
				/** @var SplFileInfo $fileInfo */
211
				if ($fileInfo->isLink()) {
212
					unlink($fileInfo->getPathname());
213
				} else if ($fileInfo->isDir()) {
214
					rmdir($fileInfo->getRealPath());
215
				} else {
216
					unlink($fileInfo->getRealPath());
217
				}
218
			}
219
			if ($deleteSelf) {
220
				rmdir($dir);
221
			}
222
		} elseif (file_exists($dir)) {
223
			if ($deleteSelf) {
224
				unlink($dir);
225
			}
226
		}
227
		if (!$deleteSelf) {
228
			return true;
229
		}
230
231
		return !file_exists($dir);
232
	}
233
234
	/**
235
	 * @return \OC\Files\Type\TemplateManager
236
	 */
237
	static public function getFileTemplateManager() {
238
		if (!self::$templateManager) {
239
			self::$templateManager = new \OC\Files\Type\TemplateManager();
240
		}
241
		return self::$templateManager;
242
	}
243
244
	/**
245
	 * detect if a given program is found in the search PATH
246
	 *
247
	 * @param string $name
248
	 * @param bool $path
249
	 * @internal param string $program name
250
	 * @internal param string $optional search path, defaults to $PATH
251
	 * @return bool    true if executable program found in path
252
	 */
253
	public static function canExecute($name, $path = false) {
254
		// path defaults to PATH from environment if not set
255
		if ($path === false) {
256
			$path = getenv("PATH");
257
		}
258
		// we look for an executable file of that name
259
		$exts = [""];
260
		$check_fn = "is_executable";
261
		// Default check will be done with $path directories :
262
		$dirs = explode(PATH_SEPARATOR, $path);
263
		// WARNING : We have to check if open_basedir is enabled :
264
		$obd = OC::$server->getIniWrapper()->getString('open_basedir');
265
		if ($obd != "none") {
266
			$obd_values = explode(PATH_SEPARATOR, $obd);
267
			if (count($obd_values) > 0 and $obd_values[0]) {
268
				// open_basedir is in effect !
269
				// We need to check if the program is in one of these dirs :
270
				$dirs = $obd_values;
271
			}
272
		}
273
		foreach ($dirs as $dir) {
274
			foreach ($exts as $ext) {
275
				if ($check_fn("$dir/$name" . $ext))
276
					return true;
277
			}
278
		}
279
		return false;
280
	}
281
282
	/**
283
	 * copy the contents of one stream to another
284
	 *
285
	 * @param resource $source
286
	 * @param resource $target
287
	 * @return array the number of bytes copied and result
288
	 */
289
	public static function streamCopy($source, $target) {
290
		if (!$source or !$target) {
291
			return array(0, false);
292
		}
293
		$bufSize = 8192;
294
		$result = true;
295
		$count = 0;
296
		while (!feof($source)) {
297
			$buf = fread($source, $bufSize);
298
			$bytesWritten = fwrite($target, $buf);
299
			if ($bytesWritten !== false) {
300
				$count += $bytesWritten;
301
			}
302
			// note: strlen is expensive so only use it when necessary,
303
			// on the last block
304
			if ($bytesWritten === false
305
				|| ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
306
			) {
307
				// write error, could be disk full ?
308
				$result = false;
309
				break;
310
			}
311
		}
312
		return array($count, $result);
313
	}
314
315
	/**
316
	 * Adds a suffix to the name in case the file exists
317
	 *
318
	 * @param string $path
319
	 * @param string $filename
320
	 * @return string
321
	 */
322
	public static function buildNotExistingFileName($path, $filename) {
323
		$view = \OC\Files\Filesystem::getView();
324
		return self::buildNotExistingFileNameForView($path, $filename, $view);
325
	}
326
327
	/**
328
	 * Adds a suffix to the name in case the file exists
329
	 *
330
	 * @param string $path
331
	 * @param string $filename
332
	 * @return string
333
	 */
334
	public static function buildNotExistingFileNameForView($path, $filename, \OC\Files\View $view) {
335
		if ($path === '/') {
336
			$path = '';
337
		}
338
		if ($pos = strrpos($filename, '.')) {
339
			$name = substr($filename, 0, $pos);
340
			$ext = substr($filename, $pos);
341
		} else {
342
			$name = $filename;
343
			$ext = '';
344
		}
345
346
		$newpath = $path . '/' . $filename;
347
		if ($view->file_exists($newpath)) {
348
			if (preg_match_all('/\((\d+)\)/', $name, $matches, PREG_OFFSET_CAPTURE)) {
349
				//Replace the last "(number)" with "(number+1)"
350
				$last_match = count($matches[0]) - 1;
351
				$counter = $matches[1][$last_match][0] + 1;
352
				$offset = $matches[0][$last_match][1];
353
				$match_length = strlen($matches[0][$last_match][0]);
354
			} else {
355
				$counter = 2;
356
				$match_length = 0;
357
				$offset = false;
358
			}
359
			do {
360
				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...
361
					//Replace the last "(number)" with "(number+1)"
362
					$newname = substr_replace($name, '(' . $counter . ')', $offset, $match_length);
363
				} else {
364
					$newname = $name . ' (' . $counter . ')';
365
				}
366
				$newpath = $path . '/' . $newname . $ext;
367
				$counter++;
368
			} while ($view->file_exists($newpath));
369
		}
370
371
		return $newpath;
372
	}
373
374
	/**
375
	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
376
	 *
377
	 * @param array $input The array to work on
378
	 * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default)
379
	 * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8
380
	 * @return array
381
	 *
382
	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
383
	 * based on http://www.php.net/manual/en/function.array-change-key-case.php#107715
384
	 *
385
	 */
386
	public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
387
		$case = ($case != MB_CASE_UPPER) ? MB_CASE_LOWER : MB_CASE_UPPER;
388
		$ret = array();
389
		foreach ($input as $k => $v) {
390
			$ret[mb_convert_case($k, $case, $encoding)] = $v;
391
		}
392
		return $ret;
393
	}
394
395
	/**
396
	 * performs a search in a nested array
397
	 * @param array $haystack the array to be searched
398
	 * @param string $needle the search string
399
	 * @param mixed $index optional, only search this key name
400
	 * @return mixed the key of the matching field, otherwise false
401
	 *
402
	 * performs a search in a nested array
403
	 *
404
	 * taken from http://www.php.net/manual/en/function.array-search.php#97645
405
	 */
406
	public static function recursiveArraySearch($haystack, $needle, $index = null) {
407
		$aIt = new RecursiveArrayIterator($haystack);
408
		$it = new RecursiveIteratorIterator($aIt);
409
410
		while ($it->valid()) {
411
			if (((isset($index) AND ($it->key() == $index)) OR !isset($index)) AND ($it->current() == $needle)) {
412
				return $aIt->key();
413
			}
414
415
			$it->next();
416
		}
417
418
		return false;
419
	}
420
421
	/**
422
	 * calculates the maximum upload size respecting system settings, free space and user quota
423
	 *
424
	 * @param string $dir the current folder where the user currently operates
425
	 * @param int $freeSpace the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly
426
	 * @return int number of bytes representing
427
	 */
428
	public static function maxUploadFilesize($dir, $freeSpace = null) {
429
		if (is_null($freeSpace) || $freeSpace < 0){
430
			$freeSpace = self::freeSpace($dir);
431
		}
432
		return min($freeSpace, self::uploadLimit());
433
	}
434
435
	/**
436
	 * Calculate free space left within user quota
437
	 *
438
	 * @param string $dir the current folder where the user currently operates
439
	 * @return int number of bytes representing
440
	 */
441
	public static function freeSpace($dir) {
442
		$freeSpace = \OC\Files\Filesystem::free_space($dir);
443 View Code Duplication
		if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
444
			$freeSpace = max($freeSpace, 0);
445
			return $freeSpace;
446
		} else {
447
			return (INF > 0)? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
448
		}
449
	}
450
451
	/**
452
	 * Calculate PHP upload limit
453
	 *
454
	 * @return int PHP upload file size limit
455
	 */
456
	public static function uploadLimit() {
457
		$ini = \OC::$server->getIniWrapper();
458
		$upload_max_filesize = OCP\Util::computerFileSize($ini->get('upload_max_filesize'));
459
		$post_max_size = OCP\Util::computerFileSize($ini->get('post_max_size'));
460
		if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) {
461
			return INF;
462
		} elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) {
463
			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 463 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...
464
		} else {
465
			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 465 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...
466
		}
467
	}
468
469
	/**
470
	 * Checks if a function is available
471
	 *
472
	 * @param string $function_name
473
	 * @return bool
474
	 */
475
	public static function is_function_enabled($function_name) {
476
		if (!function_exists($function_name)) {
477
			return false;
478
		}
479
		$ini = \OC::$server->getIniWrapper();
480
		$disabled = explode(',', $ini->get('disable_functions') ?: '');
481
		$disabled = array_map('trim', $disabled);
482
		if (in_array($function_name, $disabled)) {
483
			return false;
484
		}
485
		$disabled = explode(',', $ini->get('suhosin.executor.func.blacklist') ?: '');
486
		$disabled = array_map('trim', $disabled);
487
		if (in_array($function_name, $disabled)) {
488
			return false;
489
		}
490
		return true;
491
	}
492
493
	/**
494
	 * Try to find a program
495
	 *
496
	 * @param string $program
497
	 * @return null|string
498
	 */
499
	public static function findBinaryPath($program) {
500
		$memcache = \OC::$server->getMemCacheFactory()->createDistributed('findBinaryPath');
501
		if ($memcache->hasKey($program)) {
502
			return $memcache->get($program);
503
		}
504
		$result = null;
505
		if (self::is_function_enabled('exec')) {
506
			$exeSniffer = new ExecutableFinder();
507
			// Returns null if nothing is found
508
			$result = $exeSniffer->find($program, null, ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/opt/bin']);
509
		}
510
		// store the value for 5 minutes
511
		$memcache->set($program, $result, 300);
512
		return $result;
513
	}
514
515
	/**
516
	 * Calculate the disc space for the given path
517
	 *
518
	 * @param string $path
519
	 * @param \OCP\Files\FileInfo $rootInfo (optional)
520
	 * @return array
521
	 * @throws \OCP\Files\NotFoundException
522
	 */
523
	public static function getStorageInfo($path, $rootInfo = null) {
524
		// return storage info without adding mount points
525
		$includeExtStorage = \OC::$server->getSystemConfig()->getValue('quota_include_external_storage', false);
526
527
		if (!$rootInfo) {
528
			$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, OC\Files\Filesystem::getFileInfo() does only seem to accept boolean, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
529
		}
530
		if (!$rootInfo instanceof \OCP\Files\FileInfo) {
531
			throw new \OCP\Files\NotFoundException();
532
		}
533
		$used = $rootInfo->getSize();
534
		if ($used < 0) {
535
			$used = 0;
536
		}
537
		$quota = \OCP\Files\FileInfo::SPACE_UNLIMITED;
538
		$storage = $rootInfo->getStorage();
539
		$sourceStorage = $storage;
540
		if ($storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) {
541
			$includeExtStorage = false;
542
			$sourceStorage = $storage->getSourceStorage();
543
		}
544
		if ($includeExtStorage) {
545
			if ($storage->instanceOfStorage('\OC\Files\Storage\Home')
546
				|| $storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage')
547
			) {
548
				/** @var \OC\Files\Storage\Home $storage */
549
				$userInstance = $storage->getUser();
550
				$user = ($userInstance === null) ? null : $userInstance->getUID();
551
			} else {
552
				$user = \OC::$server->getUserSession()->getUser()->getUID();
553
			}
554
			if ($user) {
555
				$quota = OC_Util::getUserQuota($user);
556
			} else {
557
				$quota = \OCP\Files\FileInfo::SPACE_UNLIMITED;
558
			}
559
			if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
560
				// always get free space / total space from root + mount points
561
				return self::getGlobalStorageInfo();
562
			}
563
		}
564
565
		// TODO: need a better way to get total space from storage
566
		if ($sourceStorage->instanceOfStorage('\OC\Files\Storage\Wrapper\Quota')) {
567
			/** @var \OC\Files\Storage\Wrapper\Quota $storage */
568
			$quota = $sourceStorage->getQuota();
569
		}
570
		$free = $sourceStorage->free_space($rootInfo->getInternalPath());
571
		if ($free >= 0) {
572
			$total = $free + $used;
573
		} else {
574
			$total = $free; //either unknown or unlimited
575
		}
576 View Code Duplication
		if ($total > 0) {
577
			if ($quota > 0 && $total > $quota) {
578
				$total = $quota;
579
			}
580
			// prevent division by zero or error codes (negative values)
581
			$relative = round(($used / $total) * 10000) / 100;
582
		} else {
583
			$relative = 0;
584
		}
585
586
		$ownerId = $storage->getOwner($path);
587
		$ownerDisplayName = '';
588
		$owner = \OC::$server->getUserManager()->get($ownerId);
589
		if($owner) {
590
			$ownerDisplayName = $owner->getDisplayName();
591
		}
592
593
		return [
594
			'free' => $free,
595
			'used' => $used,
596
			'quota' => $quota,
597
			'total' => $total,
598
			'relative' => $relative,
599
			'owner' => $ownerId,
600
			'ownerDisplayName' => $ownerDisplayName,
601
		];
602
	}
603
604
	/**
605
	 * Get storage info including all mount points and quota
606
	 *
607
	 * @return array
608
	 */
609
	private static function getGlobalStorageInfo() {
610
		$quota = OC_Util::getUserQuota(\OCP\User::getUser());
611
612
		$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...
613
		$used = $rootInfo['size'];
614
		if ($used < 0) {
615
			$used = 0;
616
		}
617
618
		$total = $quota;
619
		$free = $quota - $used;
620
621 View Code Duplication
		if ($total > 0) {
622
			if ($quota > 0 && $total > $quota) {
623
				$total = $quota;
624
			}
625
			// prevent division by zero or error codes (negative values)
626
			$relative = round(($used / $total) * 10000) / 100;
627
		} else {
628
			$relative = 0;
629
		}
630
631
		return array('free' => $free, 'used' => $used, 'total' => $total, 'relative' => $relative);
632
633
	}
634
635
	/**
636
	 * Returns whether the config file is set manually to read-only
637
	 * @return bool
638
	 */
639
	public static function isReadOnlyConfigEnabled() {
640
		return \OC::$server->getConfig()->getSystemValue('config_is_read_only', false);
641
	}
642
}
643