Passed
Push — master ( 170348...d0f738 )
by Christoph
12:31 queued 10s
created
lib/private/legacy/OC_Helper.php 1 patch
Indentation   +559 added lines, -559 removed lines patch added patch discarded remove patch
@@ -50,563 +50,563 @@
 block discarded – undo
50 50
  * Collection of useful functions
51 51
  */
52 52
 class OC_Helper {
53
-	private static $templateManager;
54
-
55
-	/**
56
-	 * Make a human file size
57
-	 * @param int $bytes file size in bytes
58
-	 * @return string a human readable file size
59
-	 *
60
-	 * Makes 2048 to 2 kB.
61
-	 */
62
-	public static function humanFileSize($bytes) {
63
-		if ($bytes < 0) {
64
-			return "?";
65
-		}
66
-		if ($bytes < 1024) {
67
-			return "$bytes B";
68
-		}
69
-		$bytes = round($bytes / 1024, 0);
70
-		if ($bytes < 1024) {
71
-			return "$bytes KB";
72
-		}
73
-		$bytes = round($bytes / 1024, 1);
74
-		if ($bytes < 1024) {
75
-			return "$bytes MB";
76
-		}
77
-		$bytes = round($bytes / 1024, 1);
78
-		if ($bytes < 1024) {
79
-			return "$bytes GB";
80
-		}
81
-		$bytes = round($bytes / 1024, 1);
82
-		if ($bytes < 1024) {
83
-			return "$bytes TB";
84
-		}
85
-
86
-		$bytes = round($bytes / 1024, 1);
87
-		return "$bytes PB";
88
-	}
89
-
90
-	/**
91
-	 * Make a computer file size
92
-	 * @param string $str file size in human readable format
93
-	 * @return float|bool a file size in bytes
94
-	 *
95
-	 * Makes 2kB to 2048.
96
-	 *
97
-	 * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418
98
-	 */
99
-	public static function computerFileSize($str) {
100
-		$str = strtolower($str);
101
-		if (is_numeric($str)) {
102
-			return (float)$str;
103
-		}
104
-
105
-		$bytes_array = [
106
-			'b' => 1,
107
-			'k' => 1024,
108
-			'kb' => 1024,
109
-			'mb' => 1024 * 1024,
110
-			'm' => 1024 * 1024,
111
-			'gb' => 1024 * 1024 * 1024,
112
-			'g' => 1024 * 1024 * 1024,
113
-			'tb' => 1024 * 1024 * 1024 * 1024,
114
-			't' => 1024 * 1024 * 1024 * 1024,
115
-			'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
116
-			'p' => 1024 * 1024 * 1024 * 1024 * 1024,
117
-		];
118
-
119
-		$bytes = (float)$str;
120
-
121
-		if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) {
122
-			$bytes *= $bytes_array[$matches[1]];
123
-		} else {
124
-			return false;
125
-		}
126
-
127
-		$bytes = round($bytes);
128
-
129
-		return $bytes;
130
-	}
131
-
132
-	/**
133
-	 * Recursive copying of folders
134
-	 * @param string $src source folder
135
-	 * @param string $dest target folder
136
-	 *
137
-	 */
138
-	public static function copyr($src, $dest) {
139
-		if (is_dir($src)) {
140
-			if (!is_dir($dest)) {
141
-				mkdir($dest);
142
-			}
143
-			$files = scandir($src);
144
-			foreach ($files as $file) {
145
-				if ($file != "." && $file != "..") {
146
-					self::copyr("$src/$file", "$dest/$file");
147
-				}
148
-			}
149
-		} elseif (file_exists($src) && !\OC\Files\Filesystem::isFileBlacklisted($src)) {
150
-			copy($src, $dest);
151
-		}
152
-	}
153
-
154
-	/**
155
-	 * Recursive deletion of folders
156
-	 * @param string $dir path to the folder
157
-	 * @param bool $deleteSelf if set to false only the content of the folder will be deleted
158
-	 * @return bool
159
-	 */
160
-	public static function rmdirr($dir, $deleteSelf = true) {
161
-		if (is_dir($dir)) {
162
-			$files = new RecursiveIteratorIterator(
163
-				new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
164
-				RecursiveIteratorIterator::CHILD_FIRST
165
-			);
166
-
167
-			foreach ($files as $fileInfo) {
168
-				/** @var SplFileInfo $fileInfo */
169
-				if ($fileInfo->isLink()) {
170
-					unlink($fileInfo->getPathname());
171
-				} elseif ($fileInfo->isDir()) {
172
-					rmdir($fileInfo->getRealPath());
173
-				} else {
174
-					unlink($fileInfo->getRealPath());
175
-				}
176
-			}
177
-			if ($deleteSelf) {
178
-				rmdir($dir);
179
-			}
180
-		} elseif (file_exists($dir)) {
181
-			if ($deleteSelf) {
182
-				unlink($dir);
183
-			}
184
-		}
185
-		if (!$deleteSelf) {
186
-			return true;
187
-		}
188
-
189
-		return !file_exists($dir);
190
-	}
191
-
192
-	/**
193
-	 * @deprecated 18.0.0
194
-	 * @return \OC\Files\Type\TemplateManager
195
-	 */
196
-	public static function getFileTemplateManager() {
197
-		if (!self::$templateManager) {
198
-			self::$templateManager = new \OC\Files\Type\TemplateManager();
199
-		}
200
-		return self::$templateManager;
201
-	}
202
-
203
-	/**
204
-	 * detect if a given program is found in the search PATH
205
-	 *
206
-	 * @param string $name
207
-	 * @param bool $path
208
-	 * @internal param string $program name
209
-	 * @internal param string $optional search path, defaults to $PATH
210
-	 * @return bool    true if executable program found in path
211
-	 */
212
-	public static function canExecute($name, $path = false) {
213
-		// path defaults to PATH from environment if not set
214
-		if ($path === false) {
215
-			$path = getenv("PATH");
216
-		}
217
-		// we look for an executable file of that name
218
-		$exts = [""];
219
-		$check_fn = "is_executable";
220
-		// Default check will be done with $path directories :
221
-		$dirs = explode(PATH_SEPARATOR, $path);
222
-		// WARNING : We have to check if open_basedir is enabled :
223
-		$obd = OC::$server->get(IniGetWrapper::class)->getString('open_basedir');
224
-		if ($obd != "none") {
225
-			$obd_values = explode(PATH_SEPARATOR, $obd);
226
-			if (count($obd_values) > 0 and $obd_values[0]) {
227
-				// open_basedir is in effect !
228
-				// We need to check if the program is in one of these dirs :
229
-				$dirs = $obd_values;
230
-			}
231
-		}
232
-		foreach ($dirs as $dir) {
233
-			foreach ($exts as $ext) {
234
-				if ($check_fn("$dir/$name" . $ext)) {
235
-					return true;
236
-				}
237
-			}
238
-		}
239
-		return false;
240
-	}
241
-
242
-	/**
243
-	 * copy the contents of one stream to another
244
-	 *
245
-	 * @param resource $source
246
-	 * @param resource $target
247
-	 * @return array the number of bytes copied and result
248
-	 */
249
-	public static function streamCopy($source, $target) {
250
-		if (!$source or !$target) {
251
-			return [0, false];
252
-		}
253
-		$bufSize = 8192;
254
-		$result = true;
255
-		$count = 0;
256
-		while (!feof($source)) {
257
-			$buf = fread($source, $bufSize);
258
-			$bytesWritten = fwrite($target, $buf);
259
-			if ($bytesWritten !== false) {
260
-				$count += $bytesWritten;
261
-			}
262
-			// note: strlen is expensive so only use it when necessary,
263
-			// on the last block
264
-			if ($bytesWritten === false
265
-				|| ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
266
-			) {
267
-				// write error, could be disk full ?
268
-				$result = false;
269
-				break;
270
-			}
271
-		}
272
-		return [$count, $result];
273
-	}
274
-
275
-	/**
276
-	 * Adds a suffix to the name in case the file exists
277
-	 *
278
-	 * @param string $path
279
-	 * @param string $filename
280
-	 * @return string
281
-	 */
282
-	public static function buildNotExistingFileName($path, $filename) {
283
-		$view = \OC\Files\Filesystem::getView();
284
-		return self::buildNotExistingFileNameForView($path, $filename, $view);
285
-	}
286
-
287
-	/**
288
-	 * Adds a suffix to the name in case the file exists
289
-	 *
290
-	 * @param string $path
291
-	 * @param string $filename
292
-	 * @return string
293
-	 */
294
-	public static function buildNotExistingFileNameForView($path, $filename, \OC\Files\View $view) {
295
-		if ($path === '/') {
296
-			$path = '';
297
-		}
298
-		if ($pos = strrpos($filename, '.')) {
299
-			$name = substr($filename, 0, $pos);
300
-			$ext = substr($filename, $pos);
301
-		} else {
302
-			$name = $filename;
303
-			$ext = '';
304
-		}
305
-
306
-		$newpath = $path . '/' . $filename;
307
-		if ($view->file_exists($newpath)) {
308
-			if (preg_match_all('/\((\d+)\)/', $name, $matches, PREG_OFFSET_CAPTURE)) {
309
-				//Replace the last "(number)" with "(number+1)"
310
-				$last_match = count($matches[0]) - 1;
311
-				$counter = $matches[1][$last_match][0] + 1;
312
-				$offset = $matches[0][$last_match][1];
313
-				$match_length = strlen($matches[0][$last_match][0]);
314
-			} else {
315
-				$counter = 2;
316
-				$match_length = 0;
317
-				$offset = false;
318
-			}
319
-			do {
320
-				if ($offset) {
321
-					//Replace the last "(number)" with "(number+1)"
322
-					$newname = substr_replace($name, '(' . $counter . ')', $offset, $match_length);
323
-				} else {
324
-					$newname = $name . ' (' . $counter . ')';
325
-				}
326
-				$newpath = $path . '/' . $newname . $ext;
327
-				$counter++;
328
-			} while ($view->file_exists($newpath));
329
-		}
330
-
331
-		return $newpath;
332
-	}
333
-
334
-	/**
335
-	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
336
-	 *
337
-	 * @param array $input The array to work on
338
-	 * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default)
339
-	 * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8
340
-	 * @return array
341
-	 *
342
-	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
343
-	 * based on http://www.php.net/manual/en/function.array-change-key-case.php#107715
344
-	 *
345
-	 */
346
-	public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
347
-		$case = ($case != MB_CASE_UPPER) ? MB_CASE_LOWER : MB_CASE_UPPER;
348
-		$ret = [];
349
-		foreach ($input as $k => $v) {
350
-			$ret[mb_convert_case($k, $case, $encoding)] = $v;
351
-		}
352
-		return $ret;
353
-	}
354
-
355
-	/**
356
-	 * performs a search in a nested array
357
-	 * @param array $haystack the array to be searched
358
-	 * @param string $needle the search string
359
-	 * @param mixed $index optional, only search this key name
360
-	 * @return mixed the key of the matching field, otherwise false
361
-	 *
362
-	 * performs a search in a nested array
363
-	 *
364
-	 * taken from http://www.php.net/manual/en/function.array-search.php#97645
365
-	 */
366
-	public static function recursiveArraySearch($haystack, $needle, $index = null) {
367
-		$aIt = new RecursiveArrayIterator($haystack);
368
-		$it = new RecursiveIteratorIterator($aIt);
369
-
370
-		while ($it->valid()) {
371
-			if (((isset($index) and ($it->key() == $index)) or !isset($index)) and ($it->current() == $needle)) {
372
-				return $aIt->key();
373
-			}
374
-
375
-			$it->next();
376
-		}
377
-
378
-		return false;
379
-	}
380
-
381
-	/**
382
-	 * calculates the maximum upload size respecting system settings, free space and user quota
383
-	 *
384
-	 * @param string $dir the current folder where the user currently operates
385
-	 * @param int $freeSpace the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly
386
-	 * @return int number of bytes representing
387
-	 */
388
-	public static function maxUploadFilesize($dir, $freeSpace = null) {
389
-		if (is_null($freeSpace) || $freeSpace < 0) {
390
-			$freeSpace = self::freeSpace($dir);
391
-		}
392
-		return min($freeSpace, self::uploadLimit());
393
-	}
394
-
395
-	/**
396
-	 * Calculate free space left within user quota
397
-	 *
398
-	 * @param string $dir the current folder where the user currently operates
399
-	 * @return int number of bytes representing
400
-	 */
401
-	public static function freeSpace($dir) {
402
-		$freeSpace = \OC\Files\Filesystem::free_space($dir);
403
-		if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
404
-			$freeSpace = max($freeSpace, 0);
405
-			return $freeSpace;
406
-		} else {
407
-			return (INF > 0)? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
408
-		}
409
-	}
410
-
411
-	/**
412
-	 * Calculate PHP upload limit
413
-	 *
414
-	 * @return int PHP upload file size limit
415
-	 */
416
-	public static function uploadLimit() {
417
-		$ini = \OC::$server->get(IniGetWrapper::class);
418
-		$upload_max_filesize = OCP\Util::computerFileSize($ini->get('upload_max_filesize'));
419
-		$post_max_size = OCP\Util::computerFileSize($ini->get('post_max_size'));
420
-		if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) {
421
-			return INF;
422
-		} elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) {
423
-			return max($upload_max_filesize, $post_max_size); //only the non 0 value counts
424
-		} else {
425
-			return min($upload_max_filesize, $post_max_size);
426
-		}
427
-	}
428
-
429
-	/**
430
-	 * Checks if a function is available
431
-	 *
432
-	 * @param string $function_name
433
-	 * @return bool
434
-	 */
435
-	public static function is_function_enabled($function_name) {
436
-		if (!function_exists($function_name)) {
437
-			return false;
438
-		}
439
-		$ini = \OC::$server->get(IniGetWrapper::class);
440
-		$disabled = explode(',', $ini->get('disable_functions') ?: '');
441
-		$disabled = array_map('trim', $disabled);
442
-		if (in_array($function_name, $disabled)) {
443
-			return false;
444
-		}
445
-		$disabled = explode(',', $ini->get('suhosin.executor.func.blacklist') ?: '');
446
-		$disabled = array_map('trim', $disabled);
447
-		if (in_array($function_name, $disabled)) {
448
-			return false;
449
-		}
450
-		return true;
451
-	}
452
-
453
-	/**
454
-	 * Try to find a program
455
-	 *
456
-	 * @param string $program
457
-	 * @return null|string
458
-	 */
459
-	public static function findBinaryPath($program) {
460
-		$memcache = \OC::$server->getMemCacheFactory()->createDistributed('findBinaryPath');
461
-		if ($memcache->hasKey($program)) {
462
-			return $memcache->get($program);
463
-		}
464
-		$result = null;
465
-		if (self::is_function_enabled('exec')) {
466
-			$exeSniffer = new ExecutableFinder();
467
-			// Returns null if nothing is found
468
-			$result = $exeSniffer->find($program, null, ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/opt/bin']);
469
-		}
470
-		// store the value for 5 minutes
471
-		$memcache->set($program, $result, 300);
472
-		return $result;
473
-	}
474
-
475
-	/**
476
-	 * Calculate the disc space for the given path
477
-	 *
478
-	 * BEWARE: this requires that Util::setupFS() was called
479
-	 * already !
480
-	 *
481
-	 * @param string $path
482
-	 * @param \OCP\Files\FileInfo $rootInfo (optional)
483
-	 * @return array
484
-	 * @throws \OCP\Files\NotFoundException
485
-	 */
486
-	public static function getStorageInfo($path, $rootInfo = null) {
487
-		// return storage info without adding mount points
488
-		$includeExtStorage = \OC::$server->getSystemConfig()->getValue('quota_include_external_storage', false);
489
-
490
-		if (!$rootInfo) {
491
-			$rootInfo = \OC\Files\Filesystem::getFileInfo($path, $includeExtStorage ? 'ext' : false);
492
-		}
493
-		if (!$rootInfo instanceof \OCP\Files\FileInfo) {
494
-			throw new \OCP\Files\NotFoundException();
495
-		}
496
-		$used = $rootInfo->getSize();
497
-		if ($used < 0) {
498
-			$used = 0;
499
-		}
500
-		$quota = \OCP\Files\FileInfo::SPACE_UNLIMITED;
501
-		$mount = $rootInfo->getMountPoint();
502
-		$storage = $mount->getStorage();
503
-		$sourceStorage = $storage;
504
-		if ($storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) {
505
-			$includeExtStorage = false;
506
-			$sourceStorage = $storage->getSourceStorage();
507
-		}
508
-		if ($includeExtStorage) {
509
-			if ($storage->instanceOfStorage('\OC\Files\Storage\Home')
510
-				|| $storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage')
511
-			) {
512
-				/** @var \OC\Files\Storage\Home $storage */
513
-				$user = $storage->getUser();
514
-			} else {
515
-				$user = \OC::$server->getUserSession()->getUser();
516
-			}
517
-			$quota = OC_Util::getUserQuota($user);
518
-			if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
519
-				// always get free space / total space from root + mount points
520
-				return self::getGlobalStorageInfo($quota);
521
-			}
522
-		}
523
-
524
-		// TODO: need a better way to get total space from storage
525
-		if ($sourceStorage->instanceOfStorage('\OC\Files\Storage\Wrapper\Quota')) {
526
-			/** @var \OC\Files\Storage\Wrapper\Quota $storage */
527
-			$quota = $sourceStorage->getQuota();
528
-		}
529
-		$free = $sourceStorage->free_space($rootInfo->getInternalPath());
530
-		if ($free >= 0) {
531
-			$total = $free + $used;
532
-		} else {
533
-			$total = $free; //either unknown or unlimited
534
-		}
535
-		if ($total > 0) {
536
-			if ($quota > 0 && $total > $quota) {
537
-				$total = $quota;
538
-			}
539
-			// prevent division by zero or error codes (negative values)
540
-			$relative = round(($used / $total) * 10000) / 100;
541
-		} else {
542
-			$relative = 0;
543
-		}
544
-
545
-		$ownerId = $storage->getOwner($path);
546
-		$ownerDisplayName = '';
547
-		$owner = \OC::$server->getUserManager()->get($ownerId);
548
-		if ($owner) {
549
-			$ownerDisplayName = $owner->getDisplayName();
550
-		}
551
-		if (substr_count($mount->getMountPoint(), '/') < 3) {
552
-			$mountPoint = '';
553
-		} else {
554
-			[,,,$mountPoint] = explode('/', $mount->getMountPoint(), 4);
555
-		}
556
-
557
-		return [
558
-			'free' => $free,
559
-			'used' => $used,
560
-			'quota' => $quota,
561
-			'total' => $total,
562
-			'relative' => $relative,
563
-			'owner' => $ownerId,
564
-			'ownerDisplayName' => $ownerDisplayName,
565
-			'mountType' => $mount->getMountType(),
566
-			'mountPoint' => trim($mountPoint, '/'),
567
-		];
568
-	}
569
-
570
-	/**
571
-	 * Get storage info including all mount points and quota
572
-	 *
573
-	 * @param int $quota
574
-	 * @return array
575
-	 */
576
-	private static function getGlobalStorageInfo($quota) {
577
-		$rootInfo = \OC\Files\Filesystem::getFileInfo('', 'ext');
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
-		return [
597
-			'free' => $free,
598
-			'used' => $used,
599
-			'total' => $total,
600
-			'relative' => $relative,
601
-			'quota' => $quota
602
-		];
603
-	}
604
-
605
-	/**
606
-	 * Returns whether the config file is set manually to read-only
607
-	 * @return bool
608
-	 */
609
-	public static function isReadOnlyConfigEnabled() {
610
-		return \OC::$server->getConfig()->getSystemValue('config_is_read_only', false);
611
-	}
53
+    private static $templateManager;
54
+
55
+    /**
56
+     * Make a human file size
57
+     * @param int $bytes file size in bytes
58
+     * @return string a human readable file size
59
+     *
60
+     * Makes 2048 to 2 kB.
61
+     */
62
+    public static function humanFileSize($bytes) {
63
+        if ($bytes < 0) {
64
+            return "?";
65
+        }
66
+        if ($bytes < 1024) {
67
+            return "$bytes B";
68
+        }
69
+        $bytes = round($bytes / 1024, 0);
70
+        if ($bytes < 1024) {
71
+            return "$bytes KB";
72
+        }
73
+        $bytes = round($bytes / 1024, 1);
74
+        if ($bytes < 1024) {
75
+            return "$bytes MB";
76
+        }
77
+        $bytes = round($bytes / 1024, 1);
78
+        if ($bytes < 1024) {
79
+            return "$bytes GB";
80
+        }
81
+        $bytes = round($bytes / 1024, 1);
82
+        if ($bytes < 1024) {
83
+            return "$bytes TB";
84
+        }
85
+
86
+        $bytes = round($bytes / 1024, 1);
87
+        return "$bytes PB";
88
+    }
89
+
90
+    /**
91
+     * Make a computer file size
92
+     * @param string $str file size in human readable format
93
+     * @return float|bool a file size in bytes
94
+     *
95
+     * Makes 2kB to 2048.
96
+     *
97
+     * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418
98
+     */
99
+    public static function computerFileSize($str) {
100
+        $str = strtolower($str);
101
+        if (is_numeric($str)) {
102
+            return (float)$str;
103
+        }
104
+
105
+        $bytes_array = [
106
+            'b' => 1,
107
+            'k' => 1024,
108
+            'kb' => 1024,
109
+            'mb' => 1024 * 1024,
110
+            'm' => 1024 * 1024,
111
+            'gb' => 1024 * 1024 * 1024,
112
+            'g' => 1024 * 1024 * 1024,
113
+            'tb' => 1024 * 1024 * 1024 * 1024,
114
+            't' => 1024 * 1024 * 1024 * 1024,
115
+            'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
116
+            'p' => 1024 * 1024 * 1024 * 1024 * 1024,
117
+        ];
118
+
119
+        $bytes = (float)$str;
120
+
121
+        if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) {
122
+            $bytes *= $bytes_array[$matches[1]];
123
+        } else {
124
+            return false;
125
+        }
126
+
127
+        $bytes = round($bytes);
128
+
129
+        return $bytes;
130
+    }
131
+
132
+    /**
133
+     * Recursive copying of folders
134
+     * @param string $src source folder
135
+     * @param string $dest target folder
136
+     *
137
+     */
138
+    public static function copyr($src, $dest) {
139
+        if (is_dir($src)) {
140
+            if (!is_dir($dest)) {
141
+                mkdir($dest);
142
+            }
143
+            $files = scandir($src);
144
+            foreach ($files as $file) {
145
+                if ($file != "." && $file != "..") {
146
+                    self::copyr("$src/$file", "$dest/$file");
147
+                }
148
+            }
149
+        } elseif (file_exists($src) && !\OC\Files\Filesystem::isFileBlacklisted($src)) {
150
+            copy($src, $dest);
151
+        }
152
+    }
153
+
154
+    /**
155
+     * Recursive deletion of folders
156
+     * @param string $dir path to the folder
157
+     * @param bool $deleteSelf if set to false only the content of the folder will be deleted
158
+     * @return bool
159
+     */
160
+    public static function rmdirr($dir, $deleteSelf = true) {
161
+        if (is_dir($dir)) {
162
+            $files = new RecursiveIteratorIterator(
163
+                new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
164
+                RecursiveIteratorIterator::CHILD_FIRST
165
+            );
166
+
167
+            foreach ($files as $fileInfo) {
168
+                /** @var SplFileInfo $fileInfo */
169
+                if ($fileInfo->isLink()) {
170
+                    unlink($fileInfo->getPathname());
171
+                } elseif ($fileInfo->isDir()) {
172
+                    rmdir($fileInfo->getRealPath());
173
+                } else {
174
+                    unlink($fileInfo->getRealPath());
175
+                }
176
+            }
177
+            if ($deleteSelf) {
178
+                rmdir($dir);
179
+            }
180
+        } elseif (file_exists($dir)) {
181
+            if ($deleteSelf) {
182
+                unlink($dir);
183
+            }
184
+        }
185
+        if (!$deleteSelf) {
186
+            return true;
187
+        }
188
+
189
+        return !file_exists($dir);
190
+    }
191
+
192
+    /**
193
+     * @deprecated 18.0.0
194
+     * @return \OC\Files\Type\TemplateManager
195
+     */
196
+    public static function getFileTemplateManager() {
197
+        if (!self::$templateManager) {
198
+            self::$templateManager = new \OC\Files\Type\TemplateManager();
199
+        }
200
+        return self::$templateManager;
201
+    }
202
+
203
+    /**
204
+     * detect if a given program is found in the search PATH
205
+     *
206
+     * @param string $name
207
+     * @param bool $path
208
+     * @internal param string $program name
209
+     * @internal param string $optional search path, defaults to $PATH
210
+     * @return bool    true if executable program found in path
211
+     */
212
+    public static function canExecute($name, $path = false) {
213
+        // path defaults to PATH from environment if not set
214
+        if ($path === false) {
215
+            $path = getenv("PATH");
216
+        }
217
+        // we look for an executable file of that name
218
+        $exts = [""];
219
+        $check_fn = "is_executable";
220
+        // Default check will be done with $path directories :
221
+        $dirs = explode(PATH_SEPARATOR, $path);
222
+        // WARNING : We have to check if open_basedir is enabled :
223
+        $obd = OC::$server->get(IniGetWrapper::class)->getString('open_basedir');
224
+        if ($obd != "none") {
225
+            $obd_values = explode(PATH_SEPARATOR, $obd);
226
+            if (count($obd_values) > 0 and $obd_values[0]) {
227
+                // open_basedir is in effect !
228
+                // We need to check if the program is in one of these dirs :
229
+                $dirs = $obd_values;
230
+            }
231
+        }
232
+        foreach ($dirs as $dir) {
233
+            foreach ($exts as $ext) {
234
+                if ($check_fn("$dir/$name" . $ext)) {
235
+                    return true;
236
+                }
237
+            }
238
+        }
239
+        return false;
240
+    }
241
+
242
+    /**
243
+     * copy the contents of one stream to another
244
+     *
245
+     * @param resource $source
246
+     * @param resource $target
247
+     * @return array the number of bytes copied and result
248
+     */
249
+    public static function streamCopy($source, $target) {
250
+        if (!$source or !$target) {
251
+            return [0, false];
252
+        }
253
+        $bufSize = 8192;
254
+        $result = true;
255
+        $count = 0;
256
+        while (!feof($source)) {
257
+            $buf = fread($source, $bufSize);
258
+            $bytesWritten = fwrite($target, $buf);
259
+            if ($bytesWritten !== false) {
260
+                $count += $bytesWritten;
261
+            }
262
+            // note: strlen is expensive so only use it when necessary,
263
+            // on the last block
264
+            if ($bytesWritten === false
265
+                || ($bytesWritten < $bufSize && $bytesWritten < strlen($buf))
266
+            ) {
267
+                // write error, could be disk full ?
268
+                $result = false;
269
+                break;
270
+            }
271
+        }
272
+        return [$count, $result];
273
+    }
274
+
275
+    /**
276
+     * Adds a suffix to the name in case the file exists
277
+     *
278
+     * @param string $path
279
+     * @param string $filename
280
+     * @return string
281
+     */
282
+    public static function buildNotExistingFileName($path, $filename) {
283
+        $view = \OC\Files\Filesystem::getView();
284
+        return self::buildNotExistingFileNameForView($path, $filename, $view);
285
+    }
286
+
287
+    /**
288
+     * Adds a suffix to the name in case the file exists
289
+     *
290
+     * @param string $path
291
+     * @param string $filename
292
+     * @return string
293
+     */
294
+    public static function buildNotExistingFileNameForView($path, $filename, \OC\Files\View $view) {
295
+        if ($path === '/') {
296
+            $path = '';
297
+        }
298
+        if ($pos = strrpos($filename, '.')) {
299
+            $name = substr($filename, 0, $pos);
300
+            $ext = substr($filename, $pos);
301
+        } else {
302
+            $name = $filename;
303
+            $ext = '';
304
+        }
305
+
306
+        $newpath = $path . '/' . $filename;
307
+        if ($view->file_exists($newpath)) {
308
+            if (preg_match_all('/\((\d+)\)/', $name, $matches, PREG_OFFSET_CAPTURE)) {
309
+                //Replace the last "(number)" with "(number+1)"
310
+                $last_match = count($matches[0]) - 1;
311
+                $counter = $matches[1][$last_match][0] + 1;
312
+                $offset = $matches[0][$last_match][1];
313
+                $match_length = strlen($matches[0][$last_match][0]);
314
+            } else {
315
+                $counter = 2;
316
+                $match_length = 0;
317
+                $offset = false;
318
+            }
319
+            do {
320
+                if ($offset) {
321
+                    //Replace the last "(number)" with "(number+1)"
322
+                    $newname = substr_replace($name, '(' . $counter . ')', $offset, $match_length);
323
+                } else {
324
+                    $newname = $name . ' (' . $counter . ')';
325
+                }
326
+                $newpath = $path . '/' . $newname . $ext;
327
+                $counter++;
328
+            } while ($view->file_exists($newpath));
329
+        }
330
+
331
+        return $newpath;
332
+    }
333
+
334
+    /**
335
+     * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
336
+     *
337
+     * @param array $input The array to work on
338
+     * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default)
339
+     * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8
340
+     * @return array
341
+     *
342
+     * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
343
+     * based on http://www.php.net/manual/en/function.array-change-key-case.php#107715
344
+     *
345
+     */
346
+    public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
347
+        $case = ($case != MB_CASE_UPPER) ? MB_CASE_LOWER : MB_CASE_UPPER;
348
+        $ret = [];
349
+        foreach ($input as $k => $v) {
350
+            $ret[mb_convert_case($k, $case, $encoding)] = $v;
351
+        }
352
+        return $ret;
353
+    }
354
+
355
+    /**
356
+     * performs a search in a nested array
357
+     * @param array $haystack the array to be searched
358
+     * @param string $needle the search string
359
+     * @param mixed $index optional, only search this key name
360
+     * @return mixed the key of the matching field, otherwise false
361
+     *
362
+     * performs a search in a nested array
363
+     *
364
+     * taken from http://www.php.net/manual/en/function.array-search.php#97645
365
+     */
366
+    public static function recursiveArraySearch($haystack, $needle, $index = null) {
367
+        $aIt = new RecursiveArrayIterator($haystack);
368
+        $it = new RecursiveIteratorIterator($aIt);
369
+
370
+        while ($it->valid()) {
371
+            if (((isset($index) and ($it->key() == $index)) or !isset($index)) and ($it->current() == $needle)) {
372
+                return $aIt->key();
373
+            }
374
+
375
+            $it->next();
376
+        }
377
+
378
+        return false;
379
+    }
380
+
381
+    /**
382
+     * calculates the maximum upload size respecting system settings, free space and user quota
383
+     *
384
+     * @param string $dir the current folder where the user currently operates
385
+     * @param int $freeSpace the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly
386
+     * @return int number of bytes representing
387
+     */
388
+    public static function maxUploadFilesize($dir, $freeSpace = null) {
389
+        if (is_null($freeSpace) || $freeSpace < 0) {
390
+            $freeSpace = self::freeSpace($dir);
391
+        }
392
+        return min($freeSpace, self::uploadLimit());
393
+    }
394
+
395
+    /**
396
+     * Calculate free space left within user quota
397
+     *
398
+     * @param string $dir the current folder where the user currently operates
399
+     * @return int number of bytes representing
400
+     */
401
+    public static function freeSpace($dir) {
402
+        $freeSpace = \OC\Files\Filesystem::free_space($dir);
403
+        if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
404
+            $freeSpace = max($freeSpace, 0);
405
+            return $freeSpace;
406
+        } else {
407
+            return (INF > 0)? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
408
+        }
409
+    }
410
+
411
+    /**
412
+     * Calculate PHP upload limit
413
+     *
414
+     * @return int PHP upload file size limit
415
+     */
416
+    public static function uploadLimit() {
417
+        $ini = \OC::$server->get(IniGetWrapper::class);
418
+        $upload_max_filesize = OCP\Util::computerFileSize($ini->get('upload_max_filesize'));
419
+        $post_max_size = OCP\Util::computerFileSize($ini->get('post_max_size'));
420
+        if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) {
421
+            return INF;
422
+        } elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) {
423
+            return max($upload_max_filesize, $post_max_size); //only the non 0 value counts
424
+        } else {
425
+            return min($upload_max_filesize, $post_max_size);
426
+        }
427
+    }
428
+
429
+    /**
430
+     * Checks if a function is available
431
+     *
432
+     * @param string $function_name
433
+     * @return bool
434
+     */
435
+    public static function is_function_enabled($function_name) {
436
+        if (!function_exists($function_name)) {
437
+            return false;
438
+        }
439
+        $ini = \OC::$server->get(IniGetWrapper::class);
440
+        $disabled = explode(',', $ini->get('disable_functions') ?: '');
441
+        $disabled = array_map('trim', $disabled);
442
+        if (in_array($function_name, $disabled)) {
443
+            return false;
444
+        }
445
+        $disabled = explode(',', $ini->get('suhosin.executor.func.blacklist') ?: '');
446
+        $disabled = array_map('trim', $disabled);
447
+        if (in_array($function_name, $disabled)) {
448
+            return false;
449
+        }
450
+        return true;
451
+    }
452
+
453
+    /**
454
+     * Try to find a program
455
+     *
456
+     * @param string $program
457
+     * @return null|string
458
+     */
459
+    public static function findBinaryPath($program) {
460
+        $memcache = \OC::$server->getMemCacheFactory()->createDistributed('findBinaryPath');
461
+        if ($memcache->hasKey($program)) {
462
+            return $memcache->get($program);
463
+        }
464
+        $result = null;
465
+        if (self::is_function_enabled('exec')) {
466
+            $exeSniffer = new ExecutableFinder();
467
+            // Returns null if nothing is found
468
+            $result = $exeSniffer->find($program, null, ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/opt/bin']);
469
+        }
470
+        // store the value for 5 minutes
471
+        $memcache->set($program, $result, 300);
472
+        return $result;
473
+    }
474
+
475
+    /**
476
+     * Calculate the disc space for the given path
477
+     *
478
+     * BEWARE: this requires that Util::setupFS() was called
479
+     * already !
480
+     *
481
+     * @param string $path
482
+     * @param \OCP\Files\FileInfo $rootInfo (optional)
483
+     * @return array
484
+     * @throws \OCP\Files\NotFoundException
485
+     */
486
+    public static function getStorageInfo($path, $rootInfo = null) {
487
+        // return storage info without adding mount points
488
+        $includeExtStorage = \OC::$server->getSystemConfig()->getValue('quota_include_external_storage', false);
489
+
490
+        if (!$rootInfo) {
491
+            $rootInfo = \OC\Files\Filesystem::getFileInfo($path, $includeExtStorage ? 'ext' : false);
492
+        }
493
+        if (!$rootInfo instanceof \OCP\Files\FileInfo) {
494
+            throw new \OCP\Files\NotFoundException();
495
+        }
496
+        $used = $rootInfo->getSize();
497
+        if ($used < 0) {
498
+            $used = 0;
499
+        }
500
+        $quota = \OCP\Files\FileInfo::SPACE_UNLIMITED;
501
+        $mount = $rootInfo->getMountPoint();
502
+        $storage = $mount->getStorage();
503
+        $sourceStorage = $storage;
504
+        if ($storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) {
505
+            $includeExtStorage = false;
506
+            $sourceStorage = $storage->getSourceStorage();
507
+        }
508
+        if ($includeExtStorage) {
509
+            if ($storage->instanceOfStorage('\OC\Files\Storage\Home')
510
+                || $storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage')
511
+            ) {
512
+                /** @var \OC\Files\Storage\Home $storage */
513
+                $user = $storage->getUser();
514
+            } else {
515
+                $user = \OC::$server->getUserSession()->getUser();
516
+            }
517
+            $quota = OC_Util::getUserQuota($user);
518
+            if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
519
+                // always get free space / total space from root + mount points
520
+                return self::getGlobalStorageInfo($quota);
521
+            }
522
+        }
523
+
524
+        // TODO: need a better way to get total space from storage
525
+        if ($sourceStorage->instanceOfStorage('\OC\Files\Storage\Wrapper\Quota')) {
526
+            /** @var \OC\Files\Storage\Wrapper\Quota $storage */
527
+            $quota = $sourceStorage->getQuota();
528
+        }
529
+        $free = $sourceStorage->free_space($rootInfo->getInternalPath());
530
+        if ($free >= 0) {
531
+            $total = $free + $used;
532
+        } else {
533
+            $total = $free; //either unknown or unlimited
534
+        }
535
+        if ($total > 0) {
536
+            if ($quota > 0 && $total > $quota) {
537
+                $total = $quota;
538
+            }
539
+            // prevent division by zero or error codes (negative values)
540
+            $relative = round(($used / $total) * 10000) / 100;
541
+        } else {
542
+            $relative = 0;
543
+        }
544
+
545
+        $ownerId = $storage->getOwner($path);
546
+        $ownerDisplayName = '';
547
+        $owner = \OC::$server->getUserManager()->get($ownerId);
548
+        if ($owner) {
549
+            $ownerDisplayName = $owner->getDisplayName();
550
+        }
551
+        if (substr_count($mount->getMountPoint(), '/') < 3) {
552
+            $mountPoint = '';
553
+        } else {
554
+            [,,,$mountPoint] = explode('/', $mount->getMountPoint(), 4);
555
+        }
556
+
557
+        return [
558
+            'free' => $free,
559
+            'used' => $used,
560
+            'quota' => $quota,
561
+            'total' => $total,
562
+            'relative' => $relative,
563
+            'owner' => $ownerId,
564
+            'ownerDisplayName' => $ownerDisplayName,
565
+            'mountType' => $mount->getMountType(),
566
+            'mountPoint' => trim($mountPoint, '/'),
567
+        ];
568
+    }
569
+
570
+    /**
571
+     * Get storage info including all mount points and quota
572
+     *
573
+     * @param int $quota
574
+     * @return array
575
+     */
576
+    private static function getGlobalStorageInfo($quota) {
577
+        $rootInfo = \OC\Files\Filesystem::getFileInfo('', 'ext');
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
+        return [
597
+            'free' => $free,
598
+            'used' => $used,
599
+            'total' => $total,
600
+            'relative' => $relative,
601
+            'quota' => $quota
602
+        ];
603
+    }
604
+
605
+    /**
606
+     * Returns whether the config file is set manually to read-only
607
+     * @return bool
608
+     */
609
+    public static function isReadOnlyConfigEnabled() {
610
+        return \OC::$server->getConfig()->getSystemValue('config_is_read_only', false);
611
+    }
612 612
 }
Please login to merge, or discard this patch.
apps/settings/lib/Settings/Personal/PersonalInfo.php 1 patch
Indentation   +244 added lines, -244 removed lines patch added patch discarded remove patch
@@ -47,248 +47,248 @@
 block discarded – undo
47 47
 
48 48
 class PersonalInfo implements ISettings {
49 49
 
50
-	/** @var IConfig */
51
-	private $config;
52
-	/** @var IUserManager */
53
-	private $userManager;
54
-	/** @var AccountManager */
55
-	private $accountManager;
56
-	/** @var IGroupManager */
57
-	private $groupManager;
58
-	/** @var IAppManager */
59
-	private $appManager;
60
-	/** @var IFactory */
61
-	private $l10nFactory;
62
-	/** @var IL10N */
63
-	private $l;
64
-
65
-	/**
66
-	 * @param IConfig $config
67
-	 * @param IUserManager $userManager
68
-	 * @param IGroupManager $groupManager
69
-	 * @param AccountManager $accountManager
70
-	 * @param IFactory $l10nFactory
71
-	 * @param IL10N $l
72
-	 */
73
-	public function __construct(
74
-		IConfig $config,
75
-		IUserManager $userManager,
76
-		IGroupManager $groupManager,
77
-		AccountManager $accountManager,
78
-		IAppManager $appManager,
79
-		IFactory $l10nFactory,
80
-		IL10N $l
81
-	) {
82
-		$this->config = $config;
83
-		$this->userManager = $userManager;
84
-		$this->accountManager = $accountManager;
85
-		$this->groupManager = $groupManager;
86
-		$this->appManager = $appManager;
87
-		$this->l10nFactory = $l10nFactory;
88
-		$this->l = $l;
89
-	}
90
-
91
-	/**
92
-	 * @return TemplateResponse returns the instance with all parameters set, ready to be rendered
93
-	 * @since 9.1
94
-	 */
95
-	public function getForm() {
96
-		$federatedFileSharingEnabled = $this->appManager->isEnabledForUser('federatedfilesharing');
97
-		$lookupServerUploadEnabled = false;
98
-		if ($federatedFileSharingEnabled) {
99
-			/** @var FederatedShareProvider $shareProvider */
100
-			$shareProvider = \OC::$server->query(FederatedShareProvider::class);
101
-			$lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled();
102
-		}
103
-
104
-		$uid = \OC_User::getUser();
105
-		$user = $this->userManager->get($uid);
106
-		$userData = $this->accountManager->getUser($user);
107
-
108
-		// make sure FS is setup before querying storage related stuff...
109
-		\OC_Util::setupFS($user->getUID());
110
-
111
-		$storageInfo = \OC_Helper::getStorageInfo('/');
112
-		if ($storageInfo['quota'] === FileInfo::SPACE_UNLIMITED) {
113
-			$totalSpace = $this->l->t('Unlimited');
114
-		} else {
115
-			$totalSpace = \OC_Helper::humanFileSize($storageInfo['total']);
116
-		}
117
-
118
-		$languageParameters = $this->getLanguages($user);
119
-		$localeParameters = $this->getLocales($user);
120
-		$messageParameters = $this->getMessageParameters($userData);
121
-
122
-		$parameters = [
123
-			'total_space' => $totalSpace,
124
-			'usage' => \OC_Helper::humanFileSize($storageInfo['used']),
125
-			'usage_relative' => round($storageInfo['relative']),
126
-			'quota' => $storageInfo['quota'],
127
-			'avatarChangeSupported' => $user->canChangeAvatar(),
128
-			'lookupServerUploadEnabled' => $lookupServerUploadEnabled,
129
-			'avatarScope' => $userData[AccountManager::PROPERTY_AVATAR]['scope'],
130
-			'displayNameChangeSupported' => $user->canChangeDisplayName(),
131
-			'displayName' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'],
132
-			'displayNameScope' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
133
-			'email' => $userData[AccountManager::PROPERTY_EMAIL]['value'],
134
-			'emailScope' => $userData[AccountManager::PROPERTY_EMAIL]['scope'],
135
-			'emailVerification' => $userData[AccountManager::PROPERTY_EMAIL]['verified'],
136
-			'phone' => $userData[AccountManager::PROPERTY_PHONE]['value'],
137
-			'phoneScope' => $userData[AccountManager::PROPERTY_PHONE]['scope'],
138
-			'address' => $userData[AccountManager::PROPERTY_ADDRESS]['value'],
139
-			'addressScope' => $userData[AccountManager::PROPERTY_ADDRESS]['scope'],
140
-			'website' => $userData[AccountManager::PROPERTY_WEBSITE]['value'],
141
-			'websiteScope' => $userData[AccountManager::PROPERTY_WEBSITE]['scope'],
142
-			'websiteVerification' => $userData[AccountManager::PROPERTY_WEBSITE]['verified'],
143
-			'twitter' => $userData[AccountManager::PROPERTY_TWITTER]['value'],
144
-			'twitterScope' => $userData[AccountManager::PROPERTY_TWITTER]['scope'],
145
-			'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'],
146
-			'groups' => $this->getGroups($user),
147
-		] + $messageParameters + $languageParameters + $localeParameters;
148
-
149
-
150
-		return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, '');
151
-	}
152
-
153
-	/**
154
-	 * @return string the section ID, e.g. 'sharing'
155
-	 * @since 9.1
156
-	 */
157
-	public function getSection() {
158
-		return 'personal-info';
159
-	}
160
-
161
-	/**
162
-	 * @return int whether the form should be rather on the top or bottom of
163
-	 * the admin section. The forms are arranged in ascending order of the
164
-	 * priority values. It is required to return a value between 0 and 100.
165
-	 *
166
-	 * E.g.: 70
167
-	 * @since 9.1
168
-	 */
169
-	public function getPriority() {
170
-		return 10;
171
-	}
172
-
173
-	/**
174
-	 * returns a sorted list of the user's group GIDs
175
-	 *
176
-	 * @param IUser $user
177
-	 * @return array
178
-	 */
179
-	private function getGroups(IUser $user) {
180
-		$groups = array_map(
181
-			function (IGroup $group) {
182
-				return $group->getDisplayName();
183
-			},
184
-			$this->groupManager->getUserGroups($user)
185
-		);
186
-		sort($groups);
187
-
188
-		return $groups;
189
-	}
190
-
191
-	/**
192
-	 * returns the user language, common language and other languages in an
193
-	 * associative array
194
-	 *
195
-	 * @param IUser $user
196
-	 * @return array
197
-	 */
198
-	private function getLanguages(IUser $user) {
199
-		$forceLanguage = $this->config->getSystemValue('force_language', false);
200
-		if ($forceLanguage !== false) {
201
-			return [];
202
-		}
203
-
204
-		$uid = $user->getUID();
205
-
206
-		$userConfLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
207
-		$languages = $this->l10nFactory->getLanguages();
208
-
209
-		// associate the user language with the proper array
210
-		$userLangIndex = array_search($userConfLang, array_column($languages['commonlanguages'], 'code'));
211
-		$userLang = $languages['commonlanguages'][$userLangIndex];
212
-		// search in the other languages
213
-		if ($userLangIndex === false) {
214
-			$userLangIndex = array_search($userConfLang, array_column($languages['languages'], 'code'));
215
-			$userLang = $languages['languages'][$userLangIndex];
216
-		}
217
-		// if user language is not available but set somehow: show the actual code as name
218
-		if (!is_array($userLang)) {
219
-			$userLang = [
220
-				'code' => $userConfLang,
221
-				'name' => $userConfLang,
222
-			];
223
-		}
224
-
225
-		return array_merge(
226
-			['activelanguage' => $userLang],
227
-			$languages
228
-		);
229
-	}
230
-
231
-	private function getLocales(IUser $user) {
232
-		$forceLanguage = $this->config->getSystemValue('force_locale', false);
233
-		if ($forceLanguage !== false) {
234
-			return [];
235
-		}
236
-
237
-		$uid = $user->getUID();
238
-
239
-		$userLocaleString = $this->config->getUserValue($uid, 'core', 'locale', $this->l10nFactory->findLocale());
240
-
241
-		$userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
242
-
243
-		$localeCodes = $this->l10nFactory->findAvailableLocales();
244
-
245
-		$userLocale = array_filter($localeCodes, function ($value) use ($userLocaleString) {
246
-			return $userLocaleString === $value['code'];
247
-		});
248
-
249
-		if (!empty($userLocale)) {
250
-			$userLocale = reset($userLocale);
251
-		}
252
-
253
-		$localesForLanguage = array_filter($localeCodes, function ($localeCode) use ($userLang) {
254
-			return 0 === strpos($localeCode['code'], $userLang);
255
-		});
256
-
257
-		if (!$userLocale) {
258
-			$userLocale = [
259
-				'code' => 'en',
260
-				'name' => 'English'
261
-			];
262
-		}
263
-
264
-		return [
265
-			'activelocaleLang' => $userLocaleString,
266
-			'activelocale' => $userLocale,
267
-			'locales' => $localeCodes,
268
-			'localesForLanguage' => $localesForLanguage,
269
-		];
270
-	}
271
-
272
-	/**
273
-	 * @param array $userData
274
-	 * @return array
275
-	 */
276
-	private function getMessageParameters(array $userData) {
277
-		$needVerifyMessage = [AccountManager::PROPERTY_EMAIL, AccountManager::PROPERTY_WEBSITE, AccountManager::PROPERTY_TWITTER];
278
-		$messageParameters = [];
279
-		foreach ($needVerifyMessage as $property) {
280
-			switch ($userData[$property]['verified']) {
281
-				case AccountManager::VERIFIED:
282
-					$message = $this->l->t('Verifying');
283
-					break;
284
-				case AccountManager::VERIFICATION_IN_PROGRESS:
285
-					$message = $this->l->t('Verifying …');
286
-					break;
287
-				default:
288
-					$message = $this->l->t('Verify');
289
-			}
290
-			$messageParameters[$property . 'Message'] = $message;
291
-		}
292
-		return $messageParameters;
293
-	}
50
+    /** @var IConfig */
51
+    private $config;
52
+    /** @var IUserManager */
53
+    private $userManager;
54
+    /** @var AccountManager */
55
+    private $accountManager;
56
+    /** @var IGroupManager */
57
+    private $groupManager;
58
+    /** @var IAppManager */
59
+    private $appManager;
60
+    /** @var IFactory */
61
+    private $l10nFactory;
62
+    /** @var IL10N */
63
+    private $l;
64
+
65
+    /**
66
+     * @param IConfig $config
67
+     * @param IUserManager $userManager
68
+     * @param IGroupManager $groupManager
69
+     * @param AccountManager $accountManager
70
+     * @param IFactory $l10nFactory
71
+     * @param IL10N $l
72
+     */
73
+    public function __construct(
74
+        IConfig $config,
75
+        IUserManager $userManager,
76
+        IGroupManager $groupManager,
77
+        AccountManager $accountManager,
78
+        IAppManager $appManager,
79
+        IFactory $l10nFactory,
80
+        IL10N $l
81
+    ) {
82
+        $this->config = $config;
83
+        $this->userManager = $userManager;
84
+        $this->accountManager = $accountManager;
85
+        $this->groupManager = $groupManager;
86
+        $this->appManager = $appManager;
87
+        $this->l10nFactory = $l10nFactory;
88
+        $this->l = $l;
89
+    }
90
+
91
+    /**
92
+     * @return TemplateResponse returns the instance with all parameters set, ready to be rendered
93
+     * @since 9.1
94
+     */
95
+    public function getForm() {
96
+        $federatedFileSharingEnabled = $this->appManager->isEnabledForUser('federatedfilesharing');
97
+        $lookupServerUploadEnabled = false;
98
+        if ($federatedFileSharingEnabled) {
99
+            /** @var FederatedShareProvider $shareProvider */
100
+            $shareProvider = \OC::$server->query(FederatedShareProvider::class);
101
+            $lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled();
102
+        }
103
+
104
+        $uid = \OC_User::getUser();
105
+        $user = $this->userManager->get($uid);
106
+        $userData = $this->accountManager->getUser($user);
107
+
108
+        // make sure FS is setup before querying storage related stuff...
109
+        \OC_Util::setupFS($user->getUID());
110
+
111
+        $storageInfo = \OC_Helper::getStorageInfo('/');
112
+        if ($storageInfo['quota'] === FileInfo::SPACE_UNLIMITED) {
113
+            $totalSpace = $this->l->t('Unlimited');
114
+        } else {
115
+            $totalSpace = \OC_Helper::humanFileSize($storageInfo['total']);
116
+        }
117
+
118
+        $languageParameters = $this->getLanguages($user);
119
+        $localeParameters = $this->getLocales($user);
120
+        $messageParameters = $this->getMessageParameters($userData);
121
+
122
+        $parameters = [
123
+            'total_space' => $totalSpace,
124
+            'usage' => \OC_Helper::humanFileSize($storageInfo['used']),
125
+            'usage_relative' => round($storageInfo['relative']),
126
+            'quota' => $storageInfo['quota'],
127
+            'avatarChangeSupported' => $user->canChangeAvatar(),
128
+            'lookupServerUploadEnabled' => $lookupServerUploadEnabled,
129
+            'avatarScope' => $userData[AccountManager::PROPERTY_AVATAR]['scope'],
130
+            'displayNameChangeSupported' => $user->canChangeDisplayName(),
131
+            'displayName' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'],
132
+            'displayNameScope' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
133
+            'email' => $userData[AccountManager::PROPERTY_EMAIL]['value'],
134
+            'emailScope' => $userData[AccountManager::PROPERTY_EMAIL]['scope'],
135
+            'emailVerification' => $userData[AccountManager::PROPERTY_EMAIL]['verified'],
136
+            'phone' => $userData[AccountManager::PROPERTY_PHONE]['value'],
137
+            'phoneScope' => $userData[AccountManager::PROPERTY_PHONE]['scope'],
138
+            'address' => $userData[AccountManager::PROPERTY_ADDRESS]['value'],
139
+            'addressScope' => $userData[AccountManager::PROPERTY_ADDRESS]['scope'],
140
+            'website' => $userData[AccountManager::PROPERTY_WEBSITE]['value'],
141
+            'websiteScope' => $userData[AccountManager::PROPERTY_WEBSITE]['scope'],
142
+            'websiteVerification' => $userData[AccountManager::PROPERTY_WEBSITE]['verified'],
143
+            'twitter' => $userData[AccountManager::PROPERTY_TWITTER]['value'],
144
+            'twitterScope' => $userData[AccountManager::PROPERTY_TWITTER]['scope'],
145
+            'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'],
146
+            'groups' => $this->getGroups($user),
147
+        ] + $messageParameters + $languageParameters + $localeParameters;
148
+
149
+
150
+        return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, '');
151
+    }
152
+
153
+    /**
154
+     * @return string the section ID, e.g. 'sharing'
155
+     * @since 9.1
156
+     */
157
+    public function getSection() {
158
+        return 'personal-info';
159
+    }
160
+
161
+    /**
162
+     * @return int whether the form should be rather on the top or bottom of
163
+     * the admin section. The forms are arranged in ascending order of the
164
+     * priority values. It is required to return a value between 0 and 100.
165
+     *
166
+     * E.g.: 70
167
+     * @since 9.1
168
+     */
169
+    public function getPriority() {
170
+        return 10;
171
+    }
172
+
173
+    /**
174
+     * returns a sorted list of the user's group GIDs
175
+     *
176
+     * @param IUser $user
177
+     * @return array
178
+     */
179
+    private function getGroups(IUser $user) {
180
+        $groups = array_map(
181
+            function (IGroup $group) {
182
+                return $group->getDisplayName();
183
+            },
184
+            $this->groupManager->getUserGroups($user)
185
+        );
186
+        sort($groups);
187
+
188
+        return $groups;
189
+    }
190
+
191
+    /**
192
+     * returns the user language, common language and other languages in an
193
+     * associative array
194
+     *
195
+     * @param IUser $user
196
+     * @return array
197
+     */
198
+    private function getLanguages(IUser $user) {
199
+        $forceLanguage = $this->config->getSystemValue('force_language', false);
200
+        if ($forceLanguage !== false) {
201
+            return [];
202
+        }
203
+
204
+        $uid = $user->getUID();
205
+
206
+        $userConfLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
207
+        $languages = $this->l10nFactory->getLanguages();
208
+
209
+        // associate the user language with the proper array
210
+        $userLangIndex = array_search($userConfLang, array_column($languages['commonlanguages'], 'code'));
211
+        $userLang = $languages['commonlanguages'][$userLangIndex];
212
+        // search in the other languages
213
+        if ($userLangIndex === false) {
214
+            $userLangIndex = array_search($userConfLang, array_column($languages['languages'], 'code'));
215
+            $userLang = $languages['languages'][$userLangIndex];
216
+        }
217
+        // if user language is not available but set somehow: show the actual code as name
218
+        if (!is_array($userLang)) {
219
+            $userLang = [
220
+                'code' => $userConfLang,
221
+                'name' => $userConfLang,
222
+            ];
223
+        }
224
+
225
+        return array_merge(
226
+            ['activelanguage' => $userLang],
227
+            $languages
228
+        );
229
+    }
230
+
231
+    private function getLocales(IUser $user) {
232
+        $forceLanguage = $this->config->getSystemValue('force_locale', false);
233
+        if ($forceLanguage !== false) {
234
+            return [];
235
+        }
236
+
237
+        $uid = $user->getUID();
238
+
239
+        $userLocaleString = $this->config->getUserValue($uid, 'core', 'locale', $this->l10nFactory->findLocale());
240
+
241
+        $userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
242
+
243
+        $localeCodes = $this->l10nFactory->findAvailableLocales();
244
+
245
+        $userLocale = array_filter($localeCodes, function ($value) use ($userLocaleString) {
246
+            return $userLocaleString === $value['code'];
247
+        });
248
+
249
+        if (!empty($userLocale)) {
250
+            $userLocale = reset($userLocale);
251
+        }
252
+
253
+        $localesForLanguage = array_filter($localeCodes, function ($localeCode) use ($userLang) {
254
+            return 0 === strpos($localeCode['code'], $userLang);
255
+        });
256
+
257
+        if (!$userLocale) {
258
+            $userLocale = [
259
+                'code' => 'en',
260
+                'name' => 'English'
261
+            ];
262
+        }
263
+
264
+        return [
265
+            'activelocaleLang' => $userLocaleString,
266
+            'activelocale' => $userLocale,
267
+            'locales' => $localeCodes,
268
+            'localesForLanguage' => $localesForLanguage,
269
+        ];
270
+    }
271
+
272
+    /**
273
+     * @param array $userData
274
+     * @return array
275
+     */
276
+    private function getMessageParameters(array $userData) {
277
+        $needVerifyMessage = [AccountManager::PROPERTY_EMAIL, AccountManager::PROPERTY_WEBSITE, AccountManager::PROPERTY_TWITTER];
278
+        $messageParameters = [];
279
+        foreach ($needVerifyMessage as $property) {
280
+            switch ($userData[$property]['verified']) {
281
+                case AccountManager::VERIFIED:
282
+                    $message = $this->l->t('Verifying');
283
+                    break;
284
+                case AccountManager::VERIFICATION_IN_PROGRESS:
285
+                    $message = $this->l->t('Verifying …');
286
+                    break;
287
+                default:
288
+                    $message = $this->l->t('Verify');
289
+            }
290
+            $messageParameters[$property . 'Message'] = $message;
291
+        }
292
+        return $messageParameters;
293
+    }
294 294
 }
Please login to merge, or discard this patch.