Completed
Pull Request — master (#5881)
by Thomas
14:22 queued 01:53
created
lib/private/legacy/app.php 3 patches
Doc Comments   +6 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1063,7 +1063,7 @@  discard block
 block discarded – undo
1063 1063
 	 * @param string $app
1064 1064
 	 * @param \OCP\IConfig $config
1065 1065
 	 * @param \OCP\IL10N $l
1066
-	 * @return bool
1066
+	 * @return string
1067 1067
 	 *
1068 1068
 	 * @throws Exception if app is not compatible with this version of ownCloud
1069 1069
 	 * @throws Exception if no app-name was specified
@@ -1243,6 +1243,11 @@  discard block
 block discarded – undo
1243 1243
 		}
1244 1244
 	}
1245 1245
 
1246
+	/**
1247
+	 * @param string $lang
1248
+	 *
1249
+	 * @return string
1250
+	 */
1246 1251
 	protected static function findBestL10NOption($options, $lang) {
1247 1252
 		$fallback = $similarLangFallback = $englishFallback = false;
1248 1253
 
Please login to merge, or discard this patch.
Indentation   +1180 added lines, -1180 removed lines patch added patch discarded remove patch
@@ -61,1184 +61,1184 @@
 block discarded – undo
61 61
  * upgrading and removing apps.
62 62
  */
63 63
 class OC_App {
64
-	static private $appVersion = [];
65
-	static private $adminForms = array();
66
-	static private $personalForms = array();
67
-	static private $appInfo = array();
68
-	static private $appTypes = array();
69
-	static private $loadedApps = array();
70
-	static private $altLogin = array();
71
-	static private $alreadyRegistered = [];
72
-	const officialApp = 200;
73
-
74
-	/**
75
-	 * clean the appId
76
-	 *
77
-	 * @param string|boolean $app AppId that needs to be cleaned
78
-	 * @return string
79
-	 */
80
-	public static function cleanAppId($app) {
81
-		return str_replace(array('\0', '/', '\\', '..'), '', $app);
82
-	}
83
-
84
-	/**
85
-	 * Check if an app is loaded
86
-	 *
87
-	 * @param string $app
88
-	 * @return bool
89
-	 */
90
-	public static function isAppLoaded($app) {
91
-		return in_array($app, self::$loadedApps, true);
92
-	}
93
-
94
-	/**
95
-	 * loads all apps
96
-	 *
97
-	 * @param string[] | string | null $types
98
-	 * @return bool
99
-	 *
100
-	 * This function walks through the ownCloud directory and loads all apps
101
-	 * it can find. A directory contains an app if the file /appinfo/info.xml
102
-	 * exists.
103
-	 *
104
-	 * if $types is set, only apps of those types will be loaded
105
-	 */
106
-	public static function loadApps($types = null) {
107
-		if (\OC::$server->getSystemConfig()->getValue('maintenance', false)) {
108
-			return false;
109
-		}
110
-		// Load the enabled apps here
111
-		$apps = self::getEnabledApps();
112
-
113
-		// Add each apps' folder as allowed class path
114
-		foreach($apps as $app) {
115
-			$path = self::getAppPath($app);
116
-			if($path !== false) {
117
-				self::registerAutoloading($app, $path);
118
-			}
119
-		}
120
-
121
-		// prevent app.php from printing output
122
-		ob_start();
123
-		foreach ($apps as $app) {
124
-			if ((is_null($types) or self::isType($app, $types)) && !in_array($app, self::$loadedApps)) {
125
-				self::loadApp($app);
126
-			}
127
-		}
128
-		ob_end_clean();
129
-
130
-		return true;
131
-	}
132
-
133
-	/**
134
-	 * load a single app
135
-	 *
136
-	 * @param string $app
137
-	 */
138
-	public static function loadApp($app) {
139
-		self::$loadedApps[] = $app;
140
-		$appPath = self::getAppPath($app);
141
-		if($appPath === false) {
142
-			return;
143
-		}
144
-
145
-		// in case someone calls loadApp() directly
146
-		self::registerAutoloading($app, $appPath);
147
-
148
-		if (is_file($appPath . '/appinfo/app.php')) {
149
-			\OC::$server->getEventLogger()->start('load_app_' . $app, 'Load app: ' . $app);
150
-			self::requireAppFile($app);
151
-			if (self::isType($app, array('authentication'))) {
152
-				// since authentication apps affect the "is app enabled for group" check,
153
-				// the enabled apps cache needs to be cleared to make sure that the
154
-				// next time getEnableApps() is called it will also include apps that were
155
-				// enabled for groups
156
-				self::$enabledAppsCache = array();
157
-			}
158
-			\OC::$server->getEventLogger()->end('load_app_' . $app);
159
-		}
160
-
161
-		$info = self::getAppInfo($app);
162
-		if (!empty($info['activity']['filters'])) {
163
-			foreach ($info['activity']['filters'] as $filter) {
164
-				\OC::$server->getActivityManager()->registerFilter($filter);
165
-			}
166
-		}
167
-		if (!empty($info['activity']['settings'])) {
168
-			foreach ($info['activity']['settings'] as $setting) {
169
-				\OC::$server->getActivityManager()->registerSetting($setting);
170
-			}
171
-		}
172
-		if (!empty($info['activity']['providers'])) {
173
-			foreach ($info['activity']['providers'] as $provider) {
174
-				\OC::$server->getActivityManager()->registerProvider($provider);
175
-			}
176
-		}
177
-	}
178
-
179
-	/**
180
-	 * @internal
181
-	 * @param string $app
182
-	 * @param string $path
183
-	 */
184
-	public static function registerAutoloading($app, $path) {
185
-		$key = $app . '-' . $path;
186
-		if(isset(self::$alreadyRegistered[$key])) {
187
-			return;
188
-		}
189
-		self::$alreadyRegistered[$key] = true;
190
-		// Register on PSR-4 composer autoloader
191
-		$appNamespace = \OC\AppFramework\App::buildAppNamespace($app);
192
-		\OC::$server->registerNamespace($app, $appNamespace);
193
-		\OC::$composerAutoloader->addPsr4($appNamespace . '\\', $path . '/lib/', true);
194
-		if (defined('PHPUNIT_RUN') || defined('CLI_TEST_RUN')) {
195
-			\OC::$composerAutoloader->addPsr4($appNamespace . '\\Tests\\', $path . '/tests/', true);
196
-		}
197
-
198
-		// Register on legacy autoloader
199
-		\OC::$loader->addValidRoot($path);
200
-	}
201
-
202
-	/**
203
-	 * Load app.php from the given app
204
-	 *
205
-	 * @param string $app app name
206
-	 */
207
-	private static function requireAppFile($app) {
208
-		try {
209
-			// encapsulated here to avoid variable scope conflicts
210
-			require_once $app . '/appinfo/app.php';
211
-		} catch (Error $ex) {
212
-			\OC::$server->getLogger()->logException($ex);
213
-			$blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
214
-			if (!in_array($app, $blacklist)) {
215
-				self::disable($app);
216
-			}
217
-		}
218
-	}
219
-
220
-	/**
221
-	 * check if an app is of a specific type
222
-	 *
223
-	 * @param string $app
224
-	 * @param string|array $types
225
-	 * @return bool
226
-	 */
227
-	public static function isType($app, $types) {
228
-		if (is_string($types)) {
229
-			$types = array($types);
230
-		}
231
-		$appTypes = self::getAppTypes($app);
232
-		foreach ($types as $type) {
233
-			if (array_search($type, $appTypes) !== false) {
234
-				return true;
235
-			}
236
-		}
237
-		return false;
238
-	}
239
-
240
-	/**
241
-	 * get the types of an app
242
-	 *
243
-	 * @param string $app
244
-	 * @return array
245
-	 */
246
-	private static function getAppTypes($app) {
247
-		//load the cache
248
-		if (count(self::$appTypes) == 0) {
249
-			self::$appTypes = \OC::$server->getAppConfig()->getValues(false, 'types');
250
-		}
251
-
252
-		if (isset(self::$appTypes[$app])) {
253
-			return explode(',', self::$appTypes[$app]);
254
-		} else {
255
-			return array();
256
-		}
257
-	}
258
-
259
-	/**
260
-	 * read app types from info.xml and cache them in the database
261
-	 */
262
-	public static function setAppTypes($app) {
263
-		$appData = self::getAppInfo($app);
264
-		if(!is_array($appData)) {
265
-			return;
266
-		}
267
-
268
-		if (isset($appData['types'])) {
269
-			$appTypes = implode(',', $appData['types']);
270
-		} else {
271
-			$appTypes = '';
272
-			$appData['types'] = [];
273
-		}
274
-
275
-		\OC::$server->getAppConfig()->setValue($app, 'types', $appTypes);
276
-
277
-		if (\OC::$server->getAppManager()->hasProtectedAppType($appData['types'])) {
278
-			$enabled = \OC::$server->getAppConfig()->getValue($app, 'enabled', 'yes');
279
-			if ($enabled !== 'yes' && $enabled !== 'no') {
280
-				\OC::$server->getAppConfig()->setValue($app, 'enabled', 'yes');
281
-			}
282
-		}
283
-	}
284
-
285
-	/**
286
-	 * get all enabled apps
287
-	 */
288
-	protected static $enabledAppsCache = array();
289
-
290
-	/**
291
-	 * Returns apps enabled for the current user.
292
-	 *
293
-	 * @param bool $forceRefresh whether to refresh the cache
294
-	 * @param bool $all whether to return apps for all users, not only the
295
-	 * currently logged in one
296
-	 * @return string[]
297
-	 */
298
-	public static function getEnabledApps($forceRefresh = false, $all = false) {
299
-		if (!\OC::$server->getSystemConfig()->getValue('installed', false)) {
300
-			return array();
301
-		}
302
-		// in incognito mode or when logged out, $user will be false,
303
-		// which is also the case during an upgrade
304
-		$appManager = \OC::$server->getAppManager();
305
-		if ($all) {
306
-			$user = null;
307
-		} else {
308
-			$user = \OC::$server->getUserSession()->getUser();
309
-		}
310
-
311
-		if (is_null($user)) {
312
-			$apps = $appManager->getInstalledApps();
313
-		} else {
314
-			$apps = $appManager->getEnabledAppsForUser($user);
315
-		}
316
-		$apps = array_filter($apps, function ($app) {
317
-			return $app !== 'files';//we add this manually
318
-		});
319
-		sort($apps);
320
-		array_unshift($apps, 'files');
321
-		return $apps;
322
-	}
323
-
324
-	/**
325
-	 * checks whether or not an app is enabled
326
-	 *
327
-	 * @param string $app app
328
-	 * @return bool
329
-	 *
330
-	 * This function checks whether or not an app is enabled.
331
-	 */
332
-	public static function isEnabled($app) {
333
-		return \OC::$server->getAppManager()->isEnabledForUser($app);
334
-	}
335
-
336
-	/**
337
-	 * enables an app
338
-	 *
339
-	 * @param string $appId
340
-	 * @param array $groups (optional) when set, only these groups will have access to the app
341
-	 * @throws \Exception
342
-	 * @return void
343
-	 *
344
-	 * This function set an app as enabled in appconfig.
345
-	 */
346
-	public function enable($appId,
347
-						   $groups = null) {
348
-		self::$enabledAppsCache = []; // flush
349
-
350
-		// Check if app is already downloaded
351
-		$installer = new Installer(
352
-			\OC::$server->getAppFetcher(),
353
-			\OC::$server->getHTTPClientService(),
354
-			\OC::$server->getTempManager(),
355
-			\OC::$server->getLogger(),
356
-			\OC::$server->getConfig()
357
-		);
358
-		$isDownloaded = $installer->isDownloaded($appId);
359
-
360
-		if(!$isDownloaded) {
361
-			$installer->downloadApp($appId);
362
-		}
363
-
364
-		$installer->installApp($appId);
365
-
366
-		$appManager = \OC::$server->getAppManager();
367
-		if (!is_null($groups)) {
368
-			$groupManager = \OC::$server->getGroupManager();
369
-			$groupsList = [];
370
-			foreach ($groups as $group) {
371
-				$groupItem = $groupManager->get($group);
372
-				if ($groupItem instanceof \OCP\IGroup) {
373
-					$groupsList[] = $groupManager->get($group);
374
-				}
375
-			}
376
-			$appManager->enableAppForGroups($appId, $groupsList);
377
-		} else {
378
-			$appManager->enableApp($appId);
379
-		}
380
-	}
381
-
382
-	/**
383
-	 * @param string $app
384
-	 * @return bool
385
-	 */
386
-	public static function removeApp($app) {
387
-		if (\OC::$server->getAppManager()->isShipped($app)) {
388
-			return false;
389
-		}
390
-
391
-		$installer = new Installer(
392
-			\OC::$server->getAppFetcher(),
393
-			\OC::$server->getHTTPClientService(),
394
-			\OC::$server->getTempManager(),
395
-			\OC::$server->getLogger(),
396
-			\OC::$server->getConfig()
397
-		);
398
-		return $installer->removeApp($app);
399
-	}
400
-
401
-	/**
402
-	 * This function set an app as disabled in appconfig.
403
-	 *
404
-	 * @param string $app app
405
-	 * @throws Exception
406
-	 */
407
-	public static function disable($app) {
408
-		// flush
409
-		self::$enabledAppsCache = array();
410
-
411
-		// run uninstall steps
412
-		$appData = OC_App::getAppInfo($app);
413
-		if (!is_null($appData)) {
414
-			OC_App::executeRepairSteps($app, $appData['repair-steps']['uninstall']);
415
-		}
416
-
417
-		// emit disable hook - needed anymore ?
418
-		\OC_Hook::emit('OC_App', 'pre_disable', array('app' => $app));
419
-
420
-		// finally disable it
421
-		$appManager = \OC::$server->getAppManager();
422
-		$appManager->disableApp($app);
423
-	}
424
-
425
-	// This is private as well. It simply works, so don't ask for more details
426
-	private static function proceedNavigation($list) {
427
-		usort($list, function($a, $b) {
428
-			if (isset($a['order']) && isset($b['order'])) {
429
-				return ($a['order'] < $b['order']) ? -1 : 1;
430
-			} else if (isset($a['order']) || isset($b['order'])) {
431
-				return isset($a['order']) ? -1 : 1;
432
-			} else {
433
-				return ($a['name'] < $b['name']) ? -1 : 1;
434
-			}
435
-		});
436
-
437
-		$activeApp = OC::$server->getNavigationManager()->getActiveEntry();
438
-		foreach ($list as $index => &$navEntry) {
439
-			if ($navEntry['id'] == $activeApp) {
440
-				$navEntry['active'] = true;
441
-			} else {
442
-				$navEntry['active'] = false;
443
-			}
444
-		}
445
-		unset($navEntry);
446
-
447
-		return $list;
448
-	}
449
-
450
-	/**
451
-	 * Get the path where to install apps
452
-	 *
453
-	 * @return string|false
454
-	 */
455
-	public static function getInstallPath() {
456
-		if (\OC::$server->getSystemConfig()->getValue('appstoreenabled', true) == false) {
457
-			return false;
458
-		}
459
-
460
-		foreach (OC::$APPSROOTS as $dir) {
461
-			if (isset($dir['writable']) && $dir['writable'] === true) {
462
-				return $dir['path'];
463
-			}
464
-		}
465
-
466
-		\OCP\Util::writeLog('core', 'No application directories are marked as writable.', \OCP\Util::ERROR);
467
-		return null;
468
-	}
469
-
470
-
471
-	/**
472
-	 * search for an app in all app-directories
473
-	 *
474
-	 * @param string $appId
475
-	 * @return false|string
476
-	 */
477
-	public static function findAppInDirectories($appId) {
478
-		$sanitizedAppId = self::cleanAppId($appId);
479
-		if($sanitizedAppId !== $appId) {
480
-			return false;
481
-		}
482
-		static $app_dir = array();
483
-
484
-		if (isset($app_dir[$appId])) {
485
-			return $app_dir[$appId];
486
-		}
487
-
488
-		$possibleApps = array();
489
-		foreach (OC::$APPSROOTS as $dir) {
490
-			if (file_exists($dir['path'] . '/' . $appId)) {
491
-				$possibleApps[] = $dir;
492
-			}
493
-		}
494
-
495
-		if (empty($possibleApps)) {
496
-			return false;
497
-		} elseif (count($possibleApps) === 1) {
498
-			$dir = array_shift($possibleApps);
499
-			$app_dir[$appId] = $dir;
500
-			return $dir;
501
-		} else {
502
-			$versionToLoad = array();
503
-			foreach ($possibleApps as $possibleApp) {
504
-				$version = self::getAppVersionByPath($possibleApp['path']);
505
-				if (empty($versionToLoad) || version_compare($version, $versionToLoad['version'], '>')) {
506
-					$versionToLoad = array(
507
-						'dir' => $possibleApp,
508
-						'version' => $version,
509
-					);
510
-				}
511
-			}
512
-			$app_dir[$appId] = $versionToLoad['dir'];
513
-			return $versionToLoad['dir'];
514
-			//TODO - write test
515
-		}
516
-	}
517
-
518
-	/**
519
-	 * Get the directory for the given app.
520
-	 * If the app is defined in multiple directories, the first one is taken. (false if not found)
521
-	 *
522
-	 * @param string $appId
523
-	 * @return string|false
524
-	 */
525
-	public static function getAppPath($appId) {
526
-		if ($appId === null || trim($appId) === '') {
527
-			return false;
528
-		}
529
-
530
-		if (($dir = self::findAppInDirectories($appId)) != false) {
531
-			return $dir['path'] . '/' . $appId;
532
-		}
533
-		return false;
534
-	}
535
-
536
-	/**
537
-	 * Get the path for the given app on the access
538
-	 * If the app is defined in multiple directories, the first one is taken. (false if not found)
539
-	 *
540
-	 * @param string $appId
541
-	 * @return string|false
542
-	 */
543
-	public static function getAppWebPath($appId) {
544
-		if (($dir = self::findAppInDirectories($appId)) != false) {
545
-			return OC::$WEBROOT . $dir['url'] . '/' . $appId;
546
-		}
547
-		return false;
548
-	}
549
-
550
-	/**
551
-	 * get the last version of the app from appinfo/info.xml
552
-	 *
553
-	 * @param string $appId
554
-	 * @param bool $useCache
555
-	 * @return string
556
-	 */
557
-	public static function getAppVersion($appId, $useCache = true) {
558
-		if($useCache && isset(self::$appVersion[$appId])) {
559
-			return self::$appVersion[$appId];
560
-		}
561
-
562
-		$file = self::getAppPath($appId);
563
-		self::$appVersion[$appId] = ($file !== false) ? self::getAppVersionByPath($file) : '0';
564
-		return self::$appVersion[$appId];
565
-	}
566
-
567
-	/**
568
-	 * get app's version based on it's path
569
-	 *
570
-	 * @param string $path
571
-	 * @return string
572
-	 */
573
-	public static function getAppVersionByPath($path) {
574
-		$infoFile = $path . '/appinfo/info.xml';
575
-		$appData = self::getAppInfo($infoFile, true);
576
-		return isset($appData['version']) ? $appData['version'] : '';
577
-	}
578
-
579
-
580
-	/**
581
-	 * Read all app metadata from the info.xml file
582
-	 *
583
-	 * @param string $appId id of the app or the path of the info.xml file
584
-	 * @param bool $path
585
-	 * @param string $lang
586
-	 * @return array|null
587
-	 * @note all data is read from info.xml, not just pre-defined fields
588
-	 */
589
-	public static function getAppInfo($appId, $path = false, $lang = null) {
590
-		if ($path) {
591
-			$file = $appId;
592
-		} else {
593
-			if ($lang === null && isset(self::$appInfo[$appId])) {
594
-				return self::$appInfo[$appId];
595
-			}
596
-			$appPath = self::getAppPath($appId);
597
-			if($appPath === false) {
598
-				return null;
599
-			}
600
-			$file = $appPath . '/appinfo/info.xml';
601
-		}
602
-
603
-		$parser = new InfoParser(\OC::$server->getMemCacheFactory()->createLocal('core.appinfo'));
604
-		$data = $parser->parse($file);
605
-
606
-		if (is_array($data)) {
607
-			$data = OC_App::parseAppInfo($data, $lang);
608
-		}
609
-		if(isset($data['ocsid'])) {
610
-			$storedId = \OC::$server->getConfig()->getAppValue($appId, 'ocsid');
611
-			if($storedId !== '' && $storedId !== $data['ocsid']) {
612
-				$data['ocsid'] = $storedId;
613
-			}
614
-		}
615
-
616
-		if ($lang === null) {
617
-			self::$appInfo[$appId] = $data;
618
-		}
619
-
620
-		return $data;
621
-	}
622
-
623
-	/**
624
-	 * Returns the navigation
625
-	 *
626
-	 * @return array
627
-	 *
628
-	 * This function returns an array containing all entries added. The
629
-	 * entries are sorted by the key 'order' ascending. Additional to the keys
630
-	 * given for each app the following keys exist:
631
-	 *   - active: boolean, signals if the user is on this navigation entry
632
-	 */
633
-	public static function getNavigation() {
634
-		$entries = OC::$server->getNavigationManager()->getAll();
635
-		return self::proceedNavigation($entries);
636
-	}
637
-
638
-	/**
639
-	 * Returns the Settings Navigation
640
-	 *
641
-	 * @return string[]
642
-	 *
643
-	 * This function returns an array containing all settings pages added. The
644
-	 * entries are sorted by the key 'order' ascending.
645
-	 */
646
-	public static function getSettingsNavigation() {
647
-		$entries = OC::$server->getNavigationManager()->getAll('settings');
648
-		return self::proceedNavigation($entries);
649
-	}
650
-
651
-	/**
652
-	 * get the id of loaded app
653
-	 *
654
-	 * @return string
655
-	 */
656
-	public static function getCurrentApp() {
657
-		$request = \OC::$server->getRequest();
658
-		$script = substr($request->getScriptName(), strlen(OC::$WEBROOT) + 1);
659
-		$topFolder = substr($script, 0, strpos($script, '/'));
660
-		if (empty($topFolder)) {
661
-			$path_info = $request->getPathInfo();
662
-			if ($path_info) {
663
-				$topFolder = substr($path_info, 1, strpos($path_info, '/', 1) - 1);
664
-			}
665
-		}
666
-		if ($topFolder == 'apps') {
667
-			$length = strlen($topFolder);
668
-			return substr($script, $length + 1, strpos($script, '/', $length + 1) - $length - 1);
669
-		} else {
670
-			return $topFolder;
671
-		}
672
-	}
673
-
674
-	/**
675
-	 * @param string $type
676
-	 * @return array
677
-	 */
678
-	public static function getForms($type) {
679
-		$forms = array();
680
-		switch ($type) {
681
-			case 'admin':
682
-				$source = self::$adminForms;
683
-				break;
684
-			case 'personal':
685
-				$source = self::$personalForms;
686
-				break;
687
-			default:
688
-				return array();
689
-		}
690
-		foreach ($source as $form) {
691
-			$forms[] = include $form;
692
-		}
693
-		return $forms;
694
-	}
695
-
696
-	/**
697
-	 * register an admin form to be shown
698
-	 *
699
-	 * @param string $app
700
-	 * @param string $page
701
-	 */
702
-	public static function registerAdmin($app, $page) {
703
-		self::$adminForms[] = $app . '/' . $page . '.php';
704
-	}
705
-
706
-	/**
707
-	 * register a personal form to be shown
708
-	 * @param string $app
709
-	 * @param string $page
710
-	 */
711
-	public static function registerPersonal($app, $page) {
712
-		self::$personalForms[] = $app . '/' . $page . '.php';
713
-	}
714
-
715
-	/**
716
-	 * @param array $entry
717
-	 */
718
-	public static function registerLogIn(array $entry) {
719
-		self::$altLogin[] = $entry;
720
-	}
721
-
722
-	/**
723
-	 * @return array
724
-	 */
725
-	public static function getAlternativeLogIns() {
726
-		return self::$altLogin;
727
-	}
728
-
729
-	/**
730
-	 * get a list of all apps in the apps folder
731
-	 *
732
-	 * @return array an array of app names (string IDs)
733
-	 * @todo: change the name of this method to getInstalledApps, which is more accurate
734
-	 */
735
-	public static function getAllApps() {
736
-
737
-		$apps = array();
738
-
739
-		foreach (OC::$APPSROOTS as $apps_dir) {
740
-			if (!is_readable($apps_dir['path'])) {
741
-				\OCP\Util::writeLog('core', 'unable to read app folder : ' . $apps_dir['path'], \OCP\Util::WARN);
742
-				continue;
743
-			}
744
-			$dh = opendir($apps_dir['path']);
745
-
746
-			if (is_resource($dh)) {
747
-				while (($file = readdir($dh)) !== false) {
748
-
749
-					if ($file[0] != '.' and is_dir($apps_dir['path'] . '/' . $file) and is_file($apps_dir['path'] . '/' . $file . '/appinfo/info.xml')) {
750
-
751
-						$apps[] = $file;
752
-					}
753
-				}
754
-			}
755
-		}
756
-
757
-		return $apps;
758
-	}
759
-
760
-	/**
761
-	 * List all apps, this is used in apps.php
762
-	 *
763
-	 * @return array
764
-	 */
765
-	public function listAllApps() {
766
-		$installedApps = OC_App::getAllApps();
767
-
768
-		$appManager = \OC::$server->getAppManager();
769
-		//we don't want to show configuration for these
770
-		$blacklist = $appManager->getAlwaysEnabledApps();
771
-		$appList = array();
772
-		$langCode = \OC::$server->getL10N('core')->getLanguageCode();
773
-		$urlGenerator = \OC::$server->getURLGenerator();
774
-
775
-		foreach ($installedApps as $app) {
776
-			if (array_search($app, $blacklist) === false) {
777
-
778
-				$info = OC_App::getAppInfo($app, false, $langCode);
779
-				if (!is_array($info)) {
780
-					\OCP\Util::writeLog('core', 'Could not read app info file for app "' . $app . '"', \OCP\Util::ERROR);
781
-					continue;
782
-				}
783
-
784
-				if (!isset($info['name'])) {
785
-					\OCP\Util::writeLog('core', 'App id "' . $app . '" has no name in appinfo', \OCP\Util::ERROR);
786
-					continue;
787
-				}
788
-
789
-				$enabled = \OC::$server->getAppConfig()->getValue($app, 'enabled', 'no');
790
-				$info['groups'] = null;
791
-				if ($enabled === 'yes') {
792
-					$active = true;
793
-				} else if ($enabled === 'no') {
794
-					$active = false;
795
-				} else {
796
-					$active = true;
797
-					$info['groups'] = $enabled;
798
-				}
799
-
800
-				$info['active'] = $active;
801
-
802
-				if ($appManager->isShipped($app)) {
803
-					$info['internal'] = true;
804
-					$info['level'] = self::officialApp;
805
-					$info['removable'] = false;
806
-				} else {
807
-					$info['internal'] = false;
808
-					$info['removable'] = true;
809
-				}
810
-
811
-				$appPath = self::getAppPath($app);
812
-				if($appPath !== false) {
813
-					$appIcon = $appPath . '/img/' . $app . '.svg';
814
-					if (file_exists($appIcon)) {
815
-						$info['preview'] = $urlGenerator->imagePath($app, $app . '.svg');
816
-						$info['previewAsIcon'] = true;
817
-					} else {
818
-						$appIcon = $appPath . '/img/app.svg';
819
-						if (file_exists($appIcon)) {
820
-							$info['preview'] = $urlGenerator->imagePath($app, 'app.svg');
821
-							$info['previewAsIcon'] = true;
822
-						}
823
-					}
824
-				}
825
-				// fix documentation
826
-				if (isset($info['documentation']) && is_array($info['documentation'])) {
827
-					foreach ($info['documentation'] as $key => $url) {
828
-						// If it is not an absolute URL we assume it is a key
829
-						// i.e. admin-ldap will get converted to go.php?to=admin-ldap
830
-						if (stripos($url, 'https://') !== 0 && stripos($url, 'http://') !== 0) {
831
-							$url = $urlGenerator->linkToDocs($url);
832
-						}
833
-
834
-						$info['documentation'][$key] = $url;
835
-					}
836
-				}
837
-
838
-				$info['version'] = OC_App::getAppVersion($app);
839
-				$appList[] = $info;
840
-			}
841
-		}
842
-
843
-		return $appList;
844
-	}
845
-
846
-	/**
847
-	 * Returns the internal app ID or false
848
-	 * @param string $ocsID
849
-	 * @return string|false
850
-	 */
851
-	public static function getInternalAppIdByOcs($ocsID) {
852
-		if(is_numeric($ocsID)) {
853
-			$idArray = \OC::$server->getAppConfig()->getValues(false, 'ocsid');
854
-			if(array_search($ocsID, $idArray)) {
855
-				return array_search($ocsID, $idArray);
856
-			}
857
-		}
858
-		return false;
859
-	}
860
-
861
-	public static function shouldUpgrade($app) {
862
-		$versions = self::getAppVersions();
863
-		$currentVersion = OC_App::getAppVersion($app);
864
-		if ($currentVersion && isset($versions[$app])) {
865
-			$installedVersion = $versions[$app];
866
-			if (!version_compare($currentVersion, $installedVersion, '=')) {
867
-				return true;
868
-			}
869
-		}
870
-		return false;
871
-	}
872
-
873
-	/**
874
-	 * Adjust the number of version parts of $version1 to match
875
-	 * the number of version parts of $version2.
876
-	 *
877
-	 * @param string $version1 version to adjust
878
-	 * @param string $version2 version to take the number of parts from
879
-	 * @return string shortened $version1
880
-	 */
881
-	private static function adjustVersionParts($version1, $version2) {
882
-		$version1 = explode('.', $version1);
883
-		$version2 = explode('.', $version2);
884
-		// reduce $version1 to match the number of parts in $version2
885
-		while (count($version1) > count($version2)) {
886
-			array_pop($version1);
887
-		}
888
-		// if $version1 does not have enough parts, add some
889
-		while (count($version1) < count($version2)) {
890
-			$version1[] = '0';
891
-		}
892
-		return implode('.', $version1);
893
-	}
894
-
895
-	/**
896
-	 * Check whether the current ownCloud version matches the given
897
-	 * application's version requirements.
898
-	 *
899
-	 * The comparison is made based on the number of parts that the
900
-	 * app info version has. For example for ownCloud 6.0.3 if the
901
-	 * app info version is expecting version 6.0, the comparison is
902
-	 * made on the first two parts of the ownCloud version.
903
-	 * This means that it's possible to specify "requiremin" => 6
904
-	 * and "requiremax" => 6 and it will still match ownCloud 6.0.3.
905
-	 *
906
-	 * @param string $ocVersion ownCloud version to check against
907
-	 * @param array $appInfo app info (from xml)
908
-	 *
909
-	 * @return boolean true if compatible, otherwise false
910
-	 */
911
-	public static function isAppCompatible($ocVersion, $appInfo) {
912
-		$requireMin = '';
913
-		$requireMax = '';
914
-		if (isset($appInfo['dependencies']['nextcloud']['@attributes']['min-version'])) {
915
-			$requireMin = $appInfo['dependencies']['nextcloud']['@attributes']['min-version'];
916
-		} elseif (isset($appInfo['dependencies']['owncloud']['@attributes']['min-version'])) {
917
-			$requireMin = $appInfo['dependencies']['owncloud']['@attributes']['min-version'];
918
-		} else if (isset($appInfo['requiremin'])) {
919
-			$requireMin = $appInfo['requiremin'];
920
-		} else if (isset($appInfo['require'])) {
921
-			$requireMin = $appInfo['require'];
922
-		}
923
-
924
-		if (isset($appInfo['dependencies']['nextcloud']['@attributes']['max-version'])) {
925
-			$requireMax = $appInfo['dependencies']['nextcloud']['@attributes']['max-version'];
926
-		} elseif (isset($appInfo['dependencies']['owncloud']['@attributes']['max-version'])) {
927
-			$requireMax = $appInfo['dependencies']['owncloud']['@attributes']['max-version'];
928
-		} else if (isset($appInfo['requiremax'])) {
929
-			$requireMax = $appInfo['requiremax'];
930
-		}
931
-
932
-		if (is_array($ocVersion)) {
933
-			$ocVersion = implode('.', $ocVersion);
934
-		}
935
-
936
-		if (!empty($requireMin)
937
-			&& version_compare(self::adjustVersionParts($ocVersion, $requireMin), $requireMin, '<')
938
-		) {
939
-
940
-			return false;
941
-		}
942
-
943
-		if (!empty($requireMax)
944
-			&& version_compare(self::adjustVersionParts($ocVersion, $requireMax), $requireMax, '>')
945
-		) {
946
-			return false;
947
-		}
948
-
949
-		return true;
950
-	}
951
-
952
-	/**
953
-	 * get the installed version of all apps
954
-	 */
955
-	public static function getAppVersions() {
956
-		static $versions;
957
-
958
-		if(!$versions) {
959
-			$appConfig = \OC::$server->getAppConfig();
960
-			$versions = $appConfig->getValues(false, 'installed_version');
961
-		}
962
-		return $versions;
963
-	}
964
-
965
-	/**
966
-	 * @param string $app
967
-	 * @param \OCP\IConfig $config
968
-	 * @param \OCP\IL10N $l
969
-	 * @return bool
970
-	 *
971
-	 * @throws Exception if app is not compatible with this version of ownCloud
972
-	 * @throws Exception if no app-name was specified
973
-	 */
974
-	public function installApp($app,
975
-							   \OCP\IConfig $config,
976
-							   \OCP\IL10N $l) {
977
-		if ($app !== false) {
978
-			// check if the app is compatible with this version of ownCloud
979
-			$info = self::getAppInfo($app);
980
-			if(!is_array($info)) {
981
-				throw new \Exception(
982
-					$l->t('App "%s" cannot be installed because appinfo file cannot be read.',
983
-						[$info['name']]
984
-					)
985
-				);
986
-			}
987
-
988
-			$version = \OCP\Util::getVersion();
989
-			if (!self::isAppCompatible($version, $info)) {
990
-				throw new \Exception(
991
-					$l->t('App "%s" cannot be installed because it is not compatible with this version of the server.',
992
-						array($info['name'])
993
-					)
994
-				);
995
-			}
996
-
997
-			// check for required dependencies
998
-			self::checkAppDependencies($config, $l, $info);
999
-
1000
-			$config->setAppValue($app, 'enabled', 'yes');
1001
-			if (isset($appData['id'])) {
1002
-				$config->setAppValue($app, 'ocsid', $appData['id']);
1003
-			}
1004
-
1005
-			if(isset($info['settings']) && is_array($info['settings'])) {
1006
-				$appPath = self::getAppPath($app);
1007
-				self::registerAutoloading($app, $appPath);
1008
-				\OC::$server->getSettingsManager()->setupSettings($info['settings']);
1009
-			}
1010
-
1011
-			\OC_Hook::emit('OC_App', 'post_enable', array('app' => $app));
1012
-		} else {
1013
-			if(empty($appName) ) {
1014
-				throw new \Exception($l->t("No app name specified"));
1015
-			} else {
1016
-				throw new \Exception($l->t("App '%s' could not be installed!", $appName));
1017
-			}
1018
-		}
1019
-
1020
-		return $app;
1021
-	}
1022
-
1023
-	/**
1024
-	 * update the database for the app and call the update script
1025
-	 *
1026
-	 * @param string $appId
1027
-	 * @return bool
1028
-	 */
1029
-	public static function updateApp($appId) {
1030
-		$appPath = self::getAppPath($appId);
1031
-		if($appPath === false) {
1032
-			return false;
1033
-		}
1034
-		self::registerAutoloading($appId, $appPath);
1035
-
1036
-		$appData = self::getAppInfo($appId);
1037
-		self::executeRepairSteps($appId, $appData['repair-steps']['pre-migration']);
1038
-
1039
-		if (file_exists($appPath . '/appinfo/database.xml')) {
1040
-			OC_DB::updateDbFromStructure($appPath . '/appinfo/database.xml');
1041
-		} else {
1042
-			$ms = new MigrationService($appId, \OC::$server->getDatabaseConnection());
1043
-			$ms->migrate();
1044
-		}
1045
-
1046
-		self::executeRepairSteps($appId, $appData['repair-steps']['post-migration']);
1047
-		self::setupLiveMigrations($appId, $appData['repair-steps']['live-migration']);
1048
-		unset(self::$appVersion[$appId]);
1049
-
1050
-		// run upgrade code
1051
-		if (file_exists($appPath . '/appinfo/update.php')) {
1052
-			self::loadApp($appId);
1053
-			include $appPath . '/appinfo/update.php';
1054
-		}
1055
-		self::setupBackgroundJobs($appData['background-jobs']);
1056
-		if(isset($appData['settings']) && is_array($appData['settings'])) {
1057
-			\OC::$server->getSettingsManager()->setupSettings($appData['settings']);
1058
-		}
1059
-
1060
-		//set remote/public handlers
1061
-		if (array_key_exists('ocsid', $appData)) {
1062
-			\OC::$server->getConfig()->setAppValue($appId, 'ocsid', $appData['ocsid']);
1063
-		} elseif(\OC::$server->getConfig()->getAppValue($appId, 'ocsid', null) !== null) {
1064
-			\OC::$server->getConfig()->deleteAppValue($appId, 'ocsid');
1065
-		}
1066
-		foreach ($appData['remote'] as $name => $path) {
1067
-			\OC::$server->getConfig()->setAppValue('core', 'remote_' . $name, $appId . '/' . $path);
1068
-		}
1069
-		foreach ($appData['public'] as $name => $path) {
1070
-			\OC::$server->getConfig()->setAppValue('core', 'public_' . $name, $appId . '/' . $path);
1071
-		}
1072
-
1073
-		self::setAppTypes($appId);
1074
-
1075
-		$version = \OC_App::getAppVersion($appId);
1076
-		\OC::$server->getAppConfig()->setValue($appId, 'installed_version', $version);
1077
-
1078
-		\OC::$server->getEventDispatcher()->dispatch(ManagerEvent::EVENT_APP_UPDATE, new ManagerEvent(
1079
-			ManagerEvent::EVENT_APP_UPDATE, $appId
1080
-		));
1081
-
1082
-		return true;
1083
-	}
1084
-
1085
-	/**
1086
-	 * @param string $appId
1087
-	 * @param string[] $steps
1088
-	 * @throws \OC\NeedsUpdateException
1089
-	 */
1090
-	public static function executeRepairSteps($appId, array $steps) {
1091
-		if (empty($steps)) {
1092
-			return;
1093
-		}
1094
-		// load the app
1095
-		self::loadApp($appId);
1096
-
1097
-		$dispatcher = OC::$server->getEventDispatcher();
1098
-
1099
-		// load the steps
1100
-		$r = new Repair([], $dispatcher);
1101
-		foreach ($steps as $step) {
1102
-			try {
1103
-				$r->addStep($step);
1104
-			} catch (Exception $ex) {
1105
-				$r->emit('\OC\Repair', 'error', [$ex->getMessage()]);
1106
-				\OC::$server->getLogger()->logException($ex);
1107
-			}
1108
-		}
1109
-		// run the steps
1110
-		$r->run();
1111
-	}
1112
-
1113
-	public static function setupBackgroundJobs(array $jobs) {
1114
-		$queue = \OC::$server->getJobList();
1115
-		foreach ($jobs as $job) {
1116
-			$queue->add($job);
1117
-		}
1118
-	}
1119
-
1120
-	/**
1121
-	 * @param string $appId
1122
-	 * @param string[] $steps
1123
-	 */
1124
-	private static function setupLiveMigrations($appId, array $steps) {
1125
-		$queue = \OC::$server->getJobList();
1126
-		foreach ($steps as $step) {
1127
-			$queue->add('OC\Migration\BackgroundRepair', [
1128
-				'app' => $appId,
1129
-				'step' => $step]);
1130
-		}
1131
-	}
1132
-
1133
-	/**
1134
-	 * @param string $appId
1135
-	 * @return \OC\Files\View|false
1136
-	 */
1137
-	public static function getStorage($appId) {
1138
-		if (OC_App::isEnabled($appId)) { //sanity check
1139
-			if (\OC::$server->getUserSession()->isLoggedIn()) {
1140
-				$view = new \OC\Files\View('/' . OC_User::getUser());
1141
-				if (!$view->file_exists($appId)) {
1142
-					$view->mkdir($appId);
1143
-				}
1144
-				return new \OC\Files\View('/' . OC_User::getUser() . '/' . $appId);
1145
-			} else {
1146
-				\OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ', user not logged in', \OCP\Util::ERROR);
1147
-				return false;
1148
-			}
1149
-		} else {
1150
-			\OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ' not enabled', \OCP\Util::ERROR);
1151
-			return false;
1152
-		}
1153
-	}
1154
-
1155
-	protected static function findBestL10NOption($options, $lang) {
1156
-		$fallback = $similarLangFallback = $englishFallback = false;
1157
-
1158
-		$lang = strtolower($lang);
1159
-		$similarLang = $lang;
1160
-		if (strpos($similarLang, '_')) {
1161
-			// For "de_DE" we want to find "de" and the other way around
1162
-			$similarLang = substr($lang, 0, strpos($lang, '_'));
1163
-		}
1164
-
1165
-		foreach ($options as $option) {
1166
-			if (is_array($option)) {
1167
-				if ($fallback === false) {
1168
-					$fallback = $option['@value'];
1169
-				}
1170
-
1171
-				if (!isset($option['@attributes']['lang'])) {
1172
-					continue;
1173
-				}
1174
-
1175
-				$attributeLang = strtolower($option['@attributes']['lang']);
1176
-				if ($attributeLang === $lang) {
1177
-					return $option['@value'];
1178
-				}
1179
-
1180
-				if ($attributeLang === $similarLang) {
1181
-					$similarLangFallback = $option['@value'];
1182
-				} else if (strpos($attributeLang, $similarLang . '_') === 0) {
1183
-					if ($similarLangFallback === false) {
1184
-						$similarLangFallback =  $option['@value'];
1185
-					}
1186
-				}
1187
-			} else {
1188
-				$englishFallback = $option;
1189
-			}
1190
-		}
1191
-
1192
-		if ($similarLangFallback !== false) {
1193
-			return $similarLangFallback;
1194
-		} else if ($englishFallback !== false) {
1195
-			return $englishFallback;
1196
-		}
1197
-		return (string) $fallback;
1198
-	}
1199
-
1200
-	/**
1201
-	 * parses the app data array and enhanced the 'description' value
1202
-	 *
1203
-	 * @param array $data the app data
1204
-	 * @param string $lang
1205
-	 * @return array improved app data
1206
-	 */
1207
-	public static function parseAppInfo(array $data, $lang = null) {
1208
-
1209
-		if ($lang && isset($data['name']) && is_array($data['name'])) {
1210
-			$data['name'] = self::findBestL10NOption($data['name'], $lang);
1211
-		}
1212
-		if ($lang && isset($data['summary']) && is_array($data['summary'])) {
1213
-			$data['summary'] = self::findBestL10NOption($data['summary'], $lang);
1214
-		}
1215
-		if ($lang && isset($data['description']) && is_array($data['description'])) {
1216
-			$data['description'] = trim(self::findBestL10NOption($data['description'], $lang));
1217
-		} else if (isset($data['description']) && is_string($data['description'])) {
1218
-			$data['description'] = trim($data['description']);
1219
-		} else  {
1220
-			$data['description'] = '';
1221
-		}
1222
-
1223
-		return $data;
1224
-	}
1225
-
1226
-	/**
1227
-	 * @param \OCP\IConfig $config
1228
-	 * @param \OCP\IL10N $l
1229
-	 * @param array $info
1230
-	 * @throws \Exception
1231
-	 */
1232
-	public static function checkAppDependencies($config, $l, $info) {
1233
-		$dependencyAnalyzer = new DependencyAnalyzer(new Platform($config), $l);
1234
-		$missing = $dependencyAnalyzer->analyze($info);
1235
-		if (!empty($missing)) {
1236
-			$missingMsg = implode(PHP_EOL, $missing);
1237
-			throw new \Exception(
1238
-				$l->t('App "%s" cannot be installed because the following dependencies are not fulfilled: %s',
1239
-					[$info['name'], $missingMsg]
1240
-				)
1241
-			);
1242
-		}
1243
-	}
64
+    static private $appVersion = [];
65
+    static private $adminForms = array();
66
+    static private $personalForms = array();
67
+    static private $appInfo = array();
68
+    static private $appTypes = array();
69
+    static private $loadedApps = array();
70
+    static private $altLogin = array();
71
+    static private $alreadyRegistered = [];
72
+    const officialApp = 200;
73
+
74
+    /**
75
+     * clean the appId
76
+     *
77
+     * @param string|boolean $app AppId that needs to be cleaned
78
+     * @return string
79
+     */
80
+    public static function cleanAppId($app) {
81
+        return str_replace(array('\0', '/', '\\', '..'), '', $app);
82
+    }
83
+
84
+    /**
85
+     * Check if an app is loaded
86
+     *
87
+     * @param string $app
88
+     * @return bool
89
+     */
90
+    public static function isAppLoaded($app) {
91
+        return in_array($app, self::$loadedApps, true);
92
+    }
93
+
94
+    /**
95
+     * loads all apps
96
+     *
97
+     * @param string[] | string | null $types
98
+     * @return bool
99
+     *
100
+     * This function walks through the ownCloud directory and loads all apps
101
+     * it can find. A directory contains an app if the file /appinfo/info.xml
102
+     * exists.
103
+     *
104
+     * if $types is set, only apps of those types will be loaded
105
+     */
106
+    public static function loadApps($types = null) {
107
+        if (\OC::$server->getSystemConfig()->getValue('maintenance', false)) {
108
+            return false;
109
+        }
110
+        // Load the enabled apps here
111
+        $apps = self::getEnabledApps();
112
+
113
+        // Add each apps' folder as allowed class path
114
+        foreach($apps as $app) {
115
+            $path = self::getAppPath($app);
116
+            if($path !== false) {
117
+                self::registerAutoloading($app, $path);
118
+            }
119
+        }
120
+
121
+        // prevent app.php from printing output
122
+        ob_start();
123
+        foreach ($apps as $app) {
124
+            if ((is_null($types) or self::isType($app, $types)) && !in_array($app, self::$loadedApps)) {
125
+                self::loadApp($app);
126
+            }
127
+        }
128
+        ob_end_clean();
129
+
130
+        return true;
131
+    }
132
+
133
+    /**
134
+     * load a single app
135
+     *
136
+     * @param string $app
137
+     */
138
+    public static function loadApp($app) {
139
+        self::$loadedApps[] = $app;
140
+        $appPath = self::getAppPath($app);
141
+        if($appPath === false) {
142
+            return;
143
+        }
144
+
145
+        // in case someone calls loadApp() directly
146
+        self::registerAutoloading($app, $appPath);
147
+
148
+        if (is_file($appPath . '/appinfo/app.php')) {
149
+            \OC::$server->getEventLogger()->start('load_app_' . $app, 'Load app: ' . $app);
150
+            self::requireAppFile($app);
151
+            if (self::isType($app, array('authentication'))) {
152
+                // since authentication apps affect the "is app enabled for group" check,
153
+                // the enabled apps cache needs to be cleared to make sure that the
154
+                // next time getEnableApps() is called it will also include apps that were
155
+                // enabled for groups
156
+                self::$enabledAppsCache = array();
157
+            }
158
+            \OC::$server->getEventLogger()->end('load_app_' . $app);
159
+        }
160
+
161
+        $info = self::getAppInfo($app);
162
+        if (!empty($info['activity']['filters'])) {
163
+            foreach ($info['activity']['filters'] as $filter) {
164
+                \OC::$server->getActivityManager()->registerFilter($filter);
165
+            }
166
+        }
167
+        if (!empty($info['activity']['settings'])) {
168
+            foreach ($info['activity']['settings'] as $setting) {
169
+                \OC::$server->getActivityManager()->registerSetting($setting);
170
+            }
171
+        }
172
+        if (!empty($info['activity']['providers'])) {
173
+            foreach ($info['activity']['providers'] as $provider) {
174
+                \OC::$server->getActivityManager()->registerProvider($provider);
175
+            }
176
+        }
177
+    }
178
+
179
+    /**
180
+     * @internal
181
+     * @param string $app
182
+     * @param string $path
183
+     */
184
+    public static function registerAutoloading($app, $path) {
185
+        $key = $app . '-' . $path;
186
+        if(isset(self::$alreadyRegistered[$key])) {
187
+            return;
188
+        }
189
+        self::$alreadyRegistered[$key] = true;
190
+        // Register on PSR-4 composer autoloader
191
+        $appNamespace = \OC\AppFramework\App::buildAppNamespace($app);
192
+        \OC::$server->registerNamespace($app, $appNamespace);
193
+        \OC::$composerAutoloader->addPsr4($appNamespace . '\\', $path . '/lib/', true);
194
+        if (defined('PHPUNIT_RUN') || defined('CLI_TEST_RUN')) {
195
+            \OC::$composerAutoloader->addPsr4($appNamespace . '\\Tests\\', $path . '/tests/', true);
196
+        }
197
+
198
+        // Register on legacy autoloader
199
+        \OC::$loader->addValidRoot($path);
200
+    }
201
+
202
+    /**
203
+     * Load app.php from the given app
204
+     *
205
+     * @param string $app app name
206
+     */
207
+    private static function requireAppFile($app) {
208
+        try {
209
+            // encapsulated here to avoid variable scope conflicts
210
+            require_once $app . '/appinfo/app.php';
211
+        } catch (Error $ex) {
212
+            \OC::$server->getLogger()->logException($ex);
213
+            $blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
214
+            if (!in_array($app, $blacklist)) {
215
+                self::disable($app);
216
+            }
217
+        }
218
+    }
219
+
220
+    /**
221
+     * check if an app is of a specific type
222
+     *
223
+     * @param string $app
224
+     * @param string|array $types
225
+     * @return bool
226
+     */
227
+    public static function isType($app, $types) {
228
+        if (is_string($types)) {
229
+            $types = array($types);
230
+        }
231
+        $appTypes = self::getAppTypes($app);
232
+        foreach ($types as $type) {
233
+            if (array_search($type, $appTypes) !== false) {
234
+                return true;
235
+            }
236
+        }
237
+        return false;
238
+    }
239
+
240
+    /**
241
+     * get the types of an app
242
+     *
243
+     * @param string $app
244
+     * @return array
245
+     */
246
+    private static function getAppTypes($app) {
247
+        //load the cache
248
+        if (count(self::$appTypes) == 0) {
249
+            self::$appTypes = \OC::$server->getAppConfig()->getValues(false, 'types');
250
+        }
251
+
252
+        if (isset(self::$appTypes[$app])) {
253
+            return explode(',', self::$appTypes[$app]);
254
+        } else {
255
+            return array();
256
+        }
257
+    }
258
+
259
+    /**
260
+     * read app types from info.xml and cache them in the database
261
+     */
262
+    public static function setAppTypes($app) {
263
+        $appData = self::getAppInfo($app);
264
+        if(!is_array($appData)) {
265
+            return;
266
+        }
267
+
268
+        if (isset($appData['types'])) {
269
+            $appTypes = implode(',', $appData['types']);
270
+        } else {
271
+            $appTypes = '';
272
+            $appData['types'] = [];
273
+        }
274
+
275
+        \OC::$server->getAppConfig()->setValue($app, 'types', $appTypes);
276
+
277
+        if (\OC::$server->getAppManager()->hasProtectedAppType($appData['types'])) {
278
+            $enabled = \OC::$server->getAppConfig()->getValue($app, 'enabled', 'yes');
279
+            if ($enabled !== 'yes' && $enabled !== 'no') {
280
+                \OC::$server->getAppConfig()->setValue($app, 'enabled', 'yes');
281
+            }
282
+        }
283
+    }
284
+
285
+    /**
286
+     * get all enabled apps
287
+     */
288
+    protected static $enabledAppsCache = array();
289
+
290
+    /**
291
+     * Returns apps enabled for the current user.
292
+     *
293
+     * @param bool $forceRefresh whether to refresh the cache
294
+     * @param bool $all whether to return apps for all users, not only the
295
+     * currently logged in one
296
+     * @return string[]
297
+     */
298
+    public static function getEnabledApps($forceRefresh = false, $all = false) {
299
+        if (!\OC::$server->getSystemConfig()->getValue('installed', false)) {
300
+            return array();
301
+        }
302
+        // in incognito mode or when logged out, $user will be false,
303
+        // which is also the case during an upgrade
304
+        $appManager = \OC::$server->getAppManager();
305
+        if ($all) {
306
+            $user = null;
307
+        } else {
308
+            $user = \OC::$server->getUserSession()->getUser();
309
+        }
310
+
311
+        if (is_null($user)) {
312
+            $apps = $appManager->getInstalledApps();
313
+        } else {
314
+            $apps = $appManager->getEnabledAppsForUser($user);
315
+        }
316
+        $apps = array_filter($apps, function ($app) {
317
+            return $app !== 'files';//we add this manually
318
+        });
319
+        sort($apps);
320
+        array_unshift($apps, 'files');
321
+        return $apps;
322
+    }
323
+
324
+    /**
325
+     * checks whether or not an app is enabled
326
+     *
327
+     * @param string $app app
328
+     * @return bool
329
+     *
330
+     * This function checks whether or not an app is enabled.
331
+     */
332
+    public static function isEnabled($app) {
333
+        return \OC::$server->getAppManager()->isEnabledForUser($app);
334
+    }
335
+
336
+    /**
337
+     * enables an app
338
+     *
339
+     * @param string $appId
340
+     * @param array $groups (optional) when set, only these groups will have access to the app
341
+     * @throws \Exception
342
+     * @return void
343
+     *
344
+     * This function set an app as enabled in appconfig.
345
+     */
346
+    public function enable($appId,
347
+                            $groups = null) {
348
+        self::$enabledAppsCache = []; // flush
349
+
350
+        // Check if app is already downloaded
351
+        $installer = new Installer(
352
+            \OC::$server->getAppFetcher(),
353
+            \OC::$server->getHTTPClientService(),
354
+            \OC::$server->getTempManager(),
355
+            \OC::$server->getLogger(),
356
+            \OC::$server->getConfig()
357
+        );
358
+        $isDownloaded = $installer->isDownloaded($appId);
359
+
360
+        if(!$isDownloaded) {
361
+            $installer->downloadApp($appId);
362
+        }
363
+
364
+        $installer->installApp($appId);
365
+
366
+        $appManager = \OC::$server->getAppManager();
367
+        if (!is_null($groups)) {
368
+            $groupManager = \OC::$server->getGroupManager();
369
+            $groupsList = [];
370
+            foreach ($groups as $group) {
371
+                $groupItem = $groupManager->get($group);
372
+                if ($groupItem instanceof \OCP\IGroup) {
373
+                    $groupsList[] = $groupManager->get($group);
374
+                }
375
+            }
376
+            $appManager->enableAppForGroups($appId, $groupsList);
377
+        } else {
378
+            $appManager->enableApp($appId);
379
+        }
380
+    }
381
+
382
+    /**
383
+     * @param string $app
384
+     * @return bool
385
+     */
386
+    public static function removeApp($app) {
387
+        if (\OC::$server->getAppManager()->isShipped($app)) {
388
+            return false;
389
+        }
390
+
391
+        $installer = new Installer(
392
+            \OC::$server->getAppFetcher(),
393
+            \OC::$server->getHTTPClientService(),
394
+            \OC::$server->getTempManager(),
395
+            \OC::$server->getLogger(),
396
+            \OC::$server->getConfig()
397
+        );
398
+        return $installer->removeApp($app);
399
+    }
400
+
401
+    /**
402
+     * This function set an app as disabled in appconfig.
403
+     *
404
+     * @param string $app app
405
+     * @throws Exception
406
+     */
407
+    public static function disable($app) {
408
+        // flush
409
+        self::$enabledAppsCache = array();
410
+
411
+        // run uninstall steps
412
+        $appData = OC_App::getAppInfo($app);
413
+        if (!is_null($appData)) {
414
+            OC_App::executeRepairSteps($app, $appData['repair-steps']['uninstall']);
415
+        }
416
+
417
+        // emit disable hook - needed anymore ?
418
+        \OC_Hook::emit('OC_App', 'pre_disable', array('app' => $app));
419
+
420
+        // finally disable it
421
+        $appManager = \OC::$server->getAppManager();
422
+        $appManager->disableApp($app);
423
+    }
424
+
425
+    // This is private as well. It simply works, so don't ask for more details
426
+    private static function proceedNavigation($list) {
427
+        usort($list, function($a, $b) {
428
+            if (isset($a['order']) && isset($b['order'])) {
429
+                return ($a['order'] < $b['order']) ? -1 : 1;
430
+            } else if (isset($a['order']) || isset($b['order'])) {
431
+                return isset($a['order']) ? -1 : 1;
432
+            } else {
433
+                return ($a['name'] < $b['name']) ? -1 : 1;
434
+            }
435
+        });
436
+
437
+        $activeApp = OC::$server->getNavigationManager()->getActiveEntry();
438
+        foreach ($list as $index => &$navEntry) {
439
+            if ($navEntry['id'] == $activeApp) {
440
+                $navEntry['active'] = true;
441
+            } else {
442
+                $navEntry['active'] = false;
443
+            }
444
+        }
445
+        unset($navEntry);
446
+
447
+        return $list;
448
+    }
449
+
450
+    /**
451
+     * Get the path where to install apps
452
+     *
453
+     * @return string|false
454
+     */
455
+    public static function getInstallPath() {
456
+        if (\OC::$server->getSystemConfig()->getValue('appstoreenabled', true) == false) {
457
+            return false;
458
+        }
459
+
460
+        foreach (OC::$APPSROOTS as $dir) {
461
+            if (isset($dir['writable']) && $dir['writable'] === true) {
462
+                return $dir['path'];
463
+            }
464
+        }
465
+
466
+        \OCP\Util::writeLog('core', 'No application directories are marked as writable.', \OCP\Util::ERROR);
467
+        return null;
468
+    }
469
+
470
+
471
+    /**
472
+     * search for an app in all app-directories
473
+     *
474
+     * @param string $appId
475
+     * @return false|string
476
+     */
477
+    public static function findAppInDirectories($appId) {
478
+        $sanitizedAppId = self::cleanAppId($appId);
479
+        if($sanitizedAppId !== $appId) {
480
+            return false;
481
+        }
482
+        static $app_dir = array();
483
+
484
+        if (isset($app_dir[$appId])) {
485
+            return $app_dir[$appId];
486
+        }
487
+
488
+        $possibleApps = array();
489
+        foreach (OC::$APPSROOTS as $dir) {
490
+            if (file_exists($dir['path'] . '/' . $appId)) {
491
+                $possibleApps[] = $dir;
492
+            }
493
+        }
494
+
495
+        if (empty($possibleApps)) {
496
+            return false;
497
+        } elseif (count($possibleApps) === 1) {
498
+            $dir = array_shift($possibleApps);
499
+            $app_dir[$appId] = $dir;
500
+            return $dir;
501
+        } else {
502
+            $versionToLoad = array();
503
+            foreach ($possibleApps as $possibleApp) {
504
+                $version = self::getAppVersionByPath($possibleApp['path']);
505
+                if (empty($versionToLoad) || version_compare($version, $versionToLoad['version'], '>')) {
506
+                    $versionToLoad = array(
507
+                        'dir' => $possibleApp,
508
+                        'version' => $version,
509
+                    );
510
+                }
511
+            }
512
+            $app_dir[$appId] = $versionToLoad['dir'];
513
+            return $versionToLoad['dir'];
514
+            //TODO - write test
515
+        }
516
+    }
517
+
518
+    /**
519
+     * Get the directory for the given app.
520
+     * If the app is defined in multiple directories, the first one is taken. (false if not found)
521
+     *
522
+     * @param string $appId
523
+     * @return string|false
524
+     */
525
+    public static function getAppPath($appId) {
526
+        if ($appId === null || trim($appId) === '') {
527
+            return false;
528
+        }
529
+
530
+        if (($dir = self::findAppInDirectories($appId)) != false) {
531
+            return $dir['path'] . '/' . $appId;
532
+        }
533
+        return false;
534
+    }
535
+
536
+    /**
537
+     * Get the path for the given app on the access
538
+     * If the app is defined in multiple directories, the first one is taken. (false if not found)
539
+     *
540
+     * @param string $appId
541
+     * @return string|false
542
+     */
543
+    public static function getAppWebPath($appId) {
544
+        if (($dir = self::findAppInDirectories($appId)) != false) {
545
+            return OC::$WEBROOT . $dir['url'] . '/' . $appId;
546
+        }
547
+        return false;
548
+    }
549
+
550
+    /**
551
+     * get the last version of the app from appinfo/info.xml
552
+     *
553
+     * @param string $appId
554
+     * @param bool $useCache
555
+     * @return string
556
+     */
557
+    public static function getAppVersion($appId, $useCache = true) {
558
+        if($useCache && isset(self::$appVersion[$appId])) {
559
+            return self::$appVersion[$appId];
560
+        }
561
+
562
+        $file = self::getAppPath($appId);
563
+        self::$appVersion[$appId] = ($file !== false) ? self::getAppVersionByPath($file) : '0';
564
+        return self::$appVersion[$appId];
565
+    }
566
+
567
+    /**
568
+     * get app's version based on it's path
569
+     *
570
+     * @param string $path
571
+     * @return string
572
+     */
573
+    public static function getAppVersionByPath($path) {
574
+        $infoFile = $path . '/appinfo/info.xml';
575
+        $appData = self::getAppInfo($infoFile, true);
576
+        return isset($appData['version']) ? $appData['version'] : '';
577
+    }
578
+
579
+
580
+    /**
581
+     * Read all app metadata from the info.xml file
582
+     *
583
+     * @param string $appId id of the app or the path of the info.xml file
584
+     * @param bool $path
585
+     * @param string $lang
586
+     * @return array|null
587
+     * @note all data is read from info.xml, not just pre-defined fields
588
+     */
589
+    public static function getAppInfo($appId, $path = false, $lang = null) {
590
+        if ($path) {
591
+            $file = $appId;
592
+        } else {
593
+            if ($lang === null && isset(self::$appInfo[$appId])) {
594
+                return self::$appInfo[$appId];
595
+            }
596
+            $appPath = self::getAppPath($appId);
597
+            if($appPath === false) {
598
+                return null;
599
+            }
600
+            $file = $appPath . '/appinfo/info.xml';
601
+        }
602
+
603
+        $parser = new InfoParser(\OC::$server->getMemCacheFactory()->createLocal('core.appinfo'));
604
+        $data = $parser->parse($file);
605
+
606
+        if (is_array($data)) {
607
+            $data = OC_App::parseAppInfo($data, $lang);
608
+        }
609
+        if(isset($data['ocsid'])) {
610
+            $storedId = \OC::$server->getConfig()->getAppValue($appId, 'ocsid');
611
+            if($storedId !== '' && $storedId !== $data['ocsid']) {
612
+                $data['ocsid'] = $storedId;
613
+            }
614
+        }
615
+
616
+        if ($lang === null) {
617
+            self::$appInfo[$appId] = $data;
618
+        }
619
+
620
+        return $data;
621
+    }
622
+
623
+    /**
624
+     * Returns the navigation
625
+     *
626
+     * @return array
627
+     *
628
+     * This function returns an array containing all entries added. The
629
+     * entries are sorted by the key 'order' ascending. Additional to the keys
630
+     * given for each app the following keys exist:
631
+     *   - active: boolean, signals if the user is on this navigation entry
632
+     */
633
+    public static function getNavigation() {
634
+        $entries = OC::$server->getNavigationManager()->getAll();
635
+        return self::proceedNavigation($entries);
636
+    }
637
+
638
+    /**
639
+     * Returns the Settings Navigation
640
+     *
641
+     * @return string[]
642
+     *
643
+     * This function returns an array containing all settings pages added. The
644
+     * entries are sorted by the key 'order' ascending.
645
+     */
646
+    public static function getSettingsNavigation() {
647
+        $entries = OC::$server->getNavigationManager()->getAll('settings');
648
+        return self::proceedNavigation($entries);
649
+    }
650
+
651
+    /**
652
+     * get the id of loaded app
653
+     *
654
+     * @return string
655
+     */
656
+    public static function getCurrentApp() {
657
+        $request = \OC::$server->getRequest();
658
+        $script = substr($request->getScriptName(), strlen(OC::$WEBROOT) + 1);
659
+        $topFolder = substr($script, 0, strpos($script, '/'));
660
+        if (empty($topFolder)) {
661
+            $path_info = $request->getPathInfo();
662
+            if ($path_info) {
663
+                $topFolder = substr($path_info, 1, strpos($path_info, '/', 1) - 1);
664
+            }
665
+        }
666
+        if ($topFolder == 'apps') {
667
+            $length = strlen($topFolder);
668
+            return substr($script, $length + 1, strpos($script, '/', $length + 1) - $length - 1);
669
+        } else {
670
+            return $topFolder;
671
+        }
672
+    }
673
+
674
+    /**
675
+     * @param string $type
676
+     * @return array
677
+     */
678
+    public static function getForms($type) {
679
+        $forms = array();
680
+        switch ($type) {
681
+            case 'admin':
682
+                $source = self::$adminForms;
683
+                break;
684
+            case 'personal':
685
+                $source = self::$personalForms;
686
+                break;
687
+            default:
688
+                return array();
689
+        }
690
+        foreach ($source as $form) {
691
+            $forms[] = include $form;
692
+        }
693
+        return $forms;
694
+    }
695
+
696
+    /**
697
+     * register an admin form to be shown
698
+     *
699
+     * @param string $app
700
+     * @param string $page
701
+     */
702
+    public static function registerAdmin($app, $page) {
703
+        self::$adminForms[] = $app . '/' . $page . '.php';
704
+    }
705
+
706
+    /**
707
+     * register a personal form to be shown
708
+     * @param string $app
709
+     * @param string $page
710
+     */
711
+    public static function registerPersonal($app, $page) {
712
+        self::$personalForms[] = $app . '/' . $page . '.php';
713
+    }
714
+
715
+    /**
716
+     * @param array $entry
717
+     */
718
+    public static function registerLogIn(array $entry) {
719
+        self::$altLogin[] = $entry;
720
+    }
721
+
722
+    /**
723
+     * @return array
724
+     */
725
+    public static function getAlternativeLogIns() {
726
+        return self::$altLogin;
727
+    }
728
+
729
+    /**
730
+     * get a list of all apps in the apps folder
731
+     *
732
+     * @return array an array of app names (string IDs)
733
+     * @todo: change the name of this method to getInstalledApps, which is more accurate
734
+     */
735
+    public static function getAllApps() {
736
+
737
+        $apps = array();
738
+
739
+        foreach (OC::$APPSROOTS as $apps_dir) {
740
+            if (!is_readable($apps_dir['path'])) {
741
+                \OCP\Util::writeLog('core', 'unable to read app folder : ' . $apps_dir['path'], \OCP\Util::WARN);
742
+                continue;
743
+            }
744
+            $dh = opendir($apps_dir['path']);
745
+
746
+            if (is_resource($dh)) {
747
+                while (($file = readdir($dh)) !== false) {
748
+
749
+                    if ($file[0] != '.' and is_dir($apps_dir['path'] . '/' . $file) and is_file($apps_dir['path'] . '/' . $file . '/appinfo/info.xml')) {
750
+
751
+                        $apps[] = $file;
752
+                    }
753
+                }
754
+            }
755
+        }
756
+
757
+        return $apps;
758
+    }
759
+
760
+    /**
761
+     * List all apps, this is used in apps.php
762
+     *
763
+     * @return array
764
+     */
765
+    public function listAllApps() {
766
+        $installedApps = OC_App::getAllApps();
767
+
768
+        $appManager = \OC::$server->getAppManager();
769
+        //we don't want to show configuration for these
770
+        $blacklist = $appManager->getAlwaysEnabledApps();
771
+        $appList = array();
772
+        $langCode = \OC::$server->getL10N('core')->getLanguageCode();
773
+        $urlGenerator = \OC::$server->getURLGenerator();
774
+
775
+        foreach ($installedApps as $app) {
776
+            if (array_search($app, $blacklist) === false) {
777
+
778
+                $info = OC_App::getAppInfo($app, false, $langCode);
779
+                if (!is_array($info)) {
780
+                    \OCP\Util::writeLog('core', 'Could not read app info file for app "' . $app . '"', \OCP\Util::ERROR);
781
+                    continue;
782
+                }
783
+
784
+                if (!isset($info['name'])) {
785
+                    \OCP\Util::writeLog('core', 'App id "' . $app . '" has no name in appinfo', \OCP\Util::ERROR);
786
+                    continue;
787
+                }
788
+
789
+                $enabled = \OC::$server->getAppConfig()->getValue($app, 'enabled', 'no');
790
+                $info['groups'] = null;
791
+                if ($enabled === 'yes') {
792
+                    $active = true;
793
+                } else if ($enabled === 'no') {
794
+                    $active = false;
795
+                } else {
796
+                    $active = true;
797
+                    $info['groups'] = $enabled;
798
+                }
799
+
800
+                $info['active'] = $active;
801
+
802
+                if ($appManager->isShipped($app)) {
803
+                    $info['internal'] = true;
804
+                    $info['level'] = self::officialApp;
805
+                    $info['removable'] = false;
806
+                } else {
807
+                    $info['internal'] = false;
808
+                    $info['removable'] = true;
809
+                }
810
+
811
+                $appPath = self::getAppPath($app);
812
+                if($appPath !== false) {
813
+                    $appIcon = $appPath . '/img/' . $app . '.svg';
814
+                    if (file_exists($appIcon)) {
815
+                        $info['preview'] = $urlGenerator->imagePath($app, $app . '.svg');
816
+                        $info['previewAsIcon'] = true;
817
+                    } else {
818
+                        $appIcon = $appPath . '/img/app.svg';
819
+                        if (file_exists($appIcon)) {
820
+                            $info['preview'] = $urlGenerator->imagePath($app, 'app.svg');
821
+                            $info['previewAsIcon'] = true;
822
+                        }
823
+                    }
824
+                }
825
+                // fix documentation
826
+                if (isset($info['documentation']) && is_array($info['documentation'])) {
827
+                    foreach ($info['documentation'] as $key => $url) {
828
+                        // If it is not an absolute URL we assume it is a key
829
+                        // i.e. admin-ldap will get converted to go.php?to=admin-ldap
830
+                        if (stripos($url, 'https://') !== 0 && stripos($url, 'http://') !== 0) {
831
+                            $url = $urlGenerator->linkToDocs($url);
832
+                        }
833
+
834
+                        $info['documentation'][$key] = $url;
835
+                    }
836
+                }
837
+
838
+                $info['version'] = OC_App::getAppVersion($app);
839
+                $appList[] = $info;
840
+            }
841
+        }
842
+
843
+        return $appList;
844
+    }
845
+
846
+    /**
847
+     * Returns the internal app ID or false
848
+     * @param string $ocsID
849
+     * @return string|false
850
+     */
851
+    public static function getInternalAppIdByOcs($ocsID) {
852
+        if(is_numeric($ocsID)) {
853
+            $idArray = \OC::$server->getAppConfig()->getValues(false, 'ocsid');
854
+            if(array_search($ocsID, $idArray)) {
855
+                return array_search($ocsID, $idArray);
856
+            }
857
+        }
858
+        return false;
859
+    }
860
+
861
+    public static function shouldUpgrade($app) {
862
+        $versions = self::getAppVersions();
863
+        $currentVersion = OC_App::getAppVersion($app);
864
+        if ($currentVersion && isset($versions[$app])) {
865
+            $installedVersion = $versions[$app];
866
+            if (!version_compare($currentVersion, $installedVersion, '=')) {
867
+                return true;
868
+            }
869
+        }
870
+        return false;
871
+    }
872
+
873
+    /**
874
+     * Adjust the number of version parts of $version1 to match
875
+     * the number of version parts of $version2.
876
+     *
877
+     * @param string $version1 version to adjust
878
+     * @param string $version2 version to take the number of parts from
879
+     * @return string shortened $version1
880
+     */
881
+    private static function adjustVersionParts($version1, $version2) {
882
+        $version1 = explode('.', $version1);
883
+        $version2 = explode('.', $version2);
884
+        // reduce $version1 to match the number of parts in $version2
885
+        while (count($version1) > count($version2)) {
886
+            array_pop($version1);
887
+        }
888
+        // if $version1 does not have enough parts, add some
889
+        while (count($version1) < count($version2)) {
890
+            $version1[] = '0';
891
+        }
892
+        return implode('.', $version1);
893
+    }
894
+
895
+    /**
896
+     * Check whether the current ownCloud version matches the given
897
+     * application's version requirements.
898
+     *
899
+     * The comparison is made based on the number of parts that the
900
+     * app info version has. For example for ownCloud 6.0.3 if the
901
+     * app info version is expecting version 6.0, the comparison is
902
+     * made on the first two parts of the ownCloud version.
903
+     * This means that it's possible to specify "requiremin" => 6
904
+     * and "requiremax" => 6 and it will still match ownCloud 6.0.3.
905
+     *
906
+     * @param string $ocVersion ownCloud version to check against
907
+     * @param array $appInfo app info (from xml)
908
+     *
909
+     * @return boolean true if compatible, otherwise false
910
+     */
911
+    public static function isAppCompatible($ocVersion, $appInfo) {
912
+        $requireMin = '';
913
+        $requireMax = '';
914
+        if (isset($appInfo['dependencies']['nextcloud']['@attributes']['min-version'])) {
915
+            $requireMin = $appInfo['dependencies']['nextcloud']['@attributes']['min-version'];
916
+        } elseif (isset($appInfo['dependencies']['owncloud']['@attributes']['min-version'])) {
917
+            $requireMin = $appInfo['dependencies']['owncloud']['@attributes']['min-version'];
918
+        } else if (isset($appInfo['requiremin'])) {
919
+            $requireMin = $appInfo['requiremin'];
920
+        } else if (isset($appInfo['require'])) {
921
+            $requireMin = $appInfo['require'];
922
+        }
923
+
924
+        if (isset($appInfo['dependencies']['nextcloud']['@attributes']['max-version'])) {
925
+            $requireMax = $appInfo['dependencies']['nextcloud']['@attributes']['max-version'];
926
+        } elseif (isset($appInfo['dependencies']['owncloud']['@attributes']['max-version'])) {
927
+            $requireMax = $appInfo['dependencies']['owncloud']['@attributes']['max-version'];
928
+        } else if (isset($appInfo['requiremax'])) {
929
+            $requireMax = $appInfo['requiremax'];
930
+        }
931
+
932
+        if (is_array($ocVersion)) {
933
+            $ocVersion = implode('.', $ocVersion);
934
+        }
935
+
936
+        if (!empty($requireMin)
937
+            && version_compare(self::adjustVersionParts($ocVersion, $requireMin), $requireMin, '<')
938
+        ) {
939
+
940
+            return false;
941
+        }
942
+
943
+        if (!empty($requireMax)
944
+            && version_compare(self::adjustVersionParts($ocVersion, $requireMax), $requireMax, '>')
945
+        ) {
946
+            return false;
947
+        }
948
+
949
+        return true;
950
+    }
951
+
952
+    /**
953
+     * get the installed version of all apps
954
+     */
955
+    public static function getAppVersions() {
956
+        static $versions;
957
+
958
+        if(!$versions) {
959
+            $appConfig = \OC::$server->getAppConfig();
960
+            $versions = $appConfig->getValues(false, 'installed_version');
961
+        }
962
+        return $versions;
963
+    }
964
+
965
+    /**
966
+     * @param string $app
967
+     * @param \OCP\IConfig $config
968
+     * @param \OCP\IL10N $l
969
+     * @return bool
970
+     *
971
+     * @throws Exception if app is not compatible with this version of ownCloud
972
+     * @throws Exception if no app-name was specified
973
+     */
974
+    public function installApp($app,
975
+                                \OCP\IConfig $config,
976
+                                \OCP\IL10N $l) {
977
+        if ($app !== false) {
978
+            // check if the app is compatible with this version of ownCloud
979
+            $info = self::getAppInfo($app);
980
+            if(!is_array($info)) {
981
+                throw new \Exception(
982
+                    $l->t('App "%s" cannot be installed because appinfo file cannot be read.',
983
+                        [$info['name']]
984
+                    )
985
+                );
986
+            }
987
+
988
+            $version = \OCP\Util::getVersion();
989
+            if (!self::isAppCompatible($version, $info)) {
990
+                throw new \Exception(
991
+                    $l->t('App "%s" cannot be installed because it is not compatible with this version of the server.',
992
+                        array($info['name'])
993
+                    )
994
+                );
995
+            }
996
+
997
+            // check for required dependencies
998
+            self::checkAppDependencies($config, $l, $info);
999
+
1000
+            $config->setAppValue($app, 'enabled', 'yes');
1001
+            if (isset($appData['id'])) {
1002
+                $config->setAppValue($app, 'ocsid', $appData['id']);
1003
+            }
1004
+
1005
+            if(isset($info['settings']) && is_array($info['settings'])) {
1006
+                $appPath = self::getAppPath($app);
1007
+                self::registerAutoloading($app, $appPath);
1008
+                \OC::$server->getSettingsManager()->setupSettings($info['settings']);
1009
+            }
1010
+
1011
+            \OC_Hook::emit('OC_App', 'post_enable', array('app' => $app));
1012
+        } else {
1013
+            if(empty($appName) ) {
1014
+                throw new \Exception($l->t("No app name specified"));
1015
+            } else {
1016
+                throw new \Exception($l->t("App '%s' could not be installed!", $appName));
1017
+            }
1018
+        }
1019
+
1020
+        return $app;
1021
+    }
1022
+
1023
+    /**
1024
+     * update the database for the app and call the update script
1025
+     *
1026
+     * @param string $appId
1027
+     * @return bool
1028
+     */
1029
+    public static function updateApp($appId) {
1030
+        $appPath = self::getAppPath($appId);
1031
+        if($appPath === false) {
1032
+            return false;
1033
+        }
1034
+        self::registerAutoloading($appId, $appPath);
1035
+
1036
+        $appData = self::getAppInfo($appId);
1037
+        self::executeRepairSteps($appId, $appData['repair-steps']['pre-migration']);
1038
+
1039
+        if (file_exists($appPath . '/appinfo/database.xml')) {
1040
+            OC_DB::updateDbFromStructure($appPath . '/appinfo/database.xml');
1041
+        } else {
1042
+            $ms = new MigrationService($appId, \OC::$server->getDatabaseConnection());
1043
+            $ms->migrate();
1044
+        }
1045
+
1046
+        self::executeRepairSteps($appId, $appData['repair-steps']['post-migration']);
1047
+        self::setupLiveMigrations($appId, $appData['repair-steps']['live-migration']);
1048
+        unset(self::$appVersion[$appId]);
1049
+
1050
+        // run upgrade code
1051
+        if (file_exists($appPath . '/appinfo/update.php')) {
1052
+            self::loadApp($appId);
1053
+            include $appPath . '/appinfo/update.php';
1054
+        }
1055
+        self::setupBackgroundJobs($appData['background-jobs']);
1056
+        if(isset($appData['settings']) && is_array($appData['settings'])) {
1057
+            \OC::$server->getSettingsManager()->setupSettings($appData['settings']);
1058
+        }
1059
+
1060
+        //set remote/public handlers
1061
+        if (array_key_exists('ocsid', $appData)) {
1062
+            \OC::$server->getConfig()->setAppValue($appId, 'ocsid', $appData['ocsid']);
1063
+        } elseif(\OC::$server->getConfig()->getAppValue($appId, 'ocsid', null) !== null) {
1064
+            \OC::$server->getConfig()->deleteAppValue($appId, 'ocsid');
1065
+        }
1066
+        foreach ($appData['remote'] as $name => $path) {
1067
+            \OC::$server->getConfig()->setAppValue('core', 'remote_' . $name, $appId . '/' . $path);
1068
+        }
1069
+        foreach ($appData['public'] as $name => $path) {
1070
+            \OC::$server->getConfig()->setAppValue('core', 'public_' . $name, $appId . '/' . $path);
1071
+        }
1072
+
1073
+        self::setAppTypes($appId);
1074
+
1075
+        $version = \OC_App::getAppVersion($appId);
1076
+        \OC::$server->getAppConfig()->setValue($appId, 'installed_version', $version);
1077
+
1078
+        \OC::$server->getEventDispatcher()->dispatch(ManagerEvent::EVENT_APP_UPDATE, new ManagerEvent(
1079
+            ManagerEvent::EVENT_APP_UPDATE, $appId
1080
+        ));
1081
+
1082
+        return true;
1083
+    }
1084
+
1085
+    /**
1086
+     * @param string $appId
1087
+     * @param string[] $steps
1088
+     * @throws \OC\NeedsUpdateException
1089
+     */
1090
+    public static function executeRepairSteps($appId, array $steps) {
1091
+        if (empty($steps)) {
1092
+            return;
1093
+        }
1094
+        // load the app
1095
+        self::loadApp($appId);
1096
+
1097
+        $dispatcher = OC::$server->getEventDispatcher();
1098
+
1099
+        // load the steps
1100
+        $r = new Repair([], $dispatcher);
1101
+        foreach ($steps as $step) {
1102
+            try {
1103
+                $r->addStep($step);
1104
+            } catch (Exception $ex) {
1105
+                $r->emit('\OC\Repair', 'error', [$ex->getMessage()]);
1106
+                \OC::$server->getLogger()->logException($ex);
1107
+            }
1108
+        }
1109
+        // run the steps
1110
+        $r->run();
1111
+    }
1112
+
1113
+    public static function setupBackgroundJobs(array $jobs) {
1114
+        $queue = \OC::$server->getJobList();
1115
+        foreach ($jobs as $job) {
1116
+            $queue->add($job);
1117
+        }
1118
+    }
1119
+
1120
+    /**
1121
+     * @param string $appId
1122
+     * @param string[] $steps
1123
+     */
1124
+    private static function setupLiveMigrations($appId, array $steps) {
1125
+        $queue = \OC::$server->getJobList();
1126
+        foreach ($steps as $step) {
1127
+            $queue->add('OC\Migration\BackgroundRepair', [
1128
+                'app' => $appId,
1129
+                'step' => $step]);
1130
+        }
1131
+    }
1132
+
1133
+    /**
1134
+     * @param string $appId
1135
+     * @return \OC\Files\View|false
1136
+     */
1137
+    public static function getStorage($appId) {
1138
+        if (OC_App::isEnabled($appId)) { //sanity check
1139
+            if (\OC::$server->getUserSession()->isLoggedIn()) {
1140
+                $view = new \OC\Files\View('/' . OC_User::getUser());
1141
+                if (!$view->file_exists($appId)) {
1142
+                    $view->mkdir($appId);
1143
+                }
1144
+                return new \OC\Files\View('/' . OC_User::getUser() . '/' . $appId);
1145
+            } else {
1146
+                \OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ', user not logged in', \OCP\Util::ERROR);
1147
+                return false;
1148
+            }
1149
+        } else {
1150
+            \OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ' not enabled', \OCP\Util::ERROR);
1151
+            return false;
1152
+        }
1153
+    }
1154
+
1155
+    protected static function findBestL10NOption($options, $lang) {
1156
+        $fallback = $similarLangFallback = $englishFallback = false;
1157
+
1158
+        $lang = strtolower($lang);
1159
+        $similarLang = $lang;
1160
+        if (strpos($similarLang, '_')) {
1161
+            // For "de_DE" we want to find "de" and the other way around
1162
+            $similarLang = substr($lang, 0, strpos($lang, '_'));
1163
+        }
1164
+
1165
+        foreach ($options as $option) {
1166
+            if (is_array($option)) {
1167
+                if ($fallback === false) {
1168
+                    $fallback = $option['@value'];
1169
+                }
1170
+
1171
+                if (!isset($option['@attributes']['lang'])) {
1172
+                    continue;
1173
+                }
1174
+
1175
+                $attributeLang = strtolower($option['@attributes']['lang']);
1176
+                if ($attributeLang === $lang) {
1177
+                    return $option['@value'];
1178
+                }
1179
+
1180
+                if ($attributeLang === $similarLang) {
1181
+                    $similarLangFallback = $option['@value'];
1182
+                } else if (strpos($attributeLang, $similarLang . '_') === 0) {
1183
+                    if ($similarLangFallback === false) {
1184
+                        $similarLangFallback =  $option['@value'];
1185
+                    }
1186
+                }
1187
+            } else {
1188
+                $englishFallback = $option;
1189
+            }
1190
+        }
1191
+
1192
+        if ($similarLangFallback !== false) {
1193
+            return $similarLangFallback;
1194
+        } else if ($englishFallback !== false) {
1195
+            return $englishFallback;
1196
+        }
1197
+        return (string) $fallback;
1198
+    }
1199
+
1200
+    /**
1201
+     * parses the app data array and enhanced the 'description' value
1202
+     *
1203
+     * @param array $data the app data
1204
+     * @param string $lang
1205
+     * @return array improved app data
1206
+     */
1207
+    public static function parseAppInfo(array $data, $lang = null) {
1208
+
1209
+        if ($lang && isset($data['name']) && is_array($data['name'])) {
1210
+            $data['name'] = self::findBestL10NOption($data['name'], $lang);
1211
+        }
1212
+        if ($lang && isset($data['summary']) && is_array($data['summary'])) {
1213
+            $data['summary'] = self::findBestL10NOption($data['summary'], $lang);
1214
+        }
1215
+        if ($lang && isset($data['description']) && is_array($data['description'])) {
1216
+            $data['description'] = trim(self::findBestL10NOption($data['description'], $lang));
1217
+        } else if (isset($data['description']) && is_string($data['description'])) {
1218
+            $data['description'] = trim($data['description']);
1219
+        } else  {
1220
+            $data['description'] = '';
1221
+        }
1222
+
1223
+        return $data;
1224
+    }
1225
+
1226
+    /**
1227
+     * @param \OCP\IConfig $config
1228
+     * @param \OCP\IL10N $l
1229
+     * @param array $info
1230
+     * @throws \Exception
1231
+     */
1232
+    public static function checkAppDependencies($config, $l, $info) {
1233
+        $dependencyAnalyzer = new DependencyAnalyzer(new Platform($config), $l);
1234
+        $missing = $dependencyAnalyzer->analyze($info);
1235
+        if (!empty($missing)) {
1236
+            $missingMsg = implode(PHP_EOL, $missing);
1237
+            throw new \Exception(
1238
+                $l->t('App "%s" cannot be installed because the following dependencies are not fulfilled: %s',
1239
+                    [$info['name'], $missingMsg]
1240
+                )
1241
+            );
1242
+        }
1243
+    }
1244 1244
 }
Please login to merge, or discard this patch.
Spacing   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -111,9 +111,9 @@  discard block
 block discarded – undo
111 111
 		$apps = self::getEnabledApps();
112 112
 
113 113
 		// Add each apps' folder as allowed class path
114
-		foreach($apps as $app) {
114
+		foreach ($apps as $app) {
115 115
 			$path = self::getAppPath($app);
116
-			if($path !== false) {
116
+			if ($path !== false) {
117 117
 				self::registerAutoloading($app, $path);
118 118
 			}
119 119
 		}
@@ -138,15 +138,15 @@  discard block
 block discarded – undo
138 138
 	public static function loadApp($app) {
139 139
 		self::$loadedApps[] = $app;
140 140
 		$appPath = self::getAppPath($app);
141
-		if($appPath === false) {
141
+		if ($appPath === false) {
142 142
 			return;
143 143
 		}
144 144
 
145 145
 		// in case someone calls loadApp() directly
146 146
 		self::registerAutoloading($app, $appPath);
147 147
 
148
-		if (is_file($appPath . '/appinfo/app.php')) {
149
-			\OC::$server->getEventLogger()->start('load_app_' . $app, 'Load app: ' . $app);
148
+		if (is_file($appPath.'/appinfo/app.php')) {
149
+			\OC::$server->getEventLogger()->start('load_app_'.$app, 'Load app: '.$app);
150 150
 			self::requireAppFile($app);
151 151
 			if (self::isType($app, array('authentication'))) {
152 152
 				// since authentication apps affect the "is app enabled for group" check,
@@ -155,7 +155,7 @@  discard block
 block discarded – undo
155 155
 				// enabled for groups
156 156
 				self::$enabledAppsCache = array();
157 157
 			}
158
-			\OC::$server->getEventLogger()->end('load_app_' . $app);
158
+			\OC::$server->getEventLogger()->end('load_app_'.$app);
159 159
 		}
160 160
 
161 161
 		$info = self::getAppInfo($app);
@@ -182,17 +182,17 @@  discard block
 block discarded – undo
182 182
 	 * @param string $path
183 183
 	 */
184 184
 	public static function registerAutoloading($app, $path) {
185
-		$key = $app . '-' . $path;
186
-		if(isset(self::$alreadyRegistered[$key])) {
185
+		$key = $app.'-'.$path;
186
+		if (isset(self::$alreadyRegistered[$key])) {
187 187
 			return;
188 188
 		}
189 189
 		self::$alreadyRegistered[$key] = true;
190 190
 		// Register on PSR-4 composer autoloader
191 191
 		$appNamespace = \OC\AppFramework\App::buildAppNamespace($app);
192 192
 		\OC::$server->registerNamespace($app, $appNamespace);
193
-		\OC::$composerAutoloader->addPsr4($appNamespace . '\\', $path . '/lib/', true);
193
+		\OC::$composerAutoloader->addPsr4($appNamespace.'\\', $path.'/lib/', true);
194 194
 		if (defined('PHPUNIT_RUN') || defined('CLI_TEST_RUN')) {
195
-			\OC::$composerAutoloader->addPsr4($appNamespace . '\\Tests\\', $path . '/tests/', true);
195
+			\OC::$composerAutoloader->addPsr4($appNamespace.'\\Tests\\', $path.'/tests/', true);
196 196
 		}
197 197
 
198 198
 		// Register on legacy autoloader
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
 	private static function requireAppFile($app) {
208 208
 		try {
209 209
 			// encapsulated here to avoid variable scope conflicts
210
-			require_once $app . '/appinfo/app.php';
210
+			require_once $app.'/appinfo/app.php';
211 211
 		} catch (Error $ex) {
212 212
 			\OC::$server->getLogger()->logException($ex);
213 213
 			$blacklist = \OC::$server->getAppManager()->getAlwaysEnabledApps();
@@ -261,7 +261,7 @@  discard block
 block discarded – undo
261 261
 	 */
262 262
 	public static function setAppTypes($app) {
263 263
 		$appData = self::getAppInfo($app);
264
-		if(!is_array($appData)) {
264
+		if (!is_array($appData)) {
265 265
 			return;
266 266
 		}
267 267
 
@@ -313,8 +313,8 @@  discard block
 block discarded – undo
313 313
 		} else {
314 314
 			$apps = $appManager->getEnabledAppsForUser($user);
315 315
 		}
316
-		$apps = array_filter($apps, function ($app) {
317
-			return $app !== 'files';//we add this manually
316
+		$apps = array_filter($apps, function($app) {
317
+			return $app !== 'files'; //we add this manually
318 318
 		});
319 319
 		sort($apps);
320 320
 		array_unshift($apps, 'files');
@@ -357,7 +357,7 @@  discard block
 block discarded – undo
357 357
 		);
358 358
 		$isDownloaded = $installer->isDownloaded($appId);
359 359
 
360
-		if(!$isDownloaded) {
360
+		if (!$isDownloaded) {
361 361
 			$installer->downloadApp($appId);
362 362
 		}
363 363
 
@@ -476,7 +476,7 @@  discard block
 block discarded – undo
476 476
 	 */
477 477
 	public static function findAppInDirectories($appId) {
478 478
 		$sanitizedAppId = self::cleanAppId($appId);
479
-		if($sanitizedAppId !== $appId) {
479
+		if ($sanitizedAppId !== $appId) {
480 480
 			return false;
481 481
 		}
482 482
 		static $app_dir = array();
@@ -487,7 +487,7 @@  discard block
 block discarded – undo
487 487
 
488 488
 		$possibleApps = array();
489 489
 		foreach (OC::$APPSROOTS as $dir) {
490
-			if (file_exists($dir['path'] . '/' . $appId)) {
490
+			if (file_exists($dir['path'].'/'.$appId)) {
491 491
 				$possibleApps[] = $dir;
492 492
 			}
493 493
 		}
@@ -528,7 +528,7 @@  discard block
 block discarded – undo
528 528
 		}
529 529
 
530 530
 		if (($dir = self::findAppInDirectories($appId)) != false) {
531
-			return $dir['path'] . '/' . $appId;
531
+			return $dir['path'].'/'.$appId;
532 532
 		}
533 533
 		return false;
534 534
 	}
@@ -542,7 +542,7 @@  discard block
 block discarded – undo
542 542
 	 */
543 543
 	public static function getAppWebPath($appId) {
544 544
 		if (($dir = self::findAppInDirectories($appId)) != false) {
545
-			return OC::$WEBROOT . $dir['url'] . '/' . $appId;
545
+			return OC::$WEBROOT.$dir['url'].'/'.$appId;
546 546
 		}
547 547
 		return false;
548 548
 	}
@@ -555,7 +555,7 @@  discard block
 block discarded – undo
555 555
 	 * @return string
556 556
 	 */
557 557
 	public static function getAppVersion($appId, $useCache = true) {
558
-		if($useCache && isset(self::$appVersion[$appId])) {
558
+		if ($useCache && isset(self::$appVersion[$appId])) {
559 559
 			return self::$appVersion[$appId];
560 560
 		}
561 561
 
@@ -571,7 +571,7 @@  discard block
 block discarded – undo
571 571
 	 * @return string
572 572
 	 */
573 573
 	public static function getAppVersionByPath($path) {
574
-		$infoFile = $path . '/appinfo/info.xml';
574
+		$infoFile = $path.'/appinfo/info.xml';
575 575
 		$appData = self::getAppInfo($infoFile, true);
576 576
 		return isset($appData['version']) ? $appData['version'] : '';
577 577
 	}
@@ -594,10 +594,10 @@  discard block
 block discarded – undo
594 594
 				return self::$appInfo[$appId];
595 595
 			}
596 596
 			$appPath = self::getAppPath($appId);
597
-			if($appPath === false) {
597
+			if ($appPath === false) {
598 598
 				return null;
599 599
 			}
600
-			$file = $appPath . '/appinfo/info.xml';
600
+			$file = $appPath.'/appinfo/info.xml';
601 601
 		}
602 602
 
603 603
 		$parser = new InfoParser(\OC::$server->getMemCacheFactory()->createLocal('core.appinfo'));
@@ -606,9 +606,9 @@  discard block
 block discarded – undo
606 606
 		if (is_array($data)) {
607 607
 			$data = OC_App::parseAppInfo($data, $lang);
608 608
 		}
609
-		if(isset($data['ocsid'])) {
609
+		if (isset($data['ocsid'])) {
610 610
 			$storedId = \OC::$server->getConfig()->getAppValue($appId, 'ocsid');
611
-			if($storedId !== '' && $storedId !== $data['ocsid']) {
611
+			if ($storedId !== '' && $storedId !== $data['ocsid']) {
612 612
 				$data['ocsid'] = $storedId;
613 613
 			}
614 614
 		}
@@ -700,7 +700,7 @@  discard block
 block discarded – undo
700 700
 	 * @param string $page
701 701
 	 */
702 702
 	public static function registerAdmin($app, $page) {
703
-		self::$adminForms[] = $app . '/' . $page . '.php';
703
+		self::$adminForms[] = $app.'/'.$page.'.php';
704 704
 	}
705 705
 
706 706
 	/**
@@ -709,7 +709,7 @@  discard block
 block discarded – undo
709 709
 	 * @param string $page
710 710
 	 */
711 711
 	public static function registerPersonal($app, $page) {
712
-		self::$personalForms[] = $app . '/' . $page . '.php';
712
+		self::$personalForms[] = $app.'/'.$page.'.php';
713 713
 	}
714 714
 
715 715
 	/**
@@ -738,7 +738,7 @@  discard block
 block discarded – undo
738 738
 
739 739
 		foreach (OC::$APPSROOTS as $apps_dir) {
740 740
 			if (!is_readable($apps_dir['path'])) {
741
-				\OCP\Util::writeLog('core', 'unable to read app folder : ' . $apps_dir['path'], \OCP\Util::WARN);
741
+				\OCP\Util::writeLog('core', 'unable to read app folder : '.$apps_dir['path'], \OCP\Util::WARN);
742 742
 				continue;
743 743
 			}
744 744
 			$dh = opendir($apps_dir['path']);
@@ -746,7 +746,7 @@  discard block
 block discarded – undo
746 746
 			if (is_resource($dh)) {
747 747
 				while (($file = readdir($dh)) !== false) {
748 748
 
749
-					if ($file[0] != '.' and is_dir($apps_dir['path'] . '/' . $file) and is_file($apps_dir['path'] . '/' . $file . '/appinfo/info.xml')) {
749
+					if ($file[0] != '.' and is_dir($apps_dir['path'].'/'.$file) and is_file($apps_dir['path'].'/'.$file.'/appinfo/info.xml')) {
750 750
 
751 751
 						$apps[] = $file;
752 752
 					}
@@ -777,12 +777,12 @@  discard block
 block discarded – undo
777 777
 
778 778
 				$info = OC_App::getAppInfo($app, false, $langCode);
779 779
 				if (!is_array($info)) {
780
-					\OCP\Util::writeLog('core', 'Could not read app info file for app "' . $app . '"', \OCP\Util::ERROR);
780
+					\OCP\Util::writeLog('core', 'Could not read app info file for app "'.$app.'"', \OCP\Util::ERROR);
781 781
 					continue;
782 782
 				}
783 783
 
784 784
 				if (!isset($info['name'])) {
785
-					\OCP\Util::writeLog('core', 'App id "' . $app . '" has no name in appinfo', \OCP\Util::ERROR);
785
+					\OCP\Util::writeLog('core', 'App id "'.$app.'" has no name in appinfo', \OCP\Util::ERROR);
786 786
 					continue;
787 787
 				}
788 788
 
@@ -809,13 +809,13 @@  discard block
 block discarded – undo
809 809
 				}
810 810
 
811 811
 				$appPath = self::getAppPath($app);
812
-				if($appPath !== false) {
813
-					$appIcon = $appPath . '/img/' . $app . '.svg';
812
+				if ($appPath !== false) {
813
+					$appIcon = $appPath.'/img/'.$app.'.svg';
814 814
 					if (file_exists($appIcon)) {
815
-						$info['preview'] = $urlGenerator->imagePath($app, $app . '.svg');
815
+						$info['preview'] = $urlGenerator->imagePath($app, $app.'.svg');
816 816
 						$info['previewAsIcon'] = true;
817 817
 					} else {
818
-						$appIcon = $appPath . '/img/app.svg';
818
+						$appIcon = $appPath.'/img/app.svg';
819 819
 						if (file_exists($appIcon)) {
820 820
 							$info['preview'] = $urlGenerator->imagePath($app, 'app.svg');
821 821
 							$info['previewAsIcon'] = true;
@@ -849,9 +849,9 @@  discard block
 block discarded – undo
849 849
 	 * @return string|false
850 850
 	 */
851 851
 	public static function getInternalAppIdByOcs($ocsID) {
852
-		if(is_numeric($ocsID)) {
852
+		if (is_numeric($ocsID)) {
853 853
 			$idArray = \OC::$server->getAppConfig()->getValues(false, 'ocsid');
854
-			if(array_search($ocsID, $idArray)) {
854
+			if (array_search($ocsID, $idArray)) {
855 855
 				return array_search($ocsID, $idArray);
856 856
 			}
857 857
 		}
@@ -955,7 +955,7 @@  discard block
 block discarded – undo
955 955
 	public static function getAppVersions() {
956 956
 		static $versions;
957 957
 
958
-		if(!$versions) {
958
+		if (!$versions) {
959 959
 			$appConfig = \OC::$server->getAppConfig();
960 960
 			$versions = $appConfig->getValues(false, 'installed_version');
961 961
 		}
@@ -977,7 +977,7 @@  discard block
 block discarded – undo
977 977
 		if ($app !== false) {
978 978
 			// check if the app is compatible with this version of ownCloud
979 979
 			$info = self::getAppInfo($app);
980
-			if(!is_array($info)) {
980
+			if (!is_array($info)) {
981 981
 				throw new \Exception(
982 982
 					$l->t('App "%s" cannot be installed because appinfo file cannot be read.',
983 983
 						[$info['name']]
@@ -1002,7 +1002,7 @@  discard block
 block discarded – undo
1002 1002
 				$config->setAppValue($app, 'ocsid', $appData['id']);
1003 1003
 			}
1004 1004
 
1005
-			if(isset($info['settings']) && is_array($info['settings'])) {
1005
+			if (isset($info['settings']) && is_array($info['settings'])) {
1006 1006
 				$appPath = self::getAppPath($app);
1007 1007
 				self::registerAutoloading($app, $appPath);
1008 1008
 				\OC::$server->getSettingsManager()->setupSettings($info['settings']);
@@ -1010,7 +1010,7 @@  discard block
 block discarded – undo
1010 1010
 
1011 1011
 			\OC_Hook::emit('OC_App', 'post_enable', array('app' => $app));
1012 1012
 		} else {
1013
-			if(empty($appName) ) {
1013
+			if (empty($appName)) {
1014 1014
 				throw new \Exception($l->t("No app name specified"));
1015 1015
 			} else {
1016 1016
 				throw new \Exception($l->t("App '%s' could not be installed!", $appName));
@@ -1028,7 +1028,7 @@  discard block
 block discarded – undo
1028 1028
 	 */
1029 1029
 	public static function updateApp($appId) {
1030 1030
 		$appPath = self::getAppPath($appId);
1031
-		if($appPath === false) {
1031
+		if ($appPath === false) {
1032 1032
 			return false;
1033 1033
 		}
1034 1034
 		self::registerAutoloading($appId, $appPath);
@@ -1036,8 +1036,8 @@  discard block
 block discarded – undo
1036 1036
 		$appData = self::getAppInfo($appId);
1037 1037
 		self::executeRepairSteps($appId, $appData['repair-steps']['pre-migration']);
1038 1038
 
1039
-		if (file_exists($appPath . '/appinfo/database.xml')) {
1040
-			OC_DB::updateDbFromStructure($appPath . '/appinfo/database.xml');
1039
+		if (file_exists($appPath.'/appinfo/database.xml')) {
1040
+			OC_DB::updateDbFromStructure($appPath.'/appinfo/database.xml');
1041 1041
 		} else {
1042 1042
 			$ms = new MigrationService($appId, \OC::$server->getDatabaseConnection());
1043 1043
 			$ms->migrate();
@@ -1048,26 +1048,26 @@  discard block
 block discarded – undo
1048 1048
 		unset(self::$appVersion[$appId]);
1049 1049
 
1050 1050
 		// run upgrade code
1051
-		if (file_exists($appPath . '/appinfo/update.php')) {
1051
+		if (file_exists($appPath.'/appinfo/update.php')) {
1052 1052
 			self::loadApp($appId);
1053
-			include $appPath . '/appinfo/update.php';
1053
+			include $appPath.'/appinfo/update.php';
1054 1054
 		}
1055 1055
 		self::setupBackgroundJobs($appData['background-jobs']);
1056
-		if(isset($appData['settings']) && is_array($appData['settings'])) {
1056
+		if (isset($appData['settings']) && is_array($appData['settings'])) {
1057 1057
 			\OC::$server->getSettingsManager()->setupSettings($appData['settings']);
1058 1058
 		}
1059 1059
 
1060 1060
 		//set remote/public handlers
1061 1061
 		if (array_key_exists('ocsid', $appData)) {
1062 1062
 			\OC::$server->getConfig()->setAppValue($appId, 'ocsid', $appData['ocsid']);
1063
-		} elseif(\OC::$server->getConfig()->getAppValue($appId, 'ocsid', null) !== null) {
1063
+		} elseif (\OC::$server->getConfig()->getAppValue($appId, 'ocsid', null) !== null) {
1064 1064
 			\OC::$server->getConfig()->deleteAppValue($appId, 'ocsid');
1065 1065
 		}
1066 1066
 		foreach ($appData['remote'] as $name => $path) {
1067
-			\OC::$server->getConfig()->setAppValue('core', 'remote_' . $name, $appId . '/' . $path);
1067
+			\OC::$server->getConfig()->setAppValue('core', 'remote_'.$name, $appId.'/'.$path);
1068 1068
 		}
1069 1069
 		foreach ($appData['public'] as $name => $path) {
1070
-			\OC::$server->getConfig()->setAppValue('core', 'public_' . $name, $appId . '/' . $path);
1070
+			\OC::$server->getConfig()->setAppValue('core', 'public_'.$name, $appId.'/'.$path);
1071 1071
 		}
1072 1072
 
1073 1073
 		self::setAppTypes($appId);
@@ -1137,17 +1137,17 @@  discard block
 block discarded – undo
1137 1137
 	public static function getStorage($appId) {
1138 1138
 		if (OC_App::isEnabled($appId)) { //sanity check
1139 1139
 			if (\OC::$server->getUserSession()->isLoggedIn()) {
1140
-				$view = new \OC\Files\View('/' . OC_User::getUser());
1140
+				$view = new \OC\Files\View('/'.OC_User::getUser());
1141 1141
 				if (!$view->file_exists($appId)) {
1142 1142
 					$view->mkdir($appId);
1143 1143
 				}
1144
-				return new \OC\Files\View('/' . OC_User::getUser() . '/' . $appId);
1144
+				return new \OC\Files\View('/'.OC_User::getUser().'/'.$appId);
1145 1145
 			} else {
1146
-				\OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ', user not logged in', \OCP\Util::ERROR);
1146
+				\OCP\Util::writeLog('core', 'Can\'t get app storage, app '.$appId.', user not logged in', \OCP\Util::ERROR);
1147 1147
 				return false;
1148 1148
 			}
1149 1149
 		} else {
1150
-			\OCP\Util::writeLog('core', 'Can\'t get app storage, app ' . $appId . ' not enabled', \OCP\Util::ERROR);
1150
+			\OCP\Util::writeLog('core', 'Can\'t get app storage, app '.$appId.' not enabled', \OCP\Util::ERROR);
1151 1151
 			return false;
1152 1152
 		}
1153 1153
 	}
@@ -1179,9 +1179,9 @@  discard block
 block discarded – undo
1179 1179
 
1180 1180
 				if ($attributeLang === $similarLang) {
1181 1181
 					$similarLangFallback = $option['@value'];
1182
-				} else if (strpos($attributeLang, $similarLang . '_') === 0) {
1182
+				} else if (strpos($attributeLang, $similarLang.'_') === 0) {
1183 1183
 					if ($similarLangFallback === false) {
1184
-						$similarLangFallback =  $option['@value'];
1184
+						$similarLangFallback = $option['@value'];
1185 1185
 					}
1186 1186
 				}
1187 1187
 			} else {
@@ -1216,7 +1216,7 @@  discard block
 block discarded – undo
1216 1216
 			$data['description'] = trim(self::findBestL10NOption($data['description'], $lang));
1217 1217
 		} else if (isset($data['description']) && is_string($data['description'])) {
1218 1218
 			$data['description'] = trim($data['description']);
1219
-		} else  {
1219
+		} else {
1220 1220
 			$data['description'] = '';
1221 1221
 		}
1222 1222
 
Please login to merge, or discard this patch.
lib/private/Files/Node/File.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -31,7 +31,7 @@
 block discarded – undo
31 31
 	 * Creates a Folder that represents a non-existing path
32 32
 	 *
33 33
 	 * @param string $path path
34
-	 * @return string non-existing node class
34
+	 * @return NonExistingFile non-existing node class
35 35
 	 */
36 36
 	protected function createNonExistingNode($path) {
37 37
 		return new NonExistingFile($this->root, $this->view, $path);
Please login to merge, or discard this patch.
Indentation   +102 added lines, -102 removed lines patch added patch discarded remove patch
@@ -29,113 +29,113 @@
 block discarded – undo
29 29
 use OCP\Files\NotPermittedException;
30 30
 
31 31
 class File extends Node implements \OCP\Files\File {
32
-	/**
33
-	 * Creates a Folder that represents a non-existing path
34
-	 *
35
-	 * @param string $path path
36
-	 * @return string non-existing node class
37
-	 */
38
-	protected function createNonExistingNode($path) {
39
-		return new NonExistingFile($this->root, $this->view, $path);
40
-	}
32
+    /**
33
+     * Creates a Folder that represents a non-existing path
34
+     *
35
+     * @param string $path path
36
+     * @return string non-existing node class
37
+     */
38
+    protected function createNonExistingNode($path) {
39
+        return new NonExistingFile($this->root, $this->view, $path);
40
+    }
41 41
 
42
-	/**
43
-	 * @return string
44
-	 * @throws \OCP\Files\NotPermittedException
45
-	 */
46
-	public function getContent() {
47
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_READ)) {
48
-			/**
49
-			 * @var \OC\Files\Storage\Storage $storage;
50
-			 */
51
-			return $this->view->file_get_contents($this->path);
52
-		} else {
53
-			throw new NotPermittedException();
54
-		}
55
-	}
42
+    /**
43
+     * @return string
44
+     * @throws \OCP\Files\NotPermittedException
45
+     */
46
+    public function getContent() {
47
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_READ)) {
48
+            /**
49
+             * @var \OC\Files\Storage\Storage $storage;
50
+             */
51
+            return $this->view->file_get_contents($this->path);
52
+        } else {
53
+            throw new NotPermittedException();
54
+        }
55
+    }
56 56
 
57
-	/**
58
-	 * @param string $data
59
-	 * @throws \OCP\Files\NotPermittedException
60
-	 */
61
-	public function putContent($data) {
62
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) {
63
-			$this->sendHooks(array('preWrite'));
64
-			$this->view->file_put_contents($this->path, $data);
65
-			$this->fileInfo = null;
66
-			$this->sendHooks(array('postWrite'));
67
-		} else {
68
-			throw new NotPermittedException();
69
-		}
70
-	}
57
+    /**
58
+     * @param string $data
59
+     * @throws \OCP\Files\NotPermittedException
60
+     */
61
+    public function putContent($data) {
62
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) {
63
+            $this->sendHooks(array('preWrite'));
64
+            $this->view->file_put_contents($this->path, $data);
65
+            $this->fileInfo = null;
66
+            $this->sendHooks(array('postWrite'));
67
+        } else {
68
+            throw new NotPermittedException();
69
+        }
70
+    }
71 71
 
72
-	/**
73
-	 * @param string $mode
74
-	 * @return resource
75
-	 * @throws \OCP\Files\NotPermittedException
76
-	 */
77
-	public function fopen($mode) {
78
-		$preHooks = array();
79
-		$postHooks = array();
80
-		$requiredPermissions = \OCP\Constants::PERMISSION_READ;
81
-		switch ($mode) {
82
-			case 'r+':
83
-			case 'rb+':
84
-			case 'w+':
85
-			case 'wb+':
86
-			case 'x+':
87
-			case 'xb+':
88
-			case 'a+':
89
-			case 'ab+':
90
-			case 'w':
91
-			case 'wb':
92
-			case 'x':
93
-			case 'xb':
94
-			case 'a':
95
-			case 'ab':
96
-				$preHooks[] = 'preWrite';
97
-				$postHooks[] = 'postWrite';
98
-				$requiredPermissions |= \OCP\Constants::PERMISSION_UPDATE;
99
-				break;
100
-		}
72
+    /**
73
+     * @param string $mode
74
+     * @return resource
75
+     * @throws \OCP\Files\NotPermittedException
76
+     */
77
+    public function fopen($mode) {
78
+        $preHooks = array();
79
+        $postHooks = array();
80
+        $requiredPermissions = \OCP\Constants::PERMISSION_READ;
81
+        switch ($mode) {
82
+            case 'r+':
83
+            case 'rb+':
84
+            case 'w+':
85
+            case 'wb+':
86
+            case 'x+':
87
+            case 'xb+':
88
+            case 'a+':
89
+            case 'ab+':
90
+            case 'w':
91
+            case 'wb':
92
+            case 'x':
93
+            case 'xb':
94
+            case 'a':
95
+            case 'ab':
96
+                $preHooks[] = 'preWrite';
97
+                $postHooks[] = 'postWrite';
98
+                $requiredPermissions |= \OCP\Constants::PERMISSION_UPDATE;
99
+                break;
100
+        }
101 101
 
102
-		if ($this->checkPermissions($requiredPermissions)) {
103
-			$this->sendHooks($preHooks);
104
-			$result = $this->view->fopen($this->path, $mode);
105
-			$this->sendHooks($postHooks);
106
-			return $result;
107
-		} else {
108
-			throw new NotPermittedException();
109
-		}
110
-	}
102
+        if ($this->checkPermissions($requiredPermissions)) {
103
+            $this->sendHooks($preHooks);
104
+            $result = $this->view->fopen($this->path, $mode);
105
+            $this->sendHooks($postHooks);
106
+            return $result;
107
+        } else {
108
+            throw new NotPermittedException();
109
+        }
110
+    }
111 111
 
112
-	public function delete() {
113
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
114
-			$this->sendHooks(array('preDelete'));
115
-			$fileInfo = $this->getFileInfo();
116
-			$this->view->unlink($this->path);
117
-			$nonExisting = new NonExistingFile($this->root, $this->view, $this->path, $fileInfo);
118
-			$this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
119
-			$this->exists = false;
120
-			$this->fileInfo = null;
121
-		} else {
122
-			throw new NotPermittedException();
123
-		}
124
-	}
112
+    public function delete() {
113
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
114
+            $this->sendHooks(array('preDelete'));
115
+            $fileInfo = $this->getFileInfo();
116
+            $this->view->unlink($this->path);
117
+            $nonExisting = new NonExistingFile($this->root, $this->view, $this->path, $fileInfo);
118
+            $this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
119
+            $this->exists = false;
120
+            $this->fileInfo = null;
121
+        } else {
122
+            throw new NotPermittedException();
123
+        }
124
+    }
125 125
 
126
-	/**
127
-	 * @param string $type
128
-	 * @param bool $raw
129
-	 * @return string
130
-	 */
131
-	public function hash($type, $raw = false) {
132
-		return $this->view->hash($type, $this->path, $raw);
133
-	}
126
+    /**
127
+     * @param string $type
128
+     * @param bool $raw
129
+     * @return string
130
+     */
131
+    public function hash($type, $raw = false) {
132
+        return $this->view->hash($type, $this->path, $raw);
133
+    }
134 134
 
135
-	/**
136
-	 * @inheritdoc
137
-	 */
138
-	public function getChecksum() {
139
-		return $this->getFileInfo()->getChecksum();
140
-	}
135
+    /**
136
+     * @inheritdoc
137
+     */
138
+    public function getChecksum() {
139
+        return $this->getFileInfo()->getChecksum();
140
+    }
141 141
 }
Please login to merge, or discard this patch.
lib/private/Files/Node/Folder.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -37,7 +37,7 @@
 block discarded – undo
37 37
 	 * Creates a Folder that represents a non-existing path
38 38
 	 *
39 39
 	 * @param string $path path
40
-	 * @return string non-existing node class
40
+	 * @return NonExistingFolder non-existing node class
41 41
 	 */
42 42
 	protected function createNonExistingNode($path) {
43 43
 		return new NonExistingFolder($this->root, $this->view, $path);
Please login to merge, or discard this patch.
Indentation   +395 added lines, -395 removed lines patch added patch discarded remove patch
@@ -36,399 +36,399 @@
 block discarded – undo
36 36
 use OCP\Files\Search\ISearchOperator;
37 37
 
38 38
 class Folder extends Node implements \OCP\Files\Folder {
39
-	/**
40
-	 * Creates a Folder that represents a non-existing path
41
-	 *
42
-	 * @param string $path path
43
-	 * @return string non-existing node class
44
-	 */
45
-	protected function createNonExistingNode($path) {
46
-		return new NonExistingFolder($this->root, $this->view, $path);
47
-	}
48
-
49
-	/**
50
-	 * @param string $path path relative to the folder
51
-	 * @return string
52
-	 * @throws \OCP\Files\NotPermittedException
53
-	 */
54
-	public function getFullPath($path) {
55
-		if (!$this->isValidPath($path)) {
56
-			throw new NotPermittedException('Invalid path');
57
-		}
58
-		return $this->path . $this->normalizePath($path);
59
-	}
60
-
61
-	/**
62
-	 * @param string $path
63
-	 * @return string
64
-	 */
65
-	public function getRelativePath($path) {
66
-		if ($this->path === '' or $this->path === '/') {
67
-			return $this->normalizePath($path);
68
-		}
69
-		if ($path === $this->path) {
70
-			return '/';
71
-		} else if (strpos($path, $this->path . '/') !== 0) {
72
-			return null;
73
-		} else {
74
-			$path = substr($path, strlen($this->path));
75
-			return $this->normalizePath($path);
76
-		}
77
-	}
78
-
79
-	/**
80
-	 * check if a node is a (grand-)child of the folder
81
-	 *
82
-	 * @param \OC\Files\Node\Node $node
83
-	 * @return bool
84
-	 */
85
-	public function isSubNode($node) {
86
-		return strpos($node->getPath(), $this->path . '/') === 0;
87
-	}
88
-
89
-	/**
90
-	 * get the content of this directory
91
-	 *
92
-	 * @throws \OCP\Files\NotFoundException
93
-	 * @return Node[]
94
-	 */
95
-	public function getDirectoryListing() {
96
-		$folderContent = $this->view->getDirectoryContent($this->path);
97
-
98
-		return array_map(function (FileInfo $info) {
99
-			if ($info->getMimetype() === 'httpd/unix-directory') {
100
-				return new Folder($this->root, $this->view, $info->getPath(), $info);
101
-			} else {
102
-				return new File($this->root, $this->view, $info->getPath(), $info);
103
-			}
104
-		}, $folderContent);
105
-	}
106
-
107
-	/**
108
-	 * @param string $path
109
-	 * @param FileInfo $info
110
-	 * @return File|Folder
111
-	 */
112
-	protected function createNode($path, FileInfo $info = null) {
113
-		if (is_null($info)) {
114
-			$isDir = $this->view->is_dir($path);
115
-		} else {
116
-			$isDir = $info->getType() === FileInfo::TYPE_FOLDER;
117
-		}
118
-		if ($isDir) {
119
-			return new Folder($this->root, $this->view, $path, $info);
120
-		} else {
121
-			return new File($this->root, $this->view, $path, $info);
122
-		}
123
-	}
124
-
125
-	/**
126
-	 * Get the node at $path
127
-	 *
128
-	 * @param string $path
129
-	 * @return \OC\Files\Node\Node
130
-	 * @throws \OCP\Files\NotFoundException
131
-	 */
132
-	public function get($path) {
133
-		return $this->root->get($this->getFullPath($path));
134
-	}
135
-
136
-	/**
137
-	 * @param string $path
138
-	 * @return bool
139
-	 */
140
-	public function nodeExists($path) {
141
-		try {
142
-			$this->get($path);
143
-			return true;
144
-		} catch (NotFoundException $e) {
145
-			return false;
146
-		}
147
-	}
148
-
149
-	/**
150
-	 * @param string $path
151
-	 * @return \OC\Files\Node\Folder
152
-	 * @throws \OCP\Files\NotPermittedException
153
-	 */
154
-	public function newFolder($path) {
155
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
156
-			$fullPath = $this->getFullPath($path);
157
-			$nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
158
-			$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
159
-			$this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
160
-			$this->view->mkdir($fullPath);
161
-			$node = new Folder($this->root, $this->view, $fullPath);
162
-			$this->root->emit('\OC\Files', 'postWrite', array($node));
163
-			$this->root->emit('\OC\Files', 'postCreate', array($node));
164
-			return $node;
165
-		} else {
166
-			throw new NotPermittedException('No create permission for folder');
167
-		}
168
-	}
169
-
170
-	/**
171
-	 * @param string $path
172
-	 * @return \OC\Files\Node\File
173
-	 * @throws \OCP\Files\NotPermittedException
174
-	 */
175
-	public function newFile($path) {
176
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
177
-			$fullPath = $this->getFullPath($path);
178
-			$nonExisting = new NonExistingFile($this->root, $this->view, $fullPath);
179
-			$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
180
-			$this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
181
-			$this->view->touch($fullPath);
182
-			$node = new File($this->root, $this->view, $fullPath);
183
-			$this->root->emit('\OC\Files', 'postWrite', array($node));
184
-			$this->root->emit('\OC\Files', 'postCreate', array($node));
185
-			return $node;
186
-		} else {
187
-			throw new NotPermittedException('No create permission for path');
188
-		}
189
-	}
190
-
191
-	/**
192
-	 * search for files with the name matching $query
193
-	 *
194
-	 * @param string|ISearchOperator $query
195
-	 * @return \OC\Files\Node\Node[]
196
-	 */
197
-	public function search($query) {
198
-		if (is_string($query)) {
199
-			return $this->searchCommon('search', array('%' . $query . '%'));
200
-		} else {
201
-			return $this->searchCommon('searchQuery', array($query));
202
-		}
203
-	}
204
-
205
-	/**
206
-	 * search for files by mimetype
207
-	 *
208
-	 * @param string $mimetype
209
-	 * @return Node[]
210
-	 */
211
-	public function searchByMime($mimetype) {
212
-		return $this->searchCommon('searchByMime', array($mimetype));
213
-	}
214
-
215
-	/**
216
-	 * search for files by tag
217
-	 *
218
-	 * @param string|int $tag name or tag id
219
-	 * @param string $userId owner of the tags
220
-	 * @return Node[]
221
-	 */
222
-	public function searchByTag($tag, $userId) {
223
-		return $this->searchCommon('searchByTag', array($tag, $userId));
224
-	}
225
-
226
-	/**
227
-	 * @param string $method cache method
228
-	 * @param array $args call args
229
-	 * @return \OC\Files\Node\Node[]
230
-	 */
231
-	private function searchCommon($method, $args) {
232
-		$files = array();
233
-		$rootLength = strlen($this->path);
234
-		$mount = $this->root->getMount($this->path);
235
-		$storage = $mount->getStorage();
236
-		$internalPath = $mount->getInternalPath($this->path);
237
-		$internalPath = rtrim($internalPath, '/');
238
-		if ($internalPath !== '') {
239
-			$internalPath = $internalPath . '/';
240
-		}
241
-		$internalRootLength = strlen($internalPath);
242
-
243
-		$cache = $storage->getCache('');
244
-
245
-		$results = call_user_func_array(array($cache, $method), $args);
246
-		foreach ($results as $result) {
247
-			if ($internalRootLength === 0 or substr($result['path'], 0, $internalRootLength) === $internalPath) {
248
-				$result['internalPath'] = $result['path'];
249
-				$result['path'] = substr($result['path'], $internalRootLength);
250
-				$result['storage'] = $storage;
251
-				$files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
252
-			}
253
-		}
254
-
255
-		$mounts = $this->root->getMountsIn($this->path);
256
-		foreach ($mounts as $mount) {
257
-			$storage = $mount->getStorage();
258
-			if ($storage) {
259
-				$cache = $storage->getCache('');
260
-
261
-				$relativeMountPoint = substr($mount->getMountPoint(), $rootLength);
262
-				$results = call_user_func_array(array($cache, $method), $args);
263
-				foreach ($results as $result) {
264
-					$result['internalPath'] = $result['path'];
265
-					$result['path'] = $relativeMountPoint . $result['path'];
266
-					$result['storage'] = $storage;
267
-					$files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
268
-				}
269
-			}
270
-		}
271
-
272
-		return array_map(function (FileInfo $file) {
273
-			return $this->createNode($file->getPath(), $file);
274
-		}, $files);
275
-	}
276
-
277
-	/**
278
-	 * @param int $id
279
-	 * @return \OC\Files\Node\Node[]
280
-	 */
281
-	public function getById($id) {
282
-		$mountCache = $this->root->getUserMountCache();
283
-		if (strpos($this->getPath(), '/', 1) > 0) {
284
-			list(, $user) = explode('/', $this->getPath());
285
-		} else {
286
-			$user = null;
287
-		}
288
-		$mountsContainingFile = $mountCache->getMountsForFileId((int)$id, $user);
289
-		$mounts = $this->root->getMountsIn($this->path);
290
-		$mounts[] = $this->root->getMount($this->path);
291
-		/** @var IMountPoint[] $folderMounts */
292
-		$folderMounts = array_combine(array_map(function (IMountPoint $mountPoint) {
293
-			return $mountPoint->getMountPoint();
294
-		}, $mounts), $mounts);
295
-
296
-		/** @var ICachedMountInfo[] $mountsContainingFile */
297
-		$mountsContainingFile = array_values(array_filter($mountsContainingFile, function (ICachedMountInfo $cachedMountInfo) use ($folderMounts) {
298
-			return isset($folderMounts[$cachedMountInfo->getMountPoint()]);
299
-		}));
300
-
301
-		if (count($mountsContainingFile) === 0) {
302
-			return [];
303
-		}
304
-
305
-		// we only need to get the cache info once, since all mounts we found point to the same storage
306
-
307
-		$mount = $folderMounts[$mountsContainingFile[0]->getMountPoint()];
308
-		$cacheEntry = $mount->getStorage()->getCache()->get((int)$id);
309
-		if (!$cacheEntry) {
310
-			return [];
311
-		}
312
-		// cache jails will hide the "true" internal path
313
-		$internalPath = ltrim($mountsContainingFile[0]->getRootInternalPath() . '/' . $cacheEntry->getPath(), '/');
314
-
315
-		$nodes = array_map(function (ICachedMountInfo $cachedMountInfo) use ($cacheEntry, $folderMounts, $internalPath) {
316
-			$mount = $folderMounts[$cachedMountInfo->getMountPoint()];
317
-			$pathRelativeToMount = substr($internalPath, strlen($cachedMountInfo->getRootInternalPath()));
318
-			$pathRelativeToMount = ltrim($pathRelativeToMount, '/');
319
-			$absolutePath = $cachedMountInfo->getMountPoint() . $pathRelativeToMount;
320
-			return $this->root->createNode($absolutePath, new \OC\Files\FileInfo(
321
-				$absolutePath, $mount->getStorage(), $cacheEntry->getPath(), $cacheEntry, $mount,
322
-				\OC::$server->getUserManager()->get($mount->getStorage()->getOwner($pathRelativeToMount))
323
-			));
324
-		}, $mountsContainingFile);
325
-
326
-		return array_filter($nodes, function (Node $node) {
327
-			return $this->getRelativePath($node->getPath());
328
-		});
329
-	}
330
-
331
-	public function getFreeSpace() {
332
-		return $this->view->free_space($this->path);
333
-	}
334
-
335
-	public function delete() {
336
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
337
-			$this->sendHooks(array('preDelete'));
338
-			$fileInfo = $this->getFileInfo();
339
-			$this->view->rmdir($this->path);
340
-			$nonExisting = new NonExistingFolder($this->root, $this->view, $this->path, $fileInfo);
341
-			$this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
342
-			$this->exists = false;
343
-		} else {
344
-			throw new NotPermittedException('No delete permission for path');
345
-		}
346
-	}
347
-
348
-	/**
349
-	 * Add a suffix to the name in case the file exists
350
-	 *
351
-	 * @param string $name
352
-	 * @return string
353
-	 * @throws NotPermittedException
354
-	 */
355
-	public function getNonExistingName($name) {
356
-		$uniqueName = \OC_Helper::buildNotExistingFileNameForView($this->getPath(), $name, $this->view);
357
-		return trim($this->getRelativePath($uniqueName), '/');
358
-	}
359
-
360
-	/**
361
-	 * @param int $limit
362
-	 * @param int $offset
363
-	 * @return \OCP\Files\Node[]
364
-	 */
365
-	public function getRecent($limit, $offset = 0) {
366
-		$mimetypeLoader = \OC::$server->getMimeTypeLoader();
367
-		$mounts = $this->root->getMountsIn($this->path);
368
-		$mounts[] = $this->getMountPoint();
369
-
370
-		$mounts = array_filter($mounts, function (IMountPoint $mount) {
371
-			return $mount->getStorage();
372
-		});
373
-		$storageIds = array_map(function (IMountPoint $mount) {
374
-			return $mount->getStorage()->getCache()->getNumericStorageId();
375
-		}, $mounts);
376
-		/** @var IMountPoint[] $mountMap */
377
-		$mountMap = array_combine($storageIds, $mounts);
378
-		$folderMimetype = $mimetypeLoader->getId(FileInfo::MIMETYPE_FOLDER);
379
-
380
-		//todo look into options of filtering path based on storage id (only search in files/ for home storage, filter by share root for shared, etc)
381
-
382
-		$builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
383
-		$query = $builder
384
-			->select('f.*')
385
-			->from('filecache', 'f')
386
-			->andWhere($builder->expr()->in('f.storage', $builder->createNamedParameter($storageIds, IQueryBuilder::PARAM_INT_ARRAY)))
387
-			->andWhere($builder->expr()->orX(
388
-			// handle non empty folders separate
389
-				$builder->expr()->neq('f.mimetype', $builder->createNamedParameter($folderMimetype, IQueryBuilder::PARAM_INT)),
390
-				$builder->expr()->eq('f.size', new Literal(0))
391
-			))
392
-			->orderBy('f.mtime', 'DESC')
393
-			->setMaxResults($limit)
394
-			->setFirstResult($offset);
395
-
396
-		$result = $query->execute()->fetchAll();
397
-
398
-		$files = array_filter(array_map(function (array $entry) use ($mountMap, $mimetypeLoader) {
399
-			$mount = $mountMap[$entry['storage']];
400
-			$entry['internalPath'] = $entry['path'];
401
-			$entry['mimetype'] = $mimetypeLoader->getMimetypeById($entry['mimetype']);
402
-			$entry['mimepart'] = $mimetypeLoader->getMimetypeById($entry['mimepart']);
403
-			$path = $this->getAbsolutePath($mount, $entry['path']);
404
-			if (is_null($path)) {
405
-				return null;
406
-			}
407
-			$fileInfo = new \OC\Files\FileInfo($path, $mount->getStorage(), $entry['internalPath'], $entry, $mount);
408
-			return $this->root->createNode($fileInfo->getPath(), $fileInfo);
409
-		}, $result));
410
-
411
-		return array_values(array_filter($files, function (Node $node) {
412
-			$relative = $this->getRelativePath($node->getPath());
413
-			return $relative !== null && $relative !== '/';
414
-		}));
415
-	}
416
-
417
-	private function getAbsolutePath(IMountPoint $mount, $path) {
418
-		$storage = $mount->getStorage();
419
-		if ($storage->instanceOfStorage('\OC\Files\Storage\Wrapper\Jail')) {
420
-			/** @var \OC\Files\Storage\Wrapper\Jail $storage */
421
-			$jailRoot = $storage->getUnjailedPath('');
422
-			$rootLength = strlen($jailRoot) + 1;
423
-			if ($path === $jailRoot) {
424
-				return $mount->getMountPoint();
425
-			} else if (substr($path, 0, $rootLength) === $jailRoot . '/') {
426
-				return $mount->getMountPoint() . substr($path, $rootLength);
427
-			} else {
428
-				return null;
429
-			}
430
-		} else {
431
-			return $mount->getMountPoint() . $path;
432
-		}
433
-	}
39
+    /**
40
+     * Creates a Folder that represents a non-existing path
41
+     *
42
+     * @param string $path path
43
+     * @return string non-existing node class
44
+     */
45
+    protected function createNonExistingNode($path) {
46
+        return new NonExistingFolder($this->root, $this->view, $path);
47
+    }
48
+
49
+    /**
50
+     * @param string $path path relative to the folder
51
+     * @return string
52
+     * @throws \OCP\Files\NotPermittedException
53
+     */
54
+    public function getFullPath($path) {
55
+        if (!$this->isValidPath($path)) {
56
+            throw new NotPermittedException('Invalid path');
57
+        }
58
+        return $this->path . $this->normalizePath($path);
59
+    }
60
+
61
+    /**
62
+     * @param string $path
63
+     * @return string
64
+     */
65
+    public function getRelativePath($path) {
66
+        if ($this->path === '' or $this->path === '/') {
67
+            return $this->normalizePath($path);
68
+        }
69
+        if ($path === $this->path) {
70
+            return '/';
71
+        } else if (strpos($path, $this->path . '/') !== 0) {
72
+            return null;
73
+        } else {
74
+            $path = substr($path, strlen($this->path));
75
+            return $this->normalizePath($path);
76
+        }
77
+    }
78
+
79
+    /**
80
+     * check if a node is a (grand-)child of the folder
81
+     *
82
+     * @param \OC\Files\Node\Node $node
83
+     * @return bool
84
+     */
85
+    public function isSubNode($node) {
86
+        return strpos($node->getPath(), $this->path . '/') === 0;
87
+    }
88
+
89
+    /**
90
+     * get the content of this directory
91
+     *
92
+     * @throws \OCP\Files\NotFoundException
93
+     * @return Node[]
94
+     */
95
+    public function getDirectoryListing() {
96
+        $folderContent = $this->view->getDirectoryContent($this->path);
97
+
98
+        return array_map(function (FileInfo $info) {
99
+            if ($info->getMimetype() === 'httpd/unix-directory') {
100
+                return new Folder($this->root, $this->view, $info->getPath(), $info);
101
+            } else {
102
+                return new File($this->root, $this->view, $info->getPath(), $info);
103
+            }
104
+        }, $folderContent);
105
+    }
106
+
107
+    /**
108
+     * @param string $path
109
+     * @param FileInfo $info
110
+     * @return File|Folder
111
+     */
112
+    protected function createNode($path, FileInfo $info = null) {
113
+        if (is_null($info)) {
114
+            $isDir = $this->view->is_dir($path);
115
+        } else {
116
+            $isDir = $info->getType() === FileInfo::TYPE_FOLDER;
117
+        }
118
+        if ($isDir) {
119
+            return new Folder($this->root, $this->view, $path, $info);
120
+        } else {
121
+            return new File($this->root, $this->view, $path, $info);
122
+        }
123
+    }
124
+
125
+    /**
126
+     * Get the node at $path
127
+     *
128
+     * @param string $path
129
+     * @return \OC\Files\Node\Node
130
+     * @throws \OCP\Files\NotFoundException
131
+     */
132
+    public function get($path) {
133
+        return $this->root->get($this->getFullPath($path));
134
+    }
135
+
136
+    /**
137
+     * @param string $path
138
+     * @return bool
139
+     */
140
+    public function nodeExists($path) {
141
+        try {
142
+            $this->get($path);
143
+            return true;
144
+        } catch (NotFoundException $e) {
145
+            return false;
146
+        }
147
+    }
148
+
149
+    /**
150
+     * @param string $path
151
+     * @return \OC\Files\Node\Folder
152
+     * @throws \OCP\Files\NotPermittedException
153
+     */
154
+    public function newFolder($path) {
155
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
156
+            $fullPath = $this->getFullPath($path);
157
+            $nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
158
+            $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
159
+            $this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
160
+            $this->view->mkdir($fullPath);
161
+            $node = new Folder($this->root, $this->view, $fullPath);
162
+            $this->root->emit('\OC\Files', 'postWrite', array($node));
163
+            $this->root->emit('\OC\Files', 'postCreate', array($node));
164
+            return $node;
165
+        } else {
166
+            throw new NotPermittedException('No create permission for folder');
167
+        }
168
+    }
169
+
170
+    /**
171
+     * @param string $path
172
+     * @return \OC\Files\Node\File
173
+     * @throws \OCP\Files\NotPermittedException
174
+     */
175
+    public function newFile($path) {
176
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
177
+            $fullPath = $this->getFullPath($path);
178
+            $nonExisting = new NonExistingFile($this->root, $this->view, $fullPath);
179
+            $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
180
+            $this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
181
+            $this->view->touch($fullPath);
182
+            $node = new File($this->root, $this->view, $fullPath);
183
+            $this->root->emit('\OC\Files', 'postWrite', array($node));
184
+            $this->root->emit('\OC\Files', 'postCreate', array($node));
185
+            return $node;
186
+        } else {
187
+            throw new NotPermittedException('No create permission for path');
188
+        }
189
+    }
190
+
191
+    /**
192
+     * search for files with the name matching $query
193
+     *
194
+     * @param string|ISearchOperator $query
195
+     * @return \OC\Files\Node\Node[]
196
+     */
197
+    public function search($query) {
198
+        if (is_string($query)) {
199
+            return $this->searchCommon('search', array('%' . $query . '%'));
200
+        } else {
201
+            return $this->searchCommon('searchQuery', array($query));
202
+        }
203
+    }
204
+
205
+    /**
206
+     * search for files by mimetype
207
+     *
208
+     * @param string $mimetype
209
+     * @return Node[]
210
+     */
211
+    public function searchByMime($mimetype) {
212
+        return $this->searchCommon('searchByMime', array($mimetype));
213
+    }
214
+
215
+    /**
216
+     * search for files by tag
217
+     *
218
+     * @param string|int $tag name or tag id
219
+     * @param string $userId owner of the tags
220
+     * @return Node[]
221
+     */
222
+    public function searchByTag($tag, $userId) {
223
+        return $this->searchCommon('searchByTag', array($tag, $userId));
224
+    }
225
+
226
+    /**
227
+     * @param string $method cache method
228
+     * @param array $args call args
229
+     * @return \OC\Files\Node\Node[]
230
+     */
231
+    private function searchCommon($method, $args) {
232
+        $files = array();
233
+        $rootLength = strlen($this->path);
234
+        $mount = $this->root->getMount($this->path);
235
+        $storage = $mount->getStorage();
236
+        $internalPath = $mount->getInternalPath($this->path);
237
+        $internalPath = rtrim($internalPath, '/');
238
+        if ($internalPath !== '') {
239
+            $internalPath = $internalPath . '/';
240
+        }
241
+        $internalRootLength = strlen($internalPath);
242
+
243
+        $cache = $storage->getCache('');
244
+
245
+        $results = call_user_func_array(array($cache, $method), $args);
246
+        foreach ($results as $result) {
247
+            if ($internalRootLength === 0 or substr($result['path'], 0, $internalRootLength) === $internalPath) {
248
+                $result['internalPath'] = $result['path'];
249
+                $result['path'] = substr($result['path'], $internalRootLength);
250
+                $result['storage'] = $storage;
251
+                $files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
252
+            }
253
+        }
254
+
255
+        $mounts = $this->root->getMountsIn($this->path);
256
+        foreach ($mounts as $mount) {
257
+            $storage = $mount->getStorage();
258
+            if ($storage) {
259
+                $cache = $storage->getCache('');
260
+
261
+                $relativeMountPoint = substr($mount->getMountPoint(), $rootLength);
262
+                $results = call_user_func_array(array($cache, $method), $args);
263
+                foreach ($results as $result) {
264
+                    $result['internalPath'] = $result['path'];
265
+                    $result['path'] = $relativeMountPoint . $result['path'];
266
+                    $result['storage'] = $storage;
267
+                    $files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
268
+                }
269
+            }
270
+        }
271
+
272
+        return array_map(function (FileInfo $file) {
273
+            return $this->createNode($file->getPath(), $file);
274
+        }, $files);
275
+    }
276
+
277
+    /**
278
+     * @param int $id
279
+     * @return \OC\Files\Node\Node[]
280
+     */
281
+    public function getById($id) {
282
+        $mountCache = $this->root->getUserMountCache();
283
+        if (strpos($this->getPath(), '/', 1) > 0) {
284
+            list(, $user) = explode('/', $this->getPath());
285
+        } else {
286
+            $user = null;
287
+        }
288
+        $mountsContainingFile = $mountCache->getMountsForFileId((int)$id, $user);
289
+        $mounts = $this->root->getMountsIn($this->path);
290
+        $mounts[] = $this->root->getMount($this->path);
291
+        /** @var IMountPoint[] $folderMounts */
292
+        $folderMounts = array_combine(array_map(function (IMountPoint $mountPoint) {
293
+            return $mountPoint->getMountPoint();
294
+        }, $mounts), $mounts);
295
+
296
+        /** @var ICachedMountInfo[] $mountsContainingFile */
297
+        $mountsContainingFile = array_values(array_filter($mountsContainingFile, function (ICachedMountInfo $cachedMountInfo) use ($folderMounts) {
298
+            return isset($folderMounts[$cachedMountInfo->getMountPoint()]);
299
+        }));
300
+
301
+        if (count($mountsContainingFile) === 0) {
302
+            return [];
303
+        }
304
+
305
+        // we only need to get the cache info once, since all mounts we found point to the same storage
306
+
307
+        $mount = $folderMounts[$mountsContainingFile[0]->getMountPoint()];
308
+        $cacheEntry = $mount->getStorage()->getCache()->get((int)$id);
309
+        if (!$cacheEntry) {
310
+            return [];
311
+        }
312
+        // cache jails will hide the "true" internal path
313
+        $internalPath = ltrim($mountsContainingFile[0]->getRootInternalPath() . '/' . $cacheEntry->getPath(), '/');
314
+
315
+        $nodes = array_map(function (ICachedMountInfo $cachedMountInfo) use ($cacheEntry, $folderMounts, $internalPath) {
316
+            $mount = $folderMounts[$cachedMountInfo->getMountPoint()];
317
+            $pathRelativeToMount = substr($internalPath, strlen($cachedMountInfo->getRootInternalPath()));
318
+            $pathRelativeToMount = ltrim($pathRelativeToMount, '/');
319
+            $absolutePath = $cachedMountInfo->getMountPoint() . $pathRelativeToMount;
320
+            return $this->root->createNode($absolutePath, new \OC\Files\FileInfo(
321
+                $absolutePath, $mount->getStorage(), $cacheEntry->getPath(), $cacheEntry, $mount,
322
+                \OC::$server->getUserManager()->get($mount->getStorage()->getOwner($pathRelativeToMount))
323
+            ));
324
+        }, $mountsContainingFile);
325
+
326
+        return array_filter($nodes, function (Node $node) {
327
+            return $this->getRelativePath($node->getPath());
328
+        });
329
+    }
330
+
331
+    public function getFreeSpace() {
332
+        return $this->view->free_space($this->path);
333
+    }
334
+
335
+    public function delete() {
336
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
337
+            $this->sendHooks(array('preDelete'));
338
+            $fileInfo = $this->getFileInfo();
339
+            $this->view->rmdir($this->path);
340
+            $nonExisting = new NonExistingFolder($this->root, $this->view, $this->path, $fileInfo);
341
+            $this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
342
+            $this->exists = false;
343
+        } else {
344
+            throw new NotPermittedException('No delete permission for path');
345
+        }
346
+    }
347
+
348
+    /**
349
+     * Add a suffix to the name in case the file exists
350
+     *
351
+     * @param string $name
352
+     * @return string
353
+     * @throws NotPermittedException
354
+     */
355
+    public function getNonExistingName($name) {
356
+        $uniqueName = \OC_Helper::buildNotExistingFileNameForView($this->getPath(), $name, $this->view);
357
+        return trim($this->getRelativePath($uniqueName), '/');
358
+    }
359
+
360
+    /**
361
+     * @param int $limit
362
+     * @param int $offset
363
+     * @return \OCP\Files\Node[]
364
+     */
365
+    public function getRecent($limit, $offset = 0) {
366
+        $mimetypeLoader = \OC::$server->getMimeTypeLoader();
367
+        $mounts = $this->root->getMountsIn($this->path);
368
+        $mounts[] = $this->getMountPoint();
369
+
370
+        $mounts = array_filter($mounts, function (IMountPoint $mount) {
371
+            return $mount->getStorage();
372
+        });
373
+        $storageIds = array_map(function (IMountPoint $mount) {
374
+            return $mount->getStorage()->getCache()->getNumericStorageId();
375
+        }, $mounts);
376
+        /** @var IMountPoint[] $mountMap */
377
+        $mountMap = array_combine($storageIds, $mounts);
378
+        $folderMimetype = $mimetypeLoader->getId(FileInfo::MIMETYPE_FOLDER);
379
+
380
+        //todo look into options of filtering path based on storage id (only search in files/ for home storage, filter by share root for shared, etc)
381
+
382
+        $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
383
+        $query = $builder
384
+            ->select('f.*')
385
+            ->from('filecache', 'f')
386
+            ->andWhere($builder->expr()->in('f.storage', $builder->createNamedParameter($storageIds, IQueryBuilder::PARAM_INT_ARRAY)))
387
+            ->andWhere($builder->expr()->orX(
388
+            // handle non empty folders separate
389
+                $builder->expr()->neq('f.mimetype', $builder->createNamedParameter($folderMimetype, IQueryBuilder::PARAM_INT)),
390
+                $builder->expr()->eq('f.size', new Literal(0))
391
+            ))
392
+            ->orderBy('f.mtime', 'DESC')
393
+            ->setMaxResults($limit)
394
+            ->setFirstResult($offset);
395
+
396
+        $result = $query->execute()->fetchAll();
397
+
398
+        $files = array_filter(array_map(function (array $entry) use ($mountMap, $mimetypeLoader) {
399
+            $mount = $mountMap[$entry['storage']];
400
+            $entry['internalPath'] = $entry['path'];
401
+            $entry['mimetype'] = $mimetypeLoader->getMimetypeById($entry['mimetype']);
402
+            $entry['mimepart'] = $mimetypeLoader->getMimetypeById($entry['mimepart']);
403
+            $path = $this->getAbsolutePath($mount, $entry['path']);
404
+            if (is_null($path)) {
405
+                return null;
406
+            }
407
+            $fileInfo = new \OC\Files\FileInfo($path, $mount->getStorage(), $entry['internalPath'], $entry, $mount);
408
+            return $this->root->createNode($fileInfo->getPath(), $fileInfo);
409
+        }, $result));
410
+
411
+        return array_values(array_filter($files, function (Node $node) {
412
+            $relative = $this->getRelativePath($node->getPath());
413
+            return $relative !== null && $relative !== '/';
414
+        }));
415
+    }
416
+
417
+    private function getAbsolutePath(IMountPoint $mount, $path) {
418
+        $storage = $mount->getStorage();
419
+        if ($storage->instanceOfStorage('\OC\Files\Storage\Wrapper\Jail')) {
420
+            /** @var \OC\Files\Storage\Wrapper\Jail $storage */
421
+            $jailRoot = $storage->getUnjailedPath('');
422
+            $rootLength = strlen($jailRoot) + 1;
423
+            if ($path === $jailRoot) {
424
+                return $mount->getMountPoint();
425
+            } else if (substr($path, 0, $rootLength) === $jailRoot . '/') {
426
+                return $mount->getMountPoint() . substr($path, $rootLength);
427
+            } else {
428
+                return null;
429
+            }
430
+        } else {
431
+            return $mount->getMountPoint() . $path;
432
+        }
433
+    }
434 434
 }
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -55,7 +55,7 @@  discard block
 block discarded – undo
55 55
 		if (!$this->isValidPath($path)) {
56 56
 			throw new NotPermittedException('Invalid path');
57 57
 		}
58
-		return $this->path . $this->normalizePath($path);
58
+		return $this->path.$this->normalizePath($path);
59 59
 	}
60 60
 
61 61
 	/**
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
 		}
69 69
 		if ($path === $this->path) {
70 70
 			return '/';
71
-		} else if (strpos($path, $this->path . '/') !== 0) {
71
+		} else if (strpos($path, $this->path.'/') !== 0) {
72 72
 			return null;
73 73
 		} else {
74 74
 			$path = substr($path, strlen($this->path));
@@ -83,7 +83,7 @@  discard block
 block discarded – undo
83 83
 	 * @return bool
84 84
 	 */
85 85
 	public function isSubNode($node) {
86
-		return strpos($node->getPath(), $this->path . '/') === 0;
86
+		return strpos($node->getPath(), $this->path.'/') === 0;
87 87
 	}
88 88
 
89 89
 	/**
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
 	public function getDirectoryListing() {
96 96
 		$folderContent = $this->view->getDirectoryContent($this->path);
97 97
 
98
-		return array_map(function (FileInfo $info) {
98
+		return array_map(function(FileInfo $info) {
99 99
 			if ($info->getMimetype() === 'httpd/unix-directory') {
100 100
 				return new Folder($this->root, $this->view, $info->getPath(), $info);
101 101
 			} else {
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
 	 */
197 197
 	public function search($query) {
198 198
 		if (is_string($query)) {
199
-			return $this->searchCommon('search', array('%' . $query . '%'));
199
+			return $this->searchCommon('search', array('%'.$query.'%'));
200 200
 		} else {
201 201
 			return $this->searchCommon('searchQuery', array($query));
202 202
 		}
@@ -236,7 +236,7 @@  discard block
 block discarded – undo
236 236
 		$internalPath = $mount->getInternalPath($this->path);
237 237
 		$internalPath = rtrim($internalPath, '/');
238 238
 		if ($internalPath !== '') {
239
-			$internalPath = $internalPath . '/';
239
+			$internalPath = $internalPath.'/';
240 240
 		}
241 241
 		$internalRootLength = strlen($internalPath);
242 242
 
@@ -248,7 +248,7 @@  discard block
 block discarded – undo
248 248
 				$result['internalPath'] = $result['path'];
249 249
 				$result['path'] = substr($result['path'], $internalRootLength);
250 250
 				$result['storage'] = $storage;
251
-				$files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
251
+				$files[] = new \OC\Files\FileInfo($this->path.'/'.$result['path'], $storage, $result['internalPath'], $result, $mount);
252 252
 			}
253 253
 		}
254 254
 
@@ -262,14 +262,14 @@  discard block
 block discarded – undo
262 262
 				$results = call_user_func_array(array($cache, $method), $args);
263 263
 				foreach ($results as $result) {
264 264
 					$result['internalPath'] = $result['path'];
265
-					$result['path'] = $relativeMountPoint . $result['path'];
265
+					$result['path'] = $relativeMountPoint.$result['path'];
266 266
 					$result['storage'] = $storage;
267
-					$files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
267
+					$files[] = new \OC\Files\FileInfo($this->path.'/'.$result['path'], $storage, $result['internalPath'], $result, $mount);
268 268
 				}
269 269
 			}
270 270
 		}
271 271
 
272
-		return array_map(function (FileInfo $file) {
272
+		return array_map(function(FileInfo $file) {
273 273
 			return $this->createNode($file->getPath(), $file);
274 274
 		}, $files);
275 275
 	}
@@ -285,16 +285,16 @@  discard block
 block discarded – undo
285 285
 		} else {
286 286
 			$user = null;
287 287
 		}
288
-		$mountsContainingFile = $mountCache->getMountsForFileId((int)$id, $user);
288
+		$mountsContainingFile = $mountCache->getMountsForFileId((int) $id, $user);
289 289
 		$mounts = $this->root->getMountsIn($this->path);
290 290
 		$mounts[] = $this->root->getMount($this->path);
291 291
 		/** @var IMountPoint[] $folderMounts */
292
-		$folderMounts = array_combine(array_map(function (IMountPoint $mountPoint) {
292
+		$folderMounts = array_combine(array_map(function(IMountPoint $mountPoint) {
293 293
 			return $mountPoint->getMountPoint();
294 294
 		}, $mounts), $mounts);
295 295
 
296 296
 		/** @var ICachedMountInfo[] $mountsContainingFile */
297
-		$mountsContainingFile = array_values(array_filter($mountsContainingFile, function (ICachedMountInfo $cachedMountInfo) use ($folderMounts) {
297
+		$mountsContainingFile = array_values(array_filter($mountsContainingFile, function(ICachedMountInfo $cachedMountInfo) use ($folderMounts) {
298 298
 			return isset($folderMounts[$cachedMountInfo->getMountPoint()]);
299 299
 		}));
300 300
 
@@ -305,25 +305,25 @@  discard block
 block discarded – undo
305 305
 		// we only need to get the cache info once, since all mounts we found point to the same storage
306 306
 
307 307
 		$mount = $folderMounts[$mountsContainingFile[0]->getMountPoint()];
308
-		$cacheEntry = $mount->getStorage()->getCache()->get((int)$id);
308
+		$cacheEntry = $mount->getStorage()->getCache()->get((int) $id);
309 309
 		if (!$cacheEntry) {
310 310
 			return [];
311 311
 		}
312 312
 		// cache jails will hide the "true" internal path
313
-		$internalPath = ltrim($mountsContainingFile[0]->getRootInternalPath() . '/' . $cacheEntry->getPath(), '/');
313
+		$internalPath = ltrim($mountsContainingFile[0]->getRootInternalPath().'/'.$cacheEntry->getPath(), '/');
314 314
 
315
-		$nodes = array_map(function (ICachedMountInfo $cachedMountInfo) use ($cacheEntry, $folderMounts, $internalPath) {
315
+		$nodes = array_map(function(ICachedMountInfo $cachedMountInfo) use ($cacheEntry, $folderMounts, $internalPath) {
316 316
 			$mount = $folderMounts[$cachedMountInfo->getMountPoint()];
317 317
 			$pathRelativeToMount = substr($internalPath, strlen($cachedMountInfo->getRootInternalPath()));
318 318
 			$pathRelativeToMount = ltrim($pathRelativeToMount, '/');
319
-			$absolutePath = $cachedMountInfo->getMountPoint() . $pathRelativeToMount;
319
+			$absolutePath = $cachedMountInfo->getMountPoint().$pathRelativeToMount;
320 320
 			return $this->root->createNode($absolutePath, new \OC\Files\FileInfo(
321 321
 				$absolutePath, $mount->getStorage(), $cacheEntry->getPath(), $cacheEntry, $mount,
322 322
 				\OC::$server->getUserManager()->get($mount->getStorage()->getOwner($pathRelativeToMount))
323 323
 			));
324 324
 		}, $mountsContainingFile);
325 325
 
326
-		return array_filter($nodes, function (Node $node) {
326
+		return array_filter($nodes, function(Node $node) {
327 327
 			return $this->getRelativePath($node->getPath());
328 328
 		});
329 329
 	}
@@ -367,10 +367,10 @@  discard block
 block discarded – undo
367 367
 		$mounts = $this->root->getMountsIn($this->path);
368 368
 		$mounts[] = $this->getMountPoint();
369 369
 
370
-		$mounts = array_filter($mounts, function (IMountPoint $mount) {
370
+		$mounts = array_filter($mounts, function(IMountPoint $mount) {
371 371
 			return $mount->getStorage();
372 372
 		});
373
-		$storageIds = array_map(function (IMountPoint $mount) {
373
+		$storageIds = array_map(function(IMountPoint $mount) {
374 374
 			return $mount->getStorage()->getCache()->getNumericStorageId();
375 375
 		}, $mounts);
376 376
 		/** @var IMountPoint[] $mountMap */
@@ -395,7 +395,7 @@  discard block
 block discarded – undo
395 395
 
396 396
 		$result = $query->execute()->fetchAll();
397 397
 
398
-		$files = array_filter(array_map(function (array $entry) use ($mountMap, $mimetypeLoader) {
398
+		$files = array_filter(array_map(function(array $entry) use ($mountMap, $mimetypeLoader) {
399 399
 			$mount = $mountMap[$entry['storage']];
400 400
 			$entry['internalPath'] = $entry['path'];
401 401
 			$entry['mimetype'] = $mimetypeLoader->getMimetypeById($entry['mimetype']);
@@ -408,7 +408,7 @@  discard block
 block discarded – undo
408 408
 			return $this->root->createNode($fileInfo->getPath(), $fileInfo);
409 409
 		}, $result));
410 410
 
411
-		return array_values(array_filter($files, function (Node $node) {
411
+		return array_values(array_filter($files, function(Node $node) {
412 412
 			$relative = $this->getRelativePath($node->getPath());
413 413
 			return $relative !== null && $relative !== '/';
414 414
 		}));
@@ -422,13 +422,13 @@  discard block
 block discarded – undo
422 422
 			$rootLength = strlen($jailRoot) + 1;
423 423
 			if ($path === $jailRoot) {
424 424
 				return $mount->getMountPoint();
425
-			} else if (substr($path, 0, $rootLength) === $jailRoot . '/') {
426
-				return $mount->getMountPoint() . substr($path, $rootLength);
425
+			} else if (substr($path, 0, $rootLength) === $jailRoot.'/') {
426
+				return $mount->getMountPoint().substr($path, $rootLength);
427 427
 			} else {
428 428
 				return null;
429 429
 			}
430 430
 		} else {
431
-			return $mount->getMountPoint() . $path;
431
+			return $mount->getMountPoint().$path;
432 432
 		}
433 433
 	}
434 434
 }
Please login to merge, or discard this patch.
lib/public/Settings/IIconSection.php 2 patches
Doc Comments   +1 added lines patch added patch discarded remove patch
@@ -33,6 +33,7 @@
 block discarded – undo
33 33
 	 *
34 34
 	 * @returns string
35 35
 	 * @since 12
36
+	 * @return string
36 37
 	 */
37 38
 	public function getIcon();
38 39
 }
Please login to merge, or discard this patch.
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -27,12 +27,12 @@
 block discarded – undo
27 27
  * @since 12
28 28
  */
29 29
 interface IIconSection extends ISection {
30
-	/**
31
-	 * returns the relative path to an 16*16 icon describing the section.
32
-	 * e.g. '/core/img/places/files.svg'
33
-	 *
34
-	 * @returns string
35
-	 * @since 12
36
-	 */
37
-	public function getIcon();
30
+    /**
31
+     * returns the relative path to an 16*16 icon describing the section.
32
+     * e.g. '/core/img/places/files.svg'
33
+     *
34
+     * @returns string
35
+     * @since 12
36
+     */
37
+    public function getIcon();
38 38
 }
Please login to merge, or discard this patch.
apps/files_external/lib/Lib/Storage/FTP.php 4 patches
Doc Comments   +3 added lines patch added patch discarded remove patch
@@ -139,6 +139,9 @@
 block discarded – undo
139 139
 		return false;
140 140
 	}
141 141
 
142
+	/**
143
+	 * @param string $path
144
+	 */
142 145
 	public function writeBack($tmpFile, $path) {
143 146
 		$this->uploadFile($tmpFile, $path);
144 147
 		unlink($tmpFile);
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -93,8 +93,7 @@
 block discarded – undo
93 93
 	public function unlink($path) {
94 94
 		if ($this->is_dir($path)) {
95 95
 			return $this->rmdir($path);
96
-		}
97
-		else {
96
+		} else {
98 97
 			$url = $this->constructUrl($path);
99 98
 			$result = unlink($url);
100 99
 			clearstatcache(true, $url);
Please login to merge, or discard this patch.
Indentation   +109 added lines, -109 removed lines patch added patch discarded remove patch
@@ -37,122 +37,122 @@
 block discarded – undo
37 37
 use Icewind\Streams\RetryWrapper;
38 38
 
39 39
 class FTP extends StreamWrapper{
40
-	private $password;
41
-	private $user;
42
-	private $host;
43
-	private $secure;
44
-	private $root;
40
+    private $password;
41
+    private $user;
42
+    private $host;
43
+    private $secure;
44
+    private $root;
45 45
 
46
-	private static $tempFiles=array();
46
+    private static $tempFiles=array();
47 47
 
48
-	public function __construct($params) {
49
-		if (isset($params['host']) && isset($params['user']) && isset($params['password'])) {
50
-			$this->host=$params['host'];
51
-			$this->user=$params['user'];
52
-			$this->password=$params['password'];
53
-			if (isset($params['secure'])) {
54
-				$this->secure = $params['secure'];
55
-			} else {
56
-				$this->secure = false;
57
-			}
58
-			$this->root=isset($params['root'])?$params['root']:'/';
59
-			if ( ! $this->root || $this->root[0]!=='/') {
60
-				$this->root='/'.$this->root;
61
-			}
62
-			if (substr($this->root, -1) !== '/') {
63
-				$this->root .= '/';
64
-			}
65
-		} else {
66
-			throw new \Exception('Creating FTP storage failed');
67
-		}
48
+    public function __construct($params) {
49
+        if (isset($params['host']) && isset($params['user']) && isset($params['password'])) {
50
+            $this->host=$params['host'];
51
+            $this->user=$params['user'];
52
+            $this->password=$params['password'];
53
+            if (isset($params['secure'])) {
54
+                $this->secure = $params['secure'];
55
+            } else {
56
+                $this->secure = false;
57
+            }
58
+            $this->root=isset($params['root'])?$params['root']:'/';
59
+            if ( ! $this->root || $this->root[0]!=='/') {
60
+                $this->root='/'.$this->root;
61
+            }
62
+            if (substr($this->root, -1) !== '/') {
63
+                $this->root .= '/';
64
+            }
65
+        } else {
66
+            throw new \Exception('Creating FTP storage failed');
67
+        }
68 68
 		
69
-	}
69
+    }
70 70
 
71
-	public function getId(){
72
-		return 'ftp::' . $this->user . '@' . $this->host . '/' . $this->root;
73
-	}
71
+    public function getId(){
72
+        return 'ftp::' . $this->user . '@' . $this->host . '/' . $this->root;
73
+    }
74 74
 
75
-	/**
76
-	 * construct the ftp url
77
-	 * @param string $path
78
-	 * @return string
79
-	 */
80
-	public function constructUrl($path) {
81
-		$url='ftp';
82
-		if ($this->secure) {
83
-			$url.='s';
84
-		}
85
-		$url.='://'.urlencode($this->user).':'.urlencode($this->password).'@'.$this->host.$this->root.$path;
86
-		return $url;
87
-	}
75
+    /**
76
+     * construct the ftp url
77
+     * @param string $path
78
+     * @return string
79
+     */
80
+    public function constructUrl($path) {
81
+        $url='ftp';
82
+        if ($this->secure) {
83
+            $url.='s';
84
+        }
85
+        $url.='://'.urlencode($this->user).':'.urlencode($this->password).'@'.$this->host.$this->root.$path;
86
+        return $url;
87
+    }
88 88
 
89
-	/**
90
-	 * Unlinks file or directory
91
-	 * @param string $path
92
-	 */
93
-	public function unlink($path) {
94
-		if ($this->is_dir($path)) {
95
-			return $this->rmdir($path);
96
-		}
97
-		else {
98
-			$url = $this->constructUrl($path);
99
-			$result = unlink($url);
100
-			clearstatcache(true, $url);
101
-			return $result;
102
-		}
103
-	}
104
-	public function fopen($path,$mode) {
105
-		switch($mode) {
106
-			case 'r':
107
-			case 'rb':
108
-			case 'w':
109
-			case 'wb':
110
-			case 'a':
111
-			case 'ab':
112
-				//these are supported by the wrapper
113
-				$context = stream_context_create(array('ftp' => array('overwrite' => true)));
114
-				$handle = fopen($this->constructUrl($path), $mode, false, $context);
115
-				return RetryWrapper::wrap($handle);
116
-			case 'r+':
117
-			case 'w+':
118
-			case 'wb+':
119
-			case 'a+':
120
-			case 'x':
121
-			case 'x+':
122
-			case 'c':
123
-			case 'c+':
124
-				//emulate these
125
-				if (strrpos($path, '.')!==false) {
126
-					$ext=substr($path, strrpos($path, '.'));
127
-				} else {
128
-					$ext='';
129
-				}
130
-				$tmpFile=\OCP\Files::tmpFile($ext);
131
-				if ($this->file_exists($path)) {
132
-					$this->getFile($path, $tmpFile);
133
-				}
134
-				$handle = fopen($tmpFile, $mode);
135
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
136
-					$this->writeBack($tmpFile, $path);
137
-				});
138
-		}
139
-		return false;
140
-	}
89
+    /**
90
+     * Unlinks file or directory
91
+     * @param string $path
92
+     */
93
+    public function unlink($path) {
94
+        if ($this->is_dir($path)) {
95
+            return $this->rmdir($path);
96
+        }
97
+        else {
98
+            $url = $this->constructUrl($path);
99
+            $result = unlink($url);
100
+            clearstatcache(true, $url);
101
+            return $result;
102
+        }
103
+    }
104
+    public function fopen($path,$mode) {
105
+        switch($mode) {
106
+            case 'r':
107
+            case 'rb':
108
+            case 'w':
109
+            case 'wb':
110
+            case 'a':
111
+            case 'ab':
112
+                //these are supported by the wrapper
113
+                $context = stream_context_create(array('ftp' => array('overwrite' => true)));
114
+                $handle = fopen($this->constructUrl($path), $mode, false, $context);
115
+                return RetryWrapper::wrap($handle);
116
+            case 'r+':
117
+            case 'w+':
118
+            case 'wb+':
119
+            case 'a+':
120
+            case 'x':
121
+            case 'x+':
122
+            case 'c':
123
+            case 'c+':
124
+                //emulate these
125
+                if (strrpos($path, '.')!==false) {
126
+                    $ext=substr($path, strrpos($path, '.'));
127
+                } else {
128
+                    $ext='';
129
+                }
130
+                $tmpFile=\OCP\Files::tmpFile($ext);
131
+                if ($this->file_exists($path)) {
132
+                    $this->getFile($path, $tmpFile);
133
+                }
134
+                $handle = fopen($tmpFile, $mode);
135
+                return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
136
+                    $this->writeBack($tmpFile, $path);
137
+                });
138
+        }
139
+        return false;
140
+    }
141 141
 
142
-	public function writeBack($tmpFile, $path) {
143
-		$this->uploadFile($tmpFile, $path);
144
-		unlink($tmpFile);
145
-	}
142
+    public function writeBack($tmpFile, $path) {
143
+        $this->uploadFile($tmpFile, $path);
144
+        unlink($tmpFile);
145
+    }
146 146
 
147
-	/**
148
-	 * check if php-ftp is installed
149
-	 */
150
-	public static function checkDependencies() {
151
-		if (function_exists('ftp_login')) {
152
-			return(true);
153
-		} else {
154
-			return array('ftp');
155
-		}
156
-	}
147
+    /**
148
+     * check if php-ftp is installed
149
+     */
150
+    public static function checkDependencies() {
151
+        if (function_exists('ftp_login')) {
152
+            return(true);
153
+        } else {
154
+            return array('ftp');
155
+        }
156
+    }
157 157
 
158 158
 }
Please login to merge, or discard this patch.
Spacing   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -36,28 +36,28 @@  discard block
 block discarded – undo
36 36
 use Icewind\Streams\CallbackWrapper;
37 37
 use Icewind\Streams\RetryWrapper;
38 38
 
39
-class FTP extends StreamWrapper{
39
+class FTP extends StreamWrapper {
40 40
 	private $password;
41 41
 	private $user;
42 42
 	private $host;
43 43
 	private $secure;
44 44
 	private $root;
45 45
 
46
-	private static $tempFiles=array();
46
+	private static $tempFiles = array();
47 47
 
48 48
 	public function __construct($params) {
49 49
 		if (isset($params['host']) && isset($params['user']) && isset($params['password'])) {
50
-			$this->host=$params['host'];
51
-			$this->user=$params['user'];
52
-			$this->password=$params['password'];
50
+			$this->host = $params['host'];
51
+			$this->user = $params['user'];
52
+			$this->password = $params['password'];
53 53
 			if (isset($params['secure'])) {
54 54
 				$this->secure = $params['secure'];
55 55
 			} else {
56 56
 				$this->secure = false;
57 57
 			}
58
-			$this->root=isset($params['root'])?$params['root']:'/';
59
-			if ( ! $this->root || $this->root[0]!=='/') {
60
-				$this->root='/'.$this->root;
58
+			$this->root = isset($params['root']) ? $params['root'] : '/';
59
+			if (!$this->root || $this->root[0] !== '/') {
60
+				$this->root = '/'.$this->root;
61 61
 			}
62 62
 			if (substr($this->root, -1) !== '/') {
63 63
 				$this->root .= '/';
@@ -68,8 +68,8 @@  discard block
 block discarded – undo
68 68
 		
69 69
 	}
70 70
 
71
-	public function getId(){
72
-		return 'ftp::' . $this->user . '@' . $this->host . '/' . $this->root;
71
+	public function getId() {
72
+		return 'ftp::'.$this->user.'@'.$this->host.'/'.$this->root;
73 73
 	}
74 74
 
75 75
 	/**
@@ -78,11 +78,11 @@  discard block
 block discarded – undo
78 78
 	 * @return string
79 79
 	 */
80 80
 	public function constructUrl($path) {
81
-		$url='ftp';
81
+		$url = 'ftp';
82 82
 		if ($this->secure) {
83
-			$url.='s';
83
+			$url .= 's';
84 84
 		}
85
-		$url.='://'.urlencode($this->user).':'.urlencode($this->password).'@'.$this->host.$this->root.$path;
85
+		$url .= '://'.urlencode($this->user).':'.urlencode($this->password).'@'.$this->host.$this->root.$path;
86 86
 		return $url;
87 87
 	}
88 88
 
@@ -101,8 +101,8 @@  discard block
 block discarded – undo
101 101
 			return $result;
102 102
 		}
103 103
 	}
104
-	public function fopen($path,$mode) {
105
-		switch($mode) {
104
+	public function fopen($path, $mode) {
105
+		switch ($mode) {
106 106
 			case 'r':
107 107
 			case 'rb':
108 108
 			case 'w':
@@ -122,17 +122,17 @@  discard block
 block discarded – undo
122 122
 			case 'c':
123 123
 			case 'c+':
124 124
 				//emulate these
125
-				if (strrpos($path, '.')!==false) {
126
-					$ext=substr($path, strrpos($path, '.'));
125
+				if (strrpos($path, '.') !== false) {
126
+					$ext = substr($path, strrpos($path, '.'));
127 127
 				} else {
128
-					$ext='';
128
+					$ext = '';
129 129
 				}
130
-				$tmpFile=\OCP\Files::tmpFile($ext);
130
+				$tmpFile = \OCP\Files::tmpFile($ext);
131 131
 				if ($this->file_exists($path)) {
132 132
 					$this->getFile($path, $tmpFile);
133 133
 				}
134 134
 				$handle = fopen($tmpFile, $mode);
135
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
135
+				return CallbackWrapper::wrap($handle, null, null, function() use ($path, $tmpFile) {
136 136
 					$this->writeBack($tmpFile, $path);
137 137
 				});
138 138
 		}
Please login to merge, or discard this patch.
apps/files_external/lib/Lib/Storage/Swift.php 3 patches
Doc Comments   +3 added lines patch added patch discarded remove patch
@@ -616,6 +616,9 @@
 block discarded – undo
616 616
 		return $this->container;
617 617
 	}
618 618
 
619
+	/**
620
+	 * @param string $path
621
+	 */
619 622
 	public function writeBack($tmpFile, $path) {
620 623
 		$fileData = fopen($tmpFile, 'r');
621 624
 		$this->getContainer()->uploadObject($path, $fileData);
Please login to merge, or discard this patch.
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -163,7 +163,7 @@  discard block
 block discarded – undo
163 163
 			throw new \Exception("API Key or password, Username, Bucket and Region have to be configured.");
164 164
 		}
165 165
 
166
-		$this->id = 'swift::' . $params['user'] . md5($params['bucket']);
166
+		$this->id = 'swift::'.$params['user'].md5($params['bucket']);
167 167
 
168 168
 		$bucketUrl = Url::factory($params['bucket']);
169 169
 		if ($bucketUrl->isAbsolute()) {
@@ -236,16 +236,16 @@  discard block
 block discarded – undo
236 236
 				continue;
237 237
 			}
238 238
 
239
-			if ($this->is_dir($path . '/' . $file)) {
240
-				$this->rmdir($path . '/' . $file);
239
+			if ($this->is_dir($path.'/'.$file)) {
240
+				$this->rmdir($path.'/'.$file);
241 241
 			} else {
242
-				$this->unlink($path . '/' . $file);
242
+				$this->unlink($path.'/'.$file);
243 243
 			}
244 244
 		}
245 245
 
246 246
 		try {
247
-			$this->getContainer()->dataObject()->setName($path . '/')->delete();
248
-			$this->objectCache->remove($path . '/');
247
+			$this->getContainer()->dataObject()->setName($path.'/')->delete();
248
+			$this->objectCache->remove($path.'/');
249 249
 		} catch (Exceptions\DeleteError $e) {
250 250
 			\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
251 251
 			return false;
@@ -326,7 +326,7 @@  discard block
 block discarded – undo
326 326
 		}
327 327
 
328 328
 		$stat = array();
329
-		$stat['size'] = (int)$object->getContentLength();
329
+		$stat['size'] = (int) $object->getContentLength();
330 330
 		$stat['mtime'] = $mtime;
331 331
 		$stat['atime'] = time();
332 332
 		return $stat;
@@ -358,7 +358,7 @@  discard block
 block discarded – undo
358 358
 		try {
359 359
 			$this->getContainer()->dataObject()->setName($path)->delete();
360 360
 			$this->objectCache->remove($path);
361
-			$this->objectCache->remove($path . '/');
361
+			$this->objectCache->remove($path.'/');
362 362
 		} catch (ClientErrorResponseException $e) {
363 363
 			if ($e->getResponse()->getStatusCode() !== 404) {
364 364
 				\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
@@ -387,8 +387,8 @@  discard block
 block discarded – undo
387 387
 					$streamInterface = $streamFactory->fromRequest($client->get($c->getUrl($path)));
388 388
 					$streamInterface->rewind();
389 389
 					$stream = $streamInterface->getStream();
390
-					stream_context_set_option($stream, 'swift','content', $streamInterface);
391
-					if(!strrpos($streamInterface
390
+					stream_context_set_option($stream, 'swift', 'content', $streamInterface);
391
+					if (!strrpos($streamInterface
392 392
 						->getMetaData('wrapper_data')[0], '404 Not Found')) {
393 393
 						return $stream;
394 394
 					}
@@ -422,7 +422,7 @@  discard block
 block discarded – undo
422 422
 					file_put_contents($tmpFile, $source);
423 423
 				}
424 424
 				$handle = fopen($tmpFile, $mode);
425
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
425
+				return CallbackWrapper::wrap($handle, null, null, function() use ($path, $tmpFile) {
426 426
 					$this->writeBack($tmpFile, $path);
427 427
 				});
428 428
 		}
@@ -469,10 +469,10 @@  discard block
 block discarded – undo
469 469
 
470 470
 			try {
471 471
 				$source = $this->fetchObject($path1);
472
-				$source->copy($this->bucket . '/' . $path2);
472
+				$source->copy($this->bucket.'/'.$path2);
473 473
 				// invalidate target object to force repopulation on fetch
474 474
 				$this->objectCache->remove($path2);
475
-				$this->objectCache->remove($path2 . '/');
475
+				$this->objectCache->remove($path2.'/');
476 476
 			} catch (ClientErrorResponseException $e) {
477 477
 				\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
478 478
 				return false;
@@ -484,11 +484,11 @@  discard block
 block discarded – undo
484 484
 			$this->unlink($path2);
485 485
 
486 486
 			try {
487
-				$source = $this->fetchObject($path1 . '/');
488
-				$source->copy($this->bucket . '/' . $path2 . '/');
487
+				$source = $this->fetchObject($path1.'/');
488
+				$source->copy($this->bucket.'/'.$path2.'/');
489 489
 				// invalidate target object to force repopulation on fetch
490 490
 				$this->objectCache->remove($path2);
491
-				$this->objectCache->remove($path2 . '/');
491
+				$this->objectCache->remove($path2.'/');
492 492
 			} catch (ClientErrorResponseException $e) {
493 493
 				\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
494 494
 				return false;
@@ -500,8 +500,8 @@  discard block
 block discarded – undo
500 500
 					continue;
501 501
 				}
502 502
 
503
-				$source = $path1 . '/' . $file;
504
-				$target = $path2 . '/' . $file;
503
+				$source = $path1.'/'.$file;
504
+				$target = $path2.'/'.$file;
505 505
 				$this->copy($source, $target);
506 506
 			}
507 507
 
@@ -635,7 +635,7 @@  discard block
 block discarded – undo
635 635
 			$path = '';
636 636
 		}
637 637
 		$cachedContent = $this->getCache()->getFolderContents($path);
638
-		$cachedNames = array_map(function ($content) {
638
+		$cachedNames = array_map(function($content) {
639 639
 			return $content['name'];
640 640
 		}, $cachedContent);
641 641
 		sort($cachedNames);
Please login to merge, or discard this patch.
Indentation   +596 added lines, -596 removed lines patch added patch discarded remove patch
@@ -48,601 +48,601 @@
 block discarded – undo
48 48
 
49 49
 class Swift extends \OC\Files\Storage\Common {
50 50
 
51
-	/**
52
-	 * @var \OpenCloud\ObjectStore\Service
53
-	 */
54
-	private $connection;
55
-	/**
56
-	 * @var \OpenCloud\ObjectStore\Resource\Container
57
-	 */
58
-	private $container;
59
-	/**
60
-	 * @var \OpenCloud\OpenStack
61
-	 */
62
-	private $anchor;
63
-	/**
64
-	 * @var string
65
-	 */
66
-	private $bucket;
67
-	/**
68
-	 * Connection parameters
69
-	 *
70
-	 * @var array
71
-	 */
72
-	private $params;
73
-
74
-	/** @var string  */
75
-	private $id;
76
-
77
-	/**
78
-	 * Key value cache mapping path to data object. Maps path to
79
-	 * \OpenCloud\OpenStack\ObjectStorage\Resource\DataObject for existing
80
-	 * paths and path to false for not existing paths.
81
-	 * @var \OCP\ICache
82
-	 */
83
-	private $objectCache;
84
-
85
-	/**
86
-	 * @param string $path
87
-	 */
88
-	private function normalizePath($path) {
89
-		$path = trim($path, '/');
90
-
91
-		if (!$path) {
92
-			$path = '.';
93
-		}
94
-
95
-		$path = str_replace('#', '%23', $path);
96
-
97
-		return $path;
98
-	}
99
-
100
-	const SUBCONTAINER_FILE = '.subcontainers';
101
-
102
-	/**
103
-	 * translate directory path to container name
104
-	 *
105
-	 * @param string $path
106
-	 * @return string
107
-	 */
108
-
109
-	/**
110
-	 * Fetches an object from the API.
111
-	 * If the object is cached already or a
112
-	 * failed "doesn't exist" response was cached,
113
-	 * that one will be returned.
114
-	 *
115
-	 * @param string $path
116
-	 * @return \OpenCloud\ObjectStore\Resource\DataObject|bool object
117
-	 * or false if the object did not exist
118
-	 */
119
-	private function fetchObject($path) {
120
-		if ($this->objectCache->hasKey($path)) {
121
-			// might be "false" if object did not exist from last check
122
-			return $this->objectCache->get($path);
123
-		}
124
-		try {
125
-			$object = $this->getContainer()->getPartialObject($path);
126
-			$this->objectCache->set($path, $object);
127
-			return $object;
128
-		} catch (ClientErrorResponseException $e) {
129
-			// this exception happens when the object does not exist, which
130
-			// is expected in most cases
131
-			$this->objectCache->set($path, false);
132
-			return false;
133
-		} catch (ClientErrorResponseException $e) {
134
-			// Expected response is "404 Not Found", so only log if it isn't
135
-			if ($e->getResponse()->getStatusCode() !== 404) {
136
-				\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
137
-			}
138
-			return false;
139
-		}
140
-	}
141
-
142
-	/**
143
-	 * Returns whether the given path exists.
144
-	 *
145
-	 * @param string $path
146
-	 *
147
-	 * @return bool true if the object exist, false otherwise
148
-	 */
149
-	private function doesObjectExist($path) {
150
-		return $this->fetchObject($path) !== false;
151
-	}
152
-
153
-	public function __construct($params) {
154
-		if ((empty($params['key']) and empty($params['password']))
155
-			or empty($params['user']) or empty($params['bucket'])
156
-			or empty($params['region'])
157
-		) {
158
-			throw new \Exception("API Key or password, Username, Bucket and Region have to be configured.");
159
-		}
160
-
161
-		$this->id = 'swift::' . $params['user'] . md5($params['bucket']);
162
-
163
-		$bucketUrl = Url::factory($params['bucket']);
164
-		if ($bucketUrl->isAbsolute()) {
165
-			$this->bucket = end(($bucketUrl->getPathSegments()));
166
-			$params['endpoint_url'] = $bucketUrl->addPath('..')->normalizePath();
167
-		} else {
168
-			$this->bucket = $params['bucket'];
169
-		}
170
-
171
-		if (empty($params['url'])) {
172
-			$params['url'] = 'https://identity.api.rackspacecloud.com/v2.0/';
173
-		}
174
-
175
-		if (empty($params['service_name'])) {
176
-			$params['service_name'] = 'cloudFiles';
177
-		}
178
-
179
-		$this->params = $params;
180
-		// FIXME: private class...
181
-		$this->objectCache = new \OC\Cache\CappedMemoryCache();
182
-	}
183
-
184
-	public function mkdir($path) {
185
-		$path = $this->normalizePath($path);
186
-
187
-		if ($this->is_dir($path)) {
188
-			return false;
189
-		}
190
-
191
-		if ($path !== '.') {
192
-			$path .= '/';
193
-		}
194
-
195
-		try {
196
-			$customHeaders = array('content-type' => 'httpd/unix-directory');
197
-			$metadataHeaders = DataObject::stockHeaders(array());
198
-			$allHeaders = $customHeaders + $metadataHeaders;
199
-			$this->getContainer()->uploadObject($path, '', $allHeaders);
200
-			// invalidate so that the next access gets the real object
201
-			// with all properties
202
-			$this->objectCache->remove($path);
203
-		} catch (Exceptions\CreateUpdateError $e) {
204
-			\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
205
-			return false;
206
-		}
207
-
208
-		return true;
209
-	}
210
-
211
-	public function file_exists($path) {
212
-		$path = $this->normalizePath($path);
213
-
214
-		if ($path !== '.' && $this->is_dir($path)) {
215
-			$path .= '/';
216
-		}
217
-
218
-		return $this->doesObjectExist($path);
219
-	}
220
-
221
-	public function rmdir($path) {
222
-		$path = $this->normalizePath($path);
223
-
224
-		if (!$this->is_dir($path) || !$this->isDeletable($path)) {
225
-			return false;
226
-		}
227
-
228
-		$dh = $this->opendir($path);
229
-		while ($file = readdir($dh)) {
230
-			if (\OC\Files\Filesystem::isIgnoredDir($file)) {
231
-				continue;
232
-			}
233
-
234
-			if ($this->is_dir($path . '/' . $file)) {
235
-				$this->rmdir($path . '/' . $file);
236
-			} else {
237
-				$this->unlink($path . '/' . $file);
238
-			}
239
-		}
240
-
241
-		try {
242
-			$this->getContainer()->dataObject()->setName($path . '/')->delete();
243
-			$this->objectCache->remove($path . '/');
244
-		} catch (Exceptions\DeleteError $e) {
245
-			\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
246
-			return false;
247
-		}
248
-
249
-		return true;
250
-	}
251
-
252
-	public function opendir($path) {
253
-		$path = $this->normalizePath($path);
254
-
255
-		if ($path === '.') {
256
-			$path = '';
257
-		} else {
258
-			$path .= '/';
259
-		}
260
-
261
-		$path = str_replace('%23', '#', $path); // the prefix is sent as a query param, so revert the encoding of #
262
-
263
-		try {
264
-			$files = array();
265
-			/** @var OpenCloud\Common\Collection $objects */
266
-			$objects = $this->getContainer()->objectList(array(
267
-				'prefix' => $path,
268
-				'delimiter' => '/'
269
-			));
270
-
271
-			/** @var OpenCloud\ObjectStore\Resource\DataObject $object */
272
-			foreach ($objects as $object) {
273
-				$file = basename($object->getName());
274
-				if ($file !== basename($path) && $file !== '.') {
275
-					$files[] = $file;
276
-				}
277
-			}
278
-
279
-			return IteratorDirectory::wrap($files);
280
-		} catch (\Exception $e) {
281
-			\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
282
-			return false;
283
-		}
284
-
285
-	}
286
-
287
-	public function stat($path) {
288
-		$path = $this->normalizePath($path);
289
-
290
-		if ($path === '.') {
291
-			$path = '';
292
-		} else if ($this->is_dir($path)) {
293
-			$path .= '/';
294
-		}
295
-
296
-		try {
297
-			/** @var DataObject $object */
298
-			$object = $this->fetchObject($path);
299
-			if (!$object) {
300
-				return false;
301
-			}
302
-		} catch (ClientErrorResponseException $e) {
303
-			\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
304
-			return false;
305
-		}
306
-
307
-		$dateTime = \DateTime::createFromFormat(\DateTime::RFC1123, $object->getLastModified());
308
-		if ($dateTime !== false) {
309
-			$mtime = $dateTime->getTimestamp();
310
-		} else {
311
-			$mtime = null;
312
-		}
313
-		$objectMetadata = $object->getMetadata();
314
-		$metaTimestamp = $objectMetadata->getProperty('timestamp');
315
-		if (isset($metaTimestamp)) {
316
-			$mtime = $metaTimestamp;
317
-		}
318
-
319
-		if (!empty($mtime)) {
320
-			$mtime = floor($mtime);
321
-		}
322
-
323
-		$stat = array();
324
-		$stat['size'] = (int)$object->getContentLength();
325
-		$stat['mtime'] = $mtime;
326
-		$stat['atime'] = time();
327
-		return $stat;
328
-	}
329
-
330
-	public function filetype($path) {
331
-		$path = $this->normalizePath($path);
332
-
333
-		if ($path !== '.' && $this->doesObjectExist($path)) {
334
-			return 'file';
335
-		}
336
-
337
-		if ($path !== '.') {
338
-			$path .= '/';
339
-		}
340
-
341
-		if ($this->doesObjectExist($path)) {
342
-			return 'dir';
343
-		}
344
-	}
345
-
346
-	public function unlink($path) {
347
-		$path = $this->normalizePath($path);
348
-
349
-		if ($this->is_dir($path)) {
350
-			return $this->rmdir($path);
351
-		}
352
-
353
-		try {
354
-			$this->getContainer()->dataObject()->setName($path)->delete();
355
-			$this->objectCache->remove($path);
356
-			$this->objectCache->remove($path . '/');
357
-		} catch (ClientErrorResponseException $e) {
358
-			if ($e->getResponse()->getStatusCode() !== 404) {
359
-				\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
360
-			}
361
-			return false;
362
-		}
363
-
364
-		return true;
365
-	}
366
-
367
-	public function fopen($path, $mode) {
368
-		$path = $this->normalizePath($path);
369
-
370
-		switch ($mode) {
371
-			case 'a':
372
-			case 'ab':
373
-			case 'a+':
374
-				return false;
375
-			case 'r':
376
-			case 'rb':
377
-				try {
378
-					$c = $this->getContainer();
379
-					$streamFactory = new \Guzzle\Stream\PhpStreamRequestFactory();
380
-					/** @var \OpenCloud\Common\Http\Client $client */
381
-					$client = $c->getClient();
382
-					$streamInterface = $streamFactory->fromRequest($client->get($c->getUrl($path)));
383
-					$streamInterface->rewind();
384
-					$stream = $streamInterface->getStream();
385
-					stream_context_set_option($stream, 'swift','content', $streamInterface);
386
-					if(!strrpos($streamInterface
387
-						->getMetaData('wrapper_data')[0], '404 Not Found')) {
388
-						return $stream;
389
-					}
390
-					return false;
391
-				} catch (\Guzzle\Http\Exception\BadResponseException $e) {
392
-					\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
393
-					return false;
394
-				}
395
-			case 'w':
396
-			case 'wb':
397
-			case 'r+':
398
-			case 'w+':
399
-			case 'wb+':
400
-			case 'x':
401
-			case 'x+':
402
-			case 'c':
403
-			case 'c+':
404
-				if (strrpos($path, '.') !== false) {
405
-					$ext = substr($path, strrpos($path, '.'));
406
-				} else {
407
-					$ext = '';
408
-				}
409
-				$tmpFile = \OCP\Files::tmpFile($ext);
410
-				// Fetch existing file if required
411
-				if ($mode[0] !== 'w' && $this->file_exists($path)) {
412
-					if ($mode[0] === 'x') {
413
-						// File cannot already exist
414
-						return false;
415
-					}
416
-					$source = $this->fopen($path, 'r');
417
-					file_put_contents($tmpFile, $source);
418
-				}
419
-				$handle = fopen($tmpFile, $mode);
420
-				return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
421
-					$this->writeBack($tmpFile, $path);
422
-				});
423
-		}
424
-	}
425
-
426
-	public function touch($path, $mtime = null) {
427
-		$path = $this->normalizePath($path);
428
-		if (is_null($mtime)) {
429
-			$mtime = time();
430
-		}
431
-		$metadata = array('timestamp' => $mtime);
432
-		if ($this->file_exists($path)) {
433
-			if ($this->is_dir($path) && $path !== '.') {
434
-				$path .= '/';
435
-			}
436
-
437
-			$object = $this->fetchObject($path);
438
-			if ($object->saveMetadata($metadata)) {
439
-				// invalidate target object to force repopulation on fetch
440
-				$this->objectCache->remove($path);
441
-			}
442
-			return true;
443
-		} else {
444
-			$mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
445
-			$customHeaders = array('content-type' => $mimeType);
446
-			$metadataHeaders = DataObject::stockHeaders($metadata);
447
-			$allHeaders = $customHeaders + $metadataHeaders;
448
-			$this->getContainer()->uploadObject($path, '', $allHeaders);
449
-			// invalidate target object to force repopulation on fetch
450
-			$this->objectCache->remove($path);
451
-			return true;
452
-		}
453
-	}
454
-
455
-	public function copy($path1, $path2) {
456
-		$path1 = $this->normalizePath($path1);
457
-		$path2 = $this->normalizePath($path2);
458
-
459
-		$fileType = $this->filetype($path1);
460
-		if ($fileType === 'file') {
461
-
462
-			// make way
463
-			$this->unlink($path2);
464
-
465
-			try {
466
-				$source = $this->fetchObject($path1);
467
-				$source->copy($this->bucket . '/' . $path2);
468
-				// invalidate target object to force repopulation on fetch
469
-				$this->objectCache->remove($path2);
470
-				$this->objectCache->remove($path2 . '/');
471
-			} catch (ClientErrorResponseException $e) {
472
-				\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
473
-				return false;
474
-			}
475
-
476
-		} else if ($fileType === 'dir') {
477
-
478
-			// make way
479
-			$this->unlink($path2);
480
-
481
-			try {
482
-				$source = $this->fetchObject($path1 . '/');
483
-				$source->copy($this->bucket . '/' . $path2 . '/');
484
-				// invalidate target object to force repopulation on fetch
485
-				$this->objectCache->remove($path2);
486
-				$this->objectCache->remove($path2 . '/');
487
-			} catch (ClientErrorResponseException $e) {
488
-				\OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
489
-				return false;
490
-			}
491
-
492
-			$dh = $this->opendir($path1);
493
-			while ($file = readdir($dh)) {
494
-				if (\OC\Files\Filesystem::isIgnoredDir($file)) {
495
-					continue;
496
-				}
497
-
498
-				$source = $path1 . '/' . $file;
499
-				$target = $path2 . '/' . $file;
500
-				$this->copy($source, $target);
501
-			}
502
-
503
-		} else {
504
-			//file does not exist
505
-			return false;
506
-		}
507
-
508
-		return true;
509
-	}
510
-
511
-	public function rename($path1, $path2) {
512
-		$path1 = $this->normalizePath($path1);
513
-		$path2 = $this->normalizePath($path2);
514
-
515
-		$fileType = $this->filetype($path1);
516
-
517
-		if ($fileType === 'dir' || $fileType === 'file') {
518
-			// copy
519
-			if ($this->copy($path1, $path2) === false) {
520
-				return false;
521
-			}
522
-
523
-			// cleanup
524
-			if ($this->unlink($path1) === false) {
525
-				$this->unlink($path2);
526
-				return false;
527
-			}
528
-
529
-			return true;
530
-		}
531
-
532
-		return false;
533
-	}
534
-
535
-	public function getId() {
536
-		return $this->id;
537
-	}
538
-
539
-	/**
540
-	 * Returns the connection
541
-	 *
542
-	 * @return OpenCloud\ObjectStore\Service connected client
543
-	 * @throws \Exception if connection could not be made
544
-	 */
545
-	public function getConnection() {
546
-		if (!is_null($this->connection)) {
547
-			return $this->connection;
548
-		}
549
-
550
-		$settings = array(
551
-			'username' => $this->params['user'],
552
-		);
553
-
554
-		if (!empty($this->params['password'])) {
555
-			$settings['password'] = $this->params['password'];
556
-		} else if (!empty($this->params['key'])) {
557
-			$settings['apiKey'] = $this->params['key'];
558
-		}
559
-
560
-		if (!empty($this->params['tenant'])) {
561
-			$settings['tenantName'] = $this->params['tenant'];
562
-		}
563
-
564
-		if (!empty($this->params['timeout'])) {
565
-			$settings['timeout'] = $this->params['timeout'];
566
-		}
567
-
568
-		if (isset($settings['apiKey'])) {
569
-			$this->anchor = new Rackspace($this->params['url'], $settings);
570
-		} else {
571
-			$this->anchor = new OpenStack($this->params['url'], $settings);
572
-		}
573
-
574
-		$connection = $this->anchor->objectStoreService($this->params['service_name'], $this->params['region']);
575
-
576
-		if (!empty($this->params['endpoint_url'])) {
577
-			$endpoint = $connection->getEndpoint();
578
-			$endpoint->setPublicUrl($this->params['endpoint_url']);
579
-			$endpoint->setPrivateUrl($this->params['endpoint_url']);
580
-			$connection->setEndpoint($endpoint);
581
-		}
582
-
583
-		$this->connection = $connection;
584
-
585
-		return $this->connection;
586
-	}
587
-
588
-	/**
589
-	 * Returns the initialized object store container.
590
-	 *
591
-	 * @return OpenCloud\ObjectStore\Resource\Container
592
-	 */
593
-	public function getContainer() {
594
-		if (!is_null($this->container)) {
595
-			return $this->container;
596
-		}
597
-
598
-		try {
599
-			$this->container = $this->getConnection()->getContainer($this->bucket);
600
-		} catch (ClientErrorResponseException $e) {
601
-			$this->container = $this->getConnection()->createContainer($this->bucket);
602
-		}
603
-
604
-		if (!$this->file_exists('.')) {
605
-			$this->mkdir('.');
606
-		}
607
-
608
-		return $this->container;
609
-	}
610
-
611
-	public function writeBack($tmpFile, $path) {
612
-		$fileData = fopen($tmpFile, 'r');
613
-		$this->getContainer()->uploadObject($path, $fileData);
614
-		// invalidate target object to force repopulation on fetch
615
-		$this->objectCache->remove($path);
616
-		unlink($tmpFile);
617
-	}
618
-
619
-	public function hasUpdated($path, $time) {
620
-		if ($this->is_file($path)) {
621
-			return parent::hasUpdated($path, $time);
622
-		}
623
-		$path = $this->normalizePath($path);
624
-		$dh = $this->opendir($path);
625
-		$content = array();
626
-		while (($file = readdir($dh)) !== false) {
627
-			$content[] = $file;
628
-		}
629
-		if ($path === '.') {
630
-			$path = '';
631
-		}
632
-		$cachedContent = $this->getCache()->getFolderContents($path);
633
-		$cachedNames = array_map(function ($content) {
634
-			return $content['name'];
635
-		}, $cachedContent);
636
-		sort($cachedNames);
637
-		sort($content);
638
-		return $cachedNames !== $content;
639
-	}
640
-
641
-	/**
642
-	 * check if curl is installed
643
-	 */
644
-	public static function checkDependencies() {
645
-		return true;
646
-	}
51
+    /**
52
+     * @var \OpenCloud\ObjectStore\Service
53
+     */
54
+    private $connection;
55
+    /**
56
+     * @var \OpenCloud\ObjectStore\Resource\Container
57
+     */
58
+    private $container;
59
+    /**
60
+     * @var \OpenCloud\OpenStack
61
+     */
62
+    private $anchor;
63
+    /**
64
+     * @var string
65
+     */
66
+    private $bucket;
67
+    /**
68
+     * Connection parameters
69
+     *
70
+     * @var array
71
+     */
72
+    private $params;
73
+
74
+    /** @var string  */
75
+    private $id;
76
+
77
+    /**
78
+     * Key value cache mapping path to data object. Maps path to
79
+     * \OpenCloud\OpenStack\ObjectStorage\Resource\DataObject for existing
80
+     * paths and path to false for not existing paths.
81
+     * @var \OCP\ICache
82
+     */
83
+    private $objectCache;
84
+
85
+    /**
86
+     * @param string $path
87
+     */
88
+    private function normalizePath($path) {
89
+        $path = trim($path, '/');
90
+
91
+        if (!$path) {
92
+            $path = '.';
93
+        }
94
+
95
+        $path = str_replace('#', '%23', $path);
96
+
97
+        return $path;
98
+    }
99
+
100
+    const SUBCONTAINER_FILE = '.subcontainers';
101
+
102
+    /**
103
+     * translate directory path to container name
104
+     *
105
+     * @param string $path
106
+     * @return string
107
+     */
108
+
109
+    /**
110
+     * Fetches an object from the API.
111
+     * If the object is cached already or a
112
+     * failed "doesn't exist" response was cached,
113
+     * that one will be returned.
114
+     *
115
+     * @param string $path
116
+     * @return \OpenCloud\ObjectStore\Resource\DataObject|bool object
117
+     * or false if the object did not exist
118
+     */
119
+    private function fetchObject($path) {
120
+        if ($this->objectCache->hasKey($path)) {
121
+            // might be "false" if object did not exist from last check
122
+            return $this->objectCache->get($path);
123
+        }
124
+        try {
125
+            $object = $this->getContainer()->getPartialObject($path);
126
+            $this->objectCache->set($path, $object);
127
+            return $object;
128
+        } catch (ClientErrorResponseException $e) {
129
+            // this exception happens when the object does not exist, which
130
+            // is expected in most cases
131
+            $this->objectCache->set($path, false);
132
+            return false;
133
+        } catch (ClientErrorResponseException $e) {
134
+            // Expected response is "404 Not Found", so only log if it isn't
135
+            if ($e->getResponse()->getStatusCode() !== 404) {
136
+                \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
137
+            }
138
+            return false;
139
+        }
140
+    }
141
+
142
+    /**
143
+     * Returns whether the given path exists.
144
+     *
145
+     * @param string $path
146
+     *
147
+     * @return bool true if the object exist, false otherwise
148
+     */
149
+    private function doesObjectExist($path) {
150
+        return $this->fetchObject($path) !== false;
151
+    }
152
+
153
+    public function __construct($params) {
154
+        if ((empty($params['key']) and empty($params['password']))
155
+            or empty($params['user']) or empty($params['bucket'])
156
+            or empty($params['region'])
157
+        ) {
158
+            throw new \Exception("API Key or password, Username, Bucket and Region have to be configured.");
159
+        }
160
+
161
+        $this->id = 'swift::' . $params['user'] . md5($params['bucket']);
162
+
163
+        $bucketUrl = Url::factory($params['bucket']);
164
+        if ($bucketUrl->isAbsolute()) {
165
+            $this->bucket = end(($bucketUrl->getPathSegments()));
166
+            $params['endpoint_url'] = $bucketUrl->addPath('..')->normalizePath();
167
+        } else {
168
+            $this->bucket = $params['bucket'];
169
+        }
170
+
171
+        if (empty($params['url'])) {
172
+            $params['url'] = 'https://identity.api.rackspacecloud.com/v2.0/';
173
+        }
174
+
175
+        if (empty($params['service_name'])) {
176
+            $params['service_name'] = 'cloudFiles';
177
+        }
178
+
179
+        $this->params = $params;
180
+        // FIXME: private class...
181
+        $this->objectCache = new \OC\Cache\CappedMemoryCache();
182
+    }
183
+
184
+    public function mkdir($path) {
185
+        $path = $this->normalizePath($path);
186
+
187
+        if ($this->is_dir($path)) {
188
+            return false;
189
+        }
190
+
191
+        if ($path !== '.') {
192
+            $path .= '/';
193
+        }
194
+
195
+        try {
196
+            $customHeaders = array('content-type' => 'httpd/unix-directory');
197
+            $metadataHeaders = DataObject::stockHeaders(array());
198
+            $allHeaders = $customHeaders + $metadataHeaders;
199
+            $this->getContainer()->uploadObject($path, '', $allHeaders);
200
+            // invalidate so that the next access gets the real object
201
+            // with all properties
202
+            $this->objectCache->remove($path);
203
+        } catch (Exceptions\CreateUpdateError $e) {
204
+            \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
205
+            return false;
206
+        }
207
+
208
+        return true;
209
+    }
210
+
211
+    public function file_exists($path) {
212
+        $path = $this->normalizePath($path);
213
+
214
+        if ($path !== '.' && $this->is_dir($path)) {
215
+            $path .= '/';
216
+        }
217
+
218
+        return $this->doesObjectExist($path);
219
+    }
220
+
221
+    public function rmdir($path) {
222
+        $path = $this->normalizePath($path);
223
+
224
+        if (!$this->is_dir($path) || !$this->isDeletable($path)) {
225
+            return false;
226
+        }
227
+
228
+        $dh = $this->opendir($path);
229
+        while ($file = readdir($dh)) {
230
+            if (\OC\Files\Filesystem::isIgnoredDir($file)) {
231
+                continue;
232
+            }
233
+
234
+            if ($this->is_dir($path . '/' . $file)) {
235
+                $this->rmdir($path . '/' . $file);
236
+            } else {
237
+                $this->unlink($path . '/' . $file);
238
+            }
239
+        }
240
+
241
+        try {
242
+            $this->getContainer()->dataObject()->setName($path . '/')->delete();
243
+            $this->objectCache->remove($path . '/');
244
+        } catch (Exceptions\DeleteError $e) {
245
+            \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
246
+            return false;
247
+        }
248
+
249
+        return true;
250
+    }
251
+
252
+    public function opendir($path) {
253
+        $path = $this->normalizePath($path);
254
+
255
+        if ($path === '.') {
256
+            $path = '';
257
+        } else {
258
+            $path .= '/';
259
+        }
260
+
261
+        $path = str_replace('%23', '#', $path); // the prefix is sent as a query param, so revert the encoding of #
262
+
263
+        try {
264
+            $files = array();
265
+            /** @var OpenCloud\Common\Collection $objects */
266
+            $objects = $this->getContainer()->objectList(array(
267
+                'prefix' => $path,
268
+                'delimiter' => '/'
269
+            ));
270
+
271
+            /** @var OpenCloud\ObjectStore\Resource\DataObject $object */
272
+            foreach ($objects as $object) {
273
+                $file = basename($object->getName());
274
+                if ($file !== basename($path) && $file !== '.') {
275
+                    $files[] = $file;
276
+                }
277
+            }
278
+
279
+            return IteratorDirectory::wrap($files);
280
+        } catch (\Exception $e) {
281
+            \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
282
+            return false;
283
+        }
284
+
285
+    }
286
+
287
+    public function stat($path) {
288
+        $path = $this->normalizePath($path);
289
+
290
+        if ($path === '.') {
291
+            $path = '';
292
+        } else if ($this->is_dir($path)) {
293
+            $path .= '/';
294
+        }
295
+
296
+        try {
297
+            /** @var DataObject $object */
298
+            $object = $this->fetchObject($path);
299
+            if (!$object) {
300
+                return false;
301
+            }
302
+        } catch (ClientErrorResponseException $e) {
303
+            \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
304
+            return false;
305
+        }
306
+
307
+        $dateTime = \DateTime::createFromFormat(\DateTime::RFC1123, $object->getLastModified());
308
+        if ($dateTime !== false) {
309
+            $mtime = $dateTime->getTimestamp();
310
+        } else {
311
+            $mtime = null;
312
+        }
313
+        $objectMetadata = $object->getMetadata();
314
+        $metaTimestamp = $objectMetadata->getProperty('timestamp');
315
+        if (isset($metaTimestamp)) {
316
+            $mtime = $metaTimestamp;
317
+        }
318
+
319
+        if (!empty($mtime)) {
320
+            $mtime = floor($mtime);
321
+        }
322
+
323
+        $stat = array();
324
+        $stat['size'] = (int)$object->getContentLength();
325
+        $stat['mtime'] = $mtime;
326
+        $stat['atime'] = time();
327
+        return $stat;
328
+    }
329
+
330
+    public function filetype($path) {
331
+        $path = $this->normalizePath($path);
332
+
333
+        if ($path !== '.' && $this->doesObjectExist($path)) {
334
+            return 'file';
335
+        }
336
+
337
+        if ($path !== '.') {
338
+            $path .= '/';
339
+        }
340
+
341
+        if ($this->doesObjectExist($path)) {
342
+            return 'dir';
343
+        }
344
+    }
345
+
346
+    public function unlink($path) {
347
+        $path = $this->normalizePath($path);
348
+
349
+        if ($this->is_dir($path)) {
350
+            return $this->rmdir($path);
351
+        }
352
+
353
+        try {
354
+            $this->getContainer()->dataObject()->setName($path)->delete();
355
+            $this->objectCache->remove($path);
356
+            $this->objectCache->remove($path . '/');
357
+        } catch (ClientErrorResponseException $e) {
358
+            if ($e->getResponse()->getStatusCode() !== 404) {
359
+                \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
360
+            }
361
+            return false;
362
+        }
363
+
364
+        return true;
365
+    }
366
+
367
+    public function fopen($path, $mode) {
368
+        $path = $this->normalizePath($path);
369
+
370
+        switch ($mode) {
371
+            case 'a':
372
+            case 'ab':
373
+            case 'a+':
374
+                return false;
375
+            case 'r':
376
+            case 'rb':
377
+                try {
378
+                    $c = $this->getContainer();
379
+                    $streamFactory = new \Guzzle\Stream\PhpStreamRequestFactory();
380
+                    /** @var \OpenCloud\Common\Http\Client $client */
381
+                    $client = $c->getClient();
382
+                    $streamInterface = $streamFactory->fromRequest($client->get($c->getUrl($path)));
383
+                    $streamInterface->rewind();
384
+                    $stream = $streamInterface->getStream();
385
+                    stream_context_set_option($stream, 'swift','content', $streamInterface);
386
+                    if(!strrpos($streamInterface
387
+                        ->getMetaData('wrapper_data')[0], '404 Not Found')) {
388
+                        return $stream;
389
+                    }
390
+                    return false;
391
+                } catch (\Guzzle\Http\Exception\BadResponseException $e) {
392
+                    \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
393
+                    return false;
394
+                }
395
+            case 'w':
396
+            case 'wb':
397
+            case 'r+':
398
+            case 'w+':
399
+            case 'wb+':
400
+            case 'x':
401
+            case 'x+':
402
+            case 'c':
403
+            case 'c+':
404
+                if (strrpos($path, '.') !== false) {
405
+                    $ext = substr($path, strrpos($path, '.'));
406
+                } else {
407
+                    $ext = '';
408
+                }
409
+                $tmpFile = \OCP\Files::tmpFile($ext);
410
+                // Fetch existing file if required
411
+                if ($mode[0] !== 'w' && $this->file_exists($path)) {
412
+                    if ($mode[0] === 'x') {
413
+                        // File cannot already exist
414
+                        return false;
415
+                    }
416
+                    $source = $this->fopen($path, 'r');
417
+                    file_put_contents($tmpFile, $source);
418
+                }
419
+                $handle = fopen($tmpFile, $mode);
420
+                return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
421
+                    $this->writeBack($tmpFile, $path);
422
+                });
423
+        }
424
+    }
425
+
426
+    public function touch($path, $mtime = null) {
427
+        $path = $this->normalizePath($path);
428
+        if (is_null($mtime)) {
429
+            $mtime = time();
430
+        }
431
+        $metadata = array('timestamp' => $mtime);
432
+        if ($this->file_exists($path)) {
433
+            if ($this->is_dir($path) && $path !== '.') {
434
+                $path .= '/';
435
+            }
436
+
437
+            $object = $this->fetchObject($path);
438
+            if ($object->saveMetadata($metadata)) {
439
+                // invalidate target object to force repopulation on fetch
440
+                $this->objectCache->remove($path);
441
+            }
442
+            return true;
443
+        } else {
444
+            $mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
445
+            $customHeaders = array('content-type' => $mimeType);
446
+            $metadataHeaders = DataObject::stockHeaders($metadata);
447
+            $allHeaders = $customHeaders + $metadataHeaders;
448
+            $this->getContainer()->uploadObject($path, '', $allHeaders);
449
+            // invalidate target object to force repopulation on fetch
450
+            $this->objectCache->remove($path);
451
+            return true;
452
+        }
453
+    }
454
+
455
+    public function copy($path1, $path2) {
456
+        $path1 = $this->normalizePath($path1);
457
+        $path2 = $this->normalizePath($path2);
458
+
459
+        $fileType = $this->filetype($path1);
460
+        if ($fileType === 'file') {
461
+
462
+            // make way
463
+            $this->unlink($path2);
464
+
465
+            try {
466
+                $source = $this->fetchObject($path1);
467
+                $source->copy($this->bucket . '/' . $path2);
468
+                // invalidate target object to force repopulation on fetch
469
+                $this->objectCache->remove($path2);
470
+                $this->objectCache->remove($path2 . '/');
471
+            } catch (ClientErrorResponseException $e) {
472
+                \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
473
+                return false;
474
+            }
475
+
476
+        } else if ($fileType === 'dir') {
477
+
478
+            // make way
479
+            $this->unlink($path2);
480
+
481
+            try {
482
+                $source = $this->fetchObject($path1 . '/');
483
+                $source->copy($this->bucket . '/' . $path2 . '/');
484
+                // invalidate target object to force repopulation on fetch
485
+                $this->objectCache->remove($path2);
486
+                $this->objectCache->remove($path2 . '/');
487
+            } catch (ClientErrorResponseException $e) {
488
+                \OCP\Util::writeLog('files_external', $e->getMessage(), \OCP\Util::ERROR);
489
+                return false;
490
+            }
491
+
492
+            $dh = $this->opendir($path1);
493
+            while ($file = readdir($dh)) {
494
+                if (\OC\Files\Filesystem::isIgnoredDir($file)) {
495
+                    continue;
496
+                }
497
+
498
+                $source = $path1 . '/' . $file;
499
+                $target = $path2 . '/' . $file;
500
+                $this->copy($source, $target);
501
+            }
502
+
503
+        } else {
504
+            //file does not exist
505
+            return false;
506
+        }
507
+
508
+        return true;
509
+    }
510
+
511
+    public function rename($path1, $path2) {
512
+        $path1 = $this->normalizePath($path1);
513
+        $path2 = $this->normalizePath($path2);
514
+
515
+        $fileType = $this->filetype($path1);
516
+
517
+        if ($fileType === 'dir' || $fileType === 'file') {
518
+            // copy
519
+            if ($this->copy($path1, $path2) === false) {
520
+                return false;
521
+            }
522
+
523
+            // cleanup
524
+            if ($this->unlink($path1) === false) {
525
+                $this->unlink($path2);
526
+                return false;
527
+            }
528
+
529
+            return true;
530
+        }
531
+
532
+        return false;
533
+    }
534
+
535
+    public function getId() {
536
+        return $this->id;
537
+    }
538
+
539
+    /**
540
+     * Returns the connection
541
+     *
542
+     * @return OpenCloud\ObjectStore\Service connected client
543
+     * @throws \Exception if connection could not be made
544
+     */
545
+    public function getConnection() {
546
+        if (!is_null($this->connection)) {
547
+            return $this->connection;
548
+        }
549
+
550
+        $settings = array(
551
+            'username' => $this->params['user'],
552
+        );
553
+
554
+        if (!empty($this->params['password'])) {
555
+            $settings['password'] = $this->params['password'];
556
+        } else if (!empty($this->params['key'])) {
557
+            $settings['apiKey'] = $this->params['key'];
558
+        }
559
+
560
+        if (!empty($this->params['tenant'])) {
561
+            $settings['tenantName'] = $this->params['tenant'];
562
+        }
563
+
564
+        if (!empty($this->params['timeout'])) {
565
+            $settings['timeout'] = $this->params['timeout'];
566
+        }
567
+
568
+        if (isset($settings['apiKey'])) {
569
+            $this->anchor = new Rackspace($this->params['url'], $settings);
570
+        } else {
571
+            $this->anchor = new OpenStack($this->params['url'], $settings);
572
+        }
573
+
574
+        $connection = $this->anchor->objectStoreService($this->params['service_name'], $this->params['region']);
575
+
576
+        if (!empty($this->params['endpoint_url'])) {
577
+            $endpoint = $connection->getEndpoint();
578
+            $endpoint->setPublicUrl($this->params['endpoint_url']);
579
+            $endpoint->setPrivateUrl($this->params['endpoint_url']);
580
+            $connection->setEndpoint($endpoint);
581
+        }
582
+
583
+        $this->connection = $connection;
584
+
585
+        return $this->connection;
586
+    }
587
+
588
+    /**
589
+     * Returns the initialized object store container.
590
+     *
591
+     * @return OpenCloud\ObjectStore\Resource\Container
592
+     */
593
+    public function getContainer() {
594
+        if (!is_null($this->container)) {
595
+            return $this->container;
596
+        }
597
+
598
+        try {
599
+            $this->container = $this->getConnection()->getContainer($this->bucket);
600
+        } catch (ClientErrorResponseException $e) {
601
+            $this->container = $this->getConnection()->createContainer($this->bucket);
602
+        }
603
+
604
+        if (!$this->file_exists('.')) {
605
+            $this->mkdir('.');
606
+        }
607
+
608
+        return $this->container;
609
+    }
610
+
611
+    public function writeBack($tmpFile, $path) {
612
+        $fileData = fopen($tmpFile, 'r');
613
+        $this->getContainer()->uploadObject($path, $fileData);
614
+        // invalidate target object to force repopulation on fetch
615
+        $this->objectCache->remove($path);
616
+        unlink($tmpFile);
617
+    }
618
+
619
+    public function hasUpdated($path, $time) {
620
+        if ($this->is_file($path)) {
621
+            return parent::hasUpdated($path, $time);
622
+        }
623
+        $path = $this->normalizePath($path);
624
+        $dh = $this->opendir($path);
625
+        $content = array();
626
+        while (($file = readdir($dh)) !== false) {
627
+            $content[] = $file;
628
+        }
629
+        if ($path === '.') {
630
+            $path = '';
631
+        }
632
+        $cachedContent = $this->getCache()->getFolderContents($path);
633
+        $cachedNames = array_map(function ($content) {
634
+            return $content['name'];
635
+        }, $cachedContent);
636
+        sort($cachedNames);
637
+        sort($content);
638
+        return $cachedNames !== $content;
639
+    }
640
+
641
+    /**
642
+     * check if curl is installed
643
+     */
644
+    public static function checkDependencies() {
645
+        return true;
646
+    }
647 647
 
648 648
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ShareController.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -597,7 +597,7 @@
 block discarded – undo
597 597
 	 * publish activity
598 598
 	 *
599 599
 	 * @param string $subject
600
-	 * @param array $parameters
600
+	 * @param string[] $parameters
601 601
 	 * @param string $affectedUser
602 602
 	 * @param int $fileId
603 603
 	 * @param string $filePath
Please login to merge, or discard this patch.
Indentation   +550 added lines, -550 removed lines patch added patch discarded remove patch
@@ -64,558 +64,558 @@
 block discarded – undo
64 64
  */
65 65
 class ShareController extends Controller {
66 66
 
67
-	/** @var IConfig */
68
-	protected $config;
69
-	/** @var IURLGenerator */
70
-	protected $urlGenerator;
71
-	/** @var IUserManager */
72
-	protected $userManager;
73
-	/** @var ILogger */
74
-	protected $logger;
75
-	/** @var \OCP\Activity\IManager */
76
-	protected $activityManager;
77
-	/** @var \OCP\Share\IManager */
78
-	protected $shareManager;
79
-	/** @var ISession */
80
-	protected $session;
81
-	/** @var IPreview */
82
-	protected $previewManager;
83
-	/** @var IRootFolder */
84
-	protected $rootFolder;
85
-	/** @var FederatedShareProvider */
86
-	protected $federatedShareProvider;
87
-	/** @var EventDispatcherInterface */
88
-	protected $eventDispatcher;
89
-	/** @var IL10N */
90
-	protected $l10n;
91
-	/** @var Defaults */
92
-	protected $defaults;
93
-
94
-	/**
95
-	 * @param string $appName
96
-	 * @param IRequest $request
97
-	 * @param IConfig $config
98
-	 * @param IURLGenerator $urlGenerator
99
-	 * @param IUserManager $userManager
100
-	 * @param ILogger $logger
101
-	 * @param \OCP\Activity\IManager $activityManager
102
-	 * @param \OCP\Share\IManager $shareManager
103
-	 * @param ISession $session
104
-	 * @param IPreview $previewManager
105
-	 * @param IRootFolder $rootFolder
106
-	 * @param FederatedShareProvider $federatedShareProvider
107
-	 * @param EventDispatcherInterface $eventDispatcher
108
-	 * @param IL10N $l10n
109
-	 * @param Defaults $defaults
110
-	 */
111
-	public function __construct($appName,
112
-								IRequest $request,
113
-								IConfig $config,
114
-								IURLGenerator $urlGenerator,
115
-								IUserManager $userManager,
116
-								ILogger $logger,
117
-								\OCP\Activity\IManager $activityManager,
118
-								\OCP\Share\IManager $shareManager,
119
-								ISession $session,
120
-								IPreview $previewManager,
121
-								IRootFolder $rootFolder,
122
-								FederatedShareProvider $federatedShareProvider,
123
-								EventDispatcherInterface $eventDispatcher,
124
-								IL10N $l10n,
125
-								Defaults $defaults) {
126
-		parent::__construct($appName, $request);
127
-
128
-		$this->config = $config;
129
-		$this->urlGenerator = $urlGenerator;
130
-		$this->userManager = $userManager;
131
-		$this->logger = $logger;
132
-		$this->activityManager = $activityManager;
133
-		$this->shareManager = $shareManager;
134
-		$this->session = $session;
135
-		$this->previewManager = $previewManager;
136
-		$this->rootFolder = $rootFolder;
137
-		$this->federatedShareProvider = $federatedShareProvider;
138
-		$this->eventDispatcher = $eventDispatcher;
139
-		$this->l10n = $l10n;
140
-		$this->defaults = $defaults;
141
-	}
142
-
143
-	/**
144
-	 * @PublicPage
145
-	 * @NoCSRFRequired
146
-	 *
147
-	 * @param string $token
148
-	 * @return TemplateResponse|RedirectResponse
149
-	 */
150
-	public function showAuthenticate($token) {
151
-		$share = $this->shareManager->getShareByToken($token);
152
-
153
-		if($this->linkShareAuth($share)) {
154
-			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
155
-		}
156
-
157
-		return new TemplateResponse($this->appName, 'authenticate', array(), 'guest');
158
-	}
159
-
160
-	/**
161
-	 * @PublicPage
162
-	 * @UseSession
163
-	 * @BruteForceProtection(action=publicLinkAuth)
164
-	 *
165
-	 * Authenticates against password-protected shares
166
-	 * @param string $token
167
-	 * @param string $password
168
-	 * @return RedirectResponse|TemplateResponse|NotFoundResponse
169
-	 */
170
-	public function authenticate($token, $password = '') {
171
-
172
-		// Check whether share exists
173
-		try {
174
-			$share = $this->shareManager->getShareByToken($token);
175
-		} catch (ShareNotFound $e) {
176
-			return new NotFoundResponse();
177
-		}
178
-
179
-		$authenticate = $this->linkShareAuth($share, $password);
180
-
181
-		if($authenticate === true) {
182
-			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
183
-		}
184
-
185
-		$response = new TemplateResponse($this->appName, 'authenticate', array('wrongpw' => true), 'guest');
186
-		$response->throttle();
187
-		return $response;
188
-	}
189
-
190
-	/**
191
-	 * Authenticate a link item with the given password.
192
-	 * Or use the session if no password is provided.
193
-	 *
194
-	 * This is a modified version of Helper::authenticate
195
-	 * TODO: Try to merge back eventually with Helper::authenticate
196
-	 *
197
-	 * @param \OCP\Share\IShare $share
198
-	 * @param string|null $password
199
-	 * @return bool
200
-	 */
201
-	private function linkShareAuth(\OCP\Share\IShare $share, $password = null) {
202
-		if ($password !== null) {
203
-			if ($this->shareManager->checkPassword($share, $password)) {
204
-				$this->session->set('public_link_authenticated', (string)$share->getId());
205
-			} else {
206
-				$this->emitAccessShareHook($share, 403, 'Wrong password');
207
-				return false;
208
-			}
209
-		} else {
210
-			// not authenticated ?
211
-			if ( ! $this->session->exists('public_link_authenticated')
212
-				|| $this->session->get('public_link_authenticated') !== (string)$share->getId()) {
213
-				return false;
214
-			}
215
-		}
216
-		return true;
217
-	}
218
-
219
-	/**
220
-	 * throws hooks when a share is attempted to be accessed
221
-	 *
222
-	 * @param \OCP\Share\IShare|string $share the Share instance if available,
223
-	 * otherwise token
224
-	 * @param int $errorCode
225
-	 * @param string $errorMessage
226
-	 * @throws \OC\HintException
227
-	 * @throws \OC\ServerNotAvailableException
228
-	 */
229
-	protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') {
230
-		$itemType = $itemSource = $uidOwner = '';
231
-		$token = $share;
232
-		$exception = null;
233
-		if($share instanceof \OCP\Share\IShare) {
234
-			try {
235
-				$token = $share->getToken();
236
-				$uidOwner = $share->getSharedBy();
237
-				$itemType = $share->getNodeType();
238
-				$itemSource = $share->getNodeId();
239
-			} catch (\Exception $e) {
240
-				// we log what we know and pass on the exception afterwards
241
-				$exception = $e;
242
-			}
243
-		}
244
-		\OC_Hook::emit('OCP\Share', 'share_link_access', [
245
-			'itemType' => $itemType,
246
-			'itemSource' => $itemSource,
247
-			'uidOwner' => $uidOwner,
248
-			'token' => $token,
249
-			'errorCode' => $errorCode,
250
-			'errorMessage' => $errorMessage,
251
-		]);
252
-		if(!is_null($exception)) {
253
-			throw $exception;
254
-		}
255
-	}
256
-
257
-	/**
258
-	 * Validate the permissions of the share
259
-	 *
260
-	 * @param Share\IShare $share
261
-	 * @return bool
262
-	 */
263
-	private function validateShare(\OCP\Share\IShare $share) {
264
-		return $share->getNode()->isReadable() && $share->getNode()->isShareable();
265
-	}
266
-
267
-	/**
268
-	 * @PublicPage
269
-	 * @NoCSRFRequired
270
-	 *
271
-	 * @param string $token
272
-	 * @param string $path
273
-	 * @return TemplateResponse|RedirectResponse|NotFoundResponse
274
-	 * @throws NotFoundException
275
-	 * @throws \Exception
276
-	 */
277
-	public function showShare($token, $path = '') {
278
-		\OC_User::setIncognitoMode(true);
279
-
280
-		// Check whether share exists
281
-		try {
282
-			$share = $this->shareManager->getShareByToken($token);
283
-		} catch (ShareNotFound $e) {
284
-			$this->emitAccessShareHook($token, 404, 'Share not found');
285
-			return new NotFoundResponse();
286
-		}
287
-
288
-		// Share is password protected - check whether the user is permitted to access the share
289
-		if ($share->getPassword() !== null && !$this->linkShareAuth($share)) {
290
-			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate',
291
-				array('token' => $token)));
292
-		}
293
-
294
-		if (!$this->validateShare($share)) {
295
-			throw new NotFoundException();
296
-		}
297
-		// We can't get the path of a file share
298
-		try {
299
-			if ($share->getNode() instanceof \OCP\Files\File && $path !== '') {
300
-				$this->emitAccessShareHook($share, 404, 'Share not found');
301
-				throw new NotFoundException();
302
-			}
303
-		} catch (\Exception $e) {
304
-			$this->emitAccessShareHook($share, 404, 'Share not found');
305
-			throw $e;
306
-		}
307
-
308
-		$shareTmpl = [];
309
-		$shareTmpl['displayName'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
310
-		$shareTmpl['owner'] = $share->getShareOwner();
311
-		$shareTmpl['filename'] = $share->getNode()->getName();
312
-		$shareTmpl['directory_path'] = $share->getTarget();
313
-		$shareTmpl['mimetype'] = $share->getNode()->getMimetype();
314
-		$shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->getMimetype());
315
-		$shareTmpl['dirToken'] = $token;
316
-		$shareTmpl['sharingToken'] = $token;
317
-		$shareTmpl['server2serversharing'] = $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
318
-		$shareTmpl['protected'] = $share->getPassword() !== null ? 'true' : 'false';
319
-		$shareTmpl['dir'] = '';
320
-		$shareTmpl['nonHumanFileSize'] = $share->getNode()->getSize();
321
-		$shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize());
322
-
323
-		// Show file list
324
-		$hideFileList = false;
325
-		if ($share->getNode() instanceof \OCP\Files\Folder) {
326
-			/** @var \OCP\Files\Folder $rootFolder */
327
-			$rootFolder = $share->getNode();
328
-
329
-			try {
330
-				$folderNode = $rootFolder->get($path);
331
-			} catch (\OCP\Files\NotFoundException $e) {
332
-				$this->emitAccessShareHook($share, 404, 'Share not found');
333
-				throw new NotFoundException();
334
-			}
335
-
336
-			$shareTmpl['dir'] = $rootFolder->getRelativePath($folderNode->getPath());
337
-
338
-			/*
67
+    /** @var IConfig */
68
+    protected $config;
69
+    /** @var IURLGenerator */
70
+    protected $urlGenerator;
71
+    /** @var IUserManager */
72
+    protected $userManager;
73
+    /** @var ILogger */
74
+    protected $logger;
75
+    /** @var \OCP\Activity\IManager */
76
+    protected $activityManager;
77
+    /** @var \OCP\Share\IManager */
78
+    protected $shareManager;
79
+    /** @var ISession */
80
+    protected $session;
81
+    /** @var IPreview */
82
+    protected $previewManager;
83
+    /** @var IRootFolder */
84
+    protected $rootFolder;
85
+    /** @var FederatedShareProvider */
86
+    protected $federatedShareProvider;
87
+    /** @var EventDispatcherInterface */
88
+    protected $eventDispatcher;
89
+    /** @var IL10N */
90
+    protected $l10n;
91
+    /** @var Defaults */
92
+    protected $defaults;
93
+
94
+    /**
95
+     * @param string $appName
96
+     * @param IRequest $request
97
+     * @param IConfig $config
98
+     * @param IURLGenerator $urlGenerator
99
+     * @param IUserManager $userManager
100
+     * @param ILogger $logger
101
+     * @param \OCP\Activity\IManager $activityManager
102
+     * @param \OCP\Share\IManager $shareManager
103
+     * @param ISession $session
104
+     * @param IPreview $previewManager
105
+     * @param IRootFolder $rootFolder
106
+     * @param FederatedShareProvider $federatedShareProvider
107
+     * @param EventDispatcherInterface $eventDispatcher
108
+     * @param IL10N $l10n
109
+     * @param Defaults $defaults
110
+     */
111
+    public function __construct($appName,
112
+                                IRequest $request,
113
+                                IConfig $config,
114
+                                IURLGenerator $urlGenerator,
115
+                                IUserManager $userManager,
116
+                                ILogger $logger,
117
+                                \OCP\Activity\IManager $activityManager,
118
+                                \OCP\Share\IManager $shareManager,
119
+                                ISession $session,
120
+                                IPreview $previewManager,
121
+                                IRootFolder $rootFolder,
122
+                                FederatedShareProvider $federatedShareProvider,
123
+                                EventDispatcherInterface $eventDispatcher,
124
+                                IL10N $l10n,
125
+                                Defaults $defaults) {
126
+        parent::__construct($appName, $request);
127
+
128
+        $this->config = $config;
129
+        $this->urlGenerator = $urlGenerator;
130
+        $this->userManager = $userManager;
131
+        $this->logger = $logger;
132
+        $this->activityManager = $activityManager;
133
+        $this->shareManager = $shareManager;
134
+        $this->session = $session;
135
+        $this->previewManager = $previewManager;
136
+        $this->rootFolder = $rootFolder;
137
+        $this->federatedShareProvider = $federatedShareProvider;
138
+        $this->eventDispatcher = $eventDispatcher;
139
+        $this->l10n = $l10n;
140
+        $this->defaults = $defaults;
141
+    }
142
+
143
+    /**
144
+     * @PublicPage
145
+     * @NoCSRFRequired
146
+     *
147
+     * @param string $token
148
+     * @return TemplateResponse|RedirectResponse
149
+     */
150
+    public function showAuthenticate($token) {
151
+        $share = $this->shareManager->getShareByToken($token);
152
+
153
+        if($this->linkShareAuth($share)) {
154
+            return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
155
+        }
156
+
157
+        return new TemplateResponse($this->appName, 'authenticate', array(), 'guest');
158
+    }
159
+
160
+    /**
161
+     * @PublicPage
162
+     * @UseSession
163
+     * @BruteForceProtection(action=publicLinkAuth)
164
+     *
165
+     * Authenticates against password-protected shares
166
+     * @param string $token
167
+     * @param string $password
168
+     * @return RedirectResponse|TemplateResponse|NotFoundResponse
169
+     */
170
+    public function authenticate($token, $password = '') {
171
+
172
+        // Check whether share exists
173
+        try {
174
+            $share = $this->shareManager->getShareByToken($token);
175
+        } catch (ShareNotFound $e) {
176
+            return new NotFoundResponse();
177
+        }
178
+
179
+        $authenticate = $this->linkShareAuth($share, $password);
180
+
181
+        if($authenticate === true) {
182
+            return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
183
+        }
184
+
185
+        $response = new TemplateResponse($this->appName, 'authenticate', array('wrongpw' => true), 'guest');
186
+        $response->throttle();
187
+        return $response;
188
+    }
189
+
190
+    /**
191
+     * Authenticate a link item with the given password.
192
+     * Or use the session if no password is provided.
193
+     *
194
+     * This is a modified version of Helper::authenticate
195
+     * TODO: Try to merge back eventually with Helper::authenticate
196
+     *
197
+     * @param \OCP\Share\IShare $share
198
+     * @param string|null $password
199
+     * @return bool
200
+     */
201
+    private function linkShareAuth(\OCP\Share\IShare $share, $password = null) {
202
+        if ($password !== null) {
203
+            if ($this->shareManager->checkPassword($share, $password)) {
204
+                $this->session->set('public_link_authenticated', (string)$share->getId());
205
+            } else {
206
+                $this->emitAccessShareHook($share, 403, 'Wrong password');
207
+                return false;
208
+            }
209
+        } else {
210
+            // not authenticated ?
211
+            if ( ! $this->session->exists('public_link_authenticated')
212
+                || $this->session->get('public_link_authenticated') !== (string)$share->getId()) {
213
+                return false;
214
+            }
215
+        }
216
+        return true;
217
+    }
218
+
219
+    /**
220
+     * throws hooks when a share is attempted to be accessed
221
+     *
222
+     * @param \OCP\Share\IShare|string $share the Share instance if available,
223
+     * otherwise token
224
+     * @param int $errorCode
225
+     * @param string $errorMessage
226
+     * @throws \OC\HintException
227
+     * @throws \OC\ServerNotAvailableException
228
+     */
229
+    protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') {
230
+        $itemType = $itemSource = $uidOwner = '';
231
+        $token = $share;
232
+        $exception = null;
233
+        if($share instanceof \OCP\Share\IShare) {
234
+            try {
235
+                $token = $share->getToken();
236
+                $uidOwner = $share->getSharedBy();
237
+                $itemType = $share->getNodeType();
238
+                $itemSource = $share->getNodeId();
239
+            } catch (\Exception $e) {
240
+                // we log what we know and pass on the exception afterwards
241
+                $exception = $e;
242
+            }
243
+        }
244
+        \OC_Hook::emit('OCP\Share', 'share_link_access', [
245
+            'itemType' => $itemType,
246
+            'itemSource' => $itemSource,
247
+            'uidOwner' => $uidOwner,
248
+            'token' => $token,
249
+            'errorCode' => $errorCode,
250
+            'errorMessage' => $errorMessage,
251
+        ]);
252
+        if(!is_null($exception)) {
253
+            throw $exception;
254
+        }
255
+    }
256
+
257
+    /**
258
+     * Validate the permissions of the share
259
+     *
260
+     * @param Share\IShare $share
261
+     * @return bool
262
+     */
263
+    private function validateShare(\OCP\Share\IShare $share) {
264
+        return $share->getNode()->isReadable() && $share->getNode()->isShareable();
265
+    }
266
+
267
+    /**
268
+     * @PublicPage
269
+     * @NoCSRFRequired
270
+     *
271
+     * @param string $token
272
+     * @param string $path
273
+     * @return TemplateResponse|RedirectResponse|NotFoundResponse
274
+     * @throws NotFoundException
275
+     * @throws \Exception
276
+     */
277
+    public function showShare($token, $path = '') {
278
+        \OC_User::setIncognitoMode(true);
279
+
280
+        // Check whether share exists
281
+        try {
282
+            $share = $this->shareManager->getShareByToken($token);
283
+        } catch (ShareNotFound $e) {
284
+            $this->emitAccessShareHook($token, 404, 'Share not found');
285
+            return new NotFoundResponse();
286
+        }
287
+
288
+        // Share is password protected - check whether the user is permitted to access the share
289
+        if ($share->getPassword() !== null && !$this->linkShareAuth($share)) {
290
+            return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate',
291
+                array('token' => $token)));
292
+        }
293
+
294
+        if (!$this->validateShare($share)) {
295
+            throw new NotFoundException();
296
+        }
297
+        // We can't get the path of a file share
298
+        try {
299
+            if ($share->getNode() instanceof \OCP\Files\File && $path !== '') {
300
+                $this->emitAccessShareHook($share, 404, 'Share not found');
301
+                throw new NotFoundException();
302
+            }
303
+        } catch (\Exception $e) {
304
+            $this->emitAccessShareHook($share, 404, 'Share not found');
305
+            throw $e;
306
+        }
307
+
308
+        $shareTmpl = [];
309
+        $shareTmpl['displayName'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
310
+        $shareTmpl['owner'] = $share->getShareOwner();
311
+        $shareTmpl['filename'] = $share->getNode()->getName();
312
+        $shareTmpl['directory_path'] = $share->getTarget();
313
+        $shareTmpl['mimetype'] = $share->getNode()->getMimetype();
314
+        $shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->getMimetype());
315
+        $shareTmpl['dirToken'] = $token;
316
+        $shareTmpl['sharingToken'] = $token;
317
+        $shareTmpl['server2serversharing'] = $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
318
+        $shareTmpl['protected'] = $share->getPassword() !== null ? 'true' : 'false';
319
+        $shareTmpl['dir'] = '';
320
+        $shareTmpl['nonHumanFileSize'] = $share->getNode()->getSize();
321
+        $shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize());
322
+
323
+        // Show file list
324
+        $hideFileList = false;
325
+        if ($share->getNode() instanceof \OCP\Files\Folder) {
326
+            /** @var \OCP\Files\Folder $rootFolder */
327
+            $rootFolder = $share->getNode();
328
+
329
+            try {
330
+                $folderNode = $rootFolder->get($path);
331
+            } catch (\OCP\Files\NotFoundException $e) {
332
+                $this->emitAccessShareHook($share, 404, 'Share not found');
333
+                throw new NotFoundException();
334
+            }
335
+
336
+            $shareTmpl['dir'] = $rootFolder->getRelativePath($folderNode->getPath());
337
+
338
+            /*
339 339
 			 * The OC_Util methods require a view. This just uses the node API
340 340
 			 */
341
-			$freeSpace = $share->getNode()->getStorage()->free_space($share->getNode()->getInternalPath());
342
-			if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
343
-				$freeSpace = max($freeSpace, 0);
344
-			} else {
345
-				$freeSpace = (INF > 0) ? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
346
-			}
347
-
348
-			$hideFileList = $share->getPermissions() & \OCP\Constants::PERMISSION_READ ? false : true;
349
-			$maxUploadFilesize = $freeSpace;
350
-
351
-			$folder = new Template('files', 'list', '');
352
-			$folder->assign('dir', $rootFolder->getRelativePath($folderNode->getPath()));
353
-			$folder->assign('dirToken', $token);
354
-			$folder->assign('permissions', \OCP\Constants::PERMISSION_READ);
355
-			$folder->assign('isPublic', true);
356
-			$folder->assign('hideFileList', $hideFileList);
357
-			$folder->assign('publicUploadEnabled', 'no');
358
-			$folder->assign('uploadMaxFilesize', $maxUploadFilesize);
359
-			$folder->assign('uploadMaxHumanFilesize', \OCP\Util::humanFileSize($maxUploadFilesize));
360
-			$folder->assign('freeSpace', $freeSpace);
361
-			$folder->assign('usedSpacePercent', 0);
362
-			$folder->assign('trash', false);
363
-			$shareTmpl['folder'] = $folder->fetchPage();
364
-		}
365
-
366
-		$shareTmpl['hideFileList'] = $hideFileList;
367
-		$shareTmpl['shareOwner'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
368
-		$shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', ['token' => $token]);
369
-		$shareTmpl['shareUrl'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $token]);
370
-		$shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
371
-		$shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
372
-		$shareTmpl['previewMaxX'] = $this->config->getSystemValue('preview_max_x', 1024);
373
-		$shareTmpl['previewMaxY'] = $this->config->getSystemValue('preview_max_y', 1024);
374
-		$shareTmpl['disclaimer'] = $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null);
375
-		if ($shareTmpl['previewSupported']) {
376
-			$shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute( 'files_sharing.PublicPreview.getPreview',
377
-				['x' => 200, 'y' => 200, 'file' => $shareTmpl['directory_path'], 't' => $shareTmpl['dirToken']]);
378
-		} else {
379
-			$shareTmpl['previewImage'] = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-fb.png'));
380
-		}
381
-
382
-		// Load files we need
383
-		\OCP\Util::addScript('files', 'file-upload');
384
-		\OCP\Util::addStyle('files_sharing', 'publicView');
385
-		\OCP\Util::addScript('files_sharing', 'public');
386
-		\OCP\Util::addScript('files', 'fileactions');
387
-		\OCP\Util::addScript('files', 'fileactionsmenu');
388
-		\OCP\Util::addScript('files', 'jquery.fileupload');
389
-		\OCP\Util::addScript('files_sharing', 'files_drop');
390
-
391
-		if (isset($shareTmpl['folder'])) {
392
-			// JS required for folders
393
-			\OCP\Util::addStyle('files', 'merged');
394
-			\OCP\Util::addScript('files', 'filesummary');
395
-			\OCP\Util::addScript('files', 'breadcrumb');
396
-			\OCP\Util::addScript('files', 'fileinfomodel');
397
-			\OCP\Util::addScript('files', 'newfilemenu');
398
-			\OCP\Util::addScript('files', 'files');
399
-			\OCP\Util::addScript('files', 'filelist');
400
-			\OCP\Util::addScript('files', 'keyboardshortcuts');
401
-		}
402
-
403
-		// OpenGraph Support: http://ogp.me/
404
-		\OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]);
405
-		\OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->l10n->t('%s is publicly shared', [$shareTmpl['filename']])]);
406
-		\OCP\Util::addHeader('meta', ['property' => "og:site_name", 'content' => $this->defaults->getName()]);
407
-		\OCP\Util::addHeader('meta', ['property' => "og:url", 'content' => $shareTmpl['shareUrl']]);
408
-		\OCP\Util::addHeader('meta', ['property' => "og:type", 'content' => "object"]);
409
-		\OCP\Util::addHeader('meta', ['property' => "og:image", 'content' => $shareTmpl['previewImage']]);
410
-
411
-		$this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts');
412
-
413
-		$csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
414
-		$csp->addAllowedFrameDomain('\'self\'');
415
-		$response = new TemplateResponse($this->appName, 'public', $shareTmpl, 'base');
416
-		$response->setContentSecurityPolicy($csp);
417
-
418
-		$this->emitAccessShareHook($share);
419
-
420
-		return $response;
421
-	}
422
-
423
-	/**
424
-	 * @PublicPage
425
-	 * @NoCSRFRequired
426
-	 *
427
-	 * @param string $token
428
-	 * @param string $files
429
-	 * @param string $path
430
-	 * @param string $downloadStartSecret
431
-	 * @return void|\OCP\AppFramework\Http\Response
432
-	 * @throws NotFoundException
433
-	 */
434
-	public function downloadShare($token, $files = null, $path = '', $downloadStartSecret = '') {
435
-		\OC_User::setIncognitoMode(true);
436
-
437
-		$share = $this->shareManager->getShareByToken($token);
438
-
439
-		if(!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
440
-			return new \OCP\AppFramework\Http\DataResponse('Share is read-only');
441
-		}
442
-
443
-		// Share is password protected - check whether the user is permitted to access the share
444
-		if ($share->getPassword() !== null && !$this->linkShareAuth($share)) {
445
-			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate',
446
-				['token' => $token]));
447
-		}
448
-
449
-		$files_list = null;
450
-		if (!is_null($files)) { // download selected files
451
-			$files_list = json_decode($files);
452
-			// in case we get only a single file
453
-			if ($files_list === null) {
454
-				$files_list = [$files];
455
-			}
456
-		}
457
-
458
-		$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
459
-		$originalSharePath = $userFolder->getRelativePath($share->getNode()->getPath());
460
-
461
-		if (!$this->validateShare($share)) {
462
-			throw new NotFoundException();
463
-		}
464
-
465
-		// Single file share
466
-		if ($share->getNode() instanceof \OCP\Files\File) {
467
-			// Single file download
468
-			$this->singleFileDownloaded($share, $share->getNode());
469
-		}
470
-		// Directory share
471
-		else {
472
-			/** @var \OCP\Files\Folder $node */
473
-			$node = $share->getNode();
474
-
475
-			// Try to get the path
476
-			if ($path !== '') {
477
-				try {
478
-					$node = $node->get($path);
479
-				} catch (NotFoundException $e) {
480
-					$this->emitAccessShareHook($share, 404, 'Share not found');
481
-					return new NotFoundResponse();
482
-				}
483
-			}
484
-
485
-			$originalSharePath = $userFolder->getRelativePath($node->getPath());
486
-
487
-			if ($node instanceof \OCP\Files\File) {
488
-				// Single file download
489
-				$this->singleFileDownloaded($share, $share->getNode());
490
-			} else if (!empty($files_list)) {
491
-				$this->fileListDownloaded($share, $files_list, $node);
492
-			} else {
493
-				// The folder is downloaded
494
-				$this->singleFileDownloaded($share, $share->getNode());
495
-			}
496
-		}
497
-
498
-		/* FIXME: We should do this all nicely in OCP */
499
-		OC_Util::tearDownFS();
500
-		OC_Util::setupFS($share->getShareOwner());
501
-
502
-		/**
503
-		 * this sets a cookie to be able to recognize the start of the download
504
-		 * the content must not be longer than 32 characters and must only contain
505
-		 * alphanumeric characters
506
-		 */
507
-		if (!empty($downloadStartSecret)
508
-			&& !isset($downloadStartSecret[32])
509
-			&& preg_match('!^[a-zA-Z0-9]+$!', $downloadStartSecret) === 1) {
510
-
511
-			// FIXME: set on the response once we use an actual app framework response
512
-			setcookie('ocDownloadStarted', $downloadStartSecret, time() + 20, '/');
513
-		}
514
-
515
-		$this->emitAccessShareHook($share);
516
-
517
-		$server_params = array( 'head' => $this->request->getMethod() === 'HEAD' );
518
-
519
-		/**
520
-		 * Http range requests support
521
-		 */
522
-		if (isset($_SERVER['HTTP_RANGE'])) {
523
-			$server_params['range'] = $this->request->getHeader('Range');
524
-		}
525
-
526
-		// download selected files
527
-		if (!is_null($files) && $files !== '') {
528
-			// FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
529
-			// after dispatching the request which results in a "Cannot modify header information" notice.
530
-			OC_Files::get($originalSharePath, $files_list, $server_params);
531
-			exit();
532
-		} else {
533
-			// FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
534
-			// after dispatching the request which results in a "Cannot modify header information" notice.
535
-			OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $server_params);
536
-			exit();
537
-		}
538
-	}
539
-
540
-	/**
541
-	 * create activity for every downloaded file
542
-	 *
543
-	 * @param Share\IShare $share
544
-	 * @param array $files_list
545
-	 * @param \OCP\Files\Folder $node
546
-	 */
547
-	protected function fileListDownloaded(Share\IShare $share, array $files_list, \OCP\Files\Folder $node) {
548
-		foreach ($files_list as $file) {
549
-			$subNode = $node->get($file);
550
-			$this->singleFileDownloaded($share, $subNode);
551
-		}
552
-
553
-	}
554
-
555
-	/**
556
-	 * create activity if a single file was downloaded from a link share
557
-	 *
558
-	 * @param Share\IShare $share
559
-	 */
560
-	protected function singleFileDownloaded(Share\IShare $share, \OCP\Files\Node $node) {
561
-
562
-		$fileId = $node->getId();
563
-
564
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
565
-		$userNodeList = $userFolder->getById($fileId);
566
-		$userNode = $userNodeList[0];
567
-		$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
568
-		$userPath = $userFolder->getRelativePath($userNode->getPath());
569
-		$ownerPath = $ownerFolder->getRelativePath($node->getPath());
570
-
571
-		$parameters = [$userPath];
572
-
573
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
574
-			if ($node instanceof \OCP\Files\File) {
575
-				$subject = Downloads::SUBJECT_SHARED_FILE_BY_EMAIL_DOWNLOADED;
576
-			} else {
577
-				$subject = Downloads::SUBJECT_SHARED_FOLDER_BY_EMAIL_DOWNLOADED;
578
-			}
579
-			$parameters[] = $share->getSharedWith();
580
-		} else {
581
-			if ($node instanceof \OCP\Files\File) {
582
-				$subject = Downloads::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED;
583
-			} else {
584
-				$subject = Downloads::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED;
585
-			}
586
-		}
587
-
588
-		$this->publishActivity($subject, $parameters, $share->getSharedBy(), $fileId, $userPath);
589
-
590
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
591
-			$parameters[0] = $ownerPath;
592
-			$this->publishActivity($subject, $parameters, $share->getShareOwner(), $fileId, $ownerPath);
593
-		}
594
-	}
595
-
596
-	/**
597
-	 * publish activity
598
-	 *
599
-	 * @param string $subject
600
-	 * @param array $parameters
601
-	 * @param string $affectedUser
602
-	 * @param int $fileId
603
-	 * @param string $filePath
604
-	 */
605
-	protected function publishActivity($subject,
606
-										array $parameters,
607
-										$affectedUser,
608
-										$fileId,
609
-										$filePath) {
610
-
611
-		$event = $this->activityManager->generateEvent();
612
-		$event->setApp('files_sharing')
613
-			->setType('public_links')
614
-			->setSubject($subject, $parameters)
615
-			->setAffectedUser($affectedUser)
616
-			->setObject('files', $fileId, $filePath);
617
-		$this->activityManager->publish($event);
618
-	}
341
+            $freeSpace = $share->getNode()->getStorage()->free_space($share->getNode()->getInternalPath());
342
+            if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
343
+                $freeSpace = max($freeSpace, 0);
344
+            } else {
345
+                $freeSpace = (INF > 0) ? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
346
+            }
347
+
348
+            $hideFileList = $share->getPermissions() & \OCP\Constants::PERMISSION_READ ? false : true;
349
+            $maxUploadFilesize = $freeSpace;
350
+
351
+            $folder = new Template('files', 'list', '');
352
+            $folder->assign('dir', $rootFolder->getRelativePath($folderNode->getPath()));
353
+            $folder->assign('dirToken', $token);
354
+            $folder->assign('permissions', \OCP\Constants::PERMISSION_READ);
355
+            $folder->assign('isPublic', true);
356
+            $folder->assign('hideFileList', $hideFileList);
357
+            $folder->assign('publicUploadEnabled', 'no');
358
+            $folder->assign('uploadMaxFilesize', $maxUploadFilesize);
359
+            $folder->assign('uploadMaxHumanFilesize', \OCP\Util::humanFileSize($maxUploadFilesize));
360
+            $folder->assign('freeSpace', $freeSpace);
361
+            $folder->assign('usedSpacePercent', 0);
362
+            $folder->assign('trash', false);
363
+            $shareTmpl['folder'] = $folder->fetchPage();
364
+        }
365
+
366
+        $shareTmpl['hideFileList'] = $hideFileList;
367
+        $shareTmpl['shareOwner'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
368
+        $shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', ['token' => $token]);
369
+        $shareTmpl['shareUrl'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $token]);
370
+        $shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
371
+        $shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
372
+        $shareTmpl['previewMaxX'] = $this->config->getSystemValue('preview_max_x', 1024);
373
+        $shareTmpl['previewMaxY'] = $this->config->getSystemValue('preview_max_y', 1024);
374
+        $shareTmpl['disclaimer'] = $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null);
375
+        if ($shareTmpl['previewSupported']) {
376
+            $shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute( 'files_sharing.PublicPreview.getPreview',
377
+                ['x' => 200, 'y' => 200, 'file' => $shareTmpl['directory_path'], 't' => $shareTmpl['dirToken']]);
378
+        } else {
379
+            $shareTmpl['previewImage'] = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-fb.png'));
380
+        }
381
+
382
+        // Load files we need
383
+        \OCP\Util::addScript('files', 'file-upload');
384
+        \OCP\Util::addStyle('files_sharing', 'publicView');
385
+        \OCP\Util::addScript('files_sharing', 'public');
386
+        \OCP\Util::addScript('files', 'fileactions');
387
+        \OCP\Util::addScript('files', 'fileactionsmenu');
388
+        \OCP\Util::addScript('files', 'jquery.fileupload');
389
+        \OCP\Util::addScript('files_sharing', 'files_drop');
390
+
391
+        if (isset($shareTmpl['folder'])) {
392
+            // JS required for folders
393
+            \OCP\Util::addStyle('files', 'merged');
394
+            \OCP\Util::addScript('files', 'filesummary');
395
+            \OCP\Util::addScript('files', 'breadcrumb');
396
+            \OCP\Util::addScript('files', 'fileinfomodel');
397
+            \OCP\Util::addScript('files', 'newfilemenu');
398
+            \OCP\Util::addScript('files', 'files');
399
+            \OCP\Util::addScript('files', 'filelist');
400
+            \OCP\Util::addScript('files', 'keyboardshortcuts');
401
+        }
402
+
403
+        // OpenGraph Support: http://ogp.me/
404
+        \OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]);
405
+        \OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->l10n->t('%s is publicly shared', [$shareTmpl['filename']])]);
406
+        \OCP\Util::addHeader('meta', ['property' => "og:site_name", 'content' => $this->defaults->getName()]);
407
+        \OCP\Util::addHeader('meta', ['property' => "og:url", 'content' => $shareTmpl['shareUrl']]);
408
+        \OCP\Util::addHeader('meta', ['property' => "og:type", 'content' => "object"]);
409
+        \OCP\Util::addHeader('meta', ['property' => "og:image", 'content' => $shareTmpl['previewImage']]);
410
+
411
+        $this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts');
412
+
413
+        $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
414
+        $csp->addAllowedFrameDomain('\'self\'');
415
+        $response = new TemplateResponse($this->appName, 'public', $shareTmpl, 'base');
416
+        $response->setContentSecurityPolicy($csp);
417
+
418
+        $this->emitAccessShareHook($share);
419
+
420
+        return $response;
421
+    }
422
+
423
+    /**
424
+     * @PublicPage
425
+     * @NoCSRFRequired
426
+     *
427
+     * @param string $token
428
+     * @param string $files
429
+     * @param string $path
430
+     * @param string $downloadStartSecret
431
+     * @return void|\OCP\AppFramework\Http\Response
432
+     * @throws NotFoundException
433
+     */
434
+    public function downloadShare($token, $files = null, $path = '', $downloadStartSecret = '') {
435
+        \OC_User::setIncognitoMode(true);
436
+
437
+        $share = $this->shareManager->getShareByToken($token);
438
+
439
+        if(!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
440
+            return new \OCP\AppFramework\Http\DataResponse('Share is read-only');
441
+        }
442
+
443
+        // Share is password protected - check whether the user is permitted to access the share
444
+        if ($share->getPassword() !== null && !$this->linkShareAuth($share)) {
445
+            return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.authenticate',
446
+                ['token' => $token]));
447
+        }
448
+
449
+        $files_list = null;
450
+        if (!is_null($files)) { // download selected files
451
+            $files_list = json_decode($files);
452
+            // in case we get only a single file
453
+            if ($files_list === null) {
454
+                $files_list = [$files];
455
+            }
456
+        }
457
+
458
+        $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
459
+        $originalSharePath = $userFolder->getRelativePath($share->getNode()->getPath());
460
+
461
+        if (!$this->validateShare($share)) {
462
+            throw new NotFoundException();
463
+        }
464
+
465
+        // Single file share
466
+        if ($share->getNode() instanceof \OCP\Files\File) {
467
+            // Single file download
468
+            $this->singleFileDownloaded($share, $share->getNode());
469
+        }
470
+        // Directory share
471
+        else {
472
+            /** @var \OCP\Files\Folder $node */
473
+            $node = $share->getNode();
474
+
475
+            // Try to get the path
476
+            if ($path !== '') {
477
+                try {
478
+                    $node = $node->get($path);
479
+                } catch (NotFoundException $e) {
480
+                    $this->emitAccessShareHook($share, 404, 'Share not found');
481
+                    return new NotFoundResponse();
482
+                }
483
+            }
484
+
485
+            $originalSharePath = $userFolder->getRelativePath($node->getPath());
486
+
487
+            if ($node instanceof \OCP\Files\File) {
488
+                // Single file download
489
+                $this->singleFileDownloaded($share, $share->getNode());
490
+            } else if (!empty($files_list)) {
491
+                $this->fileListDownloaded($share, $files_list, $node);
492
+            } else {
493
+                // The folder is downloaded
494
+                $this->singleFileDownloaded($share, $share->getNode());
495
+            }
496
+        }
497
+
498
+        /* FIXME: We should do this all nicely in OCP */
499
+        OC_Util::tearDownFS();
500
+        OC_Util::setupFS($share->getShareOwner());
501
+
502
+        /**
503
+         * this sets a cookie to be able to recognize the start of the download
504
+         * the content must not be longer than 32 characters and must only contain
505
+         * alphanumeric characters
506
+         */
507
+        if (!empty($downloadStartSecret)
508
+            && !isset($downloadStartSecret[32])
509
+            && preg_match('!^[a-zA-Z0-9]+$!', $downloadStartSecret) === 1) {
510
+
511
+            // FIXME: set on the response once we use an actual app framework response
512
+            setcookie('ocDownloadStarted', $downloadStartSecret, time() + 20, '/');
513
+        }
514
+
515
+        $this->emitAccessShareHook($share);
516
+
517
+        $server_params = array( 'head' => $this->request->getMethod() === 'HEAD' );
518
+
519
+        /**
520
+         * Http range requests support
521
+         */
522
+        if (isset($_SERVER['HTTP_RANGE'])) {
523
+            $server_params['range'] = $this->request->getHeader('Range');
524
+        }
525
+
526
+        // download selected files
527
+        if (!is_null($files) && $files !== '') {
528
+            // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
529
+            // after dispatching the request which results in a "Cannot modify header information" notice.
530
+            OC_Files::get($originalSharePath, $files_list, $server_params);
531
+            exit();
532
+        } else {
533
+            // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
534
+            // after dispatching the request which results in a "Cannot modify header information" notice.
535
+            OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $server_params);
536
+            exit();
537
+        }
538
+    }
539
+
540
+    /**
541
+     * create activity for every downloaded file
542
+     *
543
+     * @param Share\IShare $share
544
+     * @param array $files_list
545
+     * @param \OCP\Files\Folder $node
546
+     */
547
+    protected function fileListDownloaded(Share\IShare $share, array $files_list, \OCP\Files\Folder $node) {
548
+        foreach ($files_list as $file) {
549
+            $subNode = $node->get($file);
550
+            $this->singleFileDownloaded($share, $subNode);
551
+        }
552
+
553
+    }
554
+
555
+    /**
556
+     * create activity if a single file was downloaded from a link share
557
+     *
558
+     * @param Share\IShare $share
559
+     */
560
+    protected function singleFileDownloaded(Share\IShare $share, \OCP\Files\Node $node) {
561
+
562
+        $fileId = $node->getId();
563
+
564
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
565
+        $userNodeList = $userFolder->getById($fileId);
566
+        $userNode = $userNodeList[0];
567
+        $ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
568
+        $userPath = $userFolder->getRelativePath($userNode->getPath());
569
+        $ownerPath = $ownerFolder->getRelativePath($node->getPath());
570
+
571
+        $parameters = [$userPath];
572
+
573
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
574
+            if ($node instanceof \OCP\Files\File) {
575
+                $subject = Downloads::SUBJECT_SHARED_FILE_BY_EMAIL_DOWNLOADED;
576
+            } else {
577
+                $subject = Downloads::SUBJECT_SHARED_FOLDER_BY_EMAIL_DOWNLOADED;
578
+            }
579
+            $parameters[] = $share->getSharedWith();
580
+        } else {
581
+            if ($node instanceof \OCP\Files\File) {
582
+                $subject = Downloads::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED;
583
+            } else {
584
+                $subject = Downloads::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED;
585
+            }
586
+        }
587
+
588
+        $this->publishActivity($subject, $parameters, $share->getSharedBy(), $fileId, $userPath);
589
+
590
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
591
+            $parameters[0] = $ownerPath;
592
+            $this->publishActivity($subject, $parameters, $share->getShareOwner(), $fileId, $ownerPath);
593
+        }
594
+    }
595
+
596
+    /**
597
+     * publish activity
598
+     *
599
+     * @param string $subject
600
+     * @param array $parameters
601
+     * @param string $affectedUser
602
+     * @param int $fileId
603
+     * @param string $filePath
604
+     */
605
+    protected function publishActivity($subject,
606
+                                        array $parameters,
607
+                                        $affectedUser,
608
+                                        $fileId,
609
+                                        $filePath) {
610
+
611
+        $event = $this->activityManager->generateEvent();
612
+        $event->setApp('files_sharing')
613
+            ->setType('public_links')
614
+            ->setSubject($subject, $parameters)
615
+            ->setAffectedUser($affectedUser)
616
+            ->setObject('files', $fileId, $filePath);
617
+        $this->activityManager->publish($event);
618
+    }
619 619
 
620 620
 
621 621
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -150,7 +150,7 @@  discard block
 block discarded – undo
150 150
 	public function showAuthenticate($token) {
151 151
 		$share = $this->shareManager->getShareByToken($token);
152 152
 
153
-		if($this->linkShareAuth($share)) {
153
+		if ($this->linkShareAuth($share)) {
154 154
 			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
155 155
 		}
156 156
 
@@ -178,7 +178,7 @@  discard block
 block discarded – undo
178 178
 
179 179
 		$authenticate = $this->linkShareAuth($share, $password);
180 180
 
181
-		if($authenticate === true) {
181
+		if ($authenticate === true) {
182 182
 			return new RedirectResponse($this->urlGenerator->linkToRoute('files_sharing.sharecontroller.showShare', array('token' => $token)));
183 183
 		}
184 184
 
@@ -201,15 +201,15 @@  discard block
 block discarded – undo
201 201
 	private function linkShareAuth(\OCP\Share\IShare $share, $password = null) {
202 202
 		if ($password !== null) {
203 203
 			if ($this->shareManager->checkPassword($share, $password)) {
204
-				$this->session->set('public_link_authenticated', (string)$share->getId());
204
+				$this->session->set('public_link_authenticated', (string) $share->getId());
205 205
 			} else {
206 206
 				$this->emitAccessShareHook($share, 403, 'Wrong password');
207 207
 				return false;
208 208
 			}
209 209
 		} else {
210 210
 			// not authenticated ?
211
-			if ( ! $this->session->exists('public_link_authenticated')
212
-				|| $this->session->get('public_link_authenticated') !== (string)$share->getId()) {
211
+			if (!$this->session->exists('public_link_authenticated')
212
+				|| $this->session->get('public_link_authenticated') !== (string) $share->getId()) {
213 213
 				return false;
214 214
 			}
215 215
 		}
@@ -230,7 +230,7 @@  discard block
 block discarded – undo
230 230
 		$itemType = $itemSource = $uidOwner = '';
231 231
 		$token = $share;
232 232
 		$exception = null;
233
-		if($share instanceof \OCP\Share\IShare) {
233
+		if ($share instanceof \OCP\Share\IShare) {
234 234
 			try {
235 235
 				$token = $share->getToken();
236 236
 				$uidOwner = $share->getSharedBy();
@@ -249,7 +249,7 @@  discard block
 block discarded – undo
249 249
 			'errorCode' => $errorCode,
250 250
 			'errorMessage' => $errorMessage,
251 251
 		]);
252
-		if(!is_null($exception)) {
252
+		if (!is_null($exception)) {
253 253
 			throw $exception;
254 254
 		}
255 255
 	}
@@ -373,7 +373,7 @@  discard block
 block discarded – undo
373 373
 		$shareTmpl['previewMaxY'] = $this->config->getSystemValue('preview_max_y', 1024);
374 374
 		$shareTmpl['disclaimer'] = $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null);
375 375
 		if ($shareTmpl['previewSupported']) {
376
-			$shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute( 'files_sharing.PublicPreview.getPreview',
376
+			$shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.PublicPreview.getPreview',
377 377
 				['x' => 200, 'y' => 200, 'file' => $shareTmpl['directory_path'], 't' => $shareTmpl['dirToken']]);
378 378
 		} else {
379 379
 			$shareTmpl['previewImage'] = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-fb.png'));
@@ -401,7 +401,7 @@  discard block
 block discarded – undo
401 401
 		}
402 402
 
403 403
 		// OpenGraph Support: http://ogp.me/
404
-		\OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]);
404
+		\OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $this->defaults->getName().($this->defaults->getSlogan() !== '' ? ' - '.$this->defaults->getSlogan() : '')]);
405 405
 		\OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->l10n->t('%s is publicly shared', [$shareTmpl['filename']])]);
406 406
 		\OCP\Util::addHeader('meta', ['property' => "og:site_name", 'content' => $this->defaults->getName()]);
407 407
 		\OCP\Util::addHeader('meta', ['property' => "og:url", 'content' => $shareTmpl['shareUrl']]);
@@ -436,7 +436,7 @@  discard block
 block discarded – undo
436 436
 
437 437
 		$share = $this->shareManager->getShareByToken($token);
438 438
 
439
-		if(!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
439
+		if (!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
440 440
 			return new \OCP\AppFramework\Http\DataResponse('Share is read-only');
441 441
 		}
442 442
 
@@ -514,7 +514,7 @@  discard block
 block discarded – undo
514 514
 
515 515
 		$this->emitAccessShareHook($share);
516 516
 
517
-		$server_params = array( 'head' => $this->request->getMethod() === 'HEAD' );
517
+		$server_params = array('head' => $this->request->getMethod() === 'HEAD');
518 518
 
519 519
 		/**
520 520
 		 * Http range requests support
Please login to merge, or discard this patch.
apps/provisioning_api/lib/Controller/UsersController.php 4 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -225,7 +225,7 @@
 block discarded – undo
225 225
 	/**
226 226
 	 * creates a array with all user data
227 227
 	 *
228
-	 * @param $userId
228
+	 * @param string $userId
229 229
 	 * @return array
230 230
 	 * @throws OCSException
231 231
 	 */
Please login to merge, or discard this patch.
Braces   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -335,7 +335,7 @@
 block discarded – undo
335 335
 					}
336 336
 					if($quota === 0) {
337 337
 						$quota = 'default';
338
-					}else if($quota === -1) {
338
+					} else if($quota === -1) {
339 339
 						$quota = 'none';
340 340
 					} else {
341 341
 						$quota = \OCP\Util::humanFileSize($quota);
Please login to merge, or discard this patch.
Indentation   +782 added lines, -782 removed lines patch added patch discarded remove patch
@@ -49,786 +49,786 @@
 block discarded – undo
49 49
 
50 50
 class UsersController extends OCSController {
51 51
 
52
-	/** @var IUserManager */
53
-	private $userManager;
54
-	/** @var IConfig */
55
-	private $config;
56
-	/** @var IAppManager */
57
-	private $appManager;
58
-	/** @var IGroupManager|\OC\Group\Manager */ // FIXME Requires a method that is not on the interface
59
-	private $groupManager;
60
-	/** @var IUserSession */
61
-	private $userSession;
62
-	/** @var AccountManager */
63
-	private $accountManager;
64
-	/** @var ILogger */
65
-	private $logger;
66
-	/** @var IFactory */
67
-	private $l10nFactory;
68
-	/** @var NewUserMailHelper */
69
-	private $newUserMailHelper;
70
-
71
-	/**
72
-	 * @param string $appName
73
-	 * @param IRequest $request
74
-	 * @param IUserManager $userManager
75
-	 * @param IConfig $config
76
-	 * @param IAppManager $appManager
77
-	 * @param IGroupManager $groupManager
78
-	 * @param IUserSession $userSession
79
-	 * @param AccountManager $accountManager
80
-	 * @param ILogger $logger
81
-	 * @param IFactory $l10nFactory
82
-	 * @param NewUserMailHelper $newUserMailHelper
83
-	 */
84
-	public function __construct($appName,
85
-								IRequest $request,
86
-								IUserManager $userManager,
87
-								IConfig $config,
88
-								IAppManager $appManager,
89
-								IGroupManager $groupManager,
90
-								IUserSession $userSession,
91
-								AccountManager $accountManager,
92
-								ILogger $logger,
93
-								IFactory $l10nFactory,
94
-								NewUserMailHelper $newUserMailHelper) {
95
-		parent::__construct($appName, $request);
96
-
97
-		$this->userManager = $userManager;
98
-		$this->config = $config;
99
-		$this->appManager = $appManager;
100
-		$this->groupManager = $groupManager;
101
-		$this->userSession = $userSession;
102
-		$this->accountManager = $accountManager;
103
-		$this->logger = $logger;
104
-		$this->l10nFactory = $l10nFactory;
105
-		$this->newUserMailHelper = $newUserMailHelper;
106
-	}
107
-
108
-	/**
109
-	 * @NoAdminRequired
110
-	 *
111
-	 * returns a list of users
112
-	 *
113
-	 * @param string $search
114
-	 * @param int $limit
115
-	 * @param int $offset
116
-	 * @return DataResponse
117
-	 */
118
-	public function getUsers($search = '', $limit = null, $offset = null) {
119
-		$user = $this->userSession->getUser();
120
-		$users = [];
121
-
122
-		// Admin? Or SubAdmin?
123
-		$uid = $user->getUID();
124
-		$subAdminManager = $this->groupManager->getSubAdmin();
125
-		if($this->groupManager->isAdmin($uid)){
126
-			$users = $this->userManager->search($search, $limit, $offset);
127
-		} else if ($subAdminManager->isSubAdmin($user)) {
128
-			$subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
129
-			foreach ($subAdminOfGroups as $key => $group) {
130
-				$subAdminOfGroups[$key] = $group->getGID();
131
-			}
132
-
133
-			if($offset === null) {
134
-				$offset = 0;
135
-			}
136
-
137
-			$users = [];
138
-			foreach ($subAdminOfGroups as $group) {
139
-				$users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search));
140
-			}
141
-
142
-			$users = array_slice($users, $offset, $limit);
143
-		}
144
-
145
-		$users = array_keys($users);
146
-
147
-		return new DataResponse([
148
-			'users' => $users
149
-		]);
150
-	}
151
-
152
-	/**
153
-	 * @PasswordConfirmationRequired
154
-	 * @NoAdminRequired
155
-	 *
156
-	 * @param string $userid
157
-	 * @param string $password
158
-	 * @param array $groups
159
-	 * @return DataResponse
160
-	 * @throws OCSException
161
-	 */
162
-	public function addUser($userid, $password, $groups = null) {
163
-		$user = $this->userSession->getUser();
164
-		$isAdmin = $this->groupManager->isAdmin($user->getUID());
165
-		$subAdminManager = $this->groupManager->getSubAdmin();
166
-
167
-		if($this->userManager->userExists($userid)) {
168
-			$this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
169
-			throw new OCSException('User already exists', 102);
170
-		}
171
-
172
-		if(is_array($groups)) {
173
-			foreach ($groups as $group) {
174
-				if(!$this->groupManager->groupExists($group)) {
175
-					throw new OCSException('group '.$group.' does not exist', 104);
176
-				}
177
-				if(!$isAdmin && !$subAdminManager->isSubAdminofGroup($user, $this->groupManager->get($group))) {
178
-					throw new OCSException('insufficient privileges for group '. $group, 105);
179
-				}
180
-			}
181
-		} else {
182
-			if(!$isAdmin) {
183
-				throw new OCSException('no group specified (required for subadmins)', 106);
184
-			}
185
-		}
186
-
187
-		try {
188
-			$newUser = $this->userManager->createUser($userid, $password);
189
-			$this->logger->info('Successful addUser call with userid: '.$userid, ['app' => 'ocs_api']);
190
-
191
-			if (is_array($groups)) {
192
-				foreach ($groups as $group) {
193
-					$this->groupManager->get($group)->addUser($newUser);
194
-					$this->logger->info('Added userid '.$userid.' to group '.$group, ['app' => 'ocs_api']);
195
-				}
196
-			}
197
-			return new DataResponse();
198
-		} catch (\Exception $e) {
199
-			$this->logger->error('Failed addUser attempt with exception: '.$e->getMessage(), ['app' => 'ocs_api']);
200
-			throw new OCSException('Bad request', 101);
201
-		}
202
-	}
203
-
204
-	/**
205
-	 * @NoAdminRequired
206
-	 * @NoSubAdminRequired
207
-	 *
208
-	 * gets user info
209
-	 *
210
-	 * @param string $userId
211
-	 * @return DataResponse
212
-	 * @throws OCSException
213
-	 */
214
-	public function getUser($userId) {
215
-		$data = $this->getUserData($userId);
216
-		return new DataResponse($data);
217
-	}
218
-
219
-	/**
220
-	 * @NoAdminRequired
221
-	 * @NoSubAdminRequired
222
-	 *
223
-	 * gets user info from the currently logged in user
224
-	 *
225
-	 * @return DataResponse
226
-	 * @throws OCSException
227
-	 */
228
-	public function getCurrentUser() {
229
-		$user = $this->userSession->getUser();
230
-		if ($user) {
231
-			$data =  $this->getUserData($user->getUID());
232
-			// rename "displayname" to "display-name" only for this call to keep
233
-			// the API stable.
234
-			$data['display-name'] = $data['displayname'];
235
-			unset($data['displayname']);
236
-			return new DataResponse($data);
237
-
238
-		}
239
-
240
-		throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
241
-	}
242
-
243
-	/**
244
-	 * creates a array with all user data
245
-	 *
246
-	 * @param $userId
247
-	 * @return array
248
-	 * @throws OCSException
249
-	 */
250
-	protected function getUserData($userId) {
251
-		$currentLoggedInUser = $this->userSession->getUser();
252
-
253
-		$data = [];
254
-
255
-		// Check if the target user exists
256
-		$targetUserObject = $this->userManager->get($userId);
257
-		if($targetUserObject === null) {
258
-			throw new OCSException('The requested user could not be found', \OCP\API::RESPOND_NOT_FOUND);
259
-		}
260
-
261
-		// Admin? Or SubAdmin?
262
-		if($this->groupManager->isAdmin($currentLoggedInUser->getUID())
263
-			|| $this->groupManager->getSubAdmin()->isUserAccessible($currentLoggedInUser, $targetUserObject)) {
264
-			$data['enabled'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'enabled', 'true');
265
-		} else {
266
-			// Check they are looking up themselves
267
-			if($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) {
268
-				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
269
-			}
270
-		}
271
-
272
-		$userAccount = $this->accountManager->getUser($targetUserObject);
273
-		$groups = $this->groupManager->getUserGroups($targetUserObject);
274
-		$gids = [];
275
-		foreach ($groups as $group) {
276
-			$gids[] = $group->getDisplayName();
277
-		}
278
-
279
-		// Find the data
280
-		$data['id'] = $targetUserObject->getUID();
281
-		$data['quota'] = $this->fillStorageInfo($targetUserObject->getUID());
282
-		$data[AccountManager::PROPERTY_EMAIL] = $targetUserObject->getEMailAddress();
283
-		$data[AccountManager::PROPERTY_DISPLAYNAME] = $targetUserObject->getDisplayName();
284
-		$data[AccountManager::PROPERTY_PHONE] = $userAccount[AccountManager::PROPERTY_PHONE]['value'];
285
-		$data[AccountManager::PROPERTY_ADDRESS] = $userAccount[AccountManager::PROPERTY_ADDRESS]['value'];
286
-		$data[AccountManager::PROPERTY_WEBSITE] = $userAccount[AccountManager::PROPERTY_WEBSITE]['value'];
287
-		$data[AccountManager::PROPERTY_TWITTER] = $userAccount[AccountManager::PROPERTY_TWITTER]['value'];
288
-		$data['groups'] = $gids;
289
-		$data['language'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'lang');
290
-
291
-		return $data;
292
-	}
293
-
294
-	/**
295
-	 * @NoAdminRequired
296
-	 * @NoSubAdminRequired
297
-	 * @PasswordConfirmationRequired
298
-	 *
299
-	 * edit users
300
-	 *
301
-	 * @param string $userId
302
-	 * @param string $key
303
-	 * @param string $value
304
-	 * @return DataResponse
305
-	 * @throws OCSException
306
-	 * @throws OCSForbiddenException
307
-	 */
308
-	public function editUser($userId, $key, $value) {
309
-		$currentLoggedInUser = $this->userSession->getUser();
310
-
311
-		$targetUser = $this->userManager->get($userId);
312
-		if($targetUser === null) {
313
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
314
-		}
315
-
316
-		$permittedFields = [];
317
-		if($targetUser->getUID() === $currentLoggedInUser->getUID()) {
318
-			// Editing self (display, email)
319
-			if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
320
-				$permittedFields[] = 'display';
321
-				$permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
322
-				$permittedFields[] = AccountManager::PROPERTY_EMAIL;
323
-			}
324
-
325
-			$permittedFields[] = 'password';
326
-			if ($this->config->getSystemValue('force_language', false) === false ||
327
-				$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
328
-				$permittedFields[] = 'language';
329
-			}
330
-
331
-			if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
332
-				$federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
333
-				$shareProvider = $federatedFileSharing->getFederatedShareProvider();
334
-				if ($shareProvider->isLookupServerUploadEnabled()) {
335
-					$permittedFields[] = AccountManager::PROPERTY_PHONE;
336
-					$permittedFields[] = AccountManager::PROPERTY_ADDRESS;
337
-					$permittedFields[] = AccountManager::PROPERTY_WEBSITE;
338
-					$permittedFields[] = AccountManager::PROPERTY_TWITTER;
339
-				}
340
-			}
341
-
342
-			// If admin they can edit their own quota
343
-			if($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
344
-				$permittedFields[] = 'quota';
345
-			}
346
-		} else {
347
-			// Check if admin / subadmin
348
-			$subAdminManager = $this->groupManager->getSubAdmin();
349
-			if($subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
350
-			|| $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
351
-				// They have permissions over the user
352
-				$permittedFields[] = 'display';
353
-				$permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
354
-				$permittedFields[] = AccountManager::PROPERTY_EMAIL;
355
-				$permittedFields[] = 'password';
356
-				$permittedFields[] = 'language';
357
-				$permittedFields[] = AccountManager::PROPERTY_PHONE;
358
-				$permittedFields[] = AccountManager::PROPERTY_ADDRESS;
359
-				$permittedFields[] = AccountManager::PROPERTY_WEBSITE;
360
-				$permittedFields[] = AccountManager::PROPERTY_TWITTER;
361
-				$permittedFields[] = 'quota';
362
-			} else {
363
-				// No rights
364
-				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
365
-			}
366
-		}
367
-		// Check if permitted to edit this field
368
-		if(!in_array($key, $permittedFields)) {
369
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
370
-		}
371
-		// Process the edit
372
-		switch($key) {
373
-			case 'display':
374
-			case AccountManager::PROPERTY_DISPLAYNAME:
375
-				$targetUser->setDisplayName($value);
376
-				break;
377
-			case 'quota':
378
-				$quota = $value;
379
-				if($quota !== 'none' && $quota !== 'default') {
380
-					if (is_numeric($quota)) {
381
-						$quota = (float) $quota;
382
-					} else {
383
-						$quota = \OCP\Util::computerFileSize($quota);
384
-					}
385
-					if ($quota === false) {
386
-						throw new OCSException('Invalid quota value '.$value, 103);
387
-					}
388
-					if($quota === 0) {
389
-						$quota = 'default';
390
-					}else if($quota === -1) {
391
-						$quota = 'none';
392
-					} else {
393
-						$quota = \OCP\Util::humanFileSize($quota);
394
-					}
395
-				}
396
-				$targetUser->setQuota($quota);
397
-				break;
398
-			case 'password':
399
-				$targetUser->setPassword($value);
400
-				break;
401
-			case 'language':
402
-				$languagesCodes = $this->l10nFactory->findAvailableLanguages();
403
-				if (!in_array($value, $languagesCodes, true) && $value !== 'en') {
404
-					throw new OCSException('Invalid language', 102);
405
-				}
406
-				$this->config->setUserValue($targetUser->getUID(), 'core', 'lang', $value);
407
-				break;
408
-			case AccountManager::PROPERTY_EMAIL:
409
-				if(filter_var($value, FILTER_VALIDATE_EMAIL)) {
410
-					$targetUser->setEMailAddress($value);
411
-				} else {
412
-					throw new OCSException('', 102);
413
-				}
414
-				break;
415
-			case AccountManager::PROPERTY_PHONE:
416
-			case AccountManager::PROPERTY_ADDRESS:
417
-			case AccountManager::PROPERTY_WEBSITE:
418
-			case AccountManager::PROPERTY_TWITTER:
419
-				$userAccount = $this->accountManager->getUser($targetUser);
420
-				if ($userAccount[$key]['value'] !== $value) {
421
-					$userAccount[$key]['value'] = $value;
422
-					$this->accountManager->updateUser($targetUser, $userAccount);
423
-				}
424
-				break;
425
-			default:
426
-				throw new OCSException('', 103);
427
-		}
428
-		return new DataResponse();
429
-	}
430
-
431
-	/**
432
-	 * @PasswordConfirmationRequired
433
-	 * @NoAdminRequired
434
-	 *
435
-	 * @param string $userId
436
-	 * @return DataResponse
437
-	 * @throws OCSException
438
-	 * @throws OCSForbiddenException
439
-	 */
440
-	public function deleteUser($userId) {
441
-		$currentLoggedInUser = $this->userSession->getUser();
442
-
443
-		$targetUser = $this->userManager->get($userId);
444
-
445
-		if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
446
-			throw new OCSException('', 101);
447
-		}
448
-
449
-		// If not permitted
450
-		$subAdminManager = $this->groupManager->getSubAdmin();
451
-		if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
452
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
453
-		}
454
-
455
-		// Go ahead with the delete
456
-		if($targetUser->delete()) {
457
-			return new DataResponse();
458
-		} else {
459
-			throw new OCSException('', 101);
460
-		}
461
-	}
462
-
463
-	/**
464
-	 * @PasswordConfirmationRequired
465
-	 * @NoAdminRequired
466
-	 *
467
-	 * @param string $userId
468
-	 * @return DataResponse
469
-	 * @throws OCSException
470
-	 * @throws OCSForbiddenException
471
-	 */
472
-	public function disableUser($userId) {
473
-		return $this->setEnabled($userId, false);
474
-	}
475
-
476
-	/**
477
-	 * @PasswordConfirmationRequired
478
-	 * @NoAdminRequired
479
-	 *
480
-	 * @param string $userId
481
-	 * @return DataResponse
482
-	 * @throws OCSException
483
-	 * @throws OCSForbiddenException
484
-	 */
485
-	public function enableUser($userId) {
486
-		return $this->setEnabled($userId, true);
487
-	}
488
-
489
-	/**
490
-	 * @param string $userId
491
-	 * @param bool $value
492
-	 * @return DataResponse
493
-	 * @throws OCSException
494
-	 * @throws OCSForbiddenException
495
-	 */
496
-	private function setEnabled($userId, $value) {
497
-		$currentLoggedInUser = $this->userSession->getUser();
498
-
499
-		$targetUser = $this->userManager->get($userId);
500
-		if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
501
-			throw new OCSException('', 101);
502
-		}
503
-
504
-		// If not permitted
505
-		$subAdminManager = $this->groupManager->getSubAdmin();
506
-		if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
507
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
508
-		}
509
-
510
-		// enable/disable the user now
511
-		$targetUser->setEnabled($value);
512
-		return new DataResponse();
513
-	}
514
-
515
-	/**
516
-	 * @NoAdminRequired
517
-	 * @NoSubAdminRequired
518
-	 *
519
-	 * @param string $userId
520
-	 * @return DataResponse
521
-	 * @throws OCSException
522
-	 */
523
-	public function getUsersGroups($userId) {
524
-		$loggedInUser = $this->userSession->getUser();
525
-
526
-		$targetUser = $this->userManager->get($userId);
527
-		if($targetUser === null) {
528
-			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
529
-		}
530
-
531
-		if($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
532
-			// Self lookup or admin lookup
533
-			return new DataResponse([
534
-				'groups' => $this->groupManager->getUserGroupIds($targetUser)
535
-			]);
536
-		} else {
537
-			$subAdminManager = $this->groupManager->getSubAdmin();
538
-
539
-			// Looking up someone else
540
-			if($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
541
-				// Return the group that the method caller is subadmin of for the user in question
542
-				/** @var IGroup[] $getSubAdminsGroups */
543
-				$getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
544
-				foreach ($getSubAdminsGroups as $key => $group) {
545
-					$getSubAdminsGroups[$key] = $group->getGID();
546
-				}
547
-				$groups = array_intersect(
548
-					$getSubAdminsGroups,
549
-					$this->groupManager->getUserGroupIds($targetUser)
550
-				);
551
-				return new DataResponse(['groups' => $groups]);
552
-			} else {
553
-				// Not permitted
554
-				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
555
-			}
556
-		}
557
-
558
-	}
559
-
560
-	/**
561
-	 * @PasswordConfirmationRequired
562
-	 * @NoAdminRequired
563
-	 *
564
-	 * @param string $userId
565
-	 * @param string $groupid
566
-	 * @return DataResponse
567
-	 * @throws OCSException
568
-	 */
569
-	public function addToGroup($userId, $groupid = '') {
570
-		if($groupid === '') {
571
-			throw new OCSException('', 101);
572
-		}
573
-
574
-		$group = $this->groupManager->get($groupid);
575
-		$targetUser = $this->userManager->get($userId);
576
-		if($group === null) {
577
-			throw new OCSException('', 102);
578
-		}
579
-		if($targetUser === null) {
580
-			throw new OCSException('', 103);
581
-		}
582
-
583
-		// If they're not an admin, check they are a subadmin of the group in question
584
-		$loggedInUser = $this->userSession->getUser();
585
-		$subAdminManager = $this->groupManager->getSubAdmin();
586
-		if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
587
-			throw new OCSException('', 104);
588
-		}
589
-
590
-		// Add user to group
591
-		$group->addUser($targetUser);
592
-		return new DataResponse();
593
-	}
594
-
595
-	/**
596
-	 * @PasswordConfirmationRequired
597
-	 * @NoAdminRequired
598
-	 *
599
-	 * @param string $userId
600
-	 * @param string $groupid
601
-	 * @return DataResponse
602
-	 * @throws OCSException
603
-	 */
604
-	public function removeFromGroup($userId, $groupid) {
605
-		$loggedInUser = $this->userSession->getUser();
606
-
607
-		if($groupid === null || trim($groupid) === '') {
608
-			throw new OCSException('', 101);
609
-		}
610
-
611
-		$group = $this->groupManager->get($groupid);
612
-		if($group === null) {
613
-			throw new OCSException('', 102);
614
-		}
615
-
616
-		$targetUser = $this->userManager->get($userId);
617
-		if($targetUser === null) {
618
-			throw new OCSException('', 103);
619
-		}
620
-
621
-		// If they're not an admin, check they are a subadmin of the group in question
622
-		$subAdminManager = $this->groupManager->getSubAdmin();
623
-		if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
624
-			throw new OCSException('', 104);
625
-		}
626
-
627
-		// Check they aren't removing themselves from 'admin' or their 'subadmin; group
628
-		if ($targetUser->getUID() === $loggedInUser->getUID()) {
629
-			if ($this->groupManager->isAdmin($loggedInUser->getUID())) {
630
-				if ($group->getGID() === 'admin') {
631
-					throw new OCSException('Cannot remove yourself from the admin group', 105);
632
-				}
633
-			} else {
634
-				// Not an admin, so the user must be a subadmin of this group, but that is not allowed.
635
-				throw new OCSException('Cannot remove yourself from this group as you are a SubAdmin', 105);
636
-			}
637
-
638
-		} else if (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
639
-			/** @var IGroup[] $subAdminGroups */
640
-			$subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
641
-			$subAdminGroups = array_map(function (IGroup $subAdminGroup) {
642
-				return $subAdminGroup->getGID();
643
-			}, $subAdminGroups);
644
-			$userGroups = $this->groupManager->getUserGroupIds($targetUser);
645
-			$userSubAdminGroups = array_intersect($subAdminGroups, $userGroups);
646
-
647
-			if (count($userSubAdminGroups) <= 1) {
648
-				// Subadmin must not be able to remove a user from all their subadmin groups.
649
-				throw new OCSException('Cannot remove user from this group as this is the only remaining group you are a SubAdmin of', 105);
650
-			}
651
-		}
652
-
653
-		// Remove user from group
654
-		$group->removeUser($targetUser);
655
-		return new DataResponse();
656
-	}
657
-
658
-	/**
659
-	 * Creates a subadmin
660
-	 *
661
-	 * @PasswordConfirmationRequired
662
-	 *
663
-	 * @param string $userId
664
-	 * @param string $groupid
665
-	 * @return DataResponse
666
-	 * @throws OCSException
667
-	 */
668
-	public function addSubAdmin($userId, $groupid) {
669
-		$group = $this->groupManager->get($groupid);
670
-		$user = $this->userManager->get($userId);
671
-
672
-		// Check if the user exists
673
-		if($user === null) {
674
-			throw new OCSException('User does not exist', 101);
675
-		}
676
-		// Check if group exists
677
-		if($group === null) {
678
-			throw new OCSException('Group does not exist',  102);
679
-		}
680
-		// Check if trying to make subadmin of admin group
681
-		if($group->getGID() === 'admin') {
682
-			throw new OCSException('Cannot create subadmins for admin group', 103);
683
-		}
684
-
685
-		$subAdminManager = $this->groupManager->getSubAdmin();
686
-
687
-		// We cannot be subadmin twice
688
-		if ($subAdminManager->isSubAdminofGroup($user, $group)) {
689
-			return new DataResponse();
690
-		}
691
-		// Go
692
-		if($subAdminManager->createSubAdmin($user, $group)) {
693
-			return new DataResponse();
694
-		} else {
695
-			throw new OCSException('Unknown error occurred', 103);
696
-		}
697
-	}
698
-
699
-	/**
700
-	 * Removes a subadmin from a group
701
-	 *
702
-	 * @PasswordConfirmationRequired
703
-	 *
704
-	 * @param string $userId
705
-	 * @param string $groupid
706
-	 * @return DataResponse
707
-	 * @throws OCSException
708
-	 */
709
-	public function removeSubAdmin($userId, $groupid) {
710
-		$group = $this->groupManager->get($groupid);
711
-		$user = $this->userManager->get($userId);
712
-		$subAdminManager = $this->groupManager->getSubAdmin();
713
-
714
-		// Check if the user exists
715
-		if($user === null) {
716
-			throw new OCSException('User does not exist', 101);
717
-		}
718
-		// Check if the group exists
719
-		if($group === null) {
720
-			throw new OCSException('Group does not exist', 101);
721
-		}
722
-		// Check if they are a subadmin of this said group
723
-		if(!$subAdminManager->isSubAdminOfGroup($user, $group)) {
724
-			throw new OCSException('User is not a subadmin of this group', 102);
725
-		}
726
-
727
-		// Go
728
-		if($subAdminManager->deleteSubAdmin($user, $group)) {
729
-			return new DataResponse();
730
-		} else {
731
-			throw new OCSException('Unknown error occurred', 103);
732
-		}
733
-	}
734
-
735
-	/**
736
-	 * Get the groups a user is a subadmin of
737
-	 *
738
-	 * @param string $userId
739
-	 * @return DataResponse
740
-	 * @throws OCSException
741
-	 */
742
-	public function getUserSubAdminGroups($userId) {
743
-		$user = $this->userManager->get($userId);
744
-		// Check if the user exists
745
-		if($user === null) {
746
-			throw new OCSException('User does not exist', 101);
747
-		}
748
-
749
-		// Get the subadmin groups
750
-		$groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
751
-		foreach ($groups as $key => $group) {
752
-			$groups[$key] = $group->getGID();
753
-		}
754
-
755
-		if(!$groups) {
756
-			throw new OCSException('Unknown error occurred', 102);
757
-		} else {
758
-			return new DataResponse($groups);
759
-		}
760
-	}
761
-
762
-	/**
763
-	 * @param string $userId
764
-	 * @return array
765
-	 * @throws \OCP\Files\NotFoundException
766
-	 */
767
-	protected function fillStorageInfo($userId) {
768
-		try {
769
-			\OC_Util::tearDownFS();
770
-			\OC_Util::setupFS($userId);
771
-			$storage = OC_Helper::getStorageInfo('/');
772
-			$data = [
773
-				'free' => $storage['free'],
774
-				'used' => $storage['used'],
775
-				'total' => $storage['total'],
776
-				'relative' => $storage['relative'],
777
-				'quota' => $storage['quota'],
778
-			];
779
-		} catch (NotFoundException $ex) {
780
-			$data = [];
781
-		}
782
-		return $data;
783
-	}
784
-
785
-	/**
786
-	 * @NoAdminRequired
787
-	 * @PasswordConfirmationRequired
788
-	 *
789
-	 * resend welcome message
790
-	 *
791
-	 * @param string $userId
792
-	 * @return DataResponse
793
-	 * @throws OCSException
794
-	 */
795
-	public function resendWelcomeMessage($userId) {
796
-		$currentLoggedInUser = $this->userSession->getUser();
797
-
798
-		$targetUser = $this->userManager->get($userId);
799
-		if($targetUser === null) {
800
-			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
801
-		}
802
-
803
-		// Check if admin / subadmin
804
-		$subAdminManager = $this->groupManager->getSubAdmin();
805
-		if(!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
806
-			&& !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
807
-			// No rights
808
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
809
-		}
810
-
811
-		$email = $targetUser->getEMailAddress();
812
-		if ($email === '' || $email === null) {
813
-			throw new OCSException('Email address not available', 101);
814
-		}
815
-		$username = $targetUser->getUID();
816
-		$lang = $this->config->getUserValue($username, 'core', 'lang', 'en');
817
-		if (!$this->l10nFactory->languageExists('settings', $lang)) {
818
-			$lang = 'en';
819
-		}
820
-
821
-		$l10n = $this->l10nFactory->get('settings', $lang);
822
-
823
-		try {
824
-			$this->newUserMailHelper->setL10N($l10n);
825
-			$emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
826
-			$this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
827
-		} catch(\Exception $e) {
828
-			$this->logger->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
829
-			throw new OCSException('Sending email failed', 102);
830
-		}
831
-
832
-		return new DataResponse();
833
-	}
52
+    /** @var IUserManager */
53
+    private $userManager;
54
+    /** @var IConfig */
55
+    private $config;
56
+    /** @var IAppManager */
57
+    private $appManager;
58
+    /** @var IGroupManager|\OC\Group\Manager */ // FIXME Requires a method that is not on the interface
59
+    private $groupManager;
60
+    /** @var IUserSession */
61
+    private $userSession;
62
+    /** @var AccountManager */
63
+    private $accountManager;
64
+    /** @var ILogger */
65
+    private $logger;
66
+    /** @var IFactory */
67
+    private $l10nFactory;
68
+    /** @var NewUserMailHelper */
69
+    private $newUserMailHelper;
70
+
71
+    /**
72
+     * @param string $appName
73
+     * @param IRequest $request
74
+     * @param IUserManager $userManager
75
+     * @param IConfig $config
76
+     * @param IAppManager $appManager
77
+     * @param IGroupManager $groupManager
78
+     * @param IUserSession $userSession
79
+     * @param AccountManager $accountManager
80
+     * @param ILogger $logger
81
+     * @param IFactory $l10nFactory
82
+     * @param NewUserMailHelper $newUserMailHelper
83
+     */
84
+    public function __construct($appName,
85
+                                IRequest $request,
86
+                                IUserManager $userManager,
87
+                                IConfig $config,
88
+                                IAppManager $appManager,
89
+                                IGroupManager $groupManager,
90
+                                IUserSession $userSession,
91
+                                AccountManager $accountManager,
92
+                                ILogger $logger,
93
+                                IFactory $l10nFactory,
94
+                                NewUserMailHelper $newUserMailHelper) {
95
+        parent::__construct($appName, $request);
96
+
97
+        $this->userManager = $userManager;
98
+        $this->config = $config;
99
+        $this->appManager = $appManager;
100
+        $this->groupManager = $groupManager;
101
+        $this->userSession = $userSession;
102
+        $this->accountManager = $accountManager;
103
+        $this->logger = $logger;
104
+        $this->l10nFactory = $l10nFactory;
105
+        $this->newUserMailHelper = $newUserMailHelper;
106
+    }
107
+
108
+    /**
109
+     * @NoAdminRequired
110
+     *
111
+     * returns a list of users
112
+     *
113
+     * @param string $search
114
+     * @param int $limit
115
+     * @param int $offset
116
+     * @return DataResponse
117
+     */
118
+    public function getUsers($search = '', $limit = null, $offset = null) {
119
+        $user = $this->userSession->getUser();
120
+        $users = [];
121
+
122
+        // Admin? Or SubAdmin?
123
+        $uid = $user->getUID();
124
+        $subAdminManager = $this->groupManager->getSubAdmin();
125
+        if($this->groupManager->isAdmin($uid)){
126
+            $users = $this->userManager->search($search, $limit, $offset);
127
+        } else if ($subAdminManager->isSubAdmin($user)) {
128
+            $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
129
+            foreach ($subAdminOfGroups as $key => $group) {
130
+                $subAdminOfGroups[$key] = $group->getGID();
131
+            }
132
+
133
+            if($offset === null) {
134
+                $offset = 0;
135
+            }
136
+
137
+            $users = [];
138
+            foreach ($subAdminOfGroups as $group) {
139
+                $users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search));
140
+            }
141
+
142
+            $users = array_slice($users, $offset, $limit);
143
+        }
144
+
145
+        $users = array_keys($users);
146
+
147
+        return new DataResponse([
148
+            'users' => $users
149
+        ]);
150
+    }
151
+
152
+    /**
153
+     * @PasswordConfirmationRequired
154
+     * @NoAdminRequired
155
+     *
156
+     * @param string $userid
157
+     * @param string $password
158
+     * @param array $groups
159
+     * @return DataResponse
160
+     * @throws OCSException
161
+     */
162
+    public function addUser($userid, $password, $groups = null) {
163
+        $user = $this->userSession->getUser();
164
+        $isAdmin = $this->groupManager->isAdmin($user->getUID());
165
+        $subAdminManager = $this->groupManager->getSubAdmin();
166
+
167
+        if($this->userManager->userExists($userid)) {
168
+            $this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
169
+            throw new OCSException('User already exists', 102);
170
+        }
171
+
172
+        if(is_array($groups)) {
173
+            foreach ($groups as $group) {
174
+                if(!$this->groupManager->groupExists($group)) {
175
+                    throw new OCSException('group '.$group.' does not exist', 104);
176
+                }
177
+                if(!$isAdmin && !$subAdminManager->isSubAdminofGroup($user, $this->groupManager->get($group))) {
178
+                    throw new OCSException('insufficient privileges for group '. $group, 105);
179
+                }
180
+            }
181
+        } else {
182
+            if(!$isAdmin) {
183
+                throw new OCSException('no group specified (required for subadmins)', 106);
184
+            }
185
+        }
186
+
187
+        try {
188
+            $newUser = $this->userManager->createUser($userid, $password);
189
+            $this->logger->info('Successful addUser call with userid: '.$userid, ['app' => 'ocs_api']);
190
+
191
+            if (is_array($groups)) {
192
+                foreach ($groups as $group) {
193
+                    $this->groupManager->get($group)->addUser($newUser);
194
+                    $this->logger->info('Added userid '.$userid.' to group '.$group, ['app' => 'ocs_api']);
195
+                }
196
+            }
197
+            return new DataResponse();
198
+        } catch (\Exception $e) {
199
+            $this->logger->error('Failed addUser attempt with exception: '.$e->getMessage(), ['app' => 'ocs_api']);
200
+            throw new OCSException('Bad request', 101);
201
+        }
202
+    }
203
+
204
+    /**
205
+     * @NoAdminRequired
206
+     * @NoSubAdminRequired
207
+     *
208
+     * gets user info
209
+     *
210
+     * @param string $userId
211
+     * @return DataResponse
212
+     * @throws OCSException
213
+     */
214
+    public function getUser($userId) {
215
+        $data = $this->getUserData($userId);
216
+        return new DataResponse($data);
217
+    }
218
+
219
+    /**
220
+     * @NoAdminRequired
221
+     * @NoSubAdminRequired
222
+     *
223
+     * gets user info from the currently logged in user
224
+     *
225
+     * @return DataResponse
226
+     * @throws OCSException
227
+     */
228
+    public function getCurrentUser() {
229
+        $user = $this->userSession->getUser();
230
+        if ($user) {
231
+            $data =  $this->getUserData($user->getUID());
232
+            // rename "displayname" to "display-name" only for this call to keep
233
+            // the API stable.
234
+            $data['display-name'] = $data['displayname'];
235
+            unset($data['displayname']);
236
+            return new DataResponse($data);
237
+
238
+        }
239
+
240
+        throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
241
+    }
242
+
243
+    /**
244
+     * creates a array with all user data
245
+     *
246
+     * @param $userId
247
+     * @return array
248
+     * @throws OCSException
249
+     */
250
+    protected function getUserData($userId) {
251
+        $currentLoggedInUser = $this->userSession->getUser();
252
+
253
+        $data = [];
254
+
255
+        // Check if the target user exists
256
+        $targetUserObject = $this->userManager->get($userId);
257
+        if($targetUserObject === null) {
258
+            throw new OCSException('The requested user could not be found', \OCP\API::RESPOND_NOT_FOUND);
259
+        }
260
+
261
+        // Admin? Or SubAdmin?
262
+        if($this->groupManager->isAdmin($currentLoggedInUser->getUID())
263
+            || $this->groupManager->getSubAdmin()->isUserAccessible($currentLoggedInUser, $targetUserObject)) {
264
+            $data['enabled'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'enabled', 'true');
265
+        } else {
266
+            // Check they are looking up themselves
267
+            if($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) {
268
+                throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
269
+            }
270
+        }
271
+
272
+        $userAccount = $this->accountManager->getUser($targetUserObject);
273
+        $groups = $this->groupManager->getUserGroups($targetUserObject);
274
+        $gids = [];
275
+        foreach ($groups as $group) {
276
+            $gids[] = $group->getDisplayName();
277
+        }
278
+
279
+        // Find the data
280
+        $data['id'] = $targetUserObject->getUID();
281
+        $data['quota'] = $this->fillStorageInfo($targetUserObject->getUID());
282
+        $data[AccountManager::PROPERTY_EMAIL] = $targetUserObject->getEMailAddress();
283
+        $data[AccountManager::PROPERTY_DISPLAYNAME] = $targetUserObject->getDisplayName();
284
+        $data[AccountManager::PROPERTY_PHONE] = $userAccount[AccountManager::PROPERTY_PHONE]['value'];
285
+        $data[AccountManager::PROPERTY_ADDRESS] = $userAccount[AccountManager::PROPERTY_ADDRESS]['value'];
286
+        $data[AccountManager::PROPERTY_WEBSITE] = $userAccount[AccountManager::PROPERTY_WEBSITE]['value'];
287
+        $data[AccountManager::PROPERTY_TWITTER] = $userAccount[AccountManager::PROPERTY_TWITTER]['value'];
288
+        $data['groups'] = $gids;
289
+        $data['language'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'lang');
290
+
291
+        return $data;
292
+    }
293
+
294
+    /**
295
+     * @NoAdminRequired
296
+     * @NoSubAdminRequired
297
+     * @PasswordConfirmationRequired
298
+     *
299
+     * edit users
300
+     *
301
+     * @param string $userId
302
+     * @param string $key
303
+     * @param string $value
304
+     * @return DataResponse
305
+     * @throws OCSException
306
+     * @throws OCSForbiddenException
307
+     */
308
+    public function editUser($userId, $key, $value) {
309
+        $currentLoggedInUser = $this->userSession->getUser();
310
+
311
+        $targetUser = $this->userManager->get($userId);
312
+        if($targetUser === null) {
313
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
314
+        }
315
+
316
+        $permittedFields = [];
317
+        if($targetUser->getUID() === $currentLoggedInUser->getUID()) {
318
+            // Editing self (display, email)
319
+            if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
320
+                $permittedFields[] = 'display';
321
+                $permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
322
+                $permittedFields[] = AccountManager::PROPERTY_EMAIL;
323
+            }
324
+
325
+            $permittedFields[] = 'password';
326
+            if ($this->config->getSystemValue('force_language', false) === false ||
327
+                $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
328
+                $permittedFields[] = 'language';
329
+            }
330
+
331
+            if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
332
+                $federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
333
+                $shareProvider = $federatedFileSharing->getFederatedShareProvider();
334
+                if ($shareProvider->isLookupServerUploadEnabled()) {
335
+                    $permittedFields[] = AccountManager::PROPERTY_PHONE;
336
+                    $permittedFields[] = AccountManager::PROPERTY_ADDRESS;
337
+                    $permittedFields[] = AccountManager::PROPERTY_WEBSITE;
338
+                    $permittedFields[] = AccountManager::PROPERTY_TWITTER;
339
+                }
340
+            }
341
+
342
+            // If admin they can edit their own quota
343
+            if($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
344
+                $permittedFields[] = 'quota';
345
+            }
346
+        } else {
347
+            // Check if admin / subadmin
348
+            $subAdminManager = $this->groupManager->getSubAdmin();
349
+            if($subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
350
+            || $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
351
+                // They have permissions over the user
352
+                $permittedFields[] = 'display';
353
+                $permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
354
+                $permittedFields[] = AccountManager::PROPERTY_EMAIL;
355
+                $permittedFields[] = 'password';
356
+                $permittedFields[] = 'language';
357
+                $permittedFields[] = AccountManager::PROPERTY_PHONE;
358
+                $permittedFields[] = AccountManager::PROPERTY_ADDRESS;
359
+                $permittedFields[] = AccountManager::PROPERTY_WEBSITE;
360
+                $permittedFields[] = AccountManager::PROPERTY_TWITTER;
361
+                $permittedFields[] = 'quota';
362
+            } else {
363
+                // No rights
364
+                throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
365
+            }
366
+        }
367
+        // Check if permitted to edit this field
368
+        if(!in_array($key, $permittedFields)) {
369
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
370
+        }
371
+        // Process the edit
372
+        switch($key) {
373
+            case 'display':
374
+            case AccountManager::PROPERTY_DISPLAYNAME:
375
+                $targetUser->setDisplayName($value);
376
+                break;
377
+            case 'quota':
378
+                $quota = $value;
379
+                if($quota !== 'none' && $quota !== 'default') {
380
+                    if (is_numeric($quota)) {
381
+                        $quota = (float) $quota;
382
+                    } else {
383
+                        $quota = \OCP\Util::computerFileSize($quota);
384
+                    }
385
+                    if ($quota === false) {
386
+                        throw new OCSException('Invalid quota value '.$value, 103);
387
+                    }
388
+                    if($quota === 0) {
389
+                        $quota = 'default';
390
+                    }else if($quota === -1) {
391
+                        $quota = 'none';
392
+                    } else {
393
+                        $quota = \OCP\Util::humanFileSize($quota);
394
+                    }
395
+                }
396
+                $targetUser->setQuota($quota);
397
+                break;
398
+            case 'password':
399
+                $targetUser->setPassword($value);
400
+                break;
401
+            case 'language':
402
+                $languagesCodes = $this->l10nFactory->findAvailableLanguages();
403
+                if (!in_array($value, $languagesCodes, true) && $value !== 'en') {
404
+                    throw new OCSException('Invalid language', 102);
405
+                }
406
+                $this->config->setUserValue($targetUser->getUID(), 'core', 'lang', $value);
407
+                break;
408
+            case AccountManager::PROPERTY_EMAIL:
409
+                if(filter_var($value, FILTER_VALIDATE_EMAIL)) {
410
+                    $targetUser->setEMailAddress($value);
411
+                } else {
412
+                    throw new OCSException('', 102);
413
+                }
414
+                break;
415
+            case AccountManager::PROPERTY_PHONE:
416
+            case AccountManager::PROPERTY_ADDRESS:
417
+            case AccountManager::PROPERTY_WEBSITE:
418
+            case AccountManager::PROPERTY_TWITTER:
419
+                $userAccount = $this->accountManager->getUser($targetUser);
420
+                if ($userAccount[$key]['value'] !== $value) {
421
+                    $userAccount[$key]['value'] = $value;
422
+                    $this->accountManager->updateUser($targetUser, $userAccount);
423
+                }
424
+                break;
425
+            default:
426
+                throw new OCSException('', 103);
427
+        }
428
+        return new DataResponse();
429
+    }
430
+
431
+    /**
432
+     * @PasswordConfirmationRequired
433
+     * @NoAdminRequired
434
+     *
435
+     * @param string $userId
436
+     * @return DataResponse
437
+     * @throws OCSException
438
+     * @throws OCSForbiddenException
439
+     */
440
+    public function deleteUser($userId) {
441
+        $currentLoggedInUser = $this->userSession->getUser();
442
+
443
+        $targetUser = $this->userManager->get($userId);
444
+
445
+        if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
446
+            throw new OCSException('', 101);
447
+        }
448
+
449
+        // If not permitted
450
+        $subAdminManager = $this->groupManager->getSubAdmin();
451
+        if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
452
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
453
+        }
454
+
455
+        // Go ahead with the delete
456
+        if($targetUser->delete()) {
457
+            return new DataResponse();
458
+        } else {
459
+            throw new OCSException('', 101);
460
+        }
461
+    }
462
+
463
+    /**
464
+     * @PasswordConfirmationRequired
465
+     * @NoAdminRequired
466
+     *
467
+     * @param string $userId
468
+     * @return DataResponse
469
+     * @throws OCSException
470
+     * @throws OCSForbiddenException
471
+     */
472
+    public function disableUser($userId) {
473
+        return $this->setEnabled($userId, false);
474
+    }
475
+
476
+    /**
477
+     * @PasswordConfirmationRequired
478
+     * @NoAdminRequired
479
+     *
480
+     * @param string $userId
481
+     * @return DataResponse
482
+     * @throws OCSException
483
+     * @throws OCSForbiddenException
484
+     */
485
+    public function enableUser($userId) {
486
+        return $this->setEnabled($userId, true);
487
+    }
488
+
489
+    /**
490
+     * @param string $userId
491
+     * @param bool $value
492
+     * @return DataResponse
493
+     * @throws OCSException
494
+     * @throws OCSForbiddenException
495
+     */
496
+    private function setEnabled($userId, $value) {
497
+        $currentLoggedInUser = $this->userSession->getUser();
498
+
499
+        $targetUser = $this->userManager->get($userId);
500
+        if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
501
+            throw new OCSException('', 101);
502
+        }
503
+
504
+        // If not permitted
505
+        $subAdminManager = $this->groupManager->getSubAdmin();
506
+        if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
507
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
508
+        }
509
+
510
+        // enable/disable the user now
511
+        $targetUser->setEnabled($value);
512
+        return new DataResponse();
513
+    }
514
+
515
+    /**
516
+     * @NoAdminRequired
517
+     * @NoSubAdminRequired
518
+     *
519
+     * @param string $userId
520
+     * @return DataResponse
521
+     * @throws OCSException
522
+     */
523
+    public function getUsersGroups($userId) {
524
+        $loggedInUser = $this->userSession->getUser();
525
+
526
+        $targetUser = $this->userManager->get($userId);
527
+        if($targetUser === null) {
528
+            throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
529
+        }
530
+
531
+        if($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
532
+            // Self lookup or admin lookup
533
+            return new DataResponse([
534
+                'groups' => $this->groupManager->getUserGroupIds($targetUser)
535
+            ]);
536
+        } else {
537
+            $subAdminManager = $this->groupManager->getSubAdmin();
538
+
539
+            // Looking up someone else
540
+            if($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
541
+                // Return the group that the method caller is subadmin of for the user in question
542
+                /** @var IGroup[] $getSubAdminsGroups */
543
+                $getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
544
+                foreach ($getSubAdminsGroups as $key => $group) {
545
+                    $getSubAdminsGroups[$key] = $group->getGID();
546
+                }
547
+                $groups = array_intersect(
548
+                    $getSubAdminsGroups,
549
+                    $this->groupManager->getUserGroupIds($targetUser)
550
+                );
551
+                return new DataResponse(['groups' => $groups]);
552
+            } else {
553
+                // Not permitted
554
+                throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
555
+            }
556
+        }
557
+
558
+    }
559
+
560
+    /**
561
+     * @PasswordConfirmationRequired
562
+     * @NoAdminRequired
563
+     *
564
+     * @param string $userId
565
+     * @param string $groupid
566
+     * @return DataResponse
567
+     * @throws OCSException
568
+     */
569
+    public function addToGroup($userId, $groupid = '') {
570
+        if($groupid === '') {
571
+            throw new OCSException('', 101);
572
+        }
573
+
574
+        $group = $this->groupManager->get($groupid);
575
+        $targetUser = $this->userManager->get($userId);
576
+        if($group === null) {
577
+            throw new OCSException('', 102);
578
+        }
579
+        if($targetUser === null) {
580
+            throw new OCSException('', 103);
581
+        }
582
+
583
+        // If they're not an admin, check they are a subadmin of the group in question
584
+        $loggedInUser = $this->userSession->getUser();
585
+        $subAdminManager = $this->groupManager->getSubAdmin();
586
+        if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
587
+            throw new OCSException('', 104);
588
+        }
589
+
590
+        // Add user to group
591
+        $group->addUser($targetUser);
592
+        return new DataResponse();
593
+    }
594
+
595
+    /**
596
+     * @PasswordConfirmationRequired
597
+     * @NoAdminRequired
598
+     *
599
+     * @param string $userId
600
+     * @param string $groupid
601
+     * @return DataResponse
602
+     * @throws OCSException
603
+     */
604
+    public function removeFromGroup($userId, $groupid) {
605
+        $loggedInUser = $this->userSession->getUser();
606
+
607
+        if($groupid === null || trim($groupid) === '') {
608
+            throw new OCSException('', 101);
609
+        }
610
+
611
+        $group = $this->groupManager->get($groupid);
612
+        if($group === null) {
613
+            throw new OCSException('', 102);
614
+        }
615
+
616
+        $targetUser = $this->userManager->get($userId);
617
+        if($targetUser === null) {
618
+            throw new OCSException('', 103);
619
+        }
620
+
621
+        // If they're not an admin, check they are a subadmin of the group in question
622
+        $subAdminManager = $this->groupManager->getSubAdmin();
623
+        if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
624
+            throw new OCSException('', 104);
625
+        }
626
+
627
+        // Check they aren't removing themselves from 'admin' or their 'subadmin; group
628
+        if ($targetUser->getUID() === $loggedInUser->getUID()) {
629
+            if ($this->groupManager->isAdmin($loggedInUser->getUID())) {
630
+                if ($group->getGID() === 'admin') {
631
+                    throw new OCSException('Cannot remove yourself from the admin group', 105);
632
+                }
633
+            } else {
634
+                // Not an admin, so the user must be a subadmin of this group, but that is not allowed.
635
+                throw new OCSException('Cannot remove yourself from this group as you are a SubAdmin', 105);
636
+            }
637
+
638
+        } else if (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
639
+            /** @var IGroup[] $subAdminGroups */
640
+            $subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
641
+            $subAdminGroups = array_map(function (IGroup $subAdminGroup) {
642
+                return $subAdminGroup->getGID();
643
+            }, $subAdminGroups);
644
+            $userGroups = $this->groupManager->getUserGroupIds($targetUser);
645
+            $userSubAdminGroups = array_intersect($subAdminGroups, $userGroups);
646
+
647
+            if (count($userSubAdminGroups) <= 1) {
648
+                // Subadmin must not be able to remove a user from all their subadmin groups.
649
+                throw new OCSException('Cannot remove user from this group as this is the only remaining group you are a SubAdmin of', 105);
650
+            }
651
+        }
652
+
653
+        // Remove user from group
654
+        $group->removeUser($targetUser);
655
+        return new DataResponse();
656
+    }
657
+
658
+    /**
659
+     * Creates a subadmin
660
+     *
661
+     * @PasswordConfirmationRequired
662
+     *
663
+     * @param string $userId
664
+     * @param string $groupid
665
+     * @return DataResponse
666
+     * @throws OCSException
667
+     */
668
+    public function addSubAdmin($userId, $groupid) {
669
+        $group = $this->groupManager->get($groupid);
670
+        $user = $this->userManager->get($userId);
671
+
672
+        // Check if the user exists
673
+        if($user === null) {
674
+            throw new OCSException('User does not exist', 101);
675
+        }
676
+        // Check if group exists
677
+        if($group === null) {
678
+            throw new OCSException('Group does not exist',  102);
679
+        }
680
+        // Check if trying to make subadmin of admin group
681
+        if($group->getGID() === 'admin') {
682
+            throw new OCSException('Cannot create subadmins for admin group', 103);
683
+        }
684
+
685
+        $subAdminManager = $this->groupManager->getSubAdmin();
686
+
687
+        // We cannot be subadmin twice
688
+        if ($subAdminManager->isSubAdminofGroup($user, $group)) {
689
+            return new DataResponse();
690
+        }
691
+        // Go
692
+        if($subAdminManager->createSubAdmin($user, $group)) {
693
+            return new DataResponse();
694
+        } else {
695
+            throw new OCSException('Unknown error occurred', 103);
696
+        }
697
+    }
698
+
699
+    /**
700
+     * Removes a subadmin from a group
701
+     *
702
+     * @PasswordConfirmationRequired
703
+     *
704
+     * @param string $userId
705
+     * @param string $groupid
706
+     * @return DataResponse
707
+     * @throws OCSException
708
+     */
709
+    public function removeSubAdmin($userId, $groupid) {
710
+        $group = $this->groupManager->get($groupid);
711
+        $user = $this->userManager->get($userId);
712
+        $subAdminManager = $this->groupManager->getSubAdmin();
713
+
714
+        // Check if the user exists
715
+        if($user === null) {
716
+            throw new OCSException('User does not exist', 101);
717
+        }
718
+        // Check if the group exists
719
+        if($group === null) {
720
+            throw new OCSException('Group does not exist', 101);
721
+        }
722
+        // Check if they are a subadmin of this said group
723
+        if(!$subAdminManager->isSubAdminOfGroup($user, $group)) {
724
+            throw new OCSException('User is not a subadmin of this group', 102);
725
+        }
726
+
727
+        // Go
728
+        if($subAdminManager->deleteSubAdmin($user, $group)) {
729
+            return new DataResponse();
730
+        } else {
731
+            throw new OCSException('Unknown error occurred', 103);
732
+        }
733
+    }
734
+
735
+    /**
736
+     * Get the groups a user is a subadmin of
737
+     *
738
+     * @param string $userId
739
+     * @return DataResponse
740
+     * @throws OCSException
741
+     */
742
+    public function getUserSubAdminGroups($userId) {
743
+        $user = $this->userManager->get($userId);
744
+        // Check if the user exists
745
+        if($user === null) {
746
+            throw new OCSException('User does not exist', 101);
747
+        }
748
+
749
+        // Get the subadmin groups
750
+        $groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
751
+        foreach ($groups as $key => $group) {
752
+            $groups[$key] = $group->getGID();
753
+        }
754
+
755
+        if(!$groups) {
756
+            throw new OCSException('Unknown error occurred', 102);
757
+        } else {
758
+            return new DataResponse($groups);
759
+        }
760
+    }
761
+
762
+    /**
763
+     * @param string $userId
764
+     * @return array
765
+     * @throws \OCP\Files\NotFoundException
766
+     */
767
+    protected function fillStorageInfo($userId) {
768
+        try {
769
+            \OC_Util::tearDownFS();
770
+            \OC_Util::setupFS($userId);
771
+            $storage = OC_Helper::getStorageInfo('/');
772
+            $data = [
773
+                'free' => $storage['free'],
774
+                'used' => $storage['used'],
775
+                'total' => $storage['total'],
776
+                'relative' => $storage['relative'],
777
+                'quota' => $storage['quota'],
778
+            ];
779
+        } catch (NotFoundException $ex) {
780
+            $data = [];
781
+        }
782
+        return $data;
783
+    }
784
+
785
+    /**
786
+     * @NoAdminRequired
787
+     * @PasswordConfirmationRequired
788
+     *
789
+     * resend welcome message
790
+     *
791
+     * @param string $userId
792
+     * @return DataResponse
793
+     * @throws OCSException
794
+     */
795
+    public function resendWelcomeMessage($userId) {
796
+        $currentLoggedInUser = $this->userSession->getUser();
797
+
798
+        $targetUser = $this->userManager->get($userId);
799
+        if($targetUser === null) {
800
+            throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
801
+        }
802
+
803
+        // Check if admin / subadmin
804
+        $subAdminManager = $this->groupManager->getSubAdmin();
805
+        if(!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
806
+            && !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
807
+            // No rights
808
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
809
+        }
810
+
811
+        $email = $targetUser->getEMailAddress();
812
+        if ($email === '' || $email === null) {
813
+            throw new OCSException('Email address not available', 101);
814
+        }
815
+        $username = $targetUser->getUID();
816
+        $lang = $this->config->getUserValue($username, 'core', 'lang', 'en');
817
+        if (!$this->l10nFactory->languageExists('settings', $lang)) {
818
+            $lang = 'en';
819
+        }
820
+
821
+        $l10n = $this->l10nFactory->get('settings', $lang);
822
+
823
+        try {
824
+            $this->newUserMailHelper->setL10N($l10n);
825
+            $emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
826
+            $this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
827
+        } catch(\Exception $e) {
828
+            $this->logger->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
829
+            throw new OCSException('Sending email failed', 102);
830
+        }
831
+
832
+        return new DataResponse();
833
+    }
834 834
 }
Please login to merge, or discard this patch.
Spacing   +52 added lines, -52 removed lines patch added patch discarded remove patch
@@ -122,7 +122,7 @@  discard block
 block discarded – undo
122 122
 		// Admin? Or SubAdmin?
123 123
 		$uid = $user->getUID();
124 124
 		$subAdminManager = $this->groupManager->getSubAdmin();
125
-		if($this->groupManager->isAdmin($uid)){
125
+		if ($this->groupManager->isAdmin($uid)) {
126 126
 			$users = $this->userManager->search($search, $limit, $offset);
127 127
 		} else if ($subAdminManager->isSubAdmin($user)) {
128 128
 			$subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
@@ -130,7 +130,7 @@  discard block
 block discarded – undo
130 130
 				$subAdminOfGroups[$key] = $group->getGID();
131 131
 			}
132 132
 
133
-			if($offset === null) {
133
+			if ($offset === null) {
134 134
 				$offset = 0;
135 135
 			}
136 136
 
@@ -164,22 +164,22 @@  discard block
 block discarded – undo
164 164
 		$isAdmin = $this->groupManager->isAdmin($user->getUID());
165 165
 		$subAdminManager = $this->groupManager->getSubAdmin();
166 166
 
167
-		if($this->userManager->userExists($userid)) {
167
+		if ($this->userManager->userExists($userid)) {
168 168
 			$this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
169 169
 			throw new OCSException('User already exists', 102);
170 170
 		}
171 171
 
172
-		if(is_array($groups)) {
172
+		if (is_array($groups)) {
173 173
 			foreach ($groups as $group) {
174
-				if(!$this->groupManager->groupExists($group)) {
174
+				if (!$this->groupManager->groupExists($group)) {
175 175
 					throw new OCSException('group '.$group.' does not exist', 104);
176 176
 				}
177
-				if(!$isAdmin && !$subAdminManager->isSubAdminofGroup($user, $this->groupManager->get($group))) {
178
-					throw new OCSException('insufficient privileges for group '. $group, 105);
177
+				if (!$isAdmin && !$subAdminManager->isSubAdminofGroup($user, $this->groupManager->get($group))) {
178
+					throw new OCSException('insufficient privileges for group '.$group, 105);
179 179
 				}
180 180
 			}
181 181
 		} else {
182
-			if(!$isAdmin) {
182
+			if (!$isAdmin) {
183 183
 				throw new OCSException('no group specified (required for subadmins)', 106);
184 184
 			}
185 185
 		}
@@ -228,7 +228,7 @@  discard block
 block discarded – undo
228 228
 	public function getCurrentUser() {
229 229
 		$user = $this->userSession->getUser();
230 230
 		if ($user) {
231
-			$data =  $this->getUserData($user->getUID());
231
+			$data = $this->getUserData($user->getUID());
232 232
 			// rename "displayname" to "display-name" only for this call to keep
233 233
 			// the API stable.
234 234
 			$data['display-name'] = $data['displayname'];
@@ -254,17 +254,17 @@  discard block
 block discarded – undo
254 254
 
255 255
 		// Check if the target user exists
256 256
 		$targetUserObject = $this->userManager->get($userId);
257
-		if($targetUserObject === null) {
257
+		if ($targetUserObject === null) {
258 258
 			throw new OCSException('The requested user could not be found', \OCP\API::RESPOND_NOT_FOUND);
259 259
 		}
260 260
 
261 261
 		// Admin? Or SubAdmin?
262
-		if($this->groupManager->isAdmin($currentLoggedInUser->getUID())
262
+		if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())
263 263
 			|| $this->groupManager->getSubAdmin()->isUserAccessible($currentLoggedInUser, $targetUserObject)) {
264 264
 			$data['enabled'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'enabled', 'true');
265 265
 		} else {
266 266
 			// Check they are looking up themselves
267
-			if($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) {
267
+			if ($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) {
268 268
 				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
269 269
 			}
270 270
 		}
@@ -309,12 +309,12 @@  discard block
 block discarded – undo
309 309
 		$currentLoggedInUser = $this->userSession->getUser();
310 310
 
311 311
 		$targetUser = $this->userManager->get($userId);
312
-		if($targetUser === null) {
312
+		if ($targetUser === null) {
313 313
 			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
314 314
 		}
315 315
 
316 316
 		$permittedFields = [];
317
-		if($targetUser->getUID() === $currentLoggedInUser->getUID()) {
317
+		if ($targetUser->getUID() === $currentLoggedInUser->getUID()) {
318 318
 			// Editing self (display, email)
319 319
 			if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
320 320
 				$permittedFields[] = 'display';
@@ -340,13 +340,13 @@  discard block
 block discarded – undo
340 340
 			}
341 341
 
342 342
 			// If admin they can edit their own quota
343
-			if($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
343
+			if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
344 344
 				$permittedFields[] = 'quota';
345 345
 			}
346 346
 		} else {
347 347
 			// Check if admin / subadmin
348 348
 			$subAdminManager = $this->groupManager->getSubAdmin();
349
-			if($subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
349
+			if ($subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
350 350
 			|| $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
351 351
 				// They have permissions over the user
352 352
 				$permittedFields[] = 'display';
@@ -365,18 +365,18 @@  discard block
 block discarded – undo
365 365
 			}
366 366
 		}
367 367
 		// Check if permitted to edit this field
368
-		if(!in_array($key, $permittedFields)) {
368
+		if (!in_array($key, $permittedFields)) {
369 369
 			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
370 370
 		}
371 371
 		// Process the edit
372
-		switch($key) {
372
+		switch ($key) {
373 373
 			case 'display':
374 374
 			case AccountManager::PROPERTY_DISPLAYNAME:
375 375
 				$targetUser->setDisplayName($value);
376 376
 				break;
377 377
 			case 'quota':
378 378
 				$quota = $value;
379
-				if($quota !== 'none' && $quota !== 'default') {
379
+				if ($quota !== 'none' && $quota !== 'default') {
380 380
 					if (is_numeric($quota)) {
381 381
 						$quota = (float) $quota;
382 382
 					} else {
@@ -385,9 +385,9 @@  discard block
 block discarded – undo
385 385
 					if ($quota === false) {
386 386
 						throw new OCSException('Invalid quota value '.$value, 103);
387 387
 					}
388
-					if($quota === 0) {
388
+					if ($quota === 0) {
389 389
 						$quota = 'default';
390
-					}else if($quota === -1) {
390
+					} else if ($quota === -1) {
391 391
 						$quota = 'none';
392 392
 					} else {
393 393
 						$quota = \OCP\Util::humanFileSize($quota);
@@ -406,7 +406,7 @@  discard block
 block discarded – undo
406 406
 				$this->config->setUserValue($targetUser->getUID(), 'core', 'lang', $value);
407 407
 				break;
408 408
 			case AccountManager::PROPERTY_EMAIL:
409
-				if(filter_var($value, FILTER_VALIDATE_EMAIL)) {
409
+				if (filter_var($value, FILTER_VALIDATE_EMAIL)) {
410 410
 					$targetUser->setEMailAddress($value);
411 411
 				} else {
412 412
 					throw new OCSException('', 102);
@@ -442,18 +442,18 @@  discard block
 block discarded – undo
442 442
 
443 443
 		$targetUser = $this->userManager->get($userId);
444 444
 
445
-		if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
445
+		if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
446 446
 			throw new OCSException('', 101);
447 447
 		}
448 448
 
449 449
 		// If not permitted
450 450
 		$subAdminManager = $this->groupManager->getSubAdmin();
451
-		if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
451
+		if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
452 452
 			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
453 453
 		}
454 454
 
455 455
 		// Go ahead with the delete
456
-		if($targetUser->delete()) {
456
+		if ($targetUser->delete()) {
457 457
 			return new DataResponse();
458 458
 		} else {
459 459
 			throw new OCSException('', 101);
@@ -497,13 +497,13 @@  discard block
 block discarded – undo
497 497
 		$currentLoggedInUser = $this->userSession->getUser();
498 498
 
499 499
 		$targetUser = $this->userManager->get($userId);
500
-		if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
500
+		if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
501 501
 			throw new OCSException('', 101);
502 502
 		}
503 503
 
504 504
 		// If not permitted
505 505
 		$subAdminManager = $this->groupManager->getSubAdmin();
506
-		if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
506
+		if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
507 507
 			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
508 508
 		}
509 509
 
@@ -524,11 +524,11 @@  discard block
 block discarded – undo
524 524
 		$loggedInUser = $this->userSession->getUser();
525 525
 
526 526
 		$targetUser = $this->userManager->get($userId);
527
-		if($targetUser === null) {
527
+		if ($targetUser === null) {
528 528
 			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
529 529
 		}
530 530
 
531
-		if($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
531
+		if ($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
532 532
 			// Self lookup or admin lookup
533 533
 			return new DataResponse([
534 534
 				'groups' => $this->groupManager->getUserGroupIds($targetUser)
@@ -537,7 +537,7 @@  discard block
 block discarded – undo
537 537
 			$subAdminManager = $this->groupManager->getSubAdmin();
538 538
 
539 539
 			// Looking up someone else
540
-			if($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
540
+			if ($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
541 541
 				// Return the group that the method caller is subadmin of for the user in question
542 542
 				/** @var IGroup[] $getSubAdminsGroups */
543 543
 				$getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
@@ -567,16 +567,16 @@  discard block
 block discarded – undo
567 567
 	 * @throws OCSException
568 568
 	 */
569 569
 	public function addToGroup($userId, $groupid = '') {
570
-		if($groupid === '') {
570
+		if ($groupid === '') {
571 571
 			throw new OCSException('', 101);
572 572
 		}
573 573
 
574 574
 		$group = $this->groupManager->get($groupid);
575 575
 		$targetUser = $this->userManager->get($userId);
576
-		if($group === null) {
576
+		if ($group === null) {
577 577
 			throw new OCSException('', 102);
578 578
 		}
579
-		if($targetUser === null) {
579
+		if ($targetUser === null) {
580 580
 			throw new OCSException('', 103);
581 581
 		}
582 582
 
@@ -604,17 +604,17 @@  discard block
 block discarded – undo
604 604
 	public function removeFromGroup($userId, $groupid) {
605 605
 		$loggedInUser = $this->userSession->getUser();
606 606
 
607
-		if($groupid === null || trim($groupid) === '') {
607
+		if ($groupid === null || trim($groupid) === '') {
608 608
 			throw new OCSException('', 101);
609 609
 		}
610 610
 
611 611
 		$group = $this->groupManager->get($groupid);
612
-		if($group === null) {
612
+		if ($group === null) {
613 613
 			throw new OCSException('', 102);
614 614
 		}
615 615
 
616 616
 		$targetUser = $this->userManager->get($userId);
617
-		if($targetUser === null) {
617
+		if ($targetUser === null) {
618 618
 			throw new OCSException('', 103);
619 619
 		}
620 620
 
@@ -638,7 +638,7 @@  discard block
 block discarded – undo
638 638
 		} else if (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
639 639
 			/** @var IGroup[] $subAdminGroups */
640 640
 			$subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
641
-			$subAdminGroups = array_map(function (IGroup $subAdminGroup) {
641
+			$subAdminGroups = array_map(function(IGroup $subAdminGroup) {
642 642
 				return $subAdminGroup->getGID();
643 643
 			}, $subAdminGroups);
644 644
 			$userGroups = $this->groupManager->getUserGroupIds($targetUser);
@@ -670,15 +670,15 @@  discard block
 block discarded – undo
670 670
 		$user = $this->userManager->get($userId);
671 671
 
672 672
 		// Check if the user exists
673
-		if($user === null) {
673
+		if ($user === null) {
674 674
 			throw new OCSException('User does not exist', 101);
675 675
 		}
676 676
 		// Check if group exists
677
-		if($group === null) {
678
-			throw new OCSException('Group does not exist',  102);
677
+		if ($group === null) {
678
+			throw new OCSException('Group does not exist', 102);
679 679
 		}
680 680
 		// Check if trying to make subadmin of admin group
681
-		if($group->getGID() === 'admin') {
681
+		if ($group->getGID() === 'admin') {
682 682
 			throw new OCSException('Cannot create subadmins for admin group', 103);
683 683
 		}
684 684
 
@@ -689,7 +689,7 @@  discard block
 block discarded – undo
689 689
 			return new DataResponse();
690 690
 		}
691 691
 		// Go
692
-		if($subAdminManager->createSubAdmin($user, $group)) {
692
+		if ($subAdminManager->createSubAdmin($user, $group)) {
693 693
 			return new DataResponse();
694 694
 		} else {
695 695
 			throw new OCSException('Unknown error occurred', 103);
@@ -712,20 +712,20 @@  discard block
 block discarded – undo
712 712
 		$subAdminManager = $this->groupManager->getSubAdmin();
713 713
 
714 714
 		// Check if the user exists
715
-		if($user === null) {
715
+		if ($user === null) {
716 716
 			throw new OCSException('User does not exist', 101);
717 717
 		}
718 718
 		// Check if the group exists
719
-		if($group === null) {
719
+		if ($group === null) {
720 720
 			throw new OCSException('Group does not exist', 101);
721 721
 		}
722 722
 		// Check if they are a subadmin of this said group
723
-		if(!$subAdminManager->isSubAdminOfGroup($user, $group)) {
723
+		if (!$subAdminManager->isSubAdminOfGroup($user, $group)) {
724 724
 			throw new OCSException('User is not a subadmin of this group', 102);
725 725
 		}
726 726
 
727 727
 		// Go
728
-		if($subAdminManager->deleteSubAdmin($user, $group)) {
728
+		if ($subAdminManager->deleteSubAdmin($user, $group)) {
729 729
 			return new DataResponse();
730 730
 		} else {
731 731
 			throw new OCSException('Unknown error occurred', 103);
@@ -742,7 +742,7 @@  discard block
 block discarded – undo
742 742
 	public function getUserSubAdminGroups($userId) {
743 743
 		$user = $this->userManager->get($userId);
744 744
 		// Check if the user exists
745
-		if($user === null) {
745
+		if ($user === null) {
746 746
 			throw new OCSException('User does not exist', 101);
747 747
 		}
748 748
 
@@ -752,7 +752,7 @@  discard block
 block discarded – undo
752 752
 			$groups[$key] = $group->getGID();
753 753
 		}
754 754
 
755
-		if(!$groups) {
755
+		if (!$groups) {
756 756
 			throw new OCSException('Unknown error occurred', 102);
757 757
 		} else {
758 758
 			return new DataResponse($groups);
@@ -796,13 +796,13 @@  discard block
 block discarded – undo
796 796
 		$currentLoggedInUser = $this->userSession->getUser();
797 797
 
798 798
 		$targetUser = $this->userManager->get($userId);
799
-		if($targetUser === null) {
799
+		if ($targetUser === null) {
800 800
 			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
801 801
 		}
802 802
 
803 803
 		// Check if admin / subadmin
804 804
 		$subAdminManager = $this->groupManager->getSubAdmin();
805
-		if(!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
805
+		if (!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
806 806
 			&& !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
807 807
 			// No rights
808 808
 			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
@@ -824,8 +824,8 @@  discard block
 block discarded – undo
824 824
 			$this->newUserMailHelper->setL10N($l10n);
825 825
 			$emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
826 826
 			$this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
827
-		} catch(\Exception $e) {
828
-			$this->logger->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
827
+		} catch (\Exception $e) {
828
+			$this->logger->error("Can't send new user mail to $email: ".$e->getMessage(), array('app' => 'settings'));
829 829
 			throw new OCSException('Sending email failed', 102);
830 830
 		}
831 831
 
Please login to merge, or discard this patch.
apps/user_ldap/lib/Helper.php 3 patches
Doc Comments   +3 added lines patch added patch discarded remove patch
@@ -124,6 +124,9 @@
 block discarded – undo
124 124
 		return $nextPrefix;
125 125
 	}
126 126
 
127
+	/**
128
+	 * @param string $value
129
+	 */
127 130
 	private function getServersConfig($value) {
128 131
 		$regex = '/' . $value . '$/S';
129 132
 
Please login to merge, or discard this patch.
Indentation   +259 added lines, -259 removed lines patch added patch discarded remove patch
@@ -34,126 +34,126 @@  discard block
 block discarded – undo
34 34
 
35 35
 class Helper {
36 36
 
37
-	/** @var IConfig */
38
-	private $config;
39
-
40
-	/**
41
-	 * Helper constructor.
42
-	 *
43
-	 * @param IConfig $config
44
-	 */
45
-	public function __construct(IConfig $config) {
46
-		$this->config = $config;
47
-	}
48
-
49
-	/**
50
-	 * returns prefixes for each saved LDAP/AD server configuration.
51
-	 * @param bool $activeConfigurations optional, whether only active configuration shall be
52
-	 * retrieved, defaults to false
53
-	 * @return array with a list of the available prefixes
54
-	 *
55
-	 * Configuration prefixes are used to set up configurations for n LDAP or
56
-	 * AD servers. Since configuration is stored in the database, table
57
-	 * appconfig under appid user_ldap, the common identifiers in column
58
-	 * 'configkey' have a prefix. The prefix for the very first server
59
-	 * configuration is empty.
60
-	 * Configkey Examples:
61
-	 * Server 1: ldap_login_filter
62
-	 * Server 2: s1_ldap_login_filter
63
-	 * Server 3: s2_ldap_login_filter
64
-	 *
65
-	 * The prefix needs to be passed to the constructor of Connection class,
66
-	 * except the default (first) server shall be connected to.
67
-	 *
68
-	 */
69
-	public function getServerConfigurationPrefixes($activeConfigurations = false) {
70
-		$referenceConfigkey = 'ldap_configuration_active';
71
-
72
-		$keys = $this->getServersConfig($referenceConfigkey);
73
-
74
-		$prefixes = [];
75
-		foreach ($keys as $key) {
76
-			if ($activeConfigurations && $this->config->getAppValue('user_ldap', $key, '0') !== '1') {
77
-				continue;
78
-			}
79
-
80
-			$len = strlen($key) - strlen($referenceConfigkey);
81
-			$prefixes[] = substr($key, 0, $len);
82
-		}
83
-
84
-		return $prefixes;
85
-	}
86
-
87
-	/**
88
-	 *
89
-	 * determines the host for every configured connection
90
-	 * @return array an array with configprefix as keys
91
-	 *
92
-	 */
93
-	public function getServerConfigurationHosts() {
94
-		$referenceConfigkey = 'ldap_host';
95
-
96
-		$keys = $this->getServersConfig($referenceConfigkey);
97
-
98
-		$result = array();
99
-		foreach($keys as $key) {
100
-			$len = strlen($key) - strlen($referenceConfigkey);
101
-			$prefix = substr($key, 0, $len);
102
-			$result[$prefix] = $this->config->getAppValue('user_ldap', $key);
103
-		}
104
-
105
-		return $result;
106
-	}
107
-
108
-	/**
109
-	 * return the next available configuration prefix
110
-	 *
111
-	 * @return string
112
-	 */
113
-	public function getNextServerConfigurationPrefix() {
114
-		$serverConnections = $this->getServerConfigurationPrefixes();
115
-
116
-		if(count($serverConnections) === 0) {
117
-			return 's01';
118
-		}
119
-
120
-		sort($serverConnections);
121
-		$lastKey = array_pop($serverConnections);
122
-		$lastNumber = intval(str_replace('s', '', $lastKey));
123
-		$nextPrefix = 's' . str_pad($lastNumber + 1, 2, '0', STR_PAD_LEFT);
124
-		return $nextPrefix;
125
-	}
126
-
127
-	private function getServersConfig($value) {
128
-		$regex = '/' . $value . '$/S';
129
-
130
-		$keys = $this->config->getAppKeys('user_ldap');
131
-		$result = [];
132
-		foreach ($keys as $key) {
133
-			if (preg_match($regex, $key) === 1) {
134
-				$result[] = $key;
135
-			}
136
-		}
137
-
138
-		return $result;
139
-	}
140
-
141
-	/**
142
-	 * deletes a given saved LDAP/AD server configuration.
143
-	 * @param string $prefix the configuration prefix of the config to delete
144
-	 * @return bool true on success, false otherwise
145
-	 */
146
-	public function deleteServerConfiguration($prefix) {
147
-		if(!in_array($prefix, self::getServerConfigurationPrefixes())) {
148
-			return false;
149
-		}
150
-
151
-		$saveOtherConfigurations = '';
152
-		if(empty($prefix)) {
153
-			$saveOtherConfigurations = 'AND `configkey` NOT LIKE \'s%\'';
154
-		}
155
-
156
-		$query = \OCP\DB::prepare('
37
+    /** @var IConfig */
38
+    private $config;
39
+
40
+    /**
41
+     * Helper constructor.
42
+     *
43
+     * @param IConfig $config
44
+     */
45
+    public function __construct(IConfig $config) {
46
+        $this->config = $config;
47
+    }
48
+
49
+    /**
50
+     * returns prefixes for each saved LDAP/AD server configuration.
51
+     * @param bool $activeConfigurations optional, whether only active configuration shall be
52
+     * retrieved, defaults to false
53
+     * @return array with a list of the available prefixes
54
+     *
55
+     * Configuration prefixes are used to set up configurations for n LDAP or
56
+     * AD servers. Since configuration is stored in the database, table
57
+     * appconfig under appid user_ldap, the common identifiers in column
58
+     * 'configkey' have a prefix. The prefix for the very first server
59
+     * configuration is empty.
60
+     * Configkey Examples:
61
+     * Server 1: ldap_login_filter
62
+     * Server 2: s1_ldap_login_filter
63
+     * Server 3: s2_ldap_login_filter
64
+     *
65
+     * The prefix needs to be passed to the constructor of Connection class,
66
+     * except the default (first) server shall be connected to.
67
+     *
68
+     */
69
+    public function getServerConfigurationPrefixes($activeConfigurations = false) {
70
+        $referenceConfigkey = 'ldap_configuration_active';
71
+
72
+        $keys = $this->getServersConfig($referenceConfigkey);
73
+
74
+        $prefixes = [];
75
+        foreach ($keys as $key) {
76
+            if ($activeConfigurations && $this->config->getAppValue('user_ldap', $key, '0') !== '1') {
77
+                continue;
78
+            }
79
+
80
+            $len = strlen($key) - strlen($referenceConfigkey);
81
+            $prefixes[] = substr($key, 0, $len);
82
+        }
83
+
84
+        return $prefixes;
85
+    }
86
+
87
+    /**
88
+     *
89
+     * determines the host for every configured connection
90
+     * @return array an array with configprefix as keys
91
+     *
92
+     */
93
+    public function getServerConfigurationHosts() {
94
+        $referenceConfigkey = 'ldap_host';
95
+
96
+        $keys = $this->getServersConfig($referenceConfigkey);
97
+
98
+        $result = array();
99
+        foreach($keys as $key) {
100
+            $len = strlen($key) - strlen($referenceConfigkey);
101
+            $prefix = substr($key, 0, $len);
102
+            $result[$prefix] = $this->config->getAppValue('user_ldap', $key);
103
+        }
104
+
105
+        return $result;
106
+    }
107
+
108
+    /**
109
+     * return the next available configuration prefix
110
+     *
111
+     * @return string
112
+     */
113
+    public function getNextServerConfigurationPrefix() {
114
+        $serverConnections = $this->getServerConfigurationPrefixes();
115
+
116
+        if(count($serverConnections) === 0) {
117
+            return 's01';
118
+        }
119
+
120
+        sort($serverConnections);
121
+        $lastKey = array_pop($serverConnections);
122
+        $lastNumber = intval(str_replace('s', '', $lastKey));
123
+        $nextPrefix = 's' . str_pad($lastNumber + 1, 2, '0', STR_PAD_LEFT);
124
+        return $nextPrefix;
125
+    }
126
+
127
+    private function getServersConfig($value) {
128
+        $regex = '/' . $value . '$/S';
129
+
130
+        $keys = $this->config->getAppKeys('user_ldap');
131
+        $result = [];
132
+        foreach ($keys as $key) {
133
+            if (preg_match($regex, $key) === 1) {
134
+                $result[] = $key;
135
+            }
136
+        }
137
+
138
+        return $result;
139
+    }
140
+
141
+    /**
142
+     * deletes a given saved LDAP/AD server configuration.
143
+     * @param string $prefix the configuration prefix of the config to delete
144
+     * @return bool true on success, false otherwise
145
+     */
146
+    public function deleteServerConfiguration($prefix) {
147
+        if(!in_array($prefix, self::getServerConfigurationPrefixes())) {
148
+            return false;
149
+        }
150
+
151
+        $saveOtherConfigurations = '';
152
+        if(empty($prefix)) {
153
+            $saveOtherConfigurations = 'AND `configkey` NOT LIKE \'s%\'';
154
+        }
155
+
156
+        $query = \OCP\DB::prepare('
157 157
 			DELETE
158 158
 			FROM `*PREFIX*appconfig`
159 159
 			WHERE `configkey` LIKE ?
@@ -161,146 +161,146 @@  discard block
 block discarded – undo
161 161
 				AND `appid` = \'user_ldap\'
162 162
 				AND `configkey` NOT IN (\'enabled\', \'installed_version\', \'types\', \'bgjUpdateGroupsLastRun\')
163 163
 		');
164
-		$delRows = $query->execute(array($prefix.'%'));
165
-
166
-		if(\OCP\DB::isError($delRows)) {
167
-			return false;
168
-		}
169
-
170
-		if($delRows === 0) {
171
-			return false;
172
-		}
173
-
174
-		return true;
175
-	}
176
-
177
-	/**
178
-	 * checks whether there is one or more disabled LDAP configurations
179
-	 * @throws \Exception
180
-	 * @return bool
181
-	 */
182
-	public function haveDisabledConfigurations() {
183
-		$all = $this->getServerConfigurationPrefixes(false);
184
-		$active = $this->getServerConfigurationPrefixes(true);
185
-
186
-		if(!is_array($all) || !is_array($active)) {
187
-			throw new \Exception('Unexpected Return Value');
188
-		}
189
-
190
-		return count($all) !== count($active) || count($all) === 0;
191
-	}
192
-
193
-	/**
194
-	 * extracts the domain from a given URL
195
-	 * @param string $url the URL
196
-	 * @return string|false domain as string on success, false otherwise
197
-	 */
198
-	public function getDomainFromURL($url) {
199
-		$uinfo = parse_url($url);
200
-		if(!is_array($uinfo)) {
201
-			return false;
202
-		}
203
-
204
-		$domain = false;
205
-		if(isset($uinfo['host'])) {
206
-			$domain = $uinfo['host'];
207
-		} else if(isset($uinfo['path'])) {
208
-			$domain = $uinfo['path'];
209
-		}
210
-
211
-		return $domain;
212
-	}
164
+        $delRows = $query->execute(array($prefix.'%'));
165
+
166
+        if(\OCP\DB::isError($delRows)) {
167
+            return false;
168
+        }
169
+
170
+        if($delRows === 0) {
171
+            return false;
172
+        }
173
+
174
+        return true;
175
+    }
176
+
177
+    /**
178
+     * checks whether there is one or more disabled LDAP configurations
179
+     * @throws \Exception
180
+     * @return bool
181
+     */
182
+    public function haveDisabledConfigurations() {
183
+        $all = $this->getServerConfigurationPrefixes(false);
184
+        $active = $this->getServerConfigurationPrefixes(true);
185
+
186
+        if(!is_array($all) || !is_array($active)) {
187
+            throw new \Exception('Unexpected Return Value');
188
+        }
189
+
190
+        return count($all) !== count($active) || count($all) === 0;
191
+    }
192
+
193
+    /**
194
+     * extracts the domain from a given URL
195
+     * @param string $url the URL
196
+     * @return string|false domain as string on success, false otherwise
197
+     */
198
+    public function getDomainFromURL($url) {
199
+        $uinfo = parse_url($url);
200
+        if(!is_array($uinfo)) {
201
+            return false;
202
+        }
203
+
204
+        $domain = false;
205
+        if(isset($uinfo['host'])) {
206
+            $domain = $uinfo['host'];
207
+        } else if(isset($uinfo['path'])) {
208
+            $domain = $uinfo['path'];
209
+        }
210
+
211
+        return $domain;
212
+    }
213 213
 	
214
-	/**
215
-	 *
216
-	 * Set the LDAPProvider in the config
217
-	 *
218
-	 */
219
-	public function setLDAPProvider() {
220
-		$current = \OC::$server->getConfig()->getSystemValue('ldapProviderFactory', null);
221
-		if(is_null($current)) {
222
-			\OC::$server->getConfig()->setSystemValue('ldapProviderFactory', '\\OCA\\User_LDAP\\LDAPProviderFactory');
223
-		}
224
-	}
214
+    /**
215
+     *
216
+     * Set the LDAPProvider in the config
217
+     *
218
+     */
219
+    public function setLDAPProvider() {
220
+        $current = \OC::$server->getConfig()->getSystemValue('ldapProviderFactory', null);
221
+        if(is_null($current)) {
222
+            \OC::$server->getConfig()->setSystemValue('ldapProviderFactory', '\\OCA\\User_LDAP\\LDAPProviderFactory');
223
+        }
224
+    }
225 225
 	
226
-	/**
227
-	 * sanitizes a DN received from the LDAP server
228
-	 * @param array $dn the DN in question
229
-	 * @return array the sanitized DN
230
-	 */
231
-	public function sanitizeDN($dn) {
232
-		//treating multiple base DNs
233
-		if(is_array($dn)) {
234
-			$result = array();
235
-			foreach($dn as $singleDN) {
236
-				$result[] = $this->sanitizeDN($singleDN);
237
-			}
238
-			return $result;
239
-		}
240
-
241
-		//OID sometimes gives back DNs with whitespace after the comma
242
-		// a la "uid=foo, cn=bar, dn=..." We need to tackle this!
243
-		$dn = preg_replace('/([^\\\]),(\s+)/u', '\1,', $dn);
244
-
245
-		//make comparisons and everything work
246
-		$dn = mb_strtolower($dn, 'UTF-8');
247
-
248
-		//escape DN values according to RFC 2253 – this is already done by ldap_explode_dn
249
-		//to use the DN in search filters, \ needs to be escaped to \5c additionally
250
-		//to use them in bases, we convert them back to simple backslashes in readAttribute()
251
-		$replacements = array(
252
-			'\,' => '\5c2C',
253
-			'\=' => '\5c3D',
254
-			'\+' => '\5c2B',
255
-			'\<' => '\5c3C',
256
-			'\>' => '\5c3E',
257
-			'\;' => '\5c3B',
258
-			'\"' => '\5c22',
259
-			'\#' => '\5c23',
260
-			'('  => '\28',
261
-			')'  => '\29',
262
-			'*'  => '\2A',
263
-		);
264
-		$dn = str_replace(array_keys($replacements), array_values($replacements), $dn);
265
-
266
-		return $dn;
267
-	}
226
+    /**
227
+     * sanitizes a DN received from the LDAP server
228
+     * @param array $dn the DN in question
229
+     * @return array the sanitized DN
230
+     */
231
+    public function sanitizeDN($dn) {
232
+        //treating multiple base DNs
233
+        if(is_array($dn)) {
234
+            $result = array();
235
+            foreach($dn as $singleDN) {
236
+                $result[] = $this->sanitizeDN($singleDN);
237
+            }
238
+            return $result;
239
+        }
240
+
241
+        //OID sometimes gives back DNs with whitespace after the comma
242
+        // a la "uid=foo, cn=bar, dn=..." We need to tackle this!
243
+        $dn = preg_replace('/([^\\\]),(\s+)/u', '\1,', $dn);
244
+
245
+        //make comparisons and everything work
246
+        $dn = mb_strtolower($dn, 'UTF-8');
247
+
248
+        //escape DN values according to RFC 2253 – this is already done by ldap_explode_dn
249
+        //to use the DN in search filters, \ needs to be escaped to \5c additionally
250
+        //to use them in bases, we convert them back to simple backslashes in readAttribute()
251
+        $replacements = array(
252
+            '\,' => '\5c2C',
253
+            '\=' => '\5c3D',
254
+            '\+' => '\5c2B',
255
+            '\<' => '\5c3C',
256
+            '\>' => '\5c3E',
257
+            '\;' => '\5c3B',
258
+            '\"' => '\5c22',
259
+            '\#' => '\5c23',
260
+            '('  => '\28',
261
+            ')'  => '\29',
262
+            '*'  => '\2A',
263
+        );
264
+        $dn = str_replace(array_keys($replacements), array_values($replacements), $dn);
265
+
266
+        return $dn;
267
+    }
268 268
 	
269
-	/**
270
-	 * converts a stored DN so it can be used as base parameter for LDAP queries, internally we store them for usage in LDAP filters
271
-	 * @param string $dn the DN
272
-	 * @return string
273
-	 */
274
-	public function DNasBaseParameter($dn) {
275
-		return str_ireplace('\\5c', '\\', $dn);
276
-	}
277
-
278
-	/**
279
-	 * listens to a hook thrown by server2server sharing and replaces the given
280
-	 * login name by a username, if it matches an LDAP user.
281
-	 *
282
-	 * @param array $param
283
-	 * @throws \Exception
284
-	 */
285
-	public static function loginName2UserName($param) {
286
-		if(!isset($param['uid'])) {
287
-			throw new \Exception('key uid is expected to be set in $param');
288
-		}
289
-
290
-		//ain't it ironic?
291
-		$helper = new Helper(\OC::$server->getConfig());
292
-
293
-		$configPrefixes = $helper->getServerConfigurationPrefixes(true);
294
-		$ldapWrapper = new LDAP();
295
-		$ocConfig = \OC::$server->getConfig();
296
-		$notificationManager = \OC::$server->getNotificationManager();
297
-
298
-		$userBackend  = new User_Proxy(
299
-			$configPrefixes, $ldapWrapper, $ocConfig, $notificationManager
300
-		);
301
-		$uid = $userBackend->loginName2UserName($param['uid'] );
302
-		if($uid !== false) {
303
-			$param['uid'] = $uid;
304
-		}
305
-	}
269
+    /**
270
+     * converts a stored DN so it can be used as base parameter for LDAP queries, internally we store them for usage in LDAP filters
271
+     * @param string $dn the DN
272
+     * @return string
273
+     */
274
+    public function DNasBaseParameter($dn) {
275
+        return str_ireplace('\\5c', '\\', $dn);
276
+    }
277
+
278
+    /**
279
+     * listens to a hook thrown by server2server sharing and replaces the given
280
+     * login name by a username, if it matches an LDAP user.
281
+     *
282
+     * @param array $param
283
+     * @throws \Exception
284
+     */
285
+    public static function loginName2UserName($param) {
286
+        if(!isset($param['uid'])) {
287
+            throw new \Exception('key uid is expected to be set in $param');
288
+        }
289
+
290
+        //ain't it ironic?
291
+        $helper = new Helper(\OC::$server->getConfig());
292
+
293
+        $configPrefixes = $helper->getServerConfigurationPrefixes(true);
294
+        $ldapWrapper = new LDAP();
295
+        $ocConfig = \OC::$server->getConfig();
296
+        $notificationManager = \OC::$server->getNotificationManager();
297
+
298
+        $userBackend  = new User_Proxy(
299
+            $configPrefixes, $ldapWrapper, $ocConfig, $notificationManager
300
+        );
301
+        $uid = $userBackend->loginName2UserName($param['uid'] );
302
+        if($uid !== false) {
303
+            $param['uid'] = $uid;
304
+        }
305
+    }
306 306
 }
Please login to merge, or discard this patch.
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -96,7 +96,7 @@  discard block
 block discarded – undo
96 96
 		$keys = $this->getServersConfig($referenceConfigkey);
97 97
 
98 98
 		$result = array();
99
-		foreach($keys as $key) {
99
+		foreach ($keys as $key) {
100 100
 			$len = strlen($key) - strlen($referenceConfigkey);
101 101
 			$prefix = substr($key, 0, $len);
102 102
 			$result[$prefix] = $this->config->getAppValue('user_ldap', $key);
@@ -113,19 +113,19 @@  discard block
 block discarded – undo
113 113
 	public function getNextServerConfigurationPrefix() {
114 114
 		$serverConnections = $this->getServerConfigurationPrefixes();
115 115
 
116
-		if(count($serverConnections) === 0) {
116
+		if (count($serverConnections) === 0) {
117 117
 			return 's01';
118 118
 		}
119 119
 
120 120
 		sort($serverConnections);
121 121
 		$lastKey = array_pop($serverConnections);
122 122
 		$lastNumber = intval(str_replace('s', '', $lastKey));
123
-		$nextPrefix = 's' . str_pad($lastNumber + 1, 2, '0', STR_PAD_LEFT);
123
+		$nextPrefix = 's'.str_pad($lastNumber + 1, 2, '0', STR_PAD_LEFT);
124 124
 		return $nextPrefix;
125 125
 	}
126 126
 
127 127
 	private function getServersConfig($value) {
128
-		$regex = '/' . $value . '$/S';
128
+		$regex = '/'.$value.'$/S';
129 129
 
130 130
 		$keys = $this->config->getAppKeys('user_ldap');
131 131
 		$result = [];
@@ -144,12 +144,12 @@  discard block
 block discarded – undo
144 144
 	 * @return bool true on success, false otherwise
145 145
 	 */
146 146
 	public function deleteServerConfiguration($prefix) {
147
-		if(!in_array($prefix, self::getServerConfigurationPrefixes())) {
147
+		if (!in_array($prefix, self::getServerConfigurationPrefixes())) {
148 148
 			return false;
149 149
 		}
150 150
 
151 151
 		$saveOtherConfigurations = '';
152
-		if(empty($prefix)) {
152
+		if (empty($prefix)) {
153 153
 			$saveOtherConfigurations = 'AND `configkey` NOT LIKE \'s%\'';
154 154
 		}
155 155
 
@@ -163,11 +163,11 @@  discard block
 block discarded – undo
163 163
 		');
164 164
 		$delRows = $query->execute(array($prefix.'%'));
165 165
 
166
-		if(\OCP\DB::isError($delRows)) {
166
+		if (\OCP\DB::isError($delRows)) {
167 167
 			return false;
168 168
 		}
169 169
 
170
-		if($delRows === 0) {
170
+		if ($delRows === 0) {
171 171
 			return false;
172 172
 		}
173 173
 
@@ -183,7 +183,7 @@  discard block
 block discarded – undo
183 183
 		$all = $this->getServerConfigurationPrefixes(false);
184 184
 		$active = $this->getServerConfigurationPrefixes(true);
185 185
 
186
-		if(!is_array($all) || !is_array($active)) {
186
+		if (!is_array($all) || !is_array($active)) {
187 187
 			throw new \Exception('Unexpected Return Value');
188 188
 		}
189 189
 
@@ -197,14 +197,14 @@  discard block
 block discarded – undo
197 197
 	 */
198 198
 	public function getDomainFromURL($url) {
199 199
 		$uinfo = parse_url($url);
200
-		if(!is_array($uinfo)) {
200
+		if (!is_array($uinfo)) {
201 201
 			return false;
202 202
 		}
203 203
 
204 204
 		$domain = false;
205
-		if(isset($uinfo['host'])) {
205
+		if (isset($uinfo['host'])) {
206 206
 			$domain = $uinfo['host'];
207
-		} else if(isset($uinfo['path'])) {
207
+		} else if (isset($uinfo['path'])) {
208 208
 			$domain = $uinfo['path'];
209 209
 		}
210 210
 
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
 	 */
219 219
 	public function setLDAPProvider() {
220 220
 		$current = \OC::$server->getConfig()->getSystemValue('ldapProviderFactory', null);
221
-		if(is_null($current)) {
221
+		if (is_null($current)) {
222 222
 			\OC::$server->getConfig()->setSystemValue('ldapProviderFactory', '\\OCA\\User_LDAP\\LDAPProviderFactory');
223 223
 		}
224 224
 	}
@@ -230,9 +230,9 @@  discard block
 block discarded – undo
230 230
 	 */
231 231
 	public function sanitizeDN($dn) {
232 232
 		//treating multiple base DNs
233
-		if(is_array($dn)) {
233
+		if (is_array($dn)) {
234 234
 			$result = array();
235
-			foreach($dn as $singleDN) {
235
+			foreach ($dn as $singleDN) {
236 236
 				$result[] = $this->sanitizeDN($singleDN);
237 237
 			}
238 238
 			return $result;
@@ -283,7 +283,7 @@  discard block
 block discarded – undo
283 283
 	 * @throws \Exception
284 284
 	 */
285 285
 	public static function loginName2UserName($param) {
286
-		if(!isset($param['uid'])) {
286
+		if (!isset($param['uid'])) {
287 287
 			throw new \Exception('key uid is expected to be set in $param');
288 288
 		}
289 289
 
@@ -295,11 +295,11 @@  discard block
 block discarded – undo
295 295
 		$ocConfig = \OC::$server->getConfig();
296 296
 		$notificationManager = \OC::$server->getNotificationManager();
297 297
 
298
-		$userBackend  = new User_Proxy(
298
+		$userBackend = new User_Proxy(
299 299
 			$configPrefixes, $ldapWrapper, $ocConfig, $notificationManager
300 300
 		);
301
-		$uid = $userBackend->loginName2UserName($param['uid'] );
302
-		if($uid !== false) {
301
+		$uid = $userBackend->loginName2UserName($param['uid']);
302
+		if ($uid !== false) {
303 303
 			$param['uid'] = $uid;
304 304
 		}
305 305
 	}
Please login to merge, or discard this patch.