Completed
Push — master ( af89db...3df2fb )
by Morris
65:06 queued 42:28
created
lib/private/legacy/util.php 1 patch
Indentation   +1432 added lines, -1432 removed lines patch added patch discarded remove patch
@@ -65,1440 +65,1440 @@
 block discarded – undo
65 65
 use OCP\IUser;
66 66
 
67 67
 class OC_Util {
68
-	public static $scripts = array();
69
-	public static $styles = array();
70
-	public static $headers = array();
71
-	private static $rootMounted = false;
72
-	private static $fsSetup = false;
73
-
74
-	/** @var array Local cache of version.php */
75
-	private static $versionCache = null;
76
-
77
-	protected static function getAppManager() {
78
-		return \OC::$server->getAppManager();
79
-	}
80
-
81
-	private static function initLocalStorageRootFS() {
82
-		// mount local file backend as root
83
-		$configDataDirectory = \OC::$server->getSystemConfig()->getValue("datadirectory", OC::$SERVERROOT . "/data");
84
-		//first set up the local "root" storage
85
-		\OC\Files\Filesystem::initMountManager();
86
-		if (!self::$rootMounted) {
87
-			\OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $configDataDirectory), '/');
88
-			self::$rootMounted = true;
89
-		}
90
-	}
91
-
92
-	/**
93
-	 * mounting an object storage as the root fs will in essence remove the
94
-	 * necessity of a data folder being present.
95
-	 * TODO make home storage aware of this and use the object storage instead of local disk access
96
-	 *
97
-	 * @param array $config containing 'class' and optional 'arguments'
98
-	 * @suppress PhanDeprecatedFunction
99
-	 */
100
-	private static function initObjectStoreRootFS($config) {
101
-		// check misconfiguration
102
-		if (empty($config['class'])) {
103
-			\OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
104
-		}
105
-		if (!isset($config['arguments'])) {
106
-			$config['arguments'] = array();
107
-		}
108
-
109
-		// instantiate object store implementation
110
-		$name = $config['class'];
111
-		if (strpos($name, 'OCA\\') === 0 && substr_count($name, '\\') >= 2) {
112
-			$segments = explode('\\', $name);
113
-			OC_App::loadApp(strtolower($segments[1]));
114
-		}
115
-		$config['arguments']['objectstore'] = new $config['class']($config['arguments']);
116
-		// mount with plain / root object store implementation
117
-		$config['class'] = '\OC\Files\ObjectStore\ObjectStoreStorage';
118
-
119
-		// mount object storage as root
120
-		\OC\Files\Filesystem::initMountManager();
121
-		if (!self::$rootMounted) {
122
-			\OC\Files\Filesystem::mount($config['class'], $config['arguments'], '/');
123
-			self::$rootMounted = true;
124
-		}
125
-	}
126
-
127
-	/**
128
-	 * mounting an object storage as the root fs will in essence remove the
129
-	 * necessity of a data folder being present.
130
-	 *
131
-	 * @param array $config containing 'class' and optional 'arguments'
132
-	 * @suppress PhanDeprecatedFunction
133
-	 */
134
-	private static function initObjectStoreMultibucketRootFS($config) {
135
-		// check misconfiguration
136
-		if (empty($config['class'])) {
137
-			\OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
138
-		}
139
-		if (!isset($config['arguments'])) {
140
-			$config['arguments'] = array();
141
-		}
142
-
143
-		// instantiate object store implementation
144
-		$name = $config['class'];
145
-		if (strpos($name, 'OCA\\') === 0 && substr_count($name, '\\') >= 2) {
146
-			$segments = explode('\\', $name);
147
-			OC_App::loadApp(strtolower($segments[1]));
148
-		}
149
-
150
-		if (!isset($config['arguments']['bucket'])) {
151
-			$config['arguments']['bucket'] = '';
152
-		}
153
-		// put the root FS always in first bucket for multibucket configuration
154
-		$config['arguments']['bucket'] .= '0';
155
-
156
-		$config['arguments']['objectstore'] = new $config['class']($config['arguments']);
157
-		// mount with plain / root object store implementation
158
-		$config['class'] = '\OC\Files\ObjectStore\ObjectStoreStorage';
159
-
160
-		// mount object storage as root
161
-		\OC\Files\Filesystem::initMountManager();
162
-		if (!self::$rootMounted) {
163
-			\OC\Files\Filesystem::mount($config['class'], $config['arguments'], '/');
164
-			self::$rootMounted = true;
165
-		}
166
-	}
167
-
168
-	/**
169
-	 * Can be set up
170
-	 *
171
-	 * @param string $user
172
-	 * @return boolean
173
-	 * @description configure the initial filesystem based on the configuration
174
-	 * @suppress PhanDeprecatedFunction
175
-	 * @suppress PhanAccessMethodInternal
176
-	 */
177
-	public static function setupFS($user = '') {
178
-		//setting up the filesystem twice can only lead to trouble
179
-		if (self::$fsSetup) {
180
-			return false;
181
-		}
182
-
183
-		\OC::$server->getEventLogger()->start('setup_fs', 'Setup filesystem');
184
-
185
-		// If we are not forced to load a specific user we load the one that is logged in
186
-		if ($user === null) {
187
-			$user = '';
188
-		} else if ($user == "" && \OC::$server->getUserSession()->isLoggedIn()) {
189
-			$user = OC_User::getUser();
190
-		}
191
-
192
-		// load all filesystem apps before, so no setup-hook gets lost
193
-		OC_App::loadApps(array('filesystem'));
194
-
195
-		// the filesystem will finish when $user is not empty,
196
-		// mark fs setup here to avoid doing the setup from loading
197
-		// OC_Filesystem
198
-		if ($user != '') {
199
-			self::$fsSetup = true;
200
-		}
201
-
202
-		\OC\Files\Filesystem::initMountManager();
203
-
204
-		\OC\Files\Filesystem::logWarningWhenAddingStorageWrapper(false);
205
-		\OC\Files\Filesystem::addStorageWrapper('mount_options', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) {
206
-			if ($storage->instanceOfStorage('\OC\Files\Storage\Common')) {
207
-				/** @var \OC\Files\Storage\Common $storage */
208
-				$storage->setMountOptions($mount->getOptions());
209
-			}
210
-			return $storage;
211
-		});
212
-
213
-		\OC\Files\Filesystem::addStorageWrapper('enable_sharing', function ($mountPoint, \OCP\Files\Storage\IStorage $storage, \OCP\Files\Mount\IMountPoint $mount) {
214
-			if (!$mount->getOption('enable_sharing', true)) {
215
-				return new \OC\Files\Storage\Wrapper\PermissionsMask([
216
-					'storage' => $storage,
217
-					'mask' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_SHARE
218
-				]);
219
-			}
220
-			return $storage;
221
-		});
222
-
223
-		// install storage availability wrapper, before most other wrappers
224
-		\OC\Files\Filesystem::addStorageWrapper('oc_availability', function ($mountPoint, \OCP\Files\Storage\IStorage $storage) {
225
-			if (!$storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage') && !$storage->isLocal()) {
226
-				return new \OC\Files\Storage\Wrapper\Availability(['storage' => $storage]);
227
-			}
228
-			return $storage;
229
-		});
230
-
231
-		\OC\Files\Filesystem::addStorageWrapper('oc_encoding', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) {
232
-			if ($mount->getOption('encoding_compatibility', false) && !$storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage') && !$storage->isLocal()) {
233
-				return new \OC\Files\Storage\Wrapper\Encoding(['storage' => $storage]);
234
-			}
235
-			return $storage;
236
-		});
237
-
238
-		\OC\Files\Filesystem::addStorageWrapper('oc_quota', function ($mountPoint, $storage) {
239
-			// set up quota for home storages, even for other users
240
-			// which can happen when using sharing
241
-
242
-			/**
243
-			 * @var \OC\Files\Storage\Storage $storage
244
-			 */
245
-			if ($storage->instanceOfStorage('\OC\Files\Storage\Home')
246
-				|| $storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage')
247
-			) {
248
-				/** @var \OC\Files\Storage\Home $storage */
249
-				if (is_object($storage->getUser())) {
250
-					$user = $storage->getUser()->getUID();
251
-					$quota = OC_Util::getUserQuota($user);
252
-					if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
253
-						return new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => $quota, 'root' => 'files'));
254
-					}
255
-				}
256
-			}
257
-
258
-			return $storage;
259
-		});
260
-
261
-		OC_Hook::emit('OC_Filesystem', 'preSetup', array('user' => $user));
262
-		\OC\Files\Filesystem::logWarningWhenAddingStorageWrapper(true);
263
-
264
-		//check if we are using an object storage
265
-		$objectStore = \OC::$server->getSystemConfig()->getValue('objectstore', null);
266
-		$objectStoreMultibucket = \OC::$server->getSystemConfig()->getValue('objectstore_multibucket', null);
267
-
268
-		// use the same order as in ObjectHomeMountProvider
269
-		if (isset($objectStoreMultibucket)) {
270
-			self::initObjectStoreMultibucketRootFS($objectStoreMultibucket);
271
-		} elseif (isset($objectStore)) {
272
-			self::initObjectStoreRootFS($objectStore);
273
-		} else {
274
-			self::initLocalStorageRootFS();
275
-		}
276
-
277
-		if ($user != '' && !\OC::$server->getUserManager()->userExists($user)) {
278
-			\OC::$server->getEventLogger()->end('setup_fs');
279
-			return false;
280
-		}
281
-
282
-		//if we aren't logged in, there is no use to set up the filesystem
283
-		if ($user != "") {
284
-
285
-			$userDir = '/' . $user . '/files';
286
-
287
-			//jail the user into his "home" directory
288
-			\OC\Files\Filesystem::init($user, $userDir);
289
-
290
-			OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $userDir));
291
-		}
292
-		\OC::$server->getEventLogger()->end('setup_fs');
293
-		return true;
294
-	}
295
-
296
-	/**
297
-	 * check if a password is required for each public link
298
-	 *
299
-	 * @return boolean
300
-	 * @suppress PhanDeprecatedFunction
301
-	 */
302
-	public static function isPublicLinkPasswordRequired() {
303
-		$enforcePassword = \OC::$server->getConfig()->getAppValue('core', 'shareapi_enforce_links_password', 'no');
304
-		return $enforcePassword === 'yes';
305
-	}
306
-
307
-	/**
308
-	 * check if sharing is disabled for the current user
309
-	 * @param IConfig $config
310
-	 * @param IGroupManager $groupManager
311
-	 * @param IUser|null $user
312
-	 * @return bool
313
-	 */
314
-	public static function isSharingDisabledForUser(IConfig $config, IGroupManager $groupManager, $user) {
315
-		if ($config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
316
-			$groupsList = $config->getAppValue('core', 'shareapi_exclude_groups_list', '');
317
-			$excludedGroups = json_decode($groupsList);
318
-			if (is_null($excludedGroups)) {
319
-				$excludedGroups = explode(',', $groupsList);
320
-				$newValue = json_encode($excludedGroups);
321
-				$config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
322
-			}
323
-			$usersGroups = $groupManager->getUserGroupIds($user);
324
-			if (!empty($usersGroups)) {
325
-				$remainingGroups = array_diff($usersGroups, $excludedGroups);
326
-				// if the user is only in groups which are disabled for sharing then
327
-				// sharing is also disabled for the user
328
-				if (empty($remainingGroups)) {
329
-					return true;
330
-				}
331
-			}
332
-		}
333
-		return false;
334
-	}
335
-
336
-	/**
337
-	 * check if share API enforces a default expire date
338
-	 *
339
-	 * @return boolean
340
-	 * @suppress PhanDeprecatedFunction
341
-	 */
342
-	public static function isDefaultExpireDateEnforced() {
343
-		$isDefaultExpireDateEnabled = \OC::$server->getConfig()->getAppValue('core', 'shareapi_default_expire_date', 'no');
344
-		$enforceDefaultExpireDate = false;
345
-		if ($isDefaultExpireDateEnabled === 'yes') {
346
-			$value = \OC::$server->getConfig()->getAppValue('core', 'shareapi_enforce_expire_date', 'no');
347
-			$enforceDefaultExpireDate = $value === 'yes';
348
-		}
349
-
350
-		return $enforceDefaultExpireDate;
351
-	}
352
-
353
-	/**
354
-	 * Get the quota of a user
355
-	 *
356
-	 * @param string $userId
357
-	 * @return float Quota bytes
358
-	 */
359
-	public static function getUserQuota($userId) {
360
-		$user = \OC::$server->getUserManager()->get($userId);
361
-		if (is_null($user)) {
362
-			return \OCP\Files\FileInfo::SPACE_UNLIMITED;
363
-		}
364
-		$userQuota = $user->getQuota();
365
-		if($userQuota === 'none') {
366
-			return \OCP\Files\FileInfo::SPACE_UNLIMITED;
367
-		}
368
-		return OC_Helper::computerFileSize($userQuota);
369
-	}
370
-
371
-	/**
372
-	 * copies the skeleton to the users /files
373
-	 *
374
-	 * @param String $userId
375
-	 * @param \OCP\Files\Folder $userDirectory
376
-	 * @throws \RuntimeException
377
-	 * @suppress PhanDeprecatedFunction
378
-	 */
379
-	public static function copySkeleton($userId, \OCP\Files\Folder $userDirectory) {
380
-
381
-		$plainSkeletonDirectory = \OC::$server->getConfig()->getSystemValue('skeletondirectory', \OC::$SERVERROOT . '/core/skeleton');
382
-		$userLang = \OC::$server->getL10NFactory()->findLanguage();
383
-		$skeletonDirectory = str_replace('{lang}', $userLang, $plainSkeletonDirectory);
384
-
385
-		if (!file_exists($skeletonDirectory)) {
386
-			$dialectStart = strpos($userLang, '_');
387
-			if ($dialectStart !== false) {
388
-				$skeletonDirectory = str_replace('{lang}', substr($userLang, 0, $dialectStart), $plainSkeletonDirectory);
389
-			}
390
-			if ($dialectStart === false || !file_exists($skeletonDirectory)) {
391
-				$skeletonDirectory = str_replace('{lang}', 'default', $plainSkeletonDirectory);
392
-			}
393
-			if (!file_exists($skeletonDirectory)) {
394
-				$skeletonDirectory = '';
395
-			}
396
-		}
397
-
398
-		$instanceId = \OC::$server->getConfig()->getSystemValue('instanceid', '');
399
-
400
-		if ($instanceId === null) {
401
-			throw new \RuntimeException('no instance id!');
402
-		}
403
-		$appdata = 'appdata_' . $instanceId;
404
-		if ($userId === $appdata) {
405
-			throw new \RuntimeException('username is reserved name: ' . $appdata);
406
-		}
407
-
408
-		if (!empty($skeletonDirectory)) {
409
-			\OCP\Util::writeLog(
410
-				'files_skeleton',
411
-				'copying skeleton for '.$userId.' from '.$skeletonDirectory.' to '.$userDirectory->getFullPath('/'),
412
-				\OCP\Util::DEBUG
413
-			);
414
-			self::copyr($skeletonDirectory, $userDirectory);
415
-			// update the file cache
416
-			$userDirectory->getStorage()->getScanner()->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE);
417
-		}
418
-	}
419
-
420
-	/**
421
-	 * copies a directory recursively by using streams
422
-	 *
423
-	 * @param string $source
424
-	 * @param \OCP\Files\Folder $target
425
-	 * @return void
426
-	 */
427
-	public static function copyr($source, \OCP\Files\Folder $target) {
428
-		$logger = \OC::$server->getLogger();
429
-
430
-		// Verify if folder exists
431
-		$dir = opendir($source);
432
-		if($dir === false) {
433
-			$logger->error(sprintf('Could not opendir "%s"', $source), ['app' => 'core']);
434
-			return;
435
-		}
436
-
437
-		// Copy the files
438
-		while (false !== ($file = readdir($dir))) {
439
-			if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
440
-				if (is_dir($source . '/' . $file)) {
441
-					$child = $target->newFolder($file);
442
-					self::copyr($source . '/' . $file, $child);
443
-				} else {
444
-					$child = $target->newFile($file);
445
-					$sourceStream = fopen($source . '/' . $file, 'r');
446
-					if($sourceStream === false) {
447
-						$logger->error(sprintf('Could not fopen "%s"', $source . '/' . $file), ['app' => 'core']);
448
-						closedir($dir);
449
-						return;
450
-					}
451
-					stream_copy_to_stream($sourceStream, $child->fopen('w'));
452
-				}
453
-			}
454
-		}
455
-		closedir($dir);
456
-	}
457
-
458
-	/**
459
-	 * @return void
460
-	 * @suppress PhanUndeclaredMethod
461
-	 */
462
-	public static function tearDownFS() {
463
-		\OC\Files\Filesystem::tearDown();
464
-		\OC::$server->getRootFolder()->clearCache();
465
-		self::$fsSetup = false;
466
-		self::$rootMounted = false;
467
-	}
468
-
469
-	/**
470
-	 * get the current installed version of ownCloud
471
-	 *
472
-	 * @return array
473
-	 */
474
-	public static function getVersion() {
475
-		OC_Util::loadVersion();
476
-		return self::$versionCache['OC_Version'];
477
-	}
478
-
479
-	/**
480
-	 * get the current installed version string of ownCloud
481
-	 *
482
-	 * @return string
483
-	 */
484
-	public static function getVersionString() {
485
-		OC_Util::loadVersion();
486
-		return self::$versionCache['OC_VersionString'];
487
-	}
488
-
489
-	/**
490
-	 * @deprecated the value is of no use anymore
491
-	 * @return string
492
-	 */
493
-	public static function getEditionString() {
494
-		return '';
495
-	}
496
-
497
-	/**
498
-	 * @description get the update channel of the current installed of ownCloud.
499
-	 * @return string
500
-	 */
501
-	public static function getChannel() {
502
-		OC_Util::loadVersion();
503
-		return \OC::$server->getConfig()->getSystemValue('updater.release.channel', self::$versionCache['OC_Channel']);
504
-	}
505
-
506
-	/**
507
-	 * @description get the build number of the current installed of ownCloud.
508
-	 * @return string
509
-	 */
510
-	public static function getBuild() {
511
-		OC_Util::loadVersion();
512
-		return self::$versionCache['OC_Build'];
513
-	}
514
-
515
-	/**
516
-	 * @description load the version.php into the session as cache
517
-	 * @suppress PhanUndeclaredVariable
518
-	 */
519
-	private static function loadVersion() {
520
-		if (self::$versionCache !== null) {
521
-			return;
522
-		}
523
-
524
-		$timestamp = filemtime(OC::$SERVERROOT . '/version.php');
525
-		require OC::$SERVERROOT . '/version.php';
526
-		/** @var $timestamp int */
527
-		self::$versionCache['OC_Version_Timestamp'] = $timestamp;
528
-		/** @var $OC_Version string */
529
-		self::$versionCache['OC_Version'] = $OC_Version;
530
-		/** @var $OC_VersionString string */
531
-		self::$versionCache['OC_VersionString'] = $OC_VersionString;
532
-		/** @var $OC_Build string */
533
-		self::$versionCache['OC_Build'] = $OC_Build;
534
-
535
-		/** @var $OC_Channel string */
536
-		self::$versionCache['OC_Channel'] = $OC_Channel;
537
-	}
538
-
539
-	/**
540
-	 * generates a path for JS/CSS files. If no application is provided it will create the path for core.
541
-	 *
542
-	 * @param string $application application to get the files from
543
-	 * @param string $directory directory within this application (css, js, vendor, etc)
544
-	 * @param string $file the file inside of the above folder
545
-	 * @return string the path
546
-	 */
547
-	private static function generatePath($application, $directory, $file) {
548
-		if (is_null($file)) {
549
-			$file = $application;
550
-			$application = "";
551
-		}
552
-		if (!empty($application)) {
553
-			return "$application/$directory/$file";
554
-		} else {
555
-			return "$directory/$file";
556
-		}
557
-	}
558
-
559
-	/**
560
-	 * add a javascript file
561
-	 *
562
-	 * @param string $application application id
563
-	 * @param string|null $file filename
564
-	 * @param bool $prepend prepend the Script to the beginning of the list
565
-	 * @return void
566
-	 */
567
-	public static function addScript($application, $file = null, $prepend = false) {
568
-		$path = OC_Util::generatePath($application, 'js', $file);
569
-
570
-		// core js files need separate handling
571
-		if ($application !== 'core' && $file !== null) {
572
-			self::addTranslations ( $application );
573
-		}
574
-		self::addExternalResource($application, $prepend, $path, "script");
575
-	}
576
-
577
-	/**
578
-	 * add a javascript file from the vendor sub folder
579
-	 *
580
-	 * @param string $application application id
581
-	 * @param string|null $file filename
582
-	 * @param bool $prepend prepend the Script to the beginning of the list
583
-	 * @return void
584
-	 */
585
-	public static function addVendorScript($application, $file = null, $prepend = false) {
586
-		$path = OC_Util::generatePath($application, 'vendor', $file);
587
-		self::addExternalResource($application, $prepend, $path, "script");
588
-	}
589
-
590
-	/**
591
-	 * add a translation JS file
592
-	 *
593
-	 * @param string $application application id
594
-	 * @param string|null $languageCode language code, defaults to the current language
595
-	 * @param bool|null $prepend prepend the Script to the beginning of the list
596
-	 */
597
-	public static function addTranslations($application, $languageCode = null, $prepend = false) {
598
-		if (is_null($languageCode)) {
599
-			$languageCode = \OC::$server->getL10NFactory()->findLanguage($application);
600
-		}
601
-		if (!empty($application)) {
602
-			$path = "$application/l10n/$languageCode";
603
-		} else {
604
-			$path = "l10n/$languageCode";
605
-		}
606
-		self::addExternalResource($application, $prepend, $path, "script");
607
-	}
608
-
609
-	/**
610
-	 * add a css file
611
-	 *
612
-	 * @param string $application application id
613
-	 * @param string|null $file filename
614
-	 * @param bool $prepend prepend the Style to the beginning of the list
615
-	 * @return void
616
-	 */
617
-	public static function addStyle($application, $file = null, $prepend = false) {
618
-		$path = OC_Util::generatePath($application, 'css', $file);
619
-		self::addExternalResource($application, $prepend, $path, "style");
620
-	}
621
-
622
-	/**
623
-	 * add a css file from the vendor sub folder
624
-	 *
625
-	 * @param string $application application id
626
-	 * @param string|null $file filename
627
-	 * @param bool $prepend prepend the Style to the beginning of the list
628
-	 * @return void
629
-	 */
630
-	public static function addVendorStyle($application, $file = null, $prepend = false) {
631
-		$path = OC_Util::generatePath($application, 'vendor', $file);
632
-		self::addExternalResource($application, $prepend, $path, "style");
633
-	}
634
-
635
-	/**
636
-	 * add an external resource css/js file
637
-	 *
638
-	 * @param string $application application id
639
-	 * @param bool $prepend prepend the file to the beginning of the list
640
-	 * @param string $path
641
-	 * @param string $type (script or style)
642
-	 * @return void
643
-	 */
644
-	private static function addExternalResource($application, $prepend, $path, $type = "script") {
645
-
646
-		if ($type === "style") {
647
-			if (!in_array($path, self::$styles)) {
648
-				if ($prepend === true) {
649
-					array_unshift ( self::$styles, $path );
650
-				} else {
651
-					self::$styles[] = $path;
652
-				}
653
-			}
654
-		} elseif ($type === "script") {
655
-			if (!in_array($path, self::$scripts)) {
656
-				if ($prepend === true) {
657
-					array_unshift ( self::$scripts, $path );
658
-				} else {
659
-					self::$scripts [] = $path;
660
-				}
661
-			}
662
-		}
663
-	}
664
-
665
-	/**
666
-	 * Add a custom element to the header
667
-	 * If $text is null then the element will be written as empty element.
668
-	 * So use "" to get a closing tag.
669
-	 * @param string $tag tag name of the element
670
-	 * @param array $attributes array of attributes for the element
671
-	 * @param string $text the text content for the element
672
-	 */
673
-	public static function addHeader($tag, $attributes, $text=null) {
674
-		self::$headers[] = array(
675
-			'tag' => $tag,
676
-			'attributes' => $attributes,
677
-			'text' => $text
678
-		);
679
-	}
680
-
681
-	/**
682
-	 * check if the current server configuration is suitable for ownCloud
683
-	 *
684
-	 * @param \OC\SystemConfig $config
685
-	 * @return array arrays with error messages and hints
686
-	 */
687
-	public static function checkServer(\OC\SystemConfig $config) {
688
-		$l = \OC::$server->getL10N('lib');
689
-		$errors = array();
690
-		$CONFIG_DATADIRECTORY = $config->getValue('datadirectory', OC::$SERVERROOT . '/data');
691
-
692
-		if (!self::needUpgrade($config) && $config->getValue('installed', false)) {
693
-			// this check needs to be done every time
694
-			$errors = self::checkDataDirectoryValidity($CONFIG_DATADIRECTORY);
695
-		}
696
-
697
-		// Assume that if checkServer() succeeded before in this session, then all is fine.
698
-		if (\OC::$server->getSession()->exists('checkServer_succeeded') && \OC::$server->getSession()->get('checkServer_succeeded')) {
699
-			return $errors;
700
-		}
701
-
702
-		$webServerRestart = false;
703
-		$setup = new \OC\Setup(
704
-			$config,
705
-			\OC::$server->getIniWrapper(),
706
-			\OC::$server->getL10N('lib'),
707
-			\OC::$server->query(\OCP\Defaults::class),
708
-			\OC::$server->getLogger(),
709
-			\OC::$server->getSecureRandom(),
710
-			\OC::$server->query(\OC\Installer::class)
711
-		);
712
-
713
-		$urlGenerator = \OC::$server->getURLGenerator();
714
-
715
-		$availableDatabases = $setup->getSupportedDatabases();
716
-		if (empty($availableDatabases)) {
717
-			$errors[] = array(
718
-				'error' => $l->t('No database drivers (sqlite, mysql, or postgresql) installed.'),
719
-				'hint' => '' //TODO: sane hint
720
-			);
721
-			$webServerRestart = true;
722
-		}
723
-
724
-		// Check if config folder is writable.
725
-		if(!OC_Helper::isReadOnlyConfigEnabled()) {
726
-			if (!is_writable(OC::$configDir) or !is_readable(OC::$configDir)) {
727
-				$errors[] = array(
728
-					'error' => $l->t('Cannot write into "config" directory'),
729
-					'hint' => $l->t('This can usually be fixed by giving the webserver write access to the config directory. See %s',
730
-						[$urlGenerator->linkToDocs('admin-dir_permissions')])
731
-				);
732
-			}
733
-		}
734
-
735
-		// Check if there is a writable install folder.
736
-		if ($config->getValue('appstoreenabled', true)) {
737
-			if (OC_App::getInstallPath() === null
738
-				|| !is_writable(OC_App::getInstallPath())
739
-				|| !is_readable(OC_App::getInstallPath())
740
-			) {
741
-				$errors[] = array(
742
-					'error' => $l->t('Cannot write into "apps" directory'),
743
-					'hint' => $l->t('This can usually be fixed by giving the webserver write access to the apps directory'
744
-						. ' or disabling the appstore in the config file. See %s',
745
-						[$urlGenerator->linkToDocs('admin-dir_permissions')])
746
-				);
747
-			}
748
-		}
749
-		// Create root dir.
750
-		if ($config->getValue('installed', false)) {
751
-			if (!is_dir($CONFIG_DATADIRECTORY)) {
752
-				$success = @mkdir($CONFIG_DATADIRECTORY);
753
-				if ($success) {
754
-					$errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY));
755
-				} else {
756
-					$errors[] = [
757
-						'error' => $l->t('Cannot create "data" directory'),
758
-						'hint' => $l->t('This can usually be fixed by giving the webserver write access to the root directory. See %s',
759
-							[$urlGenerator->linkToDocs('admin-dir_permissions')])
760
-					];
761
-				}
762
-			} else if (!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) {
763
-				//common hint for all file permissions error messages
764
-				$permissionsHint = $l->t('Permissions can usually be fixed by giving the webserver write access to the root directory. See %s.',
765
-					[$urlGenerator->linkToDocs('admin-dir_permissions')]);
766
-				$errors[] = [
767
-					'error' => 'Your data directory is not writable',
768
-					'hint' => $permissionsHint
769
-				];
770
-			} else {
771
-				$errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY));
772
-			}
773
-		}
774
-
775
-		if (!OC_Util::isSetLocaleWorking()) {
776
-			$errors[] = array(
777
-				'error' => $l->t('Setting locale to %s failed',
778
-					array('en_US.UTF-8/fr_FR.UTF-8/es_ES.UTF-8/de_DE.UTF-8/ru_RU.UTF-8/'
779
-						. 'pt_BR.UTF-8/it_IT.UTF-8/ja_JP.UTF-8/zh_CN.UTF-8')),
780
-				'hint' => $l->t('Please install one of these locales on your system and restart your webserver.')
781
-			);
782
-		}
783
-
784
-		// Contains the dependencies that should be checked against
785
-		// classes = class_exists
786
-		// functions = function_exists
787
-		// defined = defined
788
-		// ini = ini_get
789
-		// If the dependency is not found the missing module name is shown to the EndUser
790
-		// When adding new checks always verify that they pass on Travis as well
791
-		// for ini settings, see https://github.com/owncloud/administration/blob/master/travis-ci/custom.ini
792
-		$dependencies = array(
793
-			'classes' => array(
794
-				'ZipArchive' => 'zip',
795
-				'DOMDocument' => 'dom',
796
-				'XMLWriter' => 'XMLWriter',
797
-				'XMLReader' => 'XMLReader',
798
-			),
799
-			'functions' => [
800
-				'xml_parser_create' => 'libxml',
801
-				'mb_strcut' => 'mb multibyte',
802
-				'ctype_digit' => 'ctype',
803
-				'json_encode' => 'JSON',
804
-				'gd_info' => 'GD',
805
-				'gzencode' => 'zlib',
806
-				'iconv' => 'iconv',
807
-				'simplexml_load_string' => 'SimpleXML',
808
-				'hash' => 'HASH Message Digest Framework',
809
-				'curl_init' => 'cURL',
810
-				'openssl_verify' => 'OpenSSL',
811
-			],
812
-			'defined' => array(
813
-				'PDO::ATTR_DRIVER_NAME' => 'PDO'
814
-			),
815
-			'ini' => [
816
-				'default_charset' => 'UTF-8',
817
-			],
818
-		);
819
-		$missingDependencies = array();
820
-		$invalidIniSettings = [];
821
-		$moduleHint = $l->t('Please ask your server administrator to install the module.');
822
-
823
-		/**
824
-		 * FIXME: The dependency check does not work properly on HHVM on the moment
825
-		 *        and prevents installation. Once HHVM is more compatible with our
826
-		 *        approach to check for these values we should re-enable those
827
-		 *        checks.
828
-		 */
829
-		$iniWrapper = \OC::$server->getIniWrapper();
830
-		if (!self::runningOnHhvm()) {
831
-			foreach ($dependencies['classes'] as $class => $module) {
832
-				if (!class_exists($class)) {
833
-					$missingDependencies[] = $module;
834
-				}
835
-			}
836
-			foreach ($dependencies['functions'] as $function => $module) {
837
-				if (!function_exists($function)) {
838
-					$missingDependencies[] = $module;
839
-				}
840
-			}
841
-			foreach ($dependencies['defined'] as $defined => $module) {
842
-				if (!defined($defined)) {
843
-					$missingDependencies[] = $module;
844
-				}
845
-			}
846
-			foreach ($dependencies['ini'] as $setting => $expected) {
847
-				if (is_bool($expected)) {
848
-					if ($iniWrapper->getBool($setting) !== $expected) {
849
-						$invalidIniSettings[] = [$setting, $expected];
850
-					}
851
-				}
852
-				if (is_int($expected)) {
853
-					if ($iniWrapper->getNumeric($setting) !== $expected) {
854
-						$invalidIniSettings[] = [$setting, $expected];
855
-					}
856
-				}
857
-				if (is_string($expected)) {
858
-					if (strtolower($iniWrapper->getString($setting)) !== strtolower($expected)) {
859
-						$invalidIniSettings[] = [$setting, $expected];
860
-					}
861
-				}
862
-			}
863
-		}
864
-
865
-		foreach($missingDependencies as $missingDependency) {
866
-			$errors[] = array(
867
-				'error' => $l->t('PHP module %s not installed.', array($missingDependency)),
868
-				'hint' => $moduleHint
869
-			);
870
-			$webServerRestart = true;
871
-		}
872
-		foreach($invalidIniSettings as $setting) {
873
-			if(is_bool($setting[1])) {
874
-				$setting[1] = $setting[1] ? 'on' : 'off';
875
-			}
876
-			$errors[] = [
877
-				'error' => $l->t('PHP setting "%s" is not set to "%s".', [$setting[0], var_export($setting[1], true)]),
878
-				'hint' =>  $l->t('Adjusting this setting in php.ini will make Nextcloud run again')
879
-			];
880
-			$webServerRestart = true;
881
-		}
882
-
883
-		/**
884
-		 * The mbstring.func_overload check can only be performed if the mbstring
885
-		 * module is installed as it will return null if the checking setting is
886
-		 * not available and thus a check on the boolean value fails.
887
-		 *
888
-		 * TODO: Should probably be implemented in the above generic dependency
889
-		 *       check somehow in the long-term.
890
-		 */
891
-		if($iniWrapper->getBool('mbstring.func_overload') !== null &&
892
-			$iniWrapper->getBool('mbstring.func_overload') === true) {
893
-			$errors[] = array(
894
-				'error' => $l->t('mbstring.func_overload is set to "%s" instead of the expected value "0"', [$iniWrapper->getString('mbstring.func_overload')]),
895
-				'hint' => $l->t('To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini')
896
-			);
897
-		}
898
-
899
-		if(function_exists('xml_parser_create') &&
900
-			LIBXML_LOADED_VERSION < 20700 ) {
901
-			$version = LIBXML_LOADED_VERSION;
902
-			$major = floor($version/10000);
903
-			$version -= ($major * 10000);
904
-			$minor = floor($version/100);
905
-			$version -= ($minor * 100);
906
-			$patch = $version;
907
-			$errors[] = array(
908
-				'error' => $l->t('libxml2 2.7.0 is at least required. Currently %s is installed.', [$major . '.' . $minor . '.' . $patch]),
909
-				'hint' => $l->t('To fix this issue update your libxml2 version and restart your web server.')
910
-			);
911
-		}
912
-
913
-		if (!self::isAnnotationsWorking()) {
914
-			$errors[] = array(
915
-				'error' => $l->t('PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible.'),
916
-				'hint' => $l->t('This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator.')
917
-			);
918
-		}
919
-
920
-		if (!\OC::$CLI && $webServerRestart) {
921
-			$errors[] = array(
922
-				'error' => $l->t('PHP modules have been installed, but they are still listed as missing?'),
923
-				'hint' => $l->t('Please ask your server administrator to restart the web server.')
924
-			);
925
-		}
926
-
927
-		$errors = array_merge($errors, self::checkDatabaseVersion());
928
-
929
-		// Cache the result of this function
930
-		\OC::$server->getSession()->set('checkServer_succeeded', count($errors) == 0);
931
-
932
-		return $errors;
933
-	}
934
-
935
-	/**
936
-	 * Check the database version
937
-	 *
938
-	 * @return array errors array
939
-	 */
940
-	public static function checkDatabaseVersion() {
941
-		$l = \OC::$server->getL10N('lib');
942
-		$errors = array();
943
-		$dbType = \OC::$server->getSystemConfig()->getValue('dbtype', 'sqlite');
944
-		if ($dbType === 'pgsql') {
945
-			// check PostgreSQL version
946
-			try {
947
-				$result = \OC_DB::executeAudited('SHOW SERVER_VERSION');
948
-				$data = $result->fetchRow();
949
-				if (isset($data['server_version'])) {
950
-					$version = $data['server_version'];
951
-					if (version_compare($version, '9.0.0', '<')) {
952
-						$errors[] = array(
953
-							'error' => $l->t('PostgreSQL >= 9 required'),
954
-							'hint' => $l->t('Please upgrade your database version')
955
-						);
956
-					}
957
-				}
958
-			} catch (\Doctrine\DBAL\DBALException $e) {
959
-				$logger = \OC::$server->getLogger();
960
-				$logger->warning('Error occurred while checking PostgreSQL version, assuming >= 9');
961
-				$logger->logException($e);
962
-			}
963
-		}
964
-		return $errors;
965
-	}
966
-
967
-	/**
968
-	 * Check for correct file permissions of data directory
969
-	 *
970
-	 * @param string $dataDirectory
971
-	 * @return array arrays with error messages and hints
972
-	 */
973
-	public static function checkDataDirectoryPermissions($dataDirectory) {
974
-		if(\OC::$server->getConfig()->getSystemValue('check_data_directory_permissions', true) === false) {
975
-			return  [];
976
-		}
977
-		$l = \OC::$server->getL10N('lib');
978
-		$errors = [];
979
-		$permissionsModHint = $l->t('Please change the permissions to 0770 so that the directory'
980
-			. ' cannot be listed by other users.');
981
-		$perms = substr(decoct(@fileperms($dataDirectory)), -3);
982
-		if (substr($perms, -1) !== '0') {
983
-			chmod($dataDirectory, 0770);
984
-			clearstatcache();
985
-			$perms = substr(decoct(@fileperms($dataDirectory)), -3);
986
-			if ($perms[2] !== '0') {
987
-				$errors[] = [
988
-					'error' => $l->t('Your data directory is readable by other users'),
989
-					'hint' => $permissionsModHint
990
-				];
991
-			}
992
-		}
993
-		return $errors;
994
-	}
995
-
996
-	/**
997
-	 * Check that the data directory exists and is valid by
998
-	 * checking the existence of the ".ocdata" file.
999
-	 *
1000
-	 * @param string $dataDirectory data directory path
1001
-	 * @return array errors found
1002
-	 */
1003
-	public static function checkDataDirectoryValidity($dataDirectory) {
1004
-		$l = \OC::$server->getL10N('lib');
1005
-		$errors = [];
1006
-		if ($dataDirectory[0] !== '/') {
1007
-			$errors[] = [
1008
-				'error' => $l->t('Your data directory must be an absolute path'),
1009
-				'hint' => $l->t('Check the value of "datadirectory" in your configuration')
1010
-			];
1011
-		}
1012
-		if (!file_exists($dataDirectory . '/.ocdata')) {
1013
-			$errors[] = [
1014
-				'error' => $l->t('Your data directory is invalid'),
1015
-				'hint' => $l->t('Ensure there is a file called ".ocdata"' .
1016
-					' in the root of the data directory.')
1017
-			];
1018
-		}
1019
-		return $errors;
1020
-	}
1021
-
1022
-	/**
1023
-	 * Check if the user is logged in, redirects to home if not. With
1024
-	 * redirect URL parameter to the request URI.
1025
-	 *
1026
-	 * @return void
1027
-	 */
1028
-	public static function checkLoggedIn() {
1029
-		// Check if we are a user
1030
-		if (!\OC::$server->getUserSession()->isLoggedIn()) {
1031
-			header('Location: ' . \OC::$server->getURLGenerator()->linkToRoute(
1032
-						'core.login.showLoginForm',
1033
-						[
1034
-							'redirect_url' => \OC::$server->getRequest()->getRequestUri(),
1035
-						]
1036
-					)
1037
-			);
1038
-			exit();
1039
-		}
1040
-		// Redirect to 2FA challenge selection if 2FA challenge was not solved yet
1041
-		if (\OC::$server->getTwoFactorAuthManager()->needsSecondFactor(\OC::$server->getUserSession()->getUser())) {
1042
-			header('Location: ' . \OC::$server->getURLGenerator()->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
1043
-			exit();
1044
-		}
1045
-	}
1046
-
1047
-	/**
1048
-	 * Check if the user is a admin, redirects to home if not
1049
-	 *
1050
-	 * @return void
1051
-	 */
1052
-	public static function checkAdminUser() {
1053
-		OC_Util::checkLoggedIn();
1054
-		if (!OC_User::isAdminUser(OC_User::getUser())) {
1055
-			header('Location: ' . \OCP\Util::linkToAbsolute('', 'index.php'));
1056
-			exit();
1057
-		}
1058
-	}
1059
-
1060
-	/**
1061
-	 * Check if the user is a subadmin, redirects to home if not
1062
-	 *
1063
-	 * @return null|boolean $groups where the current user is subadmin
1064
-	 */
1065
-	public static function checkSubAdminUser() {
1066
-		OC_Util::checkLoggedIn();
1067
-		$userObject = \OC::$server->getUserSession()->getUser();
1068
-		$isSubAdmin = false;
1069
-		if($userObject !== null) {
1070
-			$isSubAdmin = \OC::$server->getGroupManager()->getSubAdmin()->isSubAdmin($userObject);
1071
-		}
1072
-
1073
-		if (!$isSubAdmin) {
1074
-			header('Location: ' . \OCP\Util::linkToAbsolute('', 'index.php'));
1075
-			exit();
1076
-		}
1077
-		return true;
1078
-	}
1079
-
1080
-	/**
1081
-	 * Returns the URL of the default page
1082
-	 * based on the system configuration and
1083
-	 * the apps visible for the current user
1084
-	 *
1085
-	 * @return string URL
1086
-	 * @suppress PhanDeprecatedFunction
1087
-	 */
1088
-	public static function getDefaultPageUrl() {
1089
-		$urlGenerator = \OC::$server->getURLGenerator();
1090
-		// Deny the redirect if the URL contains a @
1091
-		// This prevents unvalidated redirects like ?redirect_url=:[email protected]
1092
-		if (isset($_REQUEST['redirect_url']) && strpos($_REQUEST['redirect_url'], '@') === false) {
1093
-			$location = $urlGenerator->getAbsoluteURL(urldecode($_REQUEST['redirect_url']));
1094
-		} else {
1095
-			$defaultPage = \OC::$server->getConfig()->getAppValue('core', 'defaultpage');
1096
-			if ($defaultPage) {
1097
-				$location = $urlGenerator->getAbsoluteURL($defaultPage);
1098
-			} else {
1099
-				$appId = 'files';
1100
-				$config = \OC::$server->getConfig();
1101
-				$defaultApps = explode(',', $config->getSystemValue('defaultapp', 'files'));
1102
-				// find the first app that is enabled for the current user
1103
-				foreach ($defaultApps as $defaultApp) {
1104
-					$defaultApp = OC_App::cleanAppId(strip_tags($defaultApp));
1105
-					if (static::getAppManager()->isEnabledForUser($defaultApp)) {
1106
-						$appId = $defaultApp;
1107
-						break;
1108
-					}
1109
-				}
1110
-
1111
-				if($config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true') {
1112
-					$location = $urlGenerator->getAbsoluteURL('/apps/' . $appId . '/');
1113
-				} else {
1114
-					$location = $urlGenerator->getAbsoluteURL('/index.php/apps/' . $appId . '/');
1115
-				}
1116
-			}
1117
-		}
1118
-		return $location;
1119
-	}
1120
-
1121
-	/**
1122
-	 * Redirect to the user default page
1123
-	 *
1124
-	 * @return void
1125
-	 */
1126
-	public static function redirectToDefaultPage() {
1127
-		$location = self::getDefaultPageUrl();
1128
-		header('Location: ' . $location);
1129
-		exit();
1130
-	}
1131
-
1132
-	/**
1133
-	 * get an id unique for this instance
1134
-	 *
1135
-	 * @return string
1136
-	 */
1137
-	public static function getInstanceId() {
1138
-		$id = \OC::$server->getSystemConfig()->getValue('instanceid', null);
1139
-		if (is_null($id)) {
1140
-			// We need to guarantee at least one letter in instanceid so it can be used as the session_name
1141
-			$id = 'oc' . \OC::$server->getSecureRandom()->generate(10, \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_DIGITS);
1142
-			\OC::$server->getSystemConfig()->setValue('instanceid', $id);
1143
-		}
1144
-		return $id;
1145
-	}
1146
-
1147
-	/**
1148
-	 * Public function to sanitize HTML
1149
-	 *
1150
-	 * This function is used to sanitize HTML and should be applied on any
1151
-	 * string or array of strings before displaying it on a web page.
1152
-	 *
1153
-	 * @param string|array $value
1154
-	 * @return string|array an array of sanitized strings or a single sanitized string, depends on the input parameter.
1155
-	 */
1156
-	public static function sanitizeHTML($value) {
1157
-		if (is_array($value)) {
1158
-			$value = array_map(function($value) {
1159
-				return self::sanitizeHTML($value);
1160
-			}, $value);
1161
-		} else {
1162
-			// Specify encoding for PHP<5.4
1163
-			$value = htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
1164
-		}
1165
-		return $value;
1166
-	}
1167
-
1168
-	/**
1169
-	 * Public function to encode url parameters
1170
-	 *
1171
-	 * This function is used to encode path to file before output.
1172
-	 * Encoding is done according to RFC 3986 with one exception:
1173
-	 * Character '/' is preserved as is.
1174
-	 *
1175
-	 * @param string $component part of URI to encode
1176
-	 * @return string
1177
-	 */
1178
-	public static function encodePath($component) {
1179
-		$encoded = rawurlencode($component);
1180
-		$encoded = str_replace('%2F', '/', $encoded);
1181
-		return $encoded;
1182
-	}
1183
-
1184
-
1185
-	public function createHtaccessTestFile(\OCP\IConfig $config) {
1186
-		// php dev server does not support htaccess
1187
-		if (php_sapi_name() === 'cli-server') {
1188
-			return false;
1189
-		}
1190
-
1191
-		// testdata
1192
-		$fileName = '/htaccesstest.txt';
1193
-		$testContent = 'This is used for testing whether htaccess is properly enabled to disallow access from the outside. This file can be safely removed.';
1194
-
1195
-		// creating a test file
1196
-		$testFile = $config->getSystemValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $fileName;
1197
-
1198
-		if (file_exists($testFile)) {// already running this test, possible recursive call
1199
-			return false;
1200
-		}
1201
-
1202
-		$fp = @fopen($testFile, 'w');
1203
-		if (!$fp) {
1204
-			throw new OC\HintException('Can\'t create test file to check for working .htaccess file.',
1205
-				'Make sure it is possible for the webserver to write to ' . $testFile);
1206
-		}
1207
-		fwrite($fp, $testContent);
1208
-		fclose($fp);
1209
-
1210
-		return $testContent;
1211
-	}
1212
-
1213
-	/**
1214
-	 * Check if the .htaccess file is working
1215
-	 * @param \OCP\IConfig $config
1216
-	 * @return bool
1217
-	 * @throws Exception
1218
-	 * @throws \OC\HintException If the test file can't get written.
1219
-	 */
1220
-	public function isHtaccessWorking(\OCP\IConfig $config) {
1221
-
1222
-		if (\OC::$CLI || !$config->getSystemValue('check_for_working_htaccess', true)) {
1223
-			return true;
1224
-		}
1225
-
1226
-		$testContent = $this->createHtaccessTestFile($config);
1227
-		if ($testContent === false) {
1228
-			return false;
1229
-		}
1230
-
1231
-		$fileName = '/htaccesstest.txt';
1232
-		$testFile = $config->getSystemValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $fileName;
1233
-
1234
-		// accessing the file via http
1235
-		$url = \OC::$server->getURLGenerator()->getAbsoluteURL(OC::$WEBROOT . '/data' . $fileName);
1236
-		try {
1237
-			$content = \OC::$server->getHTTPClientService()->newClient()->get($url)->getBody();
1238
-		} catch (\Exception $e) {
1239
-			$content = false;
1240
-		}
1241
-
1242
-		// cleanup
1243
-		@unlink($testFile);
1244
-
1245
-		/*
68
+    public static $scripts = array();
69
+    public static $styles = array();
70
+    public static $headers = array();
71
+    private static $rootMounted = false;
72
+    private static $fsSetup = false;
73
+
74
+    /** @var array Local cache of version.php */
75
+    private static $versionCache = null;
76
+
77
+    protected static function getAppManager() {
78
+        return \OC::$server->getAppManager();
79
+    }
80
+
81
+    private static function initLocalStorageRootFS() {
82
+        // mount local file backend as root
83
+        $configDataDirectory = \OC::$server->getSystemConfig()->getValue("datadirectory", OC::$SERVERROOT . "/data");
84
+        //first set up the local "root" storage
85
+        \OC\Files\Filesystem::initMountManager();
86
+        if (!self::$rootMounted) {
87
+            \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $configDataDirectory), '/');
88
+            self::$rootMounted = true;
89
+        }
90
+    }
91
+
92
+    /**
93
+     * mounting an object storage as the root fs will in essence remove the
94
+     * necessity of a data folder being present.
95
+     * TODO make home storage aware of this and use the object storage instead of local disk access
96
+     *
97
+     * @param array $config containing 'class' and optional 'arguments'
98
+     * @suppress PhanDeprecatedFunction
99
+     */
100
+    private static function initObjectStoreRootFS($config) {
101
+        // check misconfiguration
102
+        if (empty($config['class'])) {
103
+            \OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
104
+        }
105
+        if (!isset($config['arguments'])) {
106
+            $config['arguments'] = array();
107
+        }
108
+
109
+        // instantiate object store implementation
110
+        $name = $config['class'];
111
+        if (strpos($name, 'OCA\\') === 0 && substr_count($name, '\\') >= 2) {
112
+            $segments = explode('\\', $name);
113
+            OC_App::loadApp(strtolower($segments[1]));
114
+        }
115
+        $config['arguments']['objectstore'] = new $config['class']($config['arguments']);
116
+        // mount with plain / root object store implementation
117
+        $config['class'] = '\OC\Files\ObjectStore\ObjectStoreStorage';
118
+
119
+        // mount object storage as root
120
+        \OC\Files\Filesystem::initMountManager();
121
+        if (!self::$rootMounted) {
122
+            \OC\Files\Filesystem::mount($config['class'], $config['arguments'], '/');
123
+            self::$rootMounted = true;
124
+        }
125
+    }
126
+
127
+    /**
128
+     * mounting an object storage as the root fs will in essence remove the
129
+     * necessity of a data folder being present.
130
+     *
131
+     * @param array $config containing 'class' and optional 'arguments'
132
+     * @suppress PhanDeprecatedFunction
133
+     */
134
+    private static function initObjectStoreMultibucketRootFS($config) {
135
+        // check misconfiguration
136
+        if (empty($config['class'])) {
137
+            \OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
138
+        }
139
+        if (!isset($config['arguments'])) {
140
+            $config['arguments'] = array();
141
+        }
142
+
143
+        // instantiate object store implementation
144
+        $name = $config['class'];
145
+        if (strpos($name, 'OCA\\') === 0 && substr_count($name, '\\') >= 2) {
146
+            $segments = explode('\\', $name);
147
+            OC_App::loadApp(strtolower($segments[1]));
148
+        }
149
+
150
+        if (!isset($config['arguments']['bucket'])) {
151
+            $config['arguments']['bucket'] = '';
152
+        }
153
+        // put the root FS always in first bucket for multibucket configuration
154
+        $config['arguments']['bucket'] .= '0';
155
+
156
+        $config['arguments']['objectstore'] = new $config['class']($config['arguments']);
157
+        // mount with plain / root object store implementation
158
+        $config['class'] = '\OC\Files\ObjectStore\ObjectStoreStorage';
159
+
160
+        // mount object storage as root
161
+        \OC\Files\Filesystem::initMountManager();
162
+        if (!self::$rootMounted) {
163
+            \OC\Files\Filesystem::mount($config['class'], $config['arguments'], '/');
164
+            self::$rootMounted = true;
165
+        }
166
+    }
167
+
168
+    /**
169
+     * Can be set up
170
+     *
171
+     * @param string $user
172
+     * @return boolean
173
+     * @description configure the initial filesystem based on the configuration
174
+     * @suppress PhanDeprecatedFunction
175
+     * @suppress PhanAccessMethodInternal
176
+     */
177
+    public static function setupFS($user = '') {
178
+        //setting up the filesystem twice can only lead to trouble
179
+        if (self::$fsSetup) {
180
+            return false;
181
+        }
182
+
183
+        \OC::$server->getEventLogger()->start('setup_fs', 'Setup filesystem');
184
+
185
+        // If we are not forced to load a specific user we load the one that is logged in
186
+        if ($user === null) {
187
+            $user = '';
188
+        } else if ($user == "" && \OC::$server->getUserSession()->isLoggedIn()) {
189
+            $user = OC_User::getUser();
190
+        }
191
+
192
+        // load all filesystem apps before, so no setup-hook gets lost
193
+        OC_App::loadApps(array('filesystem'));
194
+
195
+        // the filesystem will finish when $user is not empty,
196
+        // mark fs setup here to avoid doing the setup from loading
197
+        // OC_Filesystem
198
+        if ($user != '') {
199
+            self::$fsSetup = true;
200
+        }
201
+
202
+        \OC\Files\Filesystem::initMountManager();
203
+
204
+        \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper(false);
205
+        \OC\Files\Filesystem::addStorageWrapper('mount_options', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) {
206
+            if ($storage->instanceOfStorage('\OC\Files\Storage\Common')) {
207
+                /** @var \OC\Files\Storage\Common $storage */
208
+                $storage->setMountOptions($mount->getOptions());
209
+            }
210
+            return $storage;
211
+        });
212
+
213
+        \OC\Files\Filesystem::addStorageWrapper('enable_sharing', function ($mountPoint, \OCP\Files\Storage\IStorage $storage, \OCP\Files\Mount\IMountPoint $mount) {
214
+            if (!$mount->getOption('enable_sharing', true)) {
215
+                return new \OC\Files\Storage\Wrapper\PermissionsMask([
216
+                    'storage' => $storage,
217
+                    'mask' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_SHARE
218
+                ]);
219
+            }
220
+            return $storage;
221
+        });
222
+
223
+        // install storage availability wrapper, before most other wrappers
224
+        \OC\Files\Filesystem::addStorageWrapper('oc_availability', function ($mountPoint, \OCP\Files\Storage\IStorage $storage) {
225
+            if (!$storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage') && !$storage->isLocal()) {
226
+                return new \OC\Files\Storage\Wrapper\Availability(['storage' => $storage]);
227
+            }
228
+            return $storage;
229
+        });
230
+
231
+        \OC\Files\Filesystem::addStorageWrapper('oc_encoding', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) {
232
+            if ($mount->getOption('encoding_compatibility', false) && !$storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage') && !$storage->isLocal()) {
233
+                return new \OC\Files\Storage\Wrapper\Encoding(['storage' => $storage]);
234
+            }
235
+            return $storage;
236
+        });
237
+
238
+        \OC\Files\Filesystem::addStorageWrapper('oc_quota', function ($mountPoint, $storage) {
239
+            // set up quota for home storages, even for other users
240
+            // which can happen when using sharing
241
+
242
+            /**
243
+             * @var \OC\Files\Storage\Storage $storage
244
+             */
245
+            if ($storage->instanceOfStorage('\OC\Files\Storage\Home')
246
+                || $storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage')
247
+            ) {
248
+                /** @var \OC\Files\Storage\Home $storage */
249
+                if (is_object($storage->getUser())) {
250
+                    $user = $storage->getUser()->getUID();
251
+                    $quota = OC_Util::getUserQuota($user);
252
+                    if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
253
+                        return new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => $quota, 'root' => 'files'));
254
+                    }
255
+                }
256
+            }
257
+
258
+            return $storage;
259
+        });
260
+
261
+        OC_Hook::emit('OC_Filesystem', 'preSetup', array('user' => $user));
262
+        \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper(true);
263
+
264
+        //check if we are using an object storage
265
+        $objectStore = \OC::$server->getSystemConfig()->getValue('objectstore', null);
266
+        $objectStoreMultibucket = \OC::$server->getSystemConfig()->getValue('objectstore_multibucket', null);
267
+
268
+        // use the same order as in ObjectHomeMountProvider
269
+        if (isset($objectStoreMultibucket)) {
270
+            self::initObjectStoreMultibucketRootFS($objectStoreMultibucket);
271
+        } elseif (isset($objectStore)) {
272
+            self::initObjectStoreRootFS($objectStore);
273
+        } else {
274
+            self::initLocalStorageRootFS();
275
+        }
276
+
277
+        if ($user != '' && !\OC::$server->getUserManager()->userExists($user)) {
278
+            \OC::$server->getEventLogger()->end('setup_fs');
279
+            return false;
280
+        }
281
+
282
+        //if we aren't logged in, there is no use to set up the filesystem
283
+        if ($user != "") {
284
+
285
+            $userDir = '/' . $user . '/files';
286
+
287
+            //jail the user into his "home" directory
288
+            \OC\Files\Filesystem::init($user, $userDir);
289
+
290
+            OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $userDir));
291
+        }
292
+        \OC::$server->getEventLogger()->end('setup_fs');
293
+        return true;
294
+    }
295
+
296
+    /**
297
+     * check if a password is required for each public link
298
+     *
299
+     * @return boolean
300
+     * @suppress PhanDeprecatedFunction
301
+     */
302
+    public static function isPublicLinkPasswordRequired() {
303
+        $enforcePassword = \OC::$server->getConfig()->getAppValue('core', 'shareapi_enforce_links_password', 'no');
304
+        return $enforcePassword === 'yes';
305
+    }
306
+
307
+    /**
308
+     * check if sharing is disabled for the current user
309
+     * @param IConfig $config
310
+     * @param IGroupManager $groupManager
311
+     * @param IUser|null $user
312
+     * @return bool
313
+     */
314
+    public static function isSharingDisabledForUser(IConfig $config, IGroupManager $groupManager, $user) {
315
+        if ($config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
316
+            $groupsList = $config->getAppValue('core', 'shareapi_exclude_groups_list', '');
317
+            $excludedGroups = json_decode($groupsList);
318
+            if (is_null($excludedGroups)) {
319
+                $excludedGroups = explode(',', $groupsList);
320
+                $newValue = json_encode($excludedGroups);
321
+                $config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
322
+            }
323
+            $usersGroups = $groupManager->getUserGroupIds($user);
324
+            if (!empty($usersGroups)) {
325
+                $remainingGroups = array_diff($usersGroups, $excludedGroups);
326
+                // if the user is only in groups which are disabled for sharing then
327
+                // sharing is also disabled for the user
328
+                if (empty($remainingGroups)) {
329
+                    return true;
330
+                }
331
+            }
332
+        }
333
+        return false;
334
+    }
335
+
336
+    /**
337
+     * check if share API enforces a default expire date
338
+     *
339
+     * @return boolean
340
+     * @suppress PhanDeprecatedFunction
341
+     */
342
+    public static function isDefaultExpireDateEnforced() {
343
+        $isDefaultExpireDateEnabled = \OC::$server->getConfig()->getAppValue('core', 'shareapi_default_expire_date', 'no');
344
+        $enforceDefaultExpireDate = false;
345
+        if ($isDefaultExpireDateEnabled === 'yes') {
346
+            $value = \OC::$server->getConfig()->getAppValue('core', 'shareapi_enforce_expire_date', 'no');
347
+            $enforceDefaultExpireDate = $value === 'yes';
348
+        }
349
+
350
+        return $enforceDefaultExpireDate;
351
+    }
352
+
353
+    /**
354
+     * Get the quota of a user
355
+     *
356
+     * @param string $userId
357
+     * @return float Quota bytes
358
+     */
359
+    public static function getUserQuota($userId) {
360
+        $user = \OC::$server->getUserManager()->get($userId);
361
+        if (is_null($user)) {
362
+            return \OCP\Files\FileInfo::SPACE_UNLIMITED;
363
+        }
364
+        $userQuota = $user->getQuota();
365
+        if($userQuota === 'none') {
366
+            return \OCP\Files\FileInfo::SPACE_UNLIMITED;
367
+        }
368
+        return OC_Helper::computerFileSize($userQuota);
369
+    }
370
+
371
+    /**
372
+     * copies the skeleton to the users /files
373
+     *
374
+     * @param String $userId
375
+     * @param \OCP\Files\Folder $userDirectory
376
+     * @throws \RuntimeException
377
+     * @suppress PhanDeprecatedFunction
378
+     */
379
+    public static function copySkeleton($userId, \OCP\Files\Folder $userDirectory) {
380
+
381
+        $plainSkeletonDirectory = \OC::$server->getConfig()->getSystemValue('skeletondirectory', \OC::$SERVERROOT . '/core/skeleton');
382
+        $userLang = \OC::$server->getL10NFactory()->findLanguage();
383
+        $skeletonDirectory = str_replace('{lang}', $userLang, $plainSkeletonDirectory);
384
+
385
+        if (!file_exists($skeletonDirectory)) {
386
+            $dialectStart = strpos($userLang, '_');
387
+            if ($dialectStart !== false) {
388
+                $skeletonDirectory = str_replace('{lang}', substr($userLang, 0, $dialectStart), $plainSkeletonDirectory);
389
+            }
390
+            if ($dialectStart === false || !file_exists($skeletonDirectory)) {
391
+                $skeletonDirectory = str_replace('{lang}', 'default', $plainSkeletonDirectory);
392
+            }
393
+            if (!file_exists($skeletonDirectory)) {
394
+                $skeletonDirectory = '';
395
+            }
396
+        }
397
+
398
+        $instanceId = \OC::$server->getConfig()->getSystemValue('instanceid', '');
399
+
400
+        if ($instanceId === null) {
401
+            throw new \RuntimeException('no instance id!');
402
+        }
403
+        $appdata = 'appdata_' . $instanceId;
404
+        if ($userId === $appdata) {
405
+            throw new \RuntimeException('username is reserved name: ' . $appdata);
406
+        }
407
+
408
+        if (!empty($skeletonDirectory)) {
409
+            \OCP\Util::writeLog(
410
+                'files_skeleton',
411
+                'copying skeleton for '.$userId.' from '.$skeletonDirectory.' to '.$userDirectory->getFullPath('/'),
412
+                \OCP\Util::DEBUG
413
+            );
414
+            self::copyr($skeletonDirectory, $userDirectory);
415
+            // update the file cache
416
+            $userDirectory->getStorage()->getScanner()->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE);
417
+        }
418
+    }
419
+
420
+    /**
421
+     * copies a directory recursively by using streams
422
+     *
423
+     * @param string $source
424
+     * @param \OCP\Files\Folder $target
425
+     * @return void
426
+     */
427
+    public static function copyr($source, \OCP\Files\Folder $target) {
428
+        $logger = \OC::$server->getLogger();
429
+
430
+        // Verify if folder exists
431
+        $dir = opendir($source);
432
+        if($dir === false) {
433
+            $logger->error(sprintf('Could not opendir "%s"', $source), ['app' => 'core']);
434
+            return;
435
+        }
436
+
437
+        // Copy the files
438
+        while (false !== ($file = readdir($dir))) {
439
+            if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
440
+                if (is_dir($source . '/' . $file)) {
441
+                    $child = $target->newFolder($file);
442
+                    self::copyr($source . '/' . $file, $child);
443
+                } else {
444
+                    $child = $target->newFile($file);
445
+                    $sourceStream = fopen($source . '/' . $file, 'r');
446
+                    if($sourceStream === false) {
447
+                        $logger->error(sprintf('Could not fopen "%s"', $source . '/' . $file), ['app' => 'core']);
448
+                        closedir($dir);
449
+                        return;
450
+                    }
451
+                    stream_copy_to_stream($sourceStream, $child->fopen('w'));
452
+                }
453
+            }
454
+        }
455
+        closedir($dir);
456
+    }
457
+
458
+    /**
459
+     * @return void
460
+     * @suppress PhanUndeclaredMethod
461
+     */
462
+    public static function tearDownFS() {
463
+        \OC\Files\Filesystem::tearDown();
464
+        \OC::$server->getRootFolder()->clearCache();
465
+        self::$fsSetup = false;
466
+        self::$rootMounted = false;
467
+    }
468
+
469
+    /**
470
+     * get the current installed version of ownCloud
471
+     *
472
+     * @return array
473
+     */
474
+    public static function getVersion() {
475
+        OC_Util::loadVersion();
476
+        return self::$versionCache['OC_Version'];
477
+    }
478
+
479
+    /**
480
+     * get the current installed version string of ownCloud
481
+     *
482
+     * @return string
483
+     */
484
+    public static function getVersionString() {
485
+        OC_Util::loadVersion();
486
+        return self::$versionCache['OC_VersionString'];
487
+    }
488
+
489
+    /**
490
+     * @deprecated the value is of no use anymore
491
+     * @return string
492
+     */
493
+    public static function getEditionString() {
494
+        return '';
495
+    }
496
+
497
+    /**
498
+     * @description get the update channel of the current installed of ownCloud.
499
+     * @return string
500
+     */
501
+    public static function getChannel() {
502
+        OC_Util::loadVersion();
503
+        return \OC::$server->getConfig()->getSystemValue('updater.release.channel', self::$versionCache['OC_Channel']);
504
+    }
505
+
506
+    /**
507
+     * @description get the build number of the current installed of ownCloud.
508
+     * @return string
509
+     */
510
+    public static function getBuild() {
511
+        OC_Util::loadVersion();
512
+        return self::$versionCache['OC_Build'];
513
+    }
514
+
515
+    /**
516
+     * @description load the version.php into the session as cache
517
+     * @suppress PhanUndeclaredVariable
518
+     */
519
+    private static function loadVersion() {
520
+        if (self::$versionCache !== null) {
521
+            return;
522
+        }
523
+
524
+        $timestamp = filemtime(OC::$SERVERROOT . '/version.php');
525
+        require OC::$SERVERROOT . '/version.php';
526
+        /** @var $timestamp int */
527
+        self::$versionCache['OC_Version_Timestamp'] = $timestamp;
528
+        /** @var $OC_Version string */
529
+        self::$versionCache['OC_Version'] = $OC_Version;
530
+        /** @var $OC_VersionString string */
531
+        self::$versionCache['OC_VersionString'] = $OC_VersionString;
532
+        /** @var $OC_Build string */
533
+        self::$versionCache['OC_Build'] = $OC_Build;
534
+
535
+        /** @var $OC_Channel string */
536
+        self::$versionCache['OC_Channel'] = $OC_Channel;
537
+    }
538
+
539
+    /**
540
+     * generates a path for JS/CSS files. If no application is provided it will create the path for core.
541
+     *
542
+     * @param string $application application to get the files from
543
+     * @param string $directory directory within this application (css, js, vendor, etc)
544
+     * @param string $file the file inside of the above folder
545
+     * @return string the path
546
+     */
547
+    private static function generatePath($application, $directory, $file) {
548
+        if (is_null($file)) {
549
+            $file = $application;
550
+            $application = "";
551
+        }
552
+        if (!empty($application)) {
553
+            return "$application/$directory/$file";
554
+        } else {
555
+            return "$directory/$file";
556
+        }
557
+    }
558
+
559
+    /**
560
+     * add a javascript file
561
+     *
562
+     * @param string $application application id
563
+     * @param string|null $file filename
564
+     * @param bool $prepend prepend the Script to the beginning of the list
565
+     * @return void
566
+     */
567
+    public static function addScript($application, $file = null, $prepend = false) {
568
+        $path = OC_Util::generatePath($application, 'js', $file);
569
+
570
+        // core js files need separate handling
571
+        if ($application !== 'core' && $file !== null) {
572
+            self::addTranslations ( $application );
573
+        }
574
+        self::addExternalResource($application, $prepend, $path, "script");
575
+    }
576
+
577
+    /**
578
+     * add a javascript file from the vendor sub folder
579
+     *
580
+     * @param string $application application id
581
+     * @param string|null $file filename
582
+     * @param bool $prepend prepend the Script to the beginning of the list
583
+     * @return void
584
+     */
585
+    public static function addVendorScript($application, $file = null, $prepend = false) {
586
+        $path = OC_Util::generatePath($application, 'vendor', $file);
587
+        self::addExternalResource($application, $prepend, $path, "script");
588
+    }
589
+
590
+    /**
591
+     * add a translation JS file
592
+     *
593
+     * @param string $application application id
594
+     * @param string|null $languageCode language code, defaults to the current language
595
+     * @param bool|null $prepend prepend the Script to the beginning of the list
596
+     */
597
+    public static function addTranslations($application, $languageCode = null, $prepend = false) {
598
+        if (is_null($languageCode)) {
599
+            $languageCode = \OC::$server->getL10NFactory()->findLanguage($application);
600
+        }
601
+        if (!empty($application)) {
602
+            $path = "$application/l10n/$languageCode";
603
+        } else {
604
+            $path = "l10n/$languageCode";
605
+        }
606
+        self::addExternalResource($application, $prepend, $path, "script");
607
+    }
608
+
609
+    /**
610
+     * add a css file
611
+     *
612
+     * @param string $application application id
613
+     * @param string|null $file filename
614
+     * @param bool $prepend prepend the Style to the beginning of the list
615
+     * @return void
616
+     */
617
+    public static function addStyle($application, $file = null, $prepend = false) {
618
+        $path = OC_Util::generatePath($application, 'css', $file);
619
+        self::addExternalResource($application, $prepend, $path, "style");
620
+    }
621
+
622
+    /**
623
+     * add a css file from the vendor sub folder
624
+     *
625
+     * @param string $application application id
626
+     * @param string|null $file filename
627
+     * @param bool $prepend prepend the Style to the beginning of the list
628
+     * @return void
629
+     */
630
+    public static function addVendorStyle($application, $file = null, $prepend = false) {
631
+        $path = OC_Util::generatePath($application, 'vendor', $file);
632
+        self::addExternalResource($application, $prepend, $path, "style");
633
+    }
634
+
635
+    /**
636
+     * add an external resource css/js file
637
+     *
638
+     * @param string $application application id
639
+     * @param bool $prepend prepend the file to the beginning of the list
640
+     * @param string $path
641
+     * @param string $type (script or style)
642
+     * @return void
643
+     */
644
+    private static function addExternalResource($application, $prepend, $path, $type = "script") {
645
+
646
+        if ($type === "style") {
647
+            if (!in_array($path, self::$styles)) {
648
+                if ($prepend === true) {
649
+                    array_unshift ( self::$styles, $path );
650
+                } else {
651
+                    self::$styles[] = $path;
652
+                }
653
+            }
654
+        } elseif ($type === "script") {
655
+            if (!in_array($path, self::$scripts)) {
656
+                if ($prepend === true) {
657
+                    array_unshift ( self::$scripts, $path );
658
+                } else {
659
+                    self::$scripts [] = $path;
660
+                }
661
+            }
662
+        }
663
+    }
664
+
665
+    /**
666
+     * Add a custom element to the header
667
+     * If $text is null then the element will be written as empty element.
668
+     * So use "" to get a closing tag.
669
+     * @param string $tag tag name of the element
670
+     * @param array $attributes array of attributes for the element
671
+     * @param string $text the text content for the element
672
+     */
673
+    public static function addHeader($tag, $attributes, $text=null) {
674
+        self::$headers[] = array(
675
+            'tag' => $tag,
676
+            'attributes' => $attributes,
677
+            'text' => $text
678
+        );
679
+    }
680
+
681
+    /**
682
+     * check if the current server configuration is suitable for ownCloud
683
+     *
684
+     * @param \OC\SystemConfig $config
685
+     * @return array arrays with error messages and hints
686
+     */
687
+    public static function checkServer(\OC\SystemConfig $config) {
688
+        $l = \OC::$server->getL10N('lib');
689
+        $errors = array();
690
+        $CONFIG_DATADIRECTORY = $config->getValue('datadirectory', OC::$SERVERROOT . '/data');
691
+
692
+        if (!self::needUpgrade($config) && $config->getValue('installed', false)) {
693
+            // this check needs to be done every time
694
+            $errors = self::checkDataDirectoryValidity($CONFIG_DATADIRECTORY);
695
+        }
696
+
697
+        // Assume that if checkServer() succeeded before in this session, then all is fine.
698
+        if (\OC::$server->getSession()->exists('checkServer_succeeded') && \OC::$server->getSession()->get('checkServer_succeeded')) {
699
+            return $errors;
700
+        }
701
+
702
+        $webServerRestart = false;
703
+        $setup = new \OC\Setup(
704
+            $config,
705
+            \OC::$server->getIniWrapper(),
706
+            \OC::$server->getL10N('lib'),
707
+            \OC::$server->query(\OCP\Defaults::class),
708
+            \OC::$server->getLogger(),
709
+            \OC::$server->getSecureRandom(),
710
+            \OC::$server->query(\OC\Installer::class)
711
+        );
712
+
713
+        $urlGenerator = \OC::$server->getURLGenerator();
714
+
715
+        $availableDatabases = $setup->getSupportedDatabases();
716
+        if (empty($availableDatabases)) {
717
+            $errors[] = array(
718
+                'error' => $l->t('No database drivers (sqlite, mysql, or postgresql) installed.'),
719
+                'hint' => '' //TODO: sane hint
720
+            );
721
+            $webServerRestart = true;
722
+        }
723
+
724
+        // Check if config folder is writable.
725
+        if(!OC_Helper::isReadOnlyConfigEnabled()) {
726
+            if (!is_writable(OC::$configDir) or !is_readable(OC::$configDir)) {
727
+                $errors[] = array(
728
+                    'error' => $l->t('Cannot write into "config" directory'),
729
+                    'hint' => $l->t('This can usually be fixed by giving the webserver write access to the config directory. See %s',
730
+                        [$urlGenerator->linkToDocs('admin-dir_permissions')])
731
+                );
732
+            }
733
+        }
734
+
735
+        // Check if there is a writable install folder.
736
+        if ($config->getValue('appstoreenabled', true)) {
737
+            if (OC_App::getInstallPath() === null
738
+                || !is_writable(OC_App::getInstallPath())
739
+                || !is_readable(OC_App::getInstallPath())
740
+            ) {
741
+                $errors[] = array(
742
+                    'error' => $l->t('Cannot write into "apps" directory'),
743
+                    'hint' => $l->t('This can usually be fixed by giving the webserver write access to the apps directory'
744
+                        . ' or disabling the appstore in the config file. See %s',
745
+                        [$urlGenerator->linkToDocs('admin-dir_permissions')])
746
+                );
747
+            }
748
+        }
749
+        // Create root dir.
750
+        if ($config->getValue('installed', false)) {
751
+            if (!is_dir($CONFIG_DATADIRECTORY)) {
752
+                $success = @mkdir($CONFIG_DATADIRECTORY);
753
+                if ($success) {
754
+                    $errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY));
755
+                } else {
756
+                    $errors[] = [
757
+                        'error' => $l->t('Cannot create "data" directory'),
758
+                        'hint' => $l->t('This can usually be fixed by giving the webserver write access to the root directory. See %s',
759
+                            [$urlGenerator->linkToDocs('admin-dir_permissions')])
760
+                    ];
761
+                }
762
+            } else if (!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) {
763
+                //common hint for all file permissions error messages
764
+                $permissionsHint = $l->t('Permissions can usually be fixed by giving the webserver write access to the root directory. See %s.',
765
+                    [$urlGenerator->linkToDocs('admin-dir_permissions')]);
766
+                $errors[] = [
767
+                    'error' => 'Your data directory is not writable',
768
+                    'hint' => $permissionsHint
769
+                ];
770
+            } else {
771
+                $errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY));
772
+            }
773
+        }
774
+
775
+        if (!OC_Util::isSetLocaleWorking()) {
776
+            $errors[] = array(
777
+                'error' => $l->t('Setting locale to %s failed',
778
+                    array('en_US.UTF-8/fr_FR.UTF-8/es_ES.UTF-8/de_DE.UTF-8/ru_RU.UTF-8/'
779
+                        . 'pt_BR.UTF-8/it_IT.UTF-8/ja_JP.UTF-8/zh_CN.UTF-8')),
780
+                'hint' => $l->t('Please install one of these locales on your system and restart your webserver.')
781
+            );
782
+        }
783
+
784
+        // Contains the dependencies that should be checked against
785
+        // classes = class_exists
786
+        // functions = function_exists
787
+        // defined = defined
788
+        // ini = ini_get
789
+        // If the dependency is not found the missing module name is shown to the EndUser
790
+        // When adding new checks always verify that they pass on Travis as well
791
+        // for ini settings, see https://github.com/owncloud/administration/blob/master/travis-ci/custom.ini
792
+        $dependencies = array(
793
+            'classes' => array(
794
+                'ZipArchive' => 'zip',
795
+                'DOMDocument' => 'dom',
796
+                'XMLWriter' => 'XMLWriter',
797
+                'XMLReader' => 'XMLReader',
798
+            ),
799
+            'functions' => [
800
+                'xml_parser_create' => 'libxml',
801
+                'mb_strcut' => 'mb multibyte',
802
+                'ctype_digit' => 'ctype',
803
+                'json_encode' => 'JSON',
804
+                'gd_info' => 'GD',
805
+                'gzencode' => 'zlib',
806
+                'iconv' => 'iconv',
807
+                'simplexml_load_string' => 'SimpleXML',
808
+                'hash' => 'HASH Message Digest Framework',
809
+                'curl_init' => 'cURL',
810
+                'openssl_verify' => 'OpenSSL',
811
+            ],
812
+            'defined' => array(
813
+                'PDO::ATTR_DRIVER_NAME' => 'PDO'
814
+            ),
815
+            'ini' => [
816
+                'default_charset' => 'UTF-8',
817
+            ],
818
+        );
819
+        $missingDependencies = array();
820
+        $invalidIniSettings = [];
821
+        $moduleHint = $l->t('Please ask your server administrator to install the module.');
822
+
823
+        /**
824
+         * FIXME: The dependency check does not work properly on HHVM on the moment
825
+         *        and prevents installation. Once HHVM is more compatible with our
826
+         *        approach to check for these values we should re-enable those
827
+         *        checks.
828
+         */
829
+        $iniWrapper = \OC::$server->getIniWrapper();
830
+        if (!self::runningOnHhvm()) {
831
+            foreach ($dependencies['classes'] as $class => $module) {
832
+                if (!class_exists($class)) {
833
+                    $missingDependencies[] = $module;
834
+                }
835
+            }
836
+            foreach ($dependencies['functions'] as $function => $module) {
837
+                if (!function_exists($function)) {
838
+                    $missingDependencies[] = $module;
839
+                }
840
+            }
841
+            foreach ($dependencies['defined'] as $defined => $module) {
842
+                if (!defined($defined)) {
843
+                    $missingDependencies[] = $module;
844
+                }
845
+            }
846
+            foreach ($dependencies['ini'] as $setting => $expected) {
847
+                if (is_bool($expected)) {
848
+                    if ($iniWrapper->getBool($setting) !== $expected) {
849
+                        $invalidIniSettings[] = [$setting, $expected];
850
+                    }
851
+                }
852
+                if (is_int($expected)) {
853
+                    if ($iniWrapper->getNumeric($setting) !== $expected) {
854
+                        $invalidIniSettings[] = [$setting, $expected];
855
+                    }
856
+                }
857
+                if (is_string($expected)) {
858
+                    if (strtolower($iniWrapper->getString($setting)) !== strtolower($expected)) {
859
+                        $invalidIniSettings[] = [$setting, $expected];
860
+                    }
861
+                }
862
+            }
863
+        }
864
+
865
+        foreach($missingDependencies as $missingDependency) {
866
+            $errors[] = array(
867
+                'error' => $l->t('PHP module %s not installed.', array($missingDependency)),
868
+                'hint' => $moduleHint
869
+            );
870
+            $webServerRestart = true;
871
+        }
872
+        foreach($invalidIniSettings as $setting) {
873
+            if(is_bool($setting[1])) {
874
+                $setting[1] = $setting[1] ? 'on' : 'off';
875
+            }
876
+            $errors[] = [
877
+                'error' => $l->t('PHP setting "%s" is not set to "%s".', [$setting[0], var_export($setting[1], true)]),
878
+                'hint' =>  $l->t('Adjusting this setting in php.ini will make Nextcloud run again')
879
+            ];
880
+            $webServerRestart = true;
881
+        }
882
+
883
+        /**
884
+         * The mbstring.func_overload check can only be performed if the mbstring
885
+         * module is installed as it will return null if the checking setting is
886
+         * not available and thus a check on the boolean value fails.
887
+         *
888
+         * TODO: Should probably be implemented in the above generic dependency
889
+         *       check somehow in the long-term.
890
+         */
891
+        if($iniWrapper->getBool('mbstring.func_overload') !== null &&
892
+            $iniWrapper->getBool('mbstring.func_overload') === true) {
893
+            $errors[] = array(
894
+                'error' => $l->t('mbstring.func_overload is set to "%s" instead of the expected value "0"', [$iniWrapper->getString('mbstring.func_overload')]),
895
+                'hint' => $l->t('To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini')
896
+            );
897
+        }
898
+
899
+        if(function_exists('xml_parser_create') &&
900
+            LIBXML_LOADED_VERSION < 20700 ) {
901
+            $version = LIBXML_LOADED_VERSION;
902
+            $major = floor($version/10000);
903
+            $version -= ($major * 10000);
904
+            $minor = floor($version/100);
905
+            $version -= ($minor * 100);
906
+            $patch = $version;
907
+            $errors[] = array(
908
+                'error' => $l->t('libxml2 2.7.0 is at least required. Currently %s is installed.', [$major . '.' . $minor . '.' . $patch]),
909
+                'hint' => $l->t('To fix this issue update your libxml2 version and restart your web server.')
910
+            );
911
+        }
912
+
913
+        if (!self::isAnnotationsWorking()) {
914
+            $errors[] = array(
915
+                'error' => $l->t('PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible.'),
916
+                'hint' => $l->t('This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator.')
917
+            );
918
+        }
919
+
920
+        if (!\OC::$CLI && $webServerRestart) {
921
+            $errors[] = array(
922
+                'error' => $l->t('PHP modules have been installed, but they are still listed as missing?'),
923
+                'hint' => $l->t('Please ask your server administrator to restart the web server.')
924
+            );
925
+        }
926
+
927
+        $errors = array_merge($errors, self::checkDatabaseVersion());
928
+
929
+        // Cache the result of this function
930
+        \OC::$server->getSession()->set('checkServer_succeeded', count($errors) == 0);
931
+
932
+        return $errors;
933
+    }
934
+
935
+    /**
936
+     * Check the database version
937
+     *
938
+     * @return array errors array
939
+     */
940
+    public static function checkDatabaseVersion() {
941
+        $l = \OC::$server->getL10N('lib');
942
+        $errors = array();
943
+        $dbType = \OC::$server->getSystemConfig()->getValue('dbtype', 'sqlite');
944
+        if ($dbType === 'pgsql') {
945
+            // check PostgreSQL version
946
+            try {
947
+                $result = \OC_DB::executeAudited('SHOW SERVER_VERSION');
948
+                $data = $result->fetchRow();
949
+                if (isset($data['server_version'])) {
950
+                    $version = $data['server_version'];
951
+                    if (version_compare($version, '9.0.0', '<')) {
952
+                        $errors[] = array(
953
+                            'error' => $l->t('PostgreSQL >= 9 required'),
954
+                            'hint' => $l->t('Please upgrade your database version')
955
+                        );
956
+                    }
957
+                }
958
+            } catch (\Doctrine\DBAL\DBALException $e) {
959
+                $logger = \OC::$server->getLogger();
960
+                $logger->warning('Error occurred while checking PostgreSQL version, assuming >= 9');
961
+                $logger->logException($e);
962
+            }
963
+        }
964
+        return $errors;
965
+    }
966
+
967
+    /**
968
+     * Check for correct file permissions of data directory
969
+     *
970
+     * @param string $dataDirectory
971
+     * @return array arrays with error messages and hints
972
+     */
973
+    public static function checkDataDirectoryPermissions($dataDirectory) {
974
+        if(\OC::$server->getConfig()->getSystemValue('check_data_directory_permissions', true) === false) {
975
+            return  [];
976
+        }
977
+        $l = \OC::$server->getL10N('lib');
978
+        $errors = [];
979
+        $permissionsModHint = $l->t('Please change the permissions to 0770 so that the directory'
980
+            . ' cannot be listed by other users.');
981
+        $perms = substr(decoct(@fileperms($dataDirectory)), -3);
982
+        if (substr($perms, -1) !== '0') {
983
+            chmod($dataDirectory, 0770);
984
+            clearstatcache();
985
+            $perms = substr(decoct(@fileperms($dataDirectory)), -3);
986
+            if ($perms[2] !== '0') {
987
+                $errors[] = [
988
+                    'error' => $l->t('Your data directory is readable by other users'),
989
+                    'hint' => $permissionsModHint
990
+                ];
991
+            }
992
+        }
993
+        return $errors;
994
+    }
995
+
996
+    /**
997
+     * Check that the data directory exists and is valid by
998
+     * checking the existence of the ".ocdata" file.
999
+     *
1000
+     * @param string $dataDirectory data directory path
1001
+     * @return array errors found
1002
+     */
1003
+    public static function checkDataDirectoryValidity($dataDirectory) {
1004
+        $l = \OC::$server->getL10N('lib');
1005
+        $errors = [];
1006
+        if ($dataDirectory[0] !== '/') {
1007
+            $errors[] = [
1008
+                'error' => $l->t('Your data directory must be an absolute path'),
1009
+                'hint' => $l->t('Check the value of "datadirectory" in your configuration')
1010
+            ];
1011
+        }
1012
+        if (!file_exists($dataDirectory . '/.ocdata')) {
1013
+            $errors[] = [
1014
+                'error' => $l->t('Your data directory is invalid'),
1015
+                'hint' => $l->t('Ensure there is a file called ".ocdata"' .
1016
+                    ' in the root of the data directory.')
1017
+            ];
1018
+        }
1019
+        return $errors;
1020
+    }
1021
+
1022
+    /**
1023
+     * Check if the user is logged in, redirects to home if not. With
1024
+     * redirect URL parameter to the request URI.
1025
+     *
1026
+     * @return void
1027
+     */
1028
+    public static function checkLoggedIn() {
1029
+        // Check if we are a user
1030
+        if (!\OC::$server->getUserSession()->isLoggedIn()) {
1031
+            header('Location: ' . \OC::$server->getURLGenerator()->linkToRoute(
1032
+                        'core.login.showLoginForm',
1033
+                        [
1034
+                            'redirect_url' => \OC::$server->getRequest()->getRequestUri(),
1035
+                        ]
1036
+                    )
1037
+            );
1038
+            exit();
1039
+        }
1040
+        // Redirect to 2FA challenge selection if 2FA challenge was not solved yet
1041
+        if (\OC::$server->getTwoFactorAuthManager()->needsSecondFactor(\OC::$server->getUserSession()->getUser())) {
1042
+            header('Location: ' . \OC::$server->getURLGenerator()->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
1043
+            exit();
1044
+        }
1045
+    }
1046
+
1047
+    /**
1048
+     * Check if the user is a admin, redirects to home if not
1049
+     *
1050
+     * @return void
1051
+     */
1052
+    public static function checkAdminUser() {
1053
+        OC_Util::checkLoggedIn();
1054
+        if (!OC_User::isAdminUser(OC_User::getUser())) {
1055
+            header('Location: ' . \OCP\Util::linkToAbsolute('', 'index.php'));
1056
+            exit();
1057
+        }
1058
+    }
1059
+
1060
+    /**
1061
+     * Check if the user is a subadmin, redirects to home if not
1062
+     *
1063
+     * @return null|boolean $groups where the current user is subadmin
1064
+     */
1065
+    public static function checkSubAdminUser() {
1066
+        OC_Util::checkLoggedIn();
1067
+        $userObject = \OC::$server->getUserSession()->getUser();
1068
+        $isSubAdmin = false;
1069
+        if($userObject !== null) {
1070
+            $isSubAdmin = \OC::$server->getGroupManager()->getSubAdmin()->isSubAdmin($userObject);
1071
+        }
1072
+
1073
+        if (!$isSubAdmin) {
1074
+            header('Location: ' . \OCP\Util::linkToAbsolute('', 'index.php'));
1075
+            exit();
1076
+        }
1077
+        return true;
1078
+    }
1079
+
1080
+    /**
1081
+     * Returns the URL of the default page
1082
+     * based on the system configuration and
1083
+     * the apps visible for the current user
1084
+     *
1085
+     * @return string URL
1086
+     * @suppress PhanDeprecatedFunction
1087
+     */
1088
+    public static function getDefaultPageUrl() {
1089
+        $urlGenerator = \OC::$server->getURLGenerator();
1090
+        // Deny the redirect if the URL contains a @
1091
+        // This prevents unvalidated redirects like ?redirect_url=:[email protected]
1092
+        if (isset($_REQUEST['redirect_url']) && strpos($_REQUEST['redirect_url'], '@') === false) {
1093
+            $location = $urlGenerator->getAbsoluteURL(urldecode($_REQUEST['redirect_url']));
1094
+        } else {
1095
+            $defaultPage = \OC::$server->getConfig()->getAppValue('core', 'defaultpage');
1096
+            if ($defaultPage) {
1097
+                $location = $urlGenerator->getAbsoluteURL($defaultPage);
1098
+            } else {
1099
+                $appId = 'files';
1100
+                $config = \OC::$server->getConfig();
1101
+                $defaultApps = explode(',', $config->getSystemValue('defaultapp', 'files'));
1102
+                // find the first app that is enabled for the current user
1103
+                foreach ($defaultApps as $defaultApp) {
1104
+                    $defaultApp = OC_App::cleanAppId(strip_tags($defaultApp));
1105
+                    if (static::getAppManager()->isEnabledForUser($defaultApp)) {
1106
+                        $appId = $defaultApp;
1107
+                        break;
1108
+                    }
1109
+                }
1110
+
1111
+                if($config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true') {
1112
+                    $location = $urlGenerator->getAbsoluteURL('/apps/' . $appId . '/');
1113
+                } else {
1114
+                    $location = $urlGenerator->getAbsoluteURL('/index.php/apps/' . $appId . '/');
1115
+                }
1116
+            }
1117
+        }
1118
+        return $location;
1119
+    }
1120
+
1121
+    /**
1122
+     * Redirect to the user default page
1123
+     *
1124
+     * @return void
1125
+     */
1126
+    public static function redirectToDefaultPage() {
1127
+        $location = self::getDefaultPageUrl();
1128
+        header('Location: ' . $location);
1129
+        exit();
1130
+    }
1131
+
1132
+    /**
1133
+     * get an id unique for this instance
1134
+     *
1135
+     * @return string
1136
+     */
1137
+    public static function getInstanceId() {
1138
+        $id = \OC::$server->getSystemConfig()->getValue('instanceid', null);
1139
+        if (is_null($id)) {
1140
+            // We need to guarantee at least one letter in instanceid so it can be used as the session_name
1141
+            $id = 'oc' . \OC::$server->getSecureRandom()->generate(10, \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_DIGITS);
1142
+            \OC::$server->getSystemConfig()->setValue('instanceid', $id);
1143
+        }
1144
+        return $id;
1145
+    }
1146
+
1147
+    /**
1148
+     * Public function to sanitize HTML
1149
+     *
1150
+     * This function is used to sanitize HTML and should be applied on any
1151
+     * string or array of strings before displaying it on a web page.
1152
+     *
1153
+     * @param string|array $value
1154
+     * @return string|array an array of sanitized strings or a single sanitized string, depends on the input parameter.
1155
+     */
1156
+    public static function sanitizeHTML($value) {
1157
+        if (is_array($value)) {
1158
+            $value = array_map(function($value) {
1159
+                return self::sanitizeHTML($value);
1160
+            }, $value);
1161
+        } else {
1162
+            // Specify encoding for PHP<5.4
1163
+            $value = htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
1164
+        }
1165
+        return $value;
1166
+    }
1167
+
1168
+    /**
1169
+     * Public function to encode url parameters
1170
+     *
1171
+     * This function is used to encode path to file before output.
1172
+     * Encoding is done according to RFC 3986 with one exception:
1173
+     * Character '/' is preserved as is.
1174
+     *
1175
+     * @param string $component part of URI to encode
1176
+     * @return string
1177
+     */
1178
+    public static function encodePath($component) {
1179
+        $encoded = rawurlencode($component);
1180
+        $encoded = str_replace('%2F', '/', $encoded);
1181
+        return $encoded;
1182
+    }
1183
+
1184
+
1185
+    public function createHtaccessTestFile(\OCP\IConfig $config) {
1186
+        // php dev server does not support htaccess
1187
+        if (php_sapi_name() === 'cli-server') {
1188
+            return false;
1189
+        }
1190
+
1191
+        // testdata
1192
+        $fileName = '/htaccesstest.txt';
1193
+        $testContent = 'This is used for testing whether htaccess is properly enabled to disallow access from the outside. This file can be safely removed.';
1194
+
1195
+        // creating a test file
1196
+        $testFile = $config->getSystemValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $fileName;
1197
+
1198
+        if (file_exists($testFile)) {// already running this test, possible recursive call
1199
+            return false;
1200
+        }
1201
+
1202
+        $fp = @fopen($testFile, 'w');
1203
+        if (!$fp) {
1204
+            throw new OC\HintException('Can\'t create test file to check for working .htaccess file.',
1205
+                'Make sure it is possible for the webserver to write to ' . $testFile);
1206
+        }
1207
+        fwrite($fp, $testContent);
1208
+        fclose($fp);
1209
+
1210
+        return $testContent;
1211
+    }
1212
+
1213
+    /**
1214
+     * Check if the .htaccess file is working
1215
+     * @param \OCP\IConfig $config
1216
+     * @return bool
1217
+     * @throws Exception
1218
+     * @throws \OC\HintException If the test file can't get written.
1219
+     */
1220
+    public function isHtaccessWorking(\OCP\IConfig $config) {
1221
+
1222
+        if (\OC::$CLI || !$config->getSystemValue('check_for_working_htaccess', true)) {
1223
+            return true;
1224
+        }
1225
+
1226
+        $testContent = $this->createHtaccessTestFile($config);
1227
+        if ($testContent === false) {
1228
+            return false;
1229
+        }
1230
+
1231
+        $fileName = '/htaccesstest.txt';
1232
+        $testFile = $config->getSystemValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $fileName;
1233
+
1234
+        // accessing the file via http
1235
+        $url = \OC::$server->getURLGenerator()->getAbsoluteURL(OC::$WEBROOT . '/data' . $fileName);
1236
+        try {
1237
+            $content = \OC::$server->getHTTPClientService()->newClient()->get($url)->getBody();
1238
+        } catch (\Exception $e) {
1239
+            $content = false;
1240
+        }
1241
+
1242
+        // cleanup
1243
+        @unlink($testFile);
1244
+
1245
+        /*
1246 1246
 		 * If the content is not equal to test content our .htaccess
1247 1247
 		 * is working as required
1248 1248
 		 */
1249
-		return $content !== $testContent;
1250
-	}
1251
-
1252
-	/**
1253
-	 * Check if the setlocal call does not work. This can happen if the right
1254
-	 * local packages are not available on the server.
1255
-	 *
1256
-	 * @return bool
1257
-	 */
1258
-	public static function isSetLocaleWorking() {
1259
-		\Patchwork\Utf8\Bootup::initLocale();
1260
-		if ('' === basename('§')) {
1261
-			return false;
1262
-		}
1263
-		return true;
1264
-	}
1265
-
1266
-	/**
1267
-	 * Check if it's possible to get the inline annotations
1268
-	 *
1269
-	 * @return bool
1270
-	 */
1271
-	public static function isAnnotationsWorking() {
1272
-		$reflection = new \ReflectionMethod(__METHOD__);
1273
-		$docs = $reflection->getDocComment();
1274
-
1275
-		return (is_string($docs) && strlen($docs) > 50);
1276
-	}
1277
-
1278
-	/**
1279
-	 * Check if the PHP module fileinfo is loaded.
1280
-	 *
1281
-	 * @return bool
1282
-	 */
1283
-	public static function fileInfoLoaded() {
1284
-		return function_exists('finfo_open');
1285
-	}
1286
-
1287
-	/**
1288
-	 * clear all levels of output buffering
1289
-	 *
1290
-	 * @return void
1291
-	 */
1292
-	public static function obEnd() {
1293
-		while (ob_get_level()) {
1294
-			ob_end_clean();
1295
-		}
1296
-	}
1297
-
1298
-	/**
1299
-	 * Checks whether the server is running on Mac OS X
1300
-	 *
1301
-	 * @return bool true if running on Mac OS X, false otherwise
1302
-	 */
1303
-	public static function runningOnMac() {
1304
-		return (strtoupper(substr(PHP_OS, 0, 6)) === 'DARWIN');
1305
-	}
1306
-
1307
-	/**
1308
-	 * Checks whether server is running on HHVM
1309
-	 *
1310
-	 * @return bool True if running on HHVM, false otherwise
1311
-	 */
1312
-	public static function runningOnHhvm() {
1313
-		return defined('HHVM_VERSION');
1314
-	}
1315
-
1316
-	/**
1317
-	 * Handles the case that there may not be a theme, then check if a "default"
1318
-	 * theme exists and take that one
1319
-	 *
1320
-	 * @return string the theme
1321
-	 */
1322
-	public static function getTheme() {
1323
-		$theme = \OC::$server->getSystemConfig()->getValue("theme", '');
1324
-
1325
-		if ($theme === '') {
1326
-			if (is_dir(OC::$SERVERROOT . '/themes/default')) {
1327
-				$theme = 'default';
1328
-			}
1329
-		}
1330
-
1331
-		return $theme;
1332
-	}
1333
-
1334
-	/**
1335
-	 * Clear a single file from the opcode cache
1336
-	 * This is useful for writing to the config file
1337
-	 * in case the opcode cache does not re-validate files
1338
-	 * Returns true if successful, false if unsuccessful:
1339
-	 * caller should fall back on clearing the entire cache
1340
-	 * with clearOpcodeCache() if unsuccessful
1341
-	 *
1342
-	 * @param string $path the path of the file to clear from the cache
1343
-	 * @return bool true if underlying function returns true, otherwise false
1344
-	 */
1345
-	public static function deleteFromOpcodeCache($path) {
1346
-		$ret = false;
1347
-		if ($path) {
1348
-			// APC >= 3.1.1
1349
-			if (function_exists('apc_delete_file')) {
1350
-				$ret = @apc_delete_file($path);
1351
-			}
1352
-			// Zend OpCache >= 7.0.0, PHP >= 5.5.0
1353
-			if (function_exists('opcache_invalidate')) {
1354
-				$ret = opcache_invalidate($path);
1355
-			}
1356
-		}
1357
-		return $ret;
1358
-	}
1359
-
1360
-	/**
1361
-	 * Clear the opcode cache if one exists
1362
-	 * This is necessary for writing to the config file
1363
-	 * in case the opcode cache does not re-validate files
1364
-	 *
1365
-	 * @return void
1366
-	 * @suppress PhanDeprecatedFunction
1367
-	 * @suppress PhanUndeclaredConstant
1368
-	 */
1369
-	public static function clearOpcodeCache() {
1370
-		// APC
1371
-		if (function_exists('apc_clear_cache')) {
1372
-			apc_clear_cache();
1373
-		}
1374
-		// Zend Opcache
1375
-		if (function_exists('accelerator_reset')) {
1376
-			accelerator_reset();
1377
-		}
1378
-		// XCache
1379
-		if (function_exists('xcache_clear_cache')) {
1380
-			if (\OC::$server->getIniWrapper()->getBool('xcache.admin.enable_auth')) {
1381
-				\OCP\Util::writeLog('core', 'XCache opcode cache will not be cleared because "xcache.admin.enable_auth" is enabled.', \OCP\Util::WARN);
1382
-			} else {
1383
-				@xcache_clear_cache(XC_TYPE_PHP, 0);
1384
-			}
1385
-		}
1386
-		// Opcache (PHP >= 5.5)
1387
-		if (function_exists('opcache_reset')) {
1388
-			opcache_reset();
1389
-		}
1390
-	}
1391
-
1392
-	/**
1393
-	 * Normalize a unicode string
1394
-	 *
1395
-	 * @param string $value a not normalized string
1396
-	 * @return bool|string
1397
-	 */
1398
-	public static function normalizeUnicode($value) {
1399
-		if(Normalizer::isNormalized($value)) {
1400
-			return $value;
1401
-		}
1402
-
1403
-		$normalizedValue = Normalizer::normalize($value);
1404
-		if ($normalizedValue === null || $normalizedValue === false) {
1405
-			\OC::$server->getLogger()->warning('normalizing failed for "' . $value . '"', ['app' => 'core']);
1406
-			return $value;
1407
-		}
1408
-
1409
-		return $normalizedValue;
1410
-	}
1411
-
1412
-	/**
1413
-	 * A human readable string is generated based on version and build number
1414
-	 *
1415
-	 * @return string
1416
-	 */
1417
-	public static function getHumanVersion() {
1418
-		$version = OC_Util::getVersionString();
1419
-		$build = OC_Util::getBuild();
1420
-		if (!empty($build) and OC_Util::getChannel() === 'daily') {
1421
-			$version .= ' Build:' . $build;
1422
-		}
1423
-		return $version;
1424
-	}
1425
-
1426
-	/**
1427
-	 * Returns whether the given file name is valid
1428
-	 *
1429
-	 * @param string $file file name to check
1430
-	 * @return bool true if the file name is valid, false otherwise
1431
-	 * @deprecated use \OC\Files\View::verifyPath()
1432
-	 */
1433
-	public static function isValidFileName($file) {
1434
-		$trimmed = trim($file);
1435
-		if ($trimmed === '') {
1436
-			return false;
1437
-		}
1438
-		if (\OC\Files\Filesystem::isIgnoredDir($trimmed)) {
1439
-			return false;
1440
-		}
1441
-
1442
-		// detect part files
1443
-		if (preg_match('/' . \OCP\Files\FileInfo::BLACKLIST_FILES_REGEX . '/', $trimmed) !== 0) {
1444
-			return false;
1445
-		}
1446
-
1447
-		foreach (str_split($trimmed) as $char) {
1448
-			if (strpos(\OCP\Constants::FILENAME_INVALID_CHARS, $char) !== false) {
1449
-				return false;
1450
-			}
1451
-		}
1452
-		return true;
1453
-	}
1454
-
1455
-	/**
1456
-	 * Check whether the instance needs to perform an upgrade,
1457
-	 * either when the core version is higher or any app requires
1458
-	 * an upgrade.
1459
-	 *
1460
-	 * @param \OC\SystemConfig $config
1461
-	 * @return bool whether the core or any app needs an upgrade
1462
-	 * @throws \OC\HintException When the upgrade from the given version is not allowed
1463
-	 */
1464
-	public static function needUpgrade(\OC\SystemConfig $config) {
1465
-		if ($config->getValue('installed', false)) {
1466
-			$installedVersion = $config->getValue('version', '0.0.0');
1467
-			$currentVersion = implode('.', \OCP\Util::getVersion());
1468
-			$versionDiff = version_compare($currentVersion, $installedVersion);
1469
-			if ($versionDiff > 0) {
1470
-				return true;
1471
-			} else if ($config->getValue('debug', false) && $versionDiff < 0) {
1472
-				// downgrade with debug
1473
-				$installedMajor = explode('.', $installedVersion);
1474
-				$installedMajor = $installedMajor[0] . '.' . $installedMajor[1];
1475
-				$currentMajor = explode('.', $currentVersion);
1476
-				$currentMajor = $currentMajor[0] . '.' . $currentMajor[1];
1477
-				if ($installedMajor === $currentMajor) {
1478
-					// Same major, allow downgrade for developers
1479
-					return true;
1480
-				} else {
1481
-					// downgrade attempt, throw exception
1482
-					throw new \OC\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')');
1483
-				}
1484
-			} else if ($versionDiff < 0) {
1485
-				// downgrade attempt, throw exception
1486
-				throw new \OC\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')');
1487
-			}
1488
-
1489
-			// also check for upgrades for apps (independently from the user)
1490
-			$apps = \OC_App::getEnabledApps(false, true);
1491
-			$shouldUpgrade = false;
1492
-			foreach ($apps as $app) {
1493
-				if (\OC_App::shouldUpgrade($app)) {
1494
-					$shouldUpgrade = true;
1495
-					break;
1496
-				}
1497
-			}
1498
-			return $shouldUpgrade;
1499
-		} else {
1500
-			return false;
1501
-		}
1502
-	}
1249
+        return $content !== $testContent;
1250
+    }
1251
+
1252
+    /**
1253
+     * Check if the setlocal call does not work. This can happen if the right
1254
+     * local packages are not available on the server.
1255
+     *
1256
+     * @return bool
1257
+     */
1258
+    public static function isSetLocaleWorking() {
1259
+        \Patchwork\Utf8\Bootup::initLocale();
1260
+        if ('' === basename('§')) {
1261
+            return false;
1262
+        }
1263
+        return true;
1264
+    }
1265
+
1266
+    /**
1267
+     * Check if it's possible to get the inline annotations
1268
+     *
1269
+     * @return bool
1270
+     */
1271
+    public static function isAnnotationsWorking() {
1272
+        $reflection = new \ReflectionMethod(__METHOD__);
1273
+        $docs = $reflection->getDocComment();
1274
+
1275
+        return (is_string($docs) && strlen($docs) > 50);
1276
+    }
1277
+
1278
+    /**
1279
+     * Check if the PHP module fileinfo is loaded.
1280
+     *
1281
+     * @return bool
1282
+     */
1283
+    public static function fileInfoLoaded() {
1284
+        return function_exists('finfo_open');
1285
+    }
1286
+
1287
+    /**
1288
+     * clear all levels of output buffering
1289
+     *
1290
+     * @return void
1291
+     */
1292
+    public static function obEnd() {
1293
+        while (ob_get_level()) {
1294
+            ob_end_clean();
1295
+        }
1296
+    }
1297
+
1298
+    /**
1299
+     * Checks whether the server is running on Mac OS X
1300
+     *
1301
+     * @return bool true if running on Mac OS X, false otherwise
1302
+     */
1303
+    public static function runningOnMac() {
1304
+        return (strtoupper(substr(PHP_OS, 0, 6)) === 'DARWIN');
1305
+    }
1306
+
1307
+    /**
1308
+     * Checks whether server is running on HHVM
1309
+     *
1310
+     * @return bool True if running on HHVM, false otherwise
1311
+     */
1312
+    public static function runningOnHhvm() {
1313
+        return defined('HHVM_VERSION');
1314
+    }
1315
+
1316
+    /**
1317
+     * Handles the case that there may not be a theme, then check if a "default"
1318
+     * theme exists and take that one
1319
+     *
1320
+     * @return string the theme
1321
+     */
1322
+    public static function getTheme() {
1323
+        $theme = \OC::$server->getSystemConfig()->getValue("theme", '');
1324
+
1325
+        if ($theme === '') {
1326
+            if (is_dir(OC::$SERVERROOT . '/themes/default')) {
1327
+                $theme = 'default';
1328
+            }
1329
+        }
1330
+
1331
+        return $theme;
1332
+    }
1333
+
1334
+    /**
1335
+     * Clear a single file from the opcode cache
1336
+     * This is useful for writing to the config file
1337
+     * in case the opcode cache does not re-validate files
1338
+     * Returns true if successful, false if unsuccessful:
1339
+     * caller should fall back on clearing the entire cache
1340
+     * with clearOpcodeCache() if unsuccessful
1341
+     *
1342
+     * @param string $path the path of the file to clear from the cache
1343
+     * @return bool true if underlying function returns true, otherwise false
1344
+     */
1345
+    public static function deleteFromOpcodeCache($path) {
1346
+        $ret = false;
1347
+        if ($path) {
1348
+            // APC >= 3.1.1
1349
+            if (function_exists('apc_delete_file')) {
1350
+                $ret = @apc_delete_file($path);
1351
+            }
1352
+            // Zend OpCache >= 7.0.0, PHP >= 5.5.0
1353
+            if (function_exists('opcache_invalidate')) {
1354
+                $ret = opcache_invalidate($path);
1355
+            }
1356
+        }
1357
+        return $ret;
1358
+    }
1359
+
1360
+    /**
1361
+     * Clear the opcode cache if one exists
1362
+     * This is necessary for writing to the config file
1363
+     * in case the opcode cache does not re-validate files
1364
+     *
1365
+     * @return void
1366
+     * @suppress PhanDeprecatedFunction
1367
+     * @suppress PhanUndeclaredConstant
1368
+     */
1369
+    public static function clearOpcodeCache() {
1370
+        // APC
1371
+        if (function_exists('apc_clear_cache')) {
1372
+            apc_clear_cache();
1373
+        }
1374
+        // Zend Opcache
1375
+        if (function_exists('accelerator_reset')) {
1376
+            accelerator_reset();
1377
+        }
1378
+        // XCache
1379
+        if (function_exists('xcache_clear_cache')) {
1380
+            if (\OC::$server->getIniWrapper()->getBool('xcache.admin.enable_auth')) {
1381
+                \OCP\Util::writeLog('core', 'XCache opcode cache will not be cleared because "xcache.admin.enable_auth" is enabled.', \OCP\Util::WARN);
1382
+            } else {
1383
+                @xcache_clear_cache(XC_TYPE_PHP, 0);
1384
+            }
1385
+        }
1386
+        // Opcache (PHP >= 5.5)
1387
+        if (function_exists('opcache_reset')) {
1388
+            opcache_reset();
1389
+        }
1390
+    }
1391
+
1392
+    /**
1393
+     * Normalize a unicode string
1394
+     *
1395
+     * @param string $value a not normalized string
1396
+     * @return bool|string
1397
+     */
1398
+    public static function normalizeUnicode($value) {
1399
+        if(Normalizer::isNormalized($value)) {
1400
+            return $value;
1401
+        }
1402
+
1403
+        $normalizedValue = Normalizer::normalize($value);
1404
+        if ($normalizedValue === null || $normalizedValue === false) {
1405
+            \OC::$server->getLogger()->warning('normalizing failed for "' . $value . '"', ['app' => 'core']);
1406
+            return $value;
1407
+        }
1408
+
1409
+        return $normalizedValue;
1410
+    }
1411
+
1412
+    /**
1413
+     * A human readable string is generated based on version and build number
1414
+     *
1415
+     * @return string
1416
+     */
1417
+    public static function getHumanVersion() {
1418
+        $version = OC_Util::getVersionString();
1419
+        $build = OC_Util::getBuild();
1420
+        if (!empty($build) and OC_Util::getChannel() === 'daily') {
1421
+            $version .= ' Build:' . $build;
1422
+        }
1423
+        return $version;
1424
+    }
1425
+
1426
+    /**
1427
+     * Returns whether the given file name is valid
1428
+     *
1429
+     * @param string $file file name to check
1430
+     * @return bool true if the file name is valid, false otherwise
1431
+     * @deprecated use \OC\Files\View::verifyPath()
1432
+     */
1433
+    public static function isValidFileName($file) {
1434
+        $trimmed = trim($file);
1435
+        if ($trimmed === '') {
1436
+            return false;
1437
+        }
1438
+        if (\OC\Files\Filesystem::isIgnoredDir($trimmed)) {
1439
+            return false;
1440
+        }
1441
+
1442
+        // detect part files
1443
+        if (preg_match('/' . \OCP\Files\FileInfo::BLACKLIST_FILES_REGEX . '/', $trimmed) !== 0) {
1444
+            return false;
1445
+        }
1446
+
1447
+        foreach (str_split($trimmed) as $char) {
1448
+            if (strpos(\OCP\Constants::FILENAME_INVALID_CHARS, $char) !== false) {
1449
+                return false;
1450
+            }
1451
+        }
1452
+        return true;
1453
+    }
1454
+
1455
+    /**
1456
+     * Check whether the instance needs to perform an upgrade,
1457
+     * either when the core version is higher or any app requires
1458
+     * an upgrade.
1459
+     *
1460
+     * @param \OC\SystemConfig $config
1461
+     * @return bool whether the core or any app needs an upgrade
1462
+     * @throws \OC\HintException When the upgrade from the given version is not allowed
1463
+     */
1464
+    public static function needUpgrade(\OC\SystemConfig $config) {
1465
+        if ($config->getValue('installed', false)) {
1466
+            $installedVersion = $config->getValue('version', '0.0.0');
1467
+            $currentVersion = implode('.', \OCP\Util::getVersion());
1468
+            $versionDiff = version_compare($currentVersion, $installedVersion);
1469
+            if ($versionDiff > 0) {
1470
+                return true;
1471
+            } else if ($config->getValue('debug', false) && $versionDiff < 0) {
1472
+                // downgrade with debug
1473
+                $installedMajor = explode('.', $installedVersion);
1474
+                $installedMajor = $installedMajor[0] . '.' . $installedMajor[1];
1475
+                $currentMajor = explode('.', $currentVersion);
1476
+                $currentMajor = $currentMajor[0] . '.' . $currentMajor[1];
1477
+                if ($installedMajor === $currentMajor) {
1478
+                    // Same major, allow downgrade for developers
1479
+                    return true;
1480
+                } else {
1481
+                    // downgrade attempt, throw exception
1482
+                    throw new \OC\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')');
1483
+                }
1484
+            } else if ($versionDiff < 0) {
1485
+                // downgrade attempt, throw exception
1486
+                throw new \OC\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')');
1487
+            }
1488
+
1489
+            // also check for upgrades for apps (independently from the user)
1490
+            $apps = \OC_App::getEnabledApps(false, true);
1491
+            $shouldUpgrade = false;
1492
+            foreach ($apps as $app) {
1493
+                if (\OC_App::shouldUpgrade($app)) {
1494
+                    $shouldUpgrade = true;
1495
+                    break;
1496
+                }
1497
+            }
1498
+            return $shouldUpgrade;
1499
+        } else {
1500
+            return false;
1501
+        }
1502
+    }
1503 1503
 
1504 1504
 }
Please login to merge, or discard this patch.
settings/templates/settings/admin/server.php 2 patches
Indentation   +69 added lines, -69 removed lines patch added patch discarded remove patch
@@ -31,101 +31,101 @@  discard block
 block discarded – undo
31 31
 	<p class="settings-hint"><?php p($l->t('It\'s important for the security and performance of your instance that everything is configured correctly. To help you with that we are doing some automatic checks. Please see the Tips & Tricks section and the documentation for more information.'));?></p>
32 32
 	<ul>
33 33
 		<?php
34
-		// is php setup properly to query system environment variables like getenv('PATH')
35
-		if ($_['getenvServerNotWorking']) {
36
-			?>
34
+        // is php setup properly to query system environment variables like getenv('PATH')
35
+        if ($_['getenvServerNotWorking']) {
36
+            ?>
37 37
 			<li>
38 38
 				<?php p($l->t('PHP does not seem to be setup properly to query system environment variables. The test with getenv("PATH") only returns an empty response.')); ?><br>
39 39
 				<?php print_unescaped($l->t('Please check the <a target="_blank" rel="noreferrer noopener" href="%s">installation documentation ↗</a> for PHP configuration notes and the PHP configuration of your server, especially when using php-fpm.', link_to_docs('admin-php-fpm'))); ?>
40 40
 			</li>
41 41
 			<?php
42
-		}
42
+        }
43 43
 
44
-		// is read only config enabled
45
-		if ($_['readOnlyConfigEnabled']) {
46
-			?>
44
+        // is read only config enabled
45
+        if ($_['readOnlyConfigEnabled']) {
46
+            ?>
47 47
 			<li>
48 48
 				<?php p($l->t('The Read-Only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update.')); ?>
49 49
 			</li>
50 50
 			<?php
51
-		}
51
+        }
52 52
 
53
-		// Are doc blocks accessible?
54
-		if (!$_['isAnnotationsWorking']) {
55
-			?>
53
+        // Are doc blocks accessible?
54
+        if (!$_['isAnnotationsWorking']) {
55
+            ?>
56 56
 			<li>
57 57
 				<?php p($l->t('PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible.')); ?><br>
58 58
 				<?php p($l->t('This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator.')); ?>
59 59
 			</li>
60 60
 			<?php
61
-		}
61
+        }
62 62
 
63
-		// Is the Transaction isolation level READ_COMMITTED?
64
-		if ($_['invalidTransactionIsolationLevel']) {
65
-			?>
63
+        // Is the Transaction isolation level READ_COMMITTED?
64
+        if ($_['invalidTransactionIsolationLevel']) {
65
+            ?>
66 66
 			<li>
67 67
 				<?php p($l->t('Your database does not run with "READ COMMITTED" transaction isolation level. This can cause problems when multiple actions are executed in parallel.')); ?>
68 68
 			</li>
69 69
 			<?php
70
-		}
70
+        }
71 71
 
72
-		// Warning if memcache is outdated
73
-		foreach ($_['OutdatedCacheWarning'] as $php_module => $data) {
74
-			?>
72
+        // Warning if memcache is outdated
73
+        foreach ($_['OutdatedCacheWarning'] as $php_module => $data) {
74
+            ?>
75 75
 			<li>
76 76
 				<?php p($l->t('%1$s below version %2$s is installed, for stability and performance reasons it is recommended to update to a newer %1$s version.', $data)); ?>
77 77
 			</li>
78 78
 			<?php
79
-		}
79
+        }
80 80
 
81
-		// if module fileinfo available?
82
-		if (!$_['has_fileinfo']) {
83
-			?>
81
+        // if module fileinfo available?
82
+        if (!$_['has_fileinfo']) {
83
+            ?>
84 84
 			<li>
85 85
 				<?php p($l->t('The PHP module \'fileinfo\' is missing. It is strongly recommended to enable this module to get the best results with MIME type detection.')); ?>
86 86
 			</li>
87 87
 			<?php
88
-		}
88
+        }
89 89
 
90
-		// locking configured optimally?
91
-		if ($_['fileLockingType'] === 'none') {
92
-			?>
90
+        // locking configured optimally?
91
+        if ($_['fileLockingType'] === 'none') {
92
+            ?>
93 93
 			<li>
94 94
 				<?php print_unescaped($l->t('Transactional file locking is disabled, this might lead to issues with race conditions. Enable \'filelocking.enabled\' in config.php to avoid these problems. See the <a target="_blank" rel="noreferrer noopener" href="%s">documentation ↗</a> for more information.', link_to_docs('admin-transactional-locking'))); ?>
95 95
 			</li>
96 96
 			<?php
97
-		}
97
+        }
98 98
 
99
-		// is locale working ?
100
-		if (!$_['isLocaleWorking']) {
101
-			?>
99
+        // is locale working ?
100
+        if (!$_['isLocaleWorking']) {
101
+            ?>
102 102
 			<li>
103 103
 				<?php
104
-				$locales = 'en_US.UTF-8/fr_FR.UTF-8/es_ES.UTF-8/de_DE.UTF-8/ru_RU.UTF-8/pt_BR.UTF-8/it_IT.UTF-8/ja_JP.UTF-8/zh_CN.UTF-8';
105
-				p($l->t('System locale can not be set to a one which supports UTF-8.'));
106
-				?>
104
+                $locales = 'en_US.UTF-8/fr_FR.UTF-8/es_ES.UTF-8/de_DE.UTF-8/ru_RU.UTF-8/pt_BR.UTF-8/it_IT.UTF-8/ja_JP.UTF-8/zh_CN.UTF-8';
105
+                p($l->t('System locale can not be set to a one which supports UTF-8.'));
106
+                ?>
107 107
 				<br>
108 108
 				<?php
109
-				p($l->t('This means that there might be problems with certain characters in filenames.'));
110
-				?>
109
+                p($l->t('This means that there might be problems with certain characters in filenames.'));
110
+                ?>
111 111
 				<br>
112 112
 				<?php
113
-				p($l->t('It is strongly proposed to install the required packages on your system to support one of the following locales: %s.', [$locales]));
114
-				?>
113
+                p($l->t('It is strongly proposed to install the required packages on your system to support one of the following locales: %s.', [$locales]));
114
+                ?>
115 115
 			</li>
116 116
 			<?php
117
-		}
117
+        }
118 118
 
119
-		if ($_['suggestedOverwriteCliUrl']) {
120
-			?>
119
+        if ($_['suggestedOverwriteCliUrl']) {
120
+            ?>
121 121
 			<li>
122 122
 				<?php p($l->t('If your installation is not installed at the root of the domain and uses system Cron, there can be issues with the URL generation. To avoid these problems, please set the "overwrite.cli.url" option in your config.php file to the webroot path of your installation (Suggested: "%s")', $_['suggestedOverwriteCliUrl'])); ?>
123 123
 			</li>
124 124
 			<?php
125
-		}
125
+        }
126 126
 
127
-		if ($_['cronErrors']) {
128
-			?>
127
+        if ($_['cronErrors']) {
128
+            ?>
129 129
 			<li>
130 130
 				<?php p($l->t('It was not possible to execute the cron job via CLI. The following technical errors have appeared:')); ?>
131 131
 				<br>
@@ -136,8 +136,8 @@  discard block
 block discarded – undo
136 136
 				</ol>
137 137
 			</li>
138 138
 			<?php
139
-		}
140
-		?>
139
+        }
140
+        ?>
141 141
 	</ul>
142 142
 
143 143
 	<div id="postsetupchecks" data-check-wellknown="<?php if($_['checkForWorkingWellKnownSetup']) { p('true'); } else { p('false'); } ?>">
@@ -158,11 +158,11 @@  discard block
 block discarded – undo
158 158
 	<h2 class="inlineblock"><?php p($l->t('Background jobs'));?></h2>
159 159
 	<p class="cronlog inlineblock">
160 160
 		<?php if ($_['lastcron'] !== false):
161
-			$relative_time = relative_modified_date($_['lastcron']);
161
+            $relative_time = relative_modified_date($_['lastcron']);
162 162
 
163
-			$formatter = \OC::$server->getDateTimeFormatter();
164
-			$absolute_time = $formatter->formatDateTime($_['lastcron'], 'long', 'long');
165
-			if (time() - $_['lastcron'] <= 3600): ?>
163
+            $formatter = \OC::$server->getDateTimeFormatter();
164
+            $absolute_time = $formatter->formatDateTime($_['lastcron'], 'long', 'long');
165
+            if (time() - $_['lastcron'] <= 3600): ?>
166 166
 				<span class="status success"></span>
167 167
 				<span class="crondate" title="<?php p($absolute_time);?>">
168 168
 				<?php p($l->t("Last job ran %s.", [$relative_time]));?>
@@ -173,10 +173,10 @@  discard block
 block discarded – undo
173 173
 				<?php p($l->t("Last job execution ran %s. Something seems wrong.", [$relative_time]));?>
174 174
 			</span>
175 175
 			<?php endif;
176
-		else: ?>
176
+        else: ?>
177 177
 			<span class="status error"></span>
178 178
 			<?php p($l->t("Background job didn’t run yet!"));
179
-		endif; ?>
179
+        endif; ?>
180 180
 	</p>
181 181
 	<a target="_blank" rel="noreferrer noopener" class="icon-info"
182 182
 	   title="<?php p($l->t('Open documentation'));?>"
@@ -186,38 +186,38 @@  discard block
 block discarded – undo
186 186
 	<p>
187 187
 		<input type="radio" name="mode" value="ajax" class="radio"
188 188
 			   id="backgroundjobs_ajax" <?php if ($_['backgroundjobs_mode'] === "ajax") {
189
-			print_unescaped('checked="checked"');
190
-		} ?>>
189
+            print_unescaped('checked="checked"');
190
+        } ?>>
191 191
 		<label for="backgroundjobs_ajax">AJAX</label><br/>
192 192
 		<em><?php p($l->t("Execute one task with each page loaded")); ?></em>
193 193
 	</p>
194 194
 	<p>
195 195
 		<input type="radio" name="mode" value="webcron" class="radio"
196 196
 			   id="backgroundjobs_webcron" <?php if ($_['backgroundjobs_mode'] === "webcron") {
197
-			print_unescaped('checked="checked"');
198
-		} ?>>
197
+            print_unescaped('checked="checked"');
198
+        } ?>>
199 199
 		<label for="backgroundjobs_webcron">Webcron</label><br/>
200 200
 		<em><?php p($l->t("cron.php is registered at a webcron service to call cron.php every 15 minutes over HTTP.")); ?></em>
201 201
 	</p>
202 202
 	<p>
203 203
 		<input type="radio" name="mode" value="cron" class="radio"
204 204
 			   id="backgroundjobs_cron" <?php if ($_['backgroundjobs_mode'] === "cron") {
205
-			print_unescaped('checked="checked"');
206
-		}
207
-		if (!$_['cli_based_cron_possible']) {
208
-			print_unescaped('disabled');
209
-		}?>>
205
+            print_unescaped('checked="checked"');
206
+        }
207
+        if (!$_['cli_based_cron_possible']) {
208
+            print_unescaped('disabled');
209
+        }?>>
210 210
 		<label for="backgroundjobs_cron">Cron</label><br/>
211 211
 		<em><?php p($l->t("Use system cron service to call the cron.php file every 15 minutes.")); ?>
212 212
 			<?php if($_['cli_based_cron_possible']) {
213
-				p($l->t('The cron.php needs to be executed by the system user "%s".', [$_['cli_based_cron_user']]));
214
-			} else {
215
-				print_unescaped(str_replace(
216
-					['{linkstart}', '{linkend}'],
217
-					['<a href="http://php.net/manual/en/book.posix.php">', ' ↗</a>'],
218
-					$l->t('To run this you need the PHP POSIX extension. See {linkstart}PHP documentation{linkend} for more details.')
219
-				));
220
-		} ?></em>
213
+                p($l->t('The cron.php needs to be executed by the system user "%s".', [$_['cli_based_cron_user']]));
214
+            } else {
215
+                print_unescaped(str_replace(
216
+                    ['{linkstart}', '{linkend}'],
217
+                    ['<a href="http://php.net/manual/en/book.posix.php">', ' ↗</a>'],
218
+                    $l->t('To run this you need the PHP POSIX extension. See {linkstart}PHP documentation{linkend} for more details.')
219
+                ));
220
+        } ?></em>
221 221
 
222 222
 	</p>
223 223
 </div>
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -27,8 +27,8 @@  discard block
 block discarded – undo
27 27
 ?>
28 28
 
29 29
 <div id="security-warning" class="section">
30
-	<h2><?php p($l->t('Security & setup warnings'));?></h2>
31
-	<p class="settings-hint"><?php p($l->t('It\'s important for the security and performance of your instance that everything is configured correctly. To help you with that we are doing some automatic checks. Please see the Tips & Tricks section and the documentation for more information.'));?></p>
30
+	<h2><?php p($l->t('Security & setup warnings')); ?></h2>
31
+	<p class="settings-hint"><?php p($l->t('It\'s important for the security and performance of your instance that everything is configured correctly. To help you with that we are doing some automatic checks. Please see the Tips & Tricks section and the documentation for more information.')); ?></p>
32 32
 	<ul>
33 33
 		<?php
34 34
 		// is php setup properly to query system environment variables like getenv('PATH')
@@ -130,7 +130,7 @@  discard block
 block discarded – undo
130 130
 				<?php p($l->t('It was not possible to execute the cron job via CLI. The following technical errors have appeared:')); ?>
131 131
 				<br>
132 132
 				<ol>
133
-					<?php foreach(json_decode($_['cronErrors']) as $error) { if(isset($error->error)) {?>
133
+					<?php foreach (json_decode($_['cronErrors']) as $error) { if (isset($error->error)) {?>
134 134
 						<li><?php p($error->error) ?> <?php p($error->hint) ?></li>
135 135
 					<?php }} ?>
136 136
 				</ol>
@@ -140,22 +140,22 @@  discard block
 block discarded – undo
140 140
 		?>
141 141
 	</ul>
142 142
 
143
-	<div id="postsetupchecks" data-check-wellknown="<?php if($_['checkForWorkingWellKnownSetup']) { p('true'); } else { p('false'); } ?>">
143
+	<div id="postsetupchecks" data-check-wellknown="<?php if ($_['checkForWorkingWellKnownSetup']) { p('true'); } else { p('false'); } ?>">
144 144
 		<div class="loading"></div>
145 145
 		<ul class="errors hidden"></ul>
146 146
 		<ul class="warnings hidden"></ul>
147 147
 		<ul class="info hidden"></ul>
148 148
 		<p class="hint hidden">
149
-			<?php print_unescaped($l->t('Please double check the <a target="_blank" rel="noreferrer noopener" href="%s">installation guides ↗</a>, and check for any errors or warnings in the <a href="%s">log</a>.', [link_to_docs('admin-install'), \OC::$server->getURLGenerator()->linkToRoute('settings.AdminSettings.index', ['section' => 'logging'])] )); ?>
149
+			<?php print_unescaped($l->t('Please double check the <a target="_blank" rel="noreferrer noopener" href="%s">installation guides ↗</a>, and check for any errors or warnings in the <a href="%s">log</a>.', [link_to_docs('admin-install'), \OC::$server->getURLGenerator()->linkToRoute('settings.AdminSettings.index', ['section' => 'logging'])])); ?>
150 150
 		</p>
151 151
 	</div>
152 152
 	<div id="security-warning-state">
153
-		<span class="hidden icon-checkmark"><?php p($l->t('All checks passed.'));?></span>
153
+		<span class="hidden icon-checkmark"><?php p($l->t('All checks passed.')); ?></span>
154 154
 	</div>
155 155
 </div>
156 156
 
157 157
 <div class="section" id="backgroundjobs">
158
-	<h2 class="inlineblock"><?php p($l->t('Background jobs'));?></h2>
158
+	<h2 class="inlineblock"><?php p($l->t('Background jobs')); ?></h2>
159 159
 	<p class="cronlog inlineblock">
160 160
 		<?php if ($_['lastcron'] !== false):
161 161
 			$relative_time = relative_modified_date($_['lastcron']);
@@ -164,13 +164,13 @@  discard block
 block discarded – undo
164 164
 			$absolute_time = $formatter->formatDateTime($_['lastcron'], 'long', 'long');
165 165
 			if (time() - $_['lastcron'] <= 3600): ?>
166 166
 				<span class="status success"></span>
167
-				<span class="crondate" title="<?php p($absolute_time);?>">
168
-				<?php p($l->t("Last job ran %s.", [$relative_time]));?>
167
+				<span class="crondate" title="<?php p($absolute_time); ?>">
168
+				<?php p($l->t("Last job ran %s.", [$relative_time])); ?>
169 169
 			</span>
170 170
 			<?php else: ?>
171 171
 				<span class="status error"></span>
172
-				<span class="crondate" title="<?php p($absolute_time);?>">
173
-				<?php p($l->t("Last job execution ran %s. Something seems wrong.", [$relative_time]));?>
172
+				<span class="crondate" title="<?php p($absolute_time); ?>">
173
+				<?php p($l->t("Last job execution ran %s. Something seems wrong.", [$relative_time])); ?>
174 174
 			</span>
175 175
 			<?php endif;
176 176
 		else: ?>
@@ -179,10 +179,10 @@  discard block
 block discarded – undo
179 179
 		endif; ?>
180 180
 	</p>
181 181
 	<a target="_blank" rel="noreferrer noopener" class="icon-info"
182
-	   title="<?php p($l->t('Open documentation'));?>"
182
+	   title="<?php p($l->t('Open documentation')); ?>"
183 183
 	   href="<?php p(link_to_docs('admin-background-jobs')); ?>"></a>
184 184
 
185
-	<p class="settings-hint"><?php p($l->t('For optimal performance it\'s important to configure background jobs correctly. For bigger instances \'Cron\' is the recommended setting. Please see the documentation for more information.'));?></p>
185
+	<p class="settings-hint"><?php p($l->t('For optimal performance it\'s important to configure background jobs correctly. For bigger instances \'Cron\' is the recommended setting. Please see the documentation for more information.')); ?></p>
186 186
 	<p>
187 187
 		<input type="radio" name="mode" value="ajax" class="radio"
188 188
 			   id="backgroundjobs_ajax" <?php if ($_['backgroundjobs_mode'] === "ajax") {
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
 		}?>>
210 210
 		<label for="backgroundjobs_cron">Cron</label><br/>
211 211
 		<em><?php p($l->t("Use system cron service to call the cron.php file every 15 minutes.")); ?>
212
-			<?php if($_['cli_based_cron_possible']) {
212
+			<?php if ($_['cli_based_cron_possible']) {
213 213
 				p($l->t('The cron.php needs to be executed by the system user "%s".', [$_['cli_based_cron_user']]));
214 214
 			} else {
215 215
 				print_unescaped(str_replace(
@@ -224,6 +224,6 @@  discard block
 block discarded – undo
224 224
 
225 225
 <div class="section">
226 226
 	<!-- should be the last part, so Updater can follow if enabled (it has no heading therefore). -->
227
-	<h2><?php p($l->t('Version'));?></h2>
227
+	<h2><?php p($l->t('Version')); ?></h2>
228 228
 	<p><strong><a href="<?php print_unescaped($theme->getBaseUrl()); ?>" rel="noreferrer noopener" target="_blank"><?php p($theme->getTitle()); ?></a> <?php p(OC_Util::getHumanVersion()) ?></strong></p>
229 229
 </div>
Please login to merge, or discard this patch.