Passed
Push — master ( 1b4788...6ed728 )
by Morris
14:38 queued 12s
created

OC_Helper::isReadOnlyConfigEnabled()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
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 Christoph Wurst <[email protected]>
10
 * @author Daniel Kesselberg <[email protected]>
11
 * @author Felix Moeller <[email protected]>
12
 * @author J0WI <[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 Julius Härtl <[email protected]>
18
 * @author Lukas Reschke <[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
47
use bantu\IniGetWrapper\IniGetWrapper;
48
use OCP\Files\Mount\IMountPoint;
49
use OCP\IUser;
50
use Symfony\Component\Process\ExecutableFinder;
51
52
/**
53
 * Collection of useful functions
54
 */
55
class OC_Helper {
56
	private static $templateManager;
57
58
	/**
59
	 * Make a human file size
60
	 * @param int $bytes file size in bytes
61
	 * @return string a human readable file size
62
	 *
63
	 * Makes 2048 to 2 kB.
64
	 */
65
	public static function humanFileSize($bytes) {
66
		if ($bytes < 0) {
67
			return "?";
68
		}
69
		if ($bytes < 1024) {
70
			return "$bytes B";
71
		}
72
		$bytes = round($bytes / 1024, 0);
73
		if ($bytes < 1024) {
74
			return "$bytes KB";
75
		}
76
		$bytes = round($bytes / 1024, 1);
77
		if ($bytes < 1024) {
78
			return "$bytes MB";
79
		}
80
		$bytes = round($bytes / 1024, 1);
81
		if ($bytes < 1024) {
82
			return "$bytes GB";
83
		}
84
		$bytes = round($bytes / 1024, 1);
85
		if ($bytes < 1024) {
86
			return "$bytes TB";
87
		}
88
89
		$bytes = round($bytes / 1024, 1);
90
		return "$bytes PB";
91
	}
92
93
	/**
94
	 * Make a computer file size
95
	 * @param string $str file size in human readable format
96
	 * @return float|bool a file size in bytes
97
	 *
98
	 * Makes 2kB to 2048.
99
	 *
100
	 * Inspired by: https://www.php.net/manual/en/function.filesize.php#92418
101
	 */
102
	public static function computerFileSize($str) {
103
		$str = strtolower($str);
104
		if (is_numeric($str)) {
105
			return (float)$str;
106
		}
107
108
		$bytes_array = [
109
			'b' => 1,
110
			'k' => 1024,
111
			'kb' => 1024,
112
			'mb' => 1024 * 1024,
113
			'm' => 1024 * 1024,
114
			'gb' => 1024 * 1024 * 1024,
115
			'g' => 1024 * 1024 * 1024,
116
			'tb' => 1024 * 1024 * 1024 * 1024,
117
			't' => 1024 * 1024 * 1024 * 1024,
118
			'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
119
			'p' => 1024 * 1024 * 1024 * 1024 * 1024,
120
		];
121
122
		$bytes = (float)$str;
123
124
		if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) {
125
			$bytes *= $bytes_array[$matches[1]];
126
		} else {
127
			return false;
128
		}
129
130
		$bytes = round($bytes);
131
132
		return $bytes;
133
	}
134
135
	/**
136
	 * Recursive copying of folders
137
	 * @param string $src source folder
138
	 * @param string $dest target folder
139
	 *
140
	 */
141
	public static function copyr($src, $dest) {
142
		if (is_dir($src)) {
143
			if (!is_dir($dest)) {
144
				mkdir($dest);
145
			}
146
			$files = scandir($src);
147
			foreach ($files as $file) {
148
				if ($file != "." && $file != "..") {
149
					self::copyr("$src/$file", "$dest/$file");
150
				}
151
			}
152
		} elseif (file_exists($src) && !\OC\Files\Filesystem::isFileBlacklisted($src)) {
153
			copy($src, $dest);
154
		}
155
	}
156
157
	/**
158
	 * Recursive deletion of folders
159
	 * @param string $dir path to the folder
160
	 * @param bool $deleteSelf if set to false only the content of the folder will be deleted
161
	 * @return bool
162
	 */
163
	public static function rmdirr($dir, $deleteSelf = true) {
164
		if (is_dir($dir)) {
165
			$files = new RecursiveIteratorIterator(
166
				new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
167
				RecursiveIteratorIterator::CHILD_FIRST
168
			);
169
170
			foreach ($files as $fileInfo) {
171
				/** @var SplFileInfo $fileInfo */
172
				if ($fileInfo->isLink()) {
173
					unlink($fileInfo->getPathname());
174
				} elseif ($fileInfo->isDir()) {
175
					rmdir($fileInfo->getRealPath());
176
				} else {
177
					unlink($fileInfo->getRealPath());
178
				}
179
			}
180
			if ($deleteSelf) {
181
				rmdir($dir);
182
			}
183
		} elseif (file_exists($dir)) {
184
			if ($deleteSelf) {
185
				unlink($dir);
186
			}
187
		}
188
		if (!$deleteSelf) {
189
			return true;
190
		}
191
192
		return !file_exists($dir);
193
	}
194
195
	/**
196
	 * @deprecated 18.0.0
197
	 * @return \OC\Files\Type\TemplateManager
198
	 */
199
	public static function getFileTemplateManager() {
200
		if (!self::$templateManager) {
201
			self::$templateManager = new \OC\Files\Type\TemplateManager();
0 ignored issues
show
Deprecated Code introduced by
The class OC\Files\Type\TemplateManager has been deprecated: 18.0.0 ( Ignorable by Annotation )

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

201
			self::$templateManager = /** @scrutinizer ignore-deprecated */ new \OC\Files\Type\TemplateManager();
Loading history...
202
		}
203
		return self::$templateManager;
204
	}
205
206
	/**
207
	 * detect if a given program is found in the search PATH
208
	 *
209
	 * @param string $name
210
	 * @param bool $path
211
	 * @internal param string $program name
212
	 * @internal param string $optional search path, defaults to $PATH
213
	 * @return bool    true if executable program found in path
214
	 */
215
	public static function canExecute($name, $path = false) {
216
		// path defaults to PATH from environment if not set
217
		if ($path === false) {
218
			$path = getenv("PATH");
219
		}
220
		// we look for an executable file of that name
221
		$exts = [""];
222
		$check_fn = "is_executable";
223
		// Default check will be done with $path directories :
224
		$dirs = explode(PATH_SEPARATOR, $path);
225
		// WARNING : We have to check if open_basedir is enabled :
226
		$obd = OC::$server->get(IniGetWrapper::class)->getString('open_basedir');
227
		if ($obd != "none") {
228
			$obd_values = explode(PATH_SEPARATOR, $obd);
229
			if (count($obd_values) > 0 and $obd_values[0]) {
230
				// open_basedir is in effect !
231
				// We need to check if the program is in one of these dirs :
232
				$dirs = $obd_values;
233
			}
234
		}
235
		foreach ($dirs as $dir) {
236
			foreach ($exts as $ext) {
237
				if ($check_fn("$dir/$name" . $ext)) {
238
					return true;
239
				}
240
			}
241
		}
242
		return false;
243
	}
244
245
	/**
246
	 * copy the contents of one stream to another
247
	 *
248
	 * @param resource $source
249
	 * @param resource $target
250
	 * @return array the number of bytes copied and result
251
	 */
252
	public static function streamCopy($source, $target) {
253
		if (!$source or !$target) {
0 ignored issues
show
introduced by
$source is of type resource, thus it always evaluated to false.
Loading history...
254
			return [0, false];
255
		}
256
		$bufSize = 8192;
257
		$result = true;
258
		$count = 0;
259
		while (!feof($source)) {
260
			$buf = fread($source, $bufSize);
261
			$bytesWritten = fwrite($target, $buf);
262
			if ($bytesWritten !== false) {
263
				$count += $bytesWritten;
264
			}
265
			// note: strlen is expensive so only use it when necessary,
266
			// on the last block
267
			if ($bytesWritten === false
268
				|| ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
269
			) {
270
				// write error, could be disk full ?
271
				$result = false;
272
				break;
273
			}
274
		}
275
		return [$count, $result];
276
	}
277
278
	/**
279
	 * Adds a suffix to the name in case the file exists
280
	 *
281
	 * @param string $path
282
	 * @param string $filename
283
	 * @return string
284
	 */
285
	public static function buildNotExistingFileName($path, $filename) {
286
		$view = \OC\Files\Filesystem::getView();
287
		return self::buildNotExistingFileNameForView($path, $filename, $view);
288
	}
289
290
	/**
291
	 * Adds a suffix to the name in case the file exists
292
	 *
293
	 * @param string $path
294
	 * @param string $filename
295
	 * @return string
296
	 */
297
	public static function buildNotExistingFileNameForView($path, $filename, \OC\Files\View $view) {
298
		if ($path === '/') {
299
			$path = '';
300
		}
301
		if ($pos = strrpos($filename, '.')) {
302
			$name = substr($filename, 0, $pos);
303
			$ext = substr($filename, $pos);
304
		} else {
305
			$name = $filename;
306
			$ext = '';
307
		}
308
309
		$newpath = $path . '/' . $filename;
310
		if ($view->file_exists($newpath)) {
311
			if (preg_match_all('/\((\d+)\)/', $name, $matches, PREG_OFFSET_CAPTURE)) {
312
				//Replace the last "(number)" with "(number+1)"
313
				$last_match = count($matches[0]) - 1;
314
				$counter = $matches[1][$last_match][0] + 1;
315
				$offset = $matches[0][$last_match][1];
316
				$match_length = strlen($matches[0][$last_match][0]);
317
			} else {
318
				$counter = 2;
319
				$match_length = 0;
320
				$offset = false;
321
			}
322
			do {
323
				if ($offset) {
324
					//Replace the last "(number)" with "(number+1)"
325
					$newname = substr_replace($name, '(' . $counter . ')', $offset, $match_length);
326
				} else {
327
					$newname = $name . ' (' . $counter . ')';
328
				}
329
				$newpath = $path . '/' . $newname . $ext;
0 ignored issues
show
Bug introduced by
Are you sure $newname of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

329
				$newpath = $path . '/' . /** @scrutinizer ignore-type */ $newname . $ext;
Loading history...
330
				$counter++;
331
			} while ($view->file_exists($newpath));
332
		}
333
334
		return $newpath;
335
	}
336
337
	/**
338
	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
339
	 *
340
	 * @param array $input The array to work on
341
	 * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default)
342
	 * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8
343
	 * @return array
344
	 *
345
	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
346
	 * based on https://www.php.net/manual/en/function.array-change-key-case.php#107715
347
	 *
348
	 */
349
	public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
350
		$case = ($case != MB_CASE_UPPER) ? MB_CASE_LOWER : MB_CASE_UPPER;
351
		$ret = [];
352
		foreach ($input as $k => $v) {
353
			$ret[mb_convert_case($k, $case, $encoding)] = $v;
354
		}
355
		return $ret;
356
	}
357
358
	/**
359
	 * performs a search in a nested array
360
	 * @param array $haystack the array to be searched
361
	 * @param string $needle the search string
362
	 * @param mixed $index optional, only search this key name
363
	 * @return mixed the key of the matching field, otherwise false
364
	 *
365
	 * performs a search in a nested array
366
	 *
367
	 * taken from https://www.php.net/manual/en/function.array-search.php#97645
368
	 */
369
	public static function recursiveArraySearch($haystack, $needle, $index = null) {
370
		$aIt = new RecursiveArrayIterator($haystack);
371
		$it = new RecursiveIteratorIterator($aIt);
372
373
		while ($it->valid()) {
374
			if (((isset($index) and ($it->key() == $index)) or !isset($index)) and ($it->current() == $needle)) {
375
				return $aIt->key();
376
			}
377
378
			$it->next();
379
		}
380
381
		return false;
382
	}
383
384
	/**
385
	 * calculates the maximum upload size respecting system settings, free space and user quota
386
	 *
387
	 * @param string $dir the current folder where the user currently operates
388
	 * @param int $freeSpace the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly
389
	 * @return int number of bytes representing
390
	 */
391
	public static function maxUploadFilesize($dir, $freeSpace = null) {
392
		if (is_null($freeSpace) || $freeSpace < 0) {
393
			$freeSpace = self::freeSpace($dir);
394
		}
395
		return min($freeSpace, self::uploadLimit());
396
	}
397
398
	/**
399
	 * Calculate free space left within user quota
400
	 *
401
	 * @param string $dir the current folder where the user currently operates
402
	 * @return int number of bytes representing
403
	 */
404
	public static function freeSpace($dir) {
405
		$freeSpace = \OC\Files\Filesystem::free_space($dir);
406
		if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
407
			$freeSpace = max($freeSpace, 0);
408
			return $freeSpace;
409
		} else {
410
			return (INF > 0)? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
411
		}
412
	}
413
414
	/**
415
	 * Calculate PHP upload limit
416
	 *
417
	 * @return int PHP upload file size limit
418
	 */
419
	public static function uploadLimit() {
420
		$ini = \OC::$server->get(IniGetWrapper::class);
421
		$upload_max_filesize = OCP\Util::computerFileSize($ini->get('upload_max_filesize'));
422
		$post_max_size = OCP\Util::computerFileSize($ini->get('post_max_size'));
423
		if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) {
424
			return INF;
425
		} elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) {
426
			return max($upload_max_filesize, $post_max_size); //only the non 0 value counts
427
		} else {
428
			return min($upload_max_filesize, $post_max_size);
429
		}
430
	}
431
432
	/**
433
	 * Checks if a function is available
434
	 *
435
	 * @param string $function_name
436
	 * @return bool
437
	 */
438
	public static function is_function_enabled($function_name) {
439
		if (!function_exists($function_name)) {
440
			return false;
441
		}
442
		$ini = \OC::$server->get(IniGetWrapper::class);
443
		$disabled = explode(',', $ini->get('disable_functions') ?: '');
444
		$disabled = array_map('trim', $disabled);
445
		if (in_array($function_name, $disabled)) {
446
			return false;
447
		}
448
		$disabled = explode(',', $ini->get('suhosin.executor.func.blacklist') ?: '');
449
		$disabled = array_map('trim', $disabled);
450
		if (in_array($function_name, $disabled)) {
451
			return false;
452
		}
453
		return true;
454
	}
455
456
	/**
457
	 * Try to find a program
458
	 *
459
	 * @param string $program
460
	 * @return null|string
461
	 */
462
	public static function findBinaryPath($program) {
463
		$memcache = \OC::$server->getMemCacheFactory()->createDistributed('findBinaryPath');
464
		if ($memcache->hasKey($program)) {
465
			return $memcache->get($program);
466
		}
467
		$result = null;
468
		if (self::is_function_enabled('exec')) {
469
			$exeSniffer = new ExecutableFinder();
470
			// Returns null if nothing is found
471
			$result = $exeSniffer->find($program, null, ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/opt/bin']);
472
		}
473
		// store the value for 5 minutes
474
		$memcache->set($program, $result, 300);
475
		return $result;
476
	}
477
478
	/**
479
	 * Calculate the disc space for the given path
480
	 *
481
	 * BEWARE: this requires that Util::setupFS() was called
482
	 * already !
483
	 *
484
	 * @param string $path
485
	 * @param \OCP\Files\FileInfo $rootInfo (optional)
486
	 * @return array
487
	 * @throws \OCP\Files\NotFoundException
488
	 */
489
	public static function getStorageInfo($path, $rootInfo = null) {
490
		// return storage info without adding mount points
491
		$includeExtStorage = \OC::$server->getSystemConfig()->getValue('quota_include_external_storage', false);
492
493
		if (!$rootInfo) {
494
			$rootInfo = \OC\Files\Filesystem::getFileInfo($path, $includeExtStorage ? 'ext' : false);
495
		}
496
		if (!$rootInfo instanceof \OCP\Files\FileInfo) {
497
			throw new \OCP\Files\NotFoundException();
498
		}
499
		$used = $rootInfo->getSize();
500
		if ($used < 0) {
501
			$used = 0;
502
		}
503
		$quota = \OCP\Files\FileInfo::SPACE_UNLIMITED;
504
		$mount = $rootInfo->getMountPoint();
505
		$storage = $mount->getStorage();
506
		$sourceStorage = $storage;
507
		if ($storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) {
508
			$includeExtStorage = false;
509
			$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

509
			/** @scrutinizer ignore-call */ 
510
   $sourceStorage = $storage->getSourceStorage();
Loading history...
510
		}
511
		if ($includeExtStorage) {
512
			if ($storage->instanceOfStorage('\OC\Files\Storage\Home')
513
				|| $storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage')
514
			) {
515
				/** @var \OC\Files\Storage\Home $storage */
516
				$user = $storage->getUser();
517
			} else {
518
				$user = \OC::$server->getUserSession()->getUser();
519
			}
520
			$quota = OC_Util::getUserQuota($user);
521
			if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
522
				// always get free space / total space from root + mount points
523
				return self::getGlobalStorageInfo($quota, $user, $mount);
0 ignored issues
show
Bug introduced by
$quota of type double is incompatible with the type integer expected by parameter $quota of OC_Helper::getGlobalStorageInfo(). ( Ignorable by Annotation )

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

523
				return self::getGlobalStorageInfo(/** @scrutinizer ignore-type */ $quota, $user, $mount);
Loading history...
524
			}
525
		}
526
527
		// TODO: need a better way to get total space from storage
528
		if ($sourceStorage->instanceOfStorage('\OC\Files\Storage\Wrapper\Quota')) {
529
			/** @var \OC\Files\Storage\Wrapper\Quota $storage */
530
			$quota = $sourceStorage->getQuota();
531
		}
532
		$free = $sourceStorage->free_space($rootInfo->getInternalPath());
533
		if ($free >= 0) {
534
			$total = $free + $used;
535
		} else {
536
			$total = $free; //either unknown or unlimited
537
		}
538
		if ($total > 0) {
539
			if ($quota > 0 && $total > $quota) {
540
				$total = $quota;
541
			}
542
			// prevent division by zero or error codes (negative values)
543
			$relative = round(($used / $total) * 10000) / 100;
544
		} else {
545
			$relative = 0;
546
		}
547
548
		$ownerId = $storage->getOwner($path);
549
		$ownerDisplayName = '';
550
		$owner = \OC::$server->getUserManager()->get($ownerId);
551
		if ($owner) {
552
			$ownerDisplayName = $owner->getDisplayName();
553
		}
554
		if (substr_count($mount->getMountPoint(), '/') < 3) {
555
			$mountPoint = '';
556
		} else {
557
			[,,,$mountPoint] = explode('/', $mount->getMountPoint(), 4);
558
		}
559
560
		return [
561
			'free' => $free,
562
			'used' => $used,
563
			'quota' => $quota,
564
			'total' => $total,
565
			'relative' => $relative,
566
			'owner' => $ownerId,
567
			'ownerDisplayName' => $ownerDisplayName,
568
			'mountType' => $mount->getMountType(),
569
			'mountPoint' => trim($mountPoint, '/'),
570
		];
571
	}
572
573
	/**
574
	 * Get storage info including all mount points and quota
575
	 */
576
	private static function getGlobalStorageInfo(int $quota, IUser $user, IMountPoint $mount): array {
577
		$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

577
		$rootInfo = \OC\Files\Filesystem::getFileInfo('', /** @scrutinizer ignore-type */ 'ext');
Loading history...
578
		$used = $rootInfo['size'];
579
		if ($used < 0) {
580
			$used = 0;
581
		}
582
583
		$total = $quota;
584
		$free = $quota - $used;
585
586
		if ($total > 0) {
587
			if ($quota > 0 && $total > $quota) {
588
				$total = $quota;
589
			}
590
			// prevent division by zero or error codes (negative values)
591
			$relative = round(($used / $total) * 10000) / 100;
592
		} else {
593
			$relative = 0;
594
		}
595
596
		if (substr_count($mount->getMountPoint(), '/') < 3) {
597
			$mountPoint = '';
598
		} else {
599
			[,,,$mountPoint] = explode('/', $mount->getMountPoint(), 4);
600
		}
601
602
		return [
603
			'free' => $free,
604
			'used' => $used,
605
			'total' => $total,
606
			'relative' => $relative,
607
			'quota' => $quota,
608
			'owner' => $user->getUID(),
609
			'ownerDisplayName' => $user->getDisplayName(),
610
			'mountType' => $mount->getMountType(),
611
			'mountPoint' => trim($mountPoint, '/'),
612
		];
613
	}
614
615
	/**
616
	 * Returns whether the config file is set manually to read-only
617
	 * @return bool
618
	 */
619
	public static function isReadOnlyConfigEnabled() {
620
		return \OC::$server->getConfig()->getSystemValue('config_is_read_only', false);
621
	}
622
}
623