Completed
Pull Request — master (#5623)
by Thomas
16:06
created
apps/provisioning_api/lib/Controller/UsersController.php 2 patches
Indentation   +789 added lines, -789 removed lines patch added patch discarded remove patch
@@ -50,793 +50,793 @@
 block discarded – undo
50 50
 
51 51
 class UsersController extends OCSController {
52 52
 
53
-	/** @var IUserManager */
54
-	private $userManager;
55
-	/** @var IConfig */
56
-	private $config;
57
-	/** @var IAppManager */
58
-	private $appManager;
59
-	/** @var IGroupManager|\OC\Group\Manager */ // FIXME Requires a method that is not on the interface
60
-	private $groupManager;
61
-	/** @var IUserSession */
62
-	private $userSession;
63
-	/** @var AccountManager */
64
-	private $accountManager;
65
-	/** @var ILogger */
66
-	private $logger;
67
-	/** @var IFactory */
68
-	private $l10nFactory;
69
-	/** @var NewUserMailHelper */
70
-	private $newUserMailHelper;
71
-
72
-	/**
73
-	 * @param string $appName
74
-	 * @param IRequest $request
75
-	 * @param IUserManager $userManager
76
-	 * @param IConfig $config
77
-	 * @param IAppManager $appManager
78
-	 * @param IGroupManager $groupManager
79
-	 * @param IUserSession $userSession
80
-	 * @param AccountManager $accountManager
81
-	 * @param ILogger $logger
82
-	 * @param IFactory $l10nFactory
83
-	 * @param NewUserMailHelper $newUserMailHelper
84
-	 */
85
-	public function __construct($appName,
86
-								IRequest $request,
87
-								IUserManager $userManager,
88
-								IConfig $config,
89
-								IAppManager $appManager,
90
-								IGroupManager $groupManager,
91
-								IUserSession $userSession,
92
-								AccountManager $accountManager,
93
-								ILogger $logger,
94
-								IFactory $l10nFactory,
95
-								NewUserMailHelper $newUserMailHelper) {
96
-		parent::__construct($appName, $request);
97
-
98
-		$this->userManager = $userManager;
99
-		$this->config = $config;
100
-		$this->appManager = $appManager;
101
-		$this->groupManager = $groupManager;
102
-		$this->userSession = $userSession;
103
-		$this->accountManager = $accountManager;
104
-		$this->logger = $logger;
105
-		$this->l10nFactory = $l10nFactory;
106
-		$this->newUserMailHelper = $newUserMailHelper;
107
-	}
108
-
109
-	/**
110
-	 * @NoAdminRequired
111
-	 *
112
-	 * returns a list of users
113
-	 *
114
-	 * @param string $search
115
-	 * @param int $limit
116
-	 * @param int $offset
117
-	 * @return DataResponse
118
-	 */
119
-	public function getUsers($search = '', $limit = null, $offset = null) {
120
-		$user = $this->userSession->getUser();
121
-		$users = [];
122
-
123
-		// Admin? Or SubAdmin?
124
-		$uid = $user->getUID();
125
-		$subAdminManager = $this->groupManager->getSubAdmin();
126
-		if($this->groupManager->isAdmin($uid)){
127
-			$users = $this->userManager->search($search, $limit, $offset);
128
-		} else if ($subAdminManager->isSubAdmin($user)) {
129
-			$subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
130
-			foreach ($subAdminOfGroups as $key => $group) {
131
-				$subAdminOfGroups[$key] = $group->getGID();
132
-			}
133
-
134
-			if($offset === null) {
135
-				$offset = 0;
136
-			}
137
-
138
-			$users = [];
139
-			foreach ($subAdminOfGroups as $group) {
140
-				$users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search));
141
-			}
142
-
143
-			$users = array_slice($users, $offset, $limit);
144
-		}
145
-
146
-		$users = array_keys($users);
147
-
148
-		return new DataResponse([
149
-			'users' => $users
150
-		]);
151
-	}
152
-
153
-	/**
154
-	 * @PasswordConfirmationRequired
155
-	 * @NoAdminRequired
156
-	 *
157
-	 * @param string $userid
158
-	 * @param string $password
159
-	 * @param array $groups
160
-	 * @return DataResponse
161
-	 * @throws OCSException
162
-	 */
163
-	public function addUser($userid, $password, $groups = null) {
164
-		$user = $this->userSession->getUser();
165
-		$isAdmin = $this->groupManager->isAdmin($user->getUID());
166
-		$subAdminManager = $this->groupManager->getSubAdmin();
167
-
168
-		if($this->userManager->userExists($userid)) {
169
-			$this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
170
-			throw new OCSException('User already exists', 102);
171
-		}
172
-
173
-		if(is_array($groups)) {
174
-			foreach ($groups as $group) {
175
-				if(!$this->groupManager->groupExists($group)) {
176
-					throw new OCSException('group '.$group.' does not exist', 104);
177
-				}
178
-				if(!$isAdmin && !$subAdminManager->isSubAdminofGroup($user, $this->groupManager->get($group))) {
179
-					throw new OCSException('insufficient privileges for group '. $group, 105);
180
-				}
181
-			}
182
-		} else {
183
-			if(!$isAdmin) {
184
-				throw new OCSException('no group specified (required for subadmins)', 106);
185
-			}
186
-		}
187
-
188
-		try {
189
-			$newUser = $this->userManager->createUser($userid, $password);
190
-			$this->logger->info('Successful addUser call with userid: '.$userid, ['app' => 'ocs_api']);
191
-
192
-			if (is_array($groups)) {
193
-				foreach ($groups as $group) {
194
-					$this->groupManager->get($group)->addUser($newUser);
195
-					$this->logger->info('Added userid '.$userid.' to group '.$group, ['app' => 'ocs_api']);
196
-				}
197
-			}
198
-			return new DataResponse();
199
-		} catch (\Exception $e) {
200
-			$this->logger->error('Failed addUser attempt with exception: '.$e->getMessage(), ['app' => 'ocs_api']);
201
-			throw new OCSException('Bad request', 101);
202
-		}
203
-	}
204
-
205
-	/**
206
-	 * @NoAdminRequired
207
-	 * @NoSubAdminRequired
208
-	 *
209
-	 * gets user info
210
-	 *
211
-	 * @param string $userId
212
-	 * @return DataResponse
213
-	 * @throws OCSException
214
-	 */
215
-	public function getUser($userId) {
216
-		$data = $this->getUserData($userId);
217
-		return new DataResponse($data);
218
-	}
219
-
220
-	/**
221
-	 * @NoAdminRequired
222
-	 * @NoSubAdminRequired
223
-	 *
224
-	 * gets user info from the currently logged in user
225
-	 *
226
-	 * @return DataResponse
227
-	 * @throws OCSException
228
-	 */
229
-	public function getCurrentUser() {
230
-		$user = $this->userSession->getUser();
231
-		if ($user) {
232
-			$data =  $this->getUserData($user->getUID());
233
-			// rename "displayname" to "display-name" only for this call to keep
234
-			// the API stable.
235
-			$data['display-name'] = $data['displayname'];
236
-			unset($data['displayname']);
237
-			return new DataResponse($data);
238
-
239
-		}
240
-
241
-		throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
242
-	}
243
-
244
-	/**
245
-	 * creates a array with all user data
246
-	 *
247
-	 * @param $userId
248
-	 * @return array
249
-	 * @throws OCSException
250
-	 */
251
-	protected function getUserData($userId) {
252
-		$currentLoggedInUser = $this->userSession->getUser();
253
-
254
-		$data = [];
255
-
256
-		// Check if the target user exists
257
-		$targetUserObject = $this->userManager->get($userId);
258
-		if($targetUserObject === null) {
259
-			throw new OCSException('The requested user could not be found', \OCP\API::RESPOND_NOT_FOUND);
260
-		}
261
-
262
-		// Admin? Or SubAdmin?
263
-		if($this->groupManager->isAdmin($currentLoggedInUser->getUID())
264
-			|| $this->groupManager->getSubAdmin()->isUserAccessible($currentLoggedInUser, $targetUserObject)) {
265
-			$data['enabled'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'enabled', 'true');
266
-		} else {
267
-			// Check they are looking up themselves
268
-			if($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) {
269
-				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
270
-			}
271
-		}
272
-
273
-		$userAccount = $this->accountManager->getUser($targetUserObject);
274
-		$groups = $this->groupManager->getUserGroups($targetUserObject);
275
-		$gids = [];
276
-		foreach ($groups as $group) {
277
-			$gids[] = $group->getDisplayName();
278
-		}
279
-
280
-		// Find the data
281
-		$data['id'] = $targetUserObject->getUID();
282
-		$data['quota'] = $this->fillStorageInfo($targetUserObject->getUID());
283
-		$data[AccountManager::PROPERTY_EMAIL] = $targetUserObject->getEMailAddress();
284
-		$data[AccountManager::PROPERTY_DISPLAYNAME] = $targetUserObject->getDisplayName();
285
-		$data[AccountManager::PROPERTY_PHONE] = $userAccount[AccountManager::PROPERTY_PHONE]['value'];
286
-		$data[AccountManager::PROPERTY_ADDRESS] = $userAccount[AccountManager::PROPERTY_ADDRESS]['value'];
287
-		$data[AccountManager::PROPERTY_WEBSITE] = $userAccount[AccountManager::PROPERTY_WEBSITE]['value'];
288
-		$data[AccountManager::PROPERTY_TWITTER] = $userAccount[AccountManager::PROPERTY_TWITTER]['value'];
289
-		$data['groups'] = $gids;
290
-		$data['language'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'lang');
291
-		$data['locale'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'locale');
292
-
293
-		return $data;
294
-	}
295
-
296
-	/**
297
-	 * @NoAdminRequired
298
-	 * @NoSubAdminRequired
299
-	 * @PasswordConfirmationRequired
300
-	 *
301
-	 * edit users
302
-	 *
303
-	 * @param string $userId
304
-	 * @param string $key
305
-	 * @param string $value
306
-	 * @return DataResponse
307
-	 * @throws OCSException
308
-	 * @throws OCSForbiddenException
309
-	 */
310
-	public function editUser($userId, $key, $value) {
311
-		$currentLoggedInUser = $this->userSession->getUser();
312
-
313
-		$targetUser = $this->userManager->get($userId);
314
-		if($targetUser === null) {
315
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
316
-		}
317
-
318
-		$permittedFields = [];
319
-		if($targetUser->getUID() === $currentLoggedInUser->getUID()) {
320
-			// Editing self (display, email)
321
-			if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
322
-				$permittedFields[] = 'display';
323
-				$permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
324
-				$permittedFields[] = AccountManager::PROPERTY_EMAIL;
325
-			}
326
-
327
-			$permittedFields[] = 'password';
328
-			if ($this->config->getSystemValue('force_language', false) === false ||
329
-				$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
330
-				$permittedFields[] = 'language';
331
-				$permittedFields[] = 'locale';
332
-			}
333
-
334
-			if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
335
-				$federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
336
-				$shareProvider = $federatedFileSharing->getFederatedShareProvider();
337
-				if ($shareProvider->isLookupServerUploadEnabled()) {
338
-					$permittedFields[] = AccountManager::PROPERTY_PHONE;
339
-					$permittedFields[] = AccountManager::PROPERTY_ADDRESS;
340
-					$permittedFields[] = AccountManager::PROPERTY_WEBSITE;
341
-					$permittedFields[] = AccountManager::PROPERTY_TWITTER;
342
-				}
343
-			}
344
-
345
-			// If admin they can edit their own quota
346
-			if($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
347
-				$permittedFields[] = 'quota';
348
-			}
349
-		} else {
350
-			// Check if admin / subadmin
351
-			$subAdminManager = $this->groupManager->getSubAdmin();
352
-			if($subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
353
-			|| $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
354
-				// They have permissions over the user
355
-				$permittedFields[] = 'display';
356
-				$permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
357
-				$permittedFields[] = AccountManager::PROPERTY_EMAIL;
358
-				$permittedFields[] = 'password';
359
-				$permittedFields[] = 'language';
360
-				$permittedFields[] = 'locale';
361
-				$permittedFields[] = AccountManager::PROPERTY_PHONE;
362
-				$permittedFields[] = AccountManager::PROPERTY_ADDRESS;
363
-				$permittedFields[] = AccountManager::PROPERTY_WEBSITE;
364
-				$permittedFields[] = AccountManager::PROPERTY_TWITTER;
365
-				$permittedFields[] = 'quota';
366
-			} else {
367
-				// No rights
368
-				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
369
-			}
370
-		}
371
-		// Check if permitted to edit this field
372
-		if(!in_array($key, $permittedFields)) {
373
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
374
-		}
375
-		// Process the edit
376
-		switch($key) {
377
-			case 'display':
378
-			case AccountManager::PROPERTY_DISPLAYNAME:
379
-				$targetUser->setDisplayName($value);
380
-				break;
381
-			case 'quota':
382
-				$quota = $value;
383
-				if($quota !== 'none' && $quota !== 'default') {
384
-					if (is_numeric($quota)) {
385
-						$quota = (float) $quota;
386
-					} else {
387
-						$quota = \OCP\Util::computerFileSize($quota);
388
-					}
389
-					if ($quota === false) {
390
-						throw new OCSException('Invalid quota value '.$value, 103);
391
-					}
392
-					if($quota === 0) {
393
-						$quota = 'default';
394
-					}else if($quota === -1) {
395
-						$quota = 'none';
396
-					} else {
397
-						$quota = \OCP\Util::humanFileSize($quota);
398
-					}
399
-				}
400
-				$targetUser->setQuota($quota);
401
-				break;
402
-			case 'password':
403
-				$targetUser->setPassword($value);
404
-				break;
405
-			case 'language':
406
-				$languagesCodes = $this->l10nFactory->findAvailableLanguages();
407
-				if (!in_array($value, $languagesCodes, true) && $value !== 'en') {
408
-					throw new OCSException('Invalid language', 102);
409
-				}
410
-				$this->config->setUserValue($targetUser->getUID(), 'core', 'lang', $value);
411
-				break;
412
-			case 'locale':
413
-				// do some stuff
414
-				$this->config->setUserValue($targetUser->getUID(), 'core', 'locale', $value);
415
-				break;
416
-			case AccountManager::PROPERTY_EMAIL:
417
-				if(filter_var($value, FILTER_VALIDATE_EMAIL)) {
418
-					$targetUser->setEMailAddress($value);
419
-				} else {
420
-					throw new OCSException('', 102);
421
-				}
422
-				break;
423
-			case AccountManager::PROPERTY_PHONE:
424
-			case AccountManager::PROPERTY_ADDRESS:
425
-			case AccountManager::PROPERTY_WEBSITE:
426
-			case AccountManager::PROPERTY_TWITTER:
427
-				$userAccount = $this->accountManager->getUser($targetUser);
428
-				if ($userAccount[$key]['value'] !== $value) {
429
-					$userAccount[$key]['value'] = $value;
430
-					$this->accountManager->updateUser($targetUser, $userAccount);
431
-				}
432
-				break;
433
-			default:
434
-				throw new OCSException('', 103);
435
-		}
436
-		return new DataResponse();
437
-	}
438
-
439
-	/**
440
-	 * @PasswordConfirmationRequired
441
-	 * @NoAdminRequired
442
-	 *
443
-	 * @param string $userId
444
-	 * @return DataResponse
445
-	 * @throws OCSException
446
-	 * @throws OCSForbiddenException
447
-	 */
448
-	public function deleteUser($userId) {
449
-		$currentLoggedInUser = $this->userSession->getUser();
450
-
451
-		$targetUser = $this->userManager->get($userId);
452
-
453
-		if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
454
-			throw new OCSException('', 101);
455
-		}
456
-
457
-		// If not permitted
458
-		$subAdminManager = $this->groupManager->getSubAdmin();
459
-		if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
460
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
461
-		}
462
-
463
-		// Go ahead with the delete
464
-		if($targetUser->delete()) {
465
-			return new DataResponse();
466
-		} else {
467
-			throw new OCSException('', 101);
468
-		}
469
-	}
470
-
471
-	/**
472
-	 * @PasswordConfirmationRequired
473
-	 * @NoAdminRequired
474
-	 *
475
-	 * @param string $userId
476
-	 * @return DataResponse
477
-	 * @throws OCSException
478
-	 * @throws OCSForbiddenException
479
-	 */
480
-	public function disableUser($userId) {
481
-		return $this->setEnabled($userId, false);
482
-	}
483
-
484
-	/**
485
-	 * @PasswordConfirmationRequired
486
-	 * @NoAdminRequired
487
-	 *
488
-	 * @param string $userId
489
-	 * @return DataResponse
490
-	 * @throws OCSException
491
-	 * @throws OCSForbiddenException
492
-	 */
493
-	public function enableUser($userId) {
494
-		return $this->setEnabled($userId, true);
495
-	}
496
-
497
-	/**
498
-	 * @param string $userId
499
-	 * @param bool $value
500
-	 * @return DataResponse
501
-	 * @throws OCSException
502
-	 * @throws OCSForbiddenException
503
-	 */
504
-	private function setEnabled($userId, $value) {
505
-		$currentLoggedInUser = $this->userSession->getUser();
506
-
507
-		$targetUser = $this->userManager->get($userId);
508
-		if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
509
-			throw new OCSException('', 101);
510
-		}
511
-
512
-		// If not permitted
513
-		$subAdminManager = $this->groupManager->getSubAdmin();
514
-		if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
515
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
516
-		}
517
-
518
-		// enable/disable the user now
519
-		$targetUser->setEnabled($value);
520
-		return new DataResponse();
521
-	}
522
-
523
-	/**
524
-	 * @NoAdminRequired
525
-	 * @NoSubAdminRequired
526
-	 *
527
-	 * @param string $userId
528
-	 * @return DataResponse
529
-	 * @throws OCSException
530
-	 */
531
-	public function getUsersGroups($userId) {
532
-		$loggedInUser = $this->userSession->getUser();
533
-
534
-		$targetUser = $this->userManager->get($userId);
535
-		if($targetUser === null) {
536
-			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
537
-		}
538
-
539
-		if($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
540
-			// Self lookup or admin lookup
541
-			return new DataResponse([
542
-				'groups' => $this->groupManager->getUserGroupIds($targetUser)
543
-			]);
544
-		} else {
545
-			$subAdminManager = $this->groupManager->getSubAdmin();
546
-
547
-			// Looking up someone else
548
-			if($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
549
-				// Return the group that the method caller is subadmin of for the user in question
550
-				/** @var IGroup[] $getSubAdminsGroups */
551
-				$getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
552
-				foreach ($getSubAdminsGroups as $key => $group) {
553
-					$getSubAdminsGroups[$key] = $group->getGID();
554
-				}
555
-				$groups = array_intersect(
556
-					$getSubAdminsGroups,
557
-					$this->groupManager->getUserGroupIds($targetUser)
558
-				);
559
-				return new DataResponse(['groups' => $groups]);
560
-			} else {
561
-				// Not permitted
562
-				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
563
-			}
564
-		}
565
-
566
-	}
567
-
568
-	/**
569
-	 * @PasswordConfirmationRequired
570
-	 * @NoAdminRequired
571
-	 *
572
-	 * @param string $userId
573
-	 * @param string $groupid
574
-	 * @return DataResponse
575
-	 * @throws OCSException
576
-	 */
577
-	public function addToGroup($userId, $groupid = '') {
578
-		if($groupid === '') {
579
-			throw new OCSException('', 101);
580
-		}
581
-
582
-		$group = $this->groupManager->get($groupid);
583
-		$targetUser = $this->userManager->get($userId);
584
-		if($group === null) {
585
-			throw new OCSException('', 102);
586
-		}
587
-		if($targetUser === null) {
588
-			throw new OCSException('', 103);
589
-		}
590
-
591
-		// If they're not an admin, check they are a subadmin of the group in question
592
-		$loggedInUser = $this->userSession->getUser();
593
-		$subAdminManager = $this->groupManager->getSubAdmin();
594
-		if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
595
-			throw new OCSException('', 104);
596
-		}
597
-
598
-		// Add user to group
599
-		$group->addUser($targetUser);
600
-		return new DataResponse();
601
-	}
602
-
603
-	/**
604
-	 * @PasswordConfirmationRequired
605
-	 * @NoAdminRequired
606
-	 *
607
-	 * @param string $userId
608
-	 * @param string $groupid
609
-	 * @return DataResponse
610
-	 * @throws OCSException
611
-	 */
612
-	public function removeFromGroup($userId, $groupid) {
613
-		$loggedInUser = $this->userSession->getUser();
614
-
615
-		if($groupid === null) {
616
-			throw new OCSException('', 101);
617
-		}
618
-
619
-		$group = $this->groupManager->get($groupid);
620
-		if($group === null) {
621
-			throw new OCSException('', 102);
622
-		}
623
-
624
-		$targetUser = $this->userManager->get($userId);
625
-		if($targetUser === null) {
626
-			throw new OCSException('', 103);
627
-		}
628
-
629
-		// If they're not an admin, check they are a subadmin of the group in question
630
-		$subAdminManager = $this->groupManager->getSubAdmin();
631
-		if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
632
-			throw new OCSException('', 104);
633
-		}
634
-
635
-		// Check they aren't removing themselves from 'admin' or their 'subadmin; group
636
-		if ($targetUser->getUID() === $loggedInUser->getUID()) {
637
-			if ($this->groupManager->isAdmin($loggedInUser->getUID())) {
638
-				if ($group->getGID() === 'admin') {
639
-					throw new OCSException('Cannot remove yourself from the admin group', 105);
640
-				}
641
-			} else {
642
-				// Not an admin, so the user must be a subadmin of this group, but that is not allowed.
643
-				throw new OCSException('Cannot remove yourself from this group as you are a SubAdmin', 105);
644
-			}
645
-
646
-		} else if (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
647
-			/** @var IGroup[] $subAdminGroups */
648
-			$subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
649
-			$subAdminGroups = array_map(function (IGroup $subAdminGroup) {
650
-				return $subAdminGroup->getGID();
651
-			}, $subAdminGroups);
652
-			$userGroups = $this->groupManager->getUserGroupIds($targetUser);
653
-			$userSubAdminGroups = array_intersect($subAdminGroups, $userGroups);
654
-
655
-			if (count($userSubAdminGroups) <= 1) {
656
-				// Subadmin must not be able to remove a user from all their subadmin groups.
657
-				throw new OCSException('Cannot remove user from this group as this is the only remaining group you are a SubAdmin of', 105);
658
-			}
659
-		}
660
-
661
-		// Remove user from group
662
-		$group->removeUser($targetUser);
663
-		return new DataResponse();
664
-	}
665
-
666
-	/**
667
-	 * Creates a subadmin
668
-	 *
669
-	 * @PasswordConfirmationRequired
670
-	 *
671
-	 * @param string $userId
672
-	 * @param string $groupid
673
-	 * @return DataResponse
674
-	 * @throws OCSException
675
-	 */
676
-	public function addSubAdmin($userId, $groupid) {
677
-		$group = $this->groupManager->get($groupid);
678
-		$user = $this->userManager->get($userId);
679
-
680
-		// Check if the user exists
681
-		if($user === null) {
682
-			throw new OCSException('User does not exist', 101);
683
-		}
684
-		// Check if group exists
685
-		if($group === null) {
686
-			throw new OCSException('Group does not exist',  102);
687
-		}
688
-		// Check if trying to make subadmin of admin group
689
-		if($group->getGID() === 'admin') {
690
-			throw new OCSException('Cannot create subadmins for admin group', 103);
691
-		}
692
-
693
-		$subAdminManager = $this->groupManager->getSubAdmin();
694
-
695
-		// We cannot be subadmin twice
696
-		if ($subAdminManager->isSubAdminofGroup($user, $group)) {
697
-			return new DataResponse();
698
-		}
699
-		// Go
700
-		if($subAdminManager->createSubAdmin($user, $group)) {
701
-			return new DataResponse();
702
-		} else {
703
-			throw new OCSException('Unknown error occurred', 103);
704
-		}
705
-	}
706
-
707
-	/**
708
-	 * Removes a subadmin from a group
709
-	 *
710
-	 * @PasswordConfirmationRequired
711
-	 *
712
-	 * @param string $userId
713
-	 * @param string $groupid
714
-	 * @return DataResponse
715
-	 * @throws OCSException
716
-	 */
717
-	public function removeSubAdmin($userId, $groupid) {
718
-		$group = $this->groupManager->get($groupid);
719
-		$user = $this->userManager->get($userId);
720
-		$subAdminManager = $this->groupManager->getSubAdmin();
721
-
722
-		// Check if the user exists
723
-		if($user === null) {
724
-			throw new OCSException('User does not exist', 101);
725
-		}
726
-		// Check if the group exists
727
-		if($group === null) {
728
-			throw new OCSException('Group does not exist', 101);
729
-		}
730
-		// Check if they are a subadmin of this said group
731
-		if(!$subAdminManager->isSubAdminOfGroup($user, $group)) {
732
-			throw new OCSException('User is not a subadmin of this group', 102);
733
-		}
734
-
735
-		// Go
736
-		if($subAdminManager->deleteSubAdmin($user, $group)) {
737
-			return new DataResponse();
738
-		} else {
739
-			throw new OCSException('Unknown error occurred', 103);
740
-		}
741
-	}
742
-
743
-	/**
744
-	 * Get the groups a user is a subadmin of
745
-	 *
746
-	 * @param string $userId
747
-	 * @return DataResponse
748
-	 * @throws OCSException
749
-	 */
750
-	public function getUserSubAdminGroups($userId) {
751
-		$user = $this->userManager->get($userId);
752
-		// Check if the user exists
753
-		if($user === null) {
754
-			throw new OCSException('User does not exist', 101);
755
-		}
756
-
757
-		// Get the subadmin groups
758
-		$groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
759
-		foreach ($groups as $key => $group) {
760
-			$groups[$key] = $group->getGID();
761
-		}
762
-
763
-		if(!$groups) {
764
-			throw new OCSException('Unknown error occurred', 102);
765
-		} else {
766
-			return new DataResponse($groups);
767
-		}
768
-	}
769
-
770
-	/**
771
-	 * @param string $userId
772
-	 * @return array
773
-	 * @throws \OCP\Files\NotFoundException
774
-	 */
775
-	protected function fillStorageInfo($userId) {
776
-		try {
777
-			\OC_Util::tearDownFS();
778
-			\OC_Util::setupFS($userId);
779
-			$storage = OC_Helper::getStorageInfo('/');
780
-			$data = [
781
-				'free' => $storage['free'],
782
-				'used' => $storage['used'],
783
-				'total' => $storage['total'],
784
-				'relative' => $storage['relative'],
785
-				'quota' => $storage['quota'],
786
-			];
787
-		} catch (NotFoundException $ex) {
788
-			$data = [];
789
-		}
790
-		return $data;
791
-	}
792
-
793
-	/**
794
-	 * @NoAdminRequired
795
-	 * @PasswordConfirmationRequired
796
-	 *
797
-	 * resend welcome message
798
-	 *
799
-	 * @param string $userId
800
-	 * @return DataResponse
801
-	 * @throws OCSException
802
-	 */
803
-	public function resendWelcomeMessage($userId) {
804
-		$currentLoggedInUser = $this->userSession->getUser();
805
-
806
-		$targetUser = $this->userManager->get($userId);
807
-		if($targetUser === null) {
808
-			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
809
-		}
810
-
811
-		// Check if admin / subadmin
812
-		$subAdminManager = $this->groupManager->getSubAdmin();
813
-		if(!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
814
-			&& !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
815
-			// No rights
816
-			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
817
-		}
818
-
819
-		$email = $targetUser->getEMailAddress();
820
-		if ($email === '' || $email === null) {
821
-			throw new OCSException('Email address not available', 101);
822
-		}
823
-		$username = $targetUser->getUID();
824
-		$lang = $this->config->getUserValue($username, 'core', 'lang', 'en');
825
-		if (!$this->l10nFactory->languageExists('settings', $lang)) {
826
-			$lang = 'en';
827
-		}
828
-
829
-		$l10n = $this->l10nFactory->get('settings', $lang);
830
-
831
-		try {
832
-			$this->newUserMailHelper->setL10N($l10n);
833
-			$emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
834
-			$this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
835
-		} catch(\Exception $e) {
836
-			$this->logger->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
837
-			throw new OCSException('Sending email failed', 102);
838
-		}
839
-
840
-		return new DataResponse();
841
-	}
53
+    /** @var IUserManager */
54
+    private $userManager;
55
+    /** @var IConfig */
56
+    private $config;
57
+    /** @var IAppManager */
58
+    private $appManager;
59
+    /** @var IGroupManager|\OC\Group\Manager */ // FIXME Requires a method that is not on the interface
60
+    private $groupManager;
61
+    /** @var IUserSession */
62
+    private $userSession;
63
+    /** @var AccountManager */
64
+    private $accountManager;
65
+    /** @var ILogger */
66
+    private $logger;
67
+    /** @var IFactory */
68
+    private $l10nFactory;
69
+    /** @var NewUserMailHelper */
70
+    private $newUserMailHelper;
71
+
72
+    /**
73
+     * @param string $appName
74
+     * @param IRequest $request
75
+     * @param IUserManager $userManager
76
+     * @param IConfig $config
77
+     * @param IAppManager $appManager
78
+     * @param IGroupManager $groupManager
79
+     * @param IUserSession $userSession
80
+     * @param AccountManager $accountManager
81
+     * @param ILogger $logger
82
+     * @param IFactory $l10nFactory
83
+     * @param NewUserMailHelper $newUserMailHelper
84
+     */
85
+    public function __construct($appName,
86
+                                IRequest $request,
87
+                                IUserManager $userManager,
88
+                                IConfig $config,
89
+                                IAppManager $appManager,
90
+                                IGroupManager $groupManager,
91
+                                IUserSession $userSession,
92
+                                AccountManager $accountManager,
93
+                                ILogger $logger,
94
+                                IFactory $l10nFactory,
95
+                                NewUserMailHelper $newUserMailHelper) {
96
+        parent::__construct($appName, $request);
97
+
98
+        $this->userManager = $userManager;
99
+        $this->config = $config;
100
+        $this->appManager = $appManager;
101
+        $this->groupManager = $groupManager;
102
+        $this->userSession = $userSession;
103
+        $this->accountManager = $accountManager;
104
+        $this->logger = $logger;
105
+        $this->l10nFactory = $l10nFactory;
106
+        $this->newUserMailHelper = $newUserMailHelper;
107
+    }
108
+
109
+    /**
110
+     * @NoAdminRequired
111
+     *
112
+     * returns a list of users
113
+     *
114
+     * @param string $search
115
+     * @param int $limit
116
+     * @param int $offset
117
+     * @return DataResponse
118
+     */
119
+    public function getUsers($search = '', $limit = null, $offset = null) {
120
+        $user = $this->userSession->getUser();
121
+        $users = [];
122
+
123
+        // Admin? Or SubAdmin?
124
+        $uid = $user->getUID();
125
+        $subAdminManager = $this->groupManager->getSubAdmin();
126
+        if($this->groupManager->isAdmin($uid)){
127
+            $users = $this->userManager->search($search, $limit, $offset);
128
+        } else if ($subAdminManager->isSubAdmin($user)) {
129
+            $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
130
+            foreach ($subAdminOfGroups as $key => $group) {
131
+                $subAdminOfGroups[$key] = $group->getGID();
132
+            }
133
+
134
+            if($offset === null) {
135
+                $offset = 0;
136
+            }
137
+
138
+            $users = [];
139
+            foreach ($subAdminOfGroups as $group) {
140
+                $users = array_merge($users, $this->groupManager->displayNamesInGroup($group, $search));
141
+            }
142
+
143
+            $users = array_slice($users, $offset, $limit);
144
+        }
145
+
146
+        $users = array_keys($users);
147
+
148
+        return new DataResponse([
149
+            'users' => $users
150
+        ]);
151
+    }
152
+
153
+    /**
154
+     * @PasswordConfirmationRequired
155
+     * @NoAdminRequired
156
+     *
157
+     * @param string $userid
158
+     * @param string $password
159
+     * @param array $groups
160
+     * @return DataResponse
161
+     * @throws OCSException
162
+     */
163
+    public function addUser($userid, $password, $groups = null) {
164
+        $user = $this->userSession->getUser();
165
+        $isAdmin = $this->groupManager->isAdmin($user->getUID());
166
+        $subAdminManager = $this->groupManager->getSubAdmin();
167
+
168
+        if($this->userManager->userExists($userid)) {
169
+            $this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
170
+            throw new OCSException('User already exists', 102);
171
+        }
172
+
173
+        if(is_array($groups)) {
174
+            foreach ($groups as $group) {
175
+                if(!$this->groupManager->groupExists($group)) {
176
+                    throw new OCSException('group '.$group.' does not exist', 104);
177
+                }
178
+                if(!$isAdmin && !$subAdminManager->isSubAdminofGroup($user, $this->groupManager->get($group))) {
179
+                    throw new OCSException('insufficient privileges for group '. $group, 105);
180
+                }
181
+            }
182
+        } else {
183
+            if(!$isAdmin) {
184
+                throw new OCSException('no group specified (required for subadmins)', 106);
185
+            }
186
+        }
187
+
188
+        try {
189
+            $newUser = $this->userManager->createUser($userid, $password);
190
+            $this->logger->info('Successful addUser call with userid: '.$userid, ['app' => 'ocs_api']);
191
+
192
+            if (is_array($groups)) {
193
+                foreach ($groups as $group) {
194
+                    $this->groupManager->get($group)->addUser($newUser);
195
+                    $this->logger->info('Added userid '.$userid.' to group '.$group, ['app' => 'ocs_api']);
196
+                }
197
+            }
198
+            return new DataResponse();
199
+        } catch (\Exception $e) {
200
+            $this->logger->error('Failed addUser attempt with exception: '.$e->getMessage(), ['app' => 'ocs_api']);
201
+            throw new OCSException('Bad request', 101);
202
+        }
203
+    }
204
+
205
+    /**
206
+     * @NoAdminRequired
207
+     * @NoSubAdminRequired
208
+     *
209
+     * gets user info
210
+     *
211
+     * @param string $userId
212
+     * @return DataResponse
213
+     * @throws OCSException
214
+     */
215
+    public function getUser($userId) {
216
+        $data = $this->getUserData($userId);
217
+        return new DataResponse($data);
218
+    }
219
+
220
+    /**
221
+     * @NoAdminRequired
222
+     * @NoSubAdminRequired
223
+     *
224
+     * gets user info from the currently logged in user
225
+     *
226
+     * @return DataResponse
227
+     * @throws OCSException
228
+     */
229
+    public function getCurrentUser() {
230
+        $user = $this->userSession->getUser();
231
+        if ($user) {
232
+            $data =  $this->getUserData($user->getUID());
233
+            // rename "displayname" to "display-name" only for this call to keep
234
+            // the API stable.
235
+            $data['display-name'] = $data['displayname'];
236
+            unset($data['displayname']);
237
+            return new DataResponse($data);
238
+
239
+        }
240
+
241
+        throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
242
+    }
243
+
244
+    /**
245
+     * creates a array with all user data
246
+     *
247
+     * @param $userId
248
+     * @return array
249
+     * @throws OCSException
250
+     */
251
+    protected function getUserData($userId) {
252
+        $currentLoggedInUser = $this->userSession->getUser();
253
+
254
+        $data = [];
255
+
256
+        // Check if the target user exists
257
+        $targetUserObject = $this->userManager->get($userId);
258
+        if($targetUserObject === null) {
259
+            throw new OCSException('The requested user could not be found', \OCP\API::RESPOND_NOT_FOUND);
260
+        }
261
+
262
+        // Admin? Or SubAdmin?
263
+        if($this->groupManager->isAdmin($currentLoggedInUser->getUID())
264
+            || $this->groupManager->getSubAdmin()->isUserAccessible($currentLoggedInUser, $targetUserObject)) {
265
+            $data['enabled'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'enabled', 'true');
266
+        } else {
267
+            // Check they are looking up themselves
268
+            if($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) {
269
+                throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
270
+            }
271
+        }
272
+
273
+        $userAccount = $this->accountManager->getUser($targetUserObject);
274
+        $groups = $this->groupManager->getUserGroups($targetUserObject);
275
+        $gids = [];
276
+        foreach ($groups as $group) {
277
+            $gids[] = $group->getDisplayName();
278
+        }
279
+
280
+        // Find the data
281
+        $data['id'] = $targetUserObject->getUID();
282
+        $data['quota'] = $this->fillStorageInfo($targetUserObject->getUID());
283
+        $data[AccountManager::PROPERTY_EMAIL] = $targetUserObject->getEMailAddress();
284
+        $data[AccountManager::PROPERTY_DISPLAYNAME] = $targetUserObject->getDisplayName();
285
+        $data[AccountManager::PROPERTY_PHONE] = $userAccount[AccountManager::PROPERTY_PHONE]['value'];
286
+        $data[AccountManager::PROPERTY_ADDRESS] = $userAccount[AccountManager::PROPERTY_ADDRESS]['value'];
287
+        $data[AccountManager::PROPERTY_WEBSITE] = $userAccount[AccountManager::PROPERTY_WEBSITE]['value'];
288
+        $data[AccountManager::PROPERTY_TWITTER] = $userAccount[AccountManager::PROPERTY_TWITTER]['value'];
289
+        $data['groups'] = $gids;
290
+        $data['language'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'lang');
291
+        $data['locale'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'locale');
292
+
293
+        return $data;
294
+    }
295
+
296
+    /**
297
+     * @NoAdminRequired
298
+     * @NoSubAdminRequired
299
+     * @PasswordConfirmationRequired
300
+     *
301
+     * edit users
302
+     *
303
+     * @param string $userId
304
+     * @param string $key
305
+     * @param string $value
306
+     * @return DataResponse
307
+     * @throws OCSException
308
+     * @throws OCSForbiddenException
309
+     */
310
+    public function editUser($userId, $key, $value) {
311
+        $currentLoggedInUser = $this->userSession->getUser();
312
+
313
+        $targetUser = $this->userManager->get($userId);
314
+        if($targetUser === null) {
315
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
316
+        }
317
+
318
+        $permittedFields = [];
319
+        if($targetUser->getUID() === $currentLoggedInUser->getUID()) {
320
+            // Editing self (display, email)
321
+            if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
322
+                $permittedFields[] = 'display';
323
+                $permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
324
+                $permittedFields[] = AccountManager::PROPERTY_EMAIL;
325
+            }
326
+
327
+            $permittedFields[] = 'password';
328
+            if ($this->config->getSystemValue('force_language', false) === false ||
329
+                $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
330
+                $permittedFields[] = 'language';
331
+                $permittedFields[] = 'locale';
332
+            }
333
+
334
+            if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
335
+                $federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
336
+                $shareProvider = $federatedFileSharing->getFederatedShareProvider();
337
+                if ($shareProvider->isLookupServerUploadEnabled()) {
338
+                    $permittedFields[] = AccountManager::PROPERTY_PHONE;
339
+                    $permittedFields[] = AccountManager::PROPERTY_ADDRESS;
340
+                    $permittedFields[] = AccountManager::PROPERTY_WEBSITE;
341
+                    $permittedFields[] = AccountManager::PROPERTY_TWITTER;
342
+                }
343
+            }
344
+
345
+            // If admin they can edit their own quota
346
+            if($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
347
+                $permittedFields[] = 'quota';
348
+            }
349
+        } else {
350
+            // Check if admin / subadmin
351
+            $subAdminManager = $this->groupManager->getSubAdmin();
352
+            if($subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
353
+            || $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
354
+                // They have permissions over the user
355
+                $permittedFields[] = 'display';
356
+                $permittedFields[] = AccountManager::PROPERTY_DISPLAYNAME;
357
+                $permittedFields[] = AccountManager::PROPERTY_EMAIL;
358
+                $permittedFields[] = 'password';
359
+                $permittedFields[] = 'language';
360
+                $permittedFields[] = 'locale';
361
+                $permittedFields[] = AccountManager::PROPERTY_PHONE;
362
+                $permittedFields[] = AccountManager::PROPERTY_ADDRESS;
363
+                $permittedFields[] = AccountManager::PROPERTY_WEBSITE;
364
+                $permittedFields[] = AccountManager::PROPERTY_TWITTER;
365
+                $permittedFields[] = 'quota';
366
+            } else {
367
+                // No rights
368
+                throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
369
+            }
370
+        }
371
+        // Check if permitted to edit this field
372
+        if(!in_array($key, $permittedFields)) {
373
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
374
+        }
375
+        // Process the edit
376
+        switch($key) {
377
+            case 'display':
378
+            case AccountManager::PROPERTY_DISPLAYNAME:
379
+                $targetUser->setDisplayName($value);
380
+                break;
381
+            case 'quota':
382
+                $quota = $value;
383
+                if($quota !== 'none' && $quota !== 'default') {
384
+                    if (is_numeric($quota)) {
385
+                        $quota = (float) $quota;
386
+                    } else {
387
+                        $quota = \OCP\Util::computerFileSize($quota);
388
+                    }
389
+                    if ($quota === false) {
390
+                        throw new OCSException('Invalid quota value '.$value, 103);
391
+                    }
392
+                    if($quota === 0) {
393
+                        $quota = 'default';
394
+                    }else if($quota === -1) {
395
+                        $quota = 'none';
396
+                    } else {
397
+                        $quota = \OCP\Util::humanFileSize($quota);
398
+                    }
399
+                }
400
+                $targetUser->setQuota($quota);
401
+                break;
402
+            case 'password':
403
+                $targetUser->setPassword($value);
404
+                break;
405
+            case 'language':
406
+                $languagesCodes = $this->l10nFactory->findAvailableLanguages();
407
+                if (!in_array($value, $languagesCodes, true) && $value !== 'en') {
408
+                    throw new OCSException('Invalid language', 102);
409
+                }
410
+                $this->config->setUserValue($targetUser->getUID(), 'core', 'lang', $value);
411
+                break;
412
+            case 'locale':
413
+                // do some stuff
414
+                $this->config->setUserValue($targetUser->getUID(), 'core', 'locale', $value);
415
+                break;
416
+            case AccountManager::PROPERTY_EMAIL:
417
+                if(filter_var($value, FILTER_VALIDATE_EMAIL)) {
418
+                    $targetUser->setEMailAddress($value);
419
+                } else {
420
+                    throw new OCSException('', 102);
421
+                }
422
+                break;
423
+            case AccountManager::PROPERTY_PHONE:
424
+            case AccountManager::PROPERTY_ADDRESS:
425
+            case AccountManager::PROPERTY_WEBSITE:
426
+            case AccountManager::PROPERTY_TWITTER:
427
+                $userAccount = $this->accountManager->getUser($targetUser);
428
+                if ($userAccount[$key]['value'] !== $value) {
429
+                    $userAccount[$key]['value'] = $value;
430
+                    $this->accountManager->updateUser($targetUser, $userAccount);
431
+                }
432
+                break;
433
+            default:
434
+                throw new OCSException('', 103);
435
+        }
436
+        return new DataResponse();
437
+    }
438
+
439
+    /**
440
+     * @PasswordConfirmationRequired
441
+     * @NoAdminRequired
442
+     *
443
+     * @param string $userId
444
+     * @return DataResponse
445
+     * @throws OCSException
446
+     * @throws OCSForbiddenException
447
+     */
448
+    public function deleteUser($userId) {
449
+        $currentLoggedInUser = $this->userSession->getUser();
450
+
451
+        $targetUser = $this->userManager->get($userId);
452
+
453
+        if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
454
+            throw new OCSException('', 101);
455
+        }
456
+
457
+        // If not permitted
458
+        $subAdminManager = $this->groupManager->getSubAdmin();
459
+        if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
460
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
461
+        }
462
+
463
+        // Go ahead with the delete
464
+        if($targetUser->delete()) {
465
+            return new DataResponse();
466
+        } else {
467
+            throw new OCSException('', 101);
468
+        }
469
+    }
470
+
471
+    /**
472
+     * @PasswordConfirmationRequired
473
+     * @NoAdminRequired
474
+     *
475
+     * @param string $userId
476
+     * @return DataResponse
477
+     * @throws OCSException
478
+     * @throws OCSForbiddenException
479
+     */
480
+    public function disableUser($userId) {
481
+        return $this->setEnabled($userId, false);
482
+    }
483
+
484
+    /**
485
+     * @PasswordConfirmationRequired
486
+     * @NoAdminRequired
487
+     *
488
+     * @param string $userId
489
+     * @return DataResponse
490
+     * @throws OCSException
491
+     * @throws OCSForbiddenException
492
+     */
493
+    public function enableUser($userId) {
494
+        return $this->setEnabled($userId, true);
495
+    }
496
+
497
+    /**
498
+     * @param string $userId
499
+     * @param bool $value
500
+     * @return DataResponse
501
+     * @throws OCSException
502
+     * @throws OCSForbiddenException
503
+     */
504
+    private function setEnabled($userId, $value) {
505
+        $currentLoggedInUser = $this->userSession->getUser();
506
+
507
+        $targetUser = $this->userManager->get($userId);
508
+        if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
509
+            throw new OCSException('', 101);
510
+        }
511
+
512
+        // If not permitted
513
+        $subAdminManager = $this->groupManager->getSubAdmin();
514
+        if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
515
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
516
+        }
517
+
518
+        // enable/disable the user now
519
+        $targetUser->setEnabled($value);
520
+        return new DataResponse();
521
+    }
522
+
523
+    /**
524
+     * @NoAdminRequired
525
+     * @NoSubAdminRequired
526
+     *
527
+     * @param string $userId
528
+     * @return DataResponse
529
+     * @throws OCSException
530
+     */
531
+    public function getUsersGroups($userId) {
532
+        $loggedInUser = $this->userSession->getUser();
533
+
534
+        $targetUser = $this->userManager->get($userId);
535
+        if($targetUser === null) {
536
+            throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
537
+        }
538
+
539
+        if($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
540
+            // Self lookup or admin lookup
541
+            return new DataResponse([
542
+                'groups' => $this->groupManager->getUserGroupIds($targetUser)
543
+            ]);
544
+        } else {
545
+            $subAdminManager = $this->groupManager->getSubAdmin();
546
+
547
+            // Looking up someone else
548
+            if($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
549
+                // Return the group that the method caller is subadmin of for the user in question
550
+                /** @var IGroup[] $getSubAdminsGroups */
551
+                $getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
552
+                foreach ($getSubAdminsGroups as $key => $group) {
553
+                    $getSubAdminsGroups[$key] = $group->getGID();
554
+                }
555
+                $groups = array_intersect(
556
+                    $getSubAdminsGroups,
557
+                    $this->groupManager->getUserGroupIds($targetUser)
558
+                );
559
+                return new DataResponse(['groups' => $groups]);
560
+            } else {
561
+                // Not permitted
562
+                throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
563
+            }
564
+        }
565
+
566
+    }
567
+
568
+    /**
569
+     * @PasswordConfirmationRequired
570
+     * @NoAdminRequired
571
+     *
572
+     * @param string $userId
573
+     * @param string $groupid
574
+     * @return DataResponse
575
+     * @throws OCSException
576
+     */
577
+    public function addToGroup($userId, $groupid = '') {
578
+        if($groupid === '') {
579
+            throw new OCSException('', 101);
580
+        }
581
+
582
+        $group = $this->groupManager->get($groupid);
583
+        $targetUser = $this->userManager->get($userId);
584
+        if($group === null) {
585
+            throw new OCSException('', 102);
586
+        }
587
+        if($targetUser === null) {
588
+            throw new OCSException('', 103);
589
+        }
590
+
591
+        // If they're not an admin, check they are a subadmin of the group in question
592
+        $loggedInUser = $this->userSession->getUser();
593
+        $subAdminManager = $this->groupManager->getSubAdmin();
594
+        if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
595
+            throw new OCSException('', 104);
596
+        }
597
+
598
+        // Add user to group
599
+        $group->addUser($targetUser);
600
+        return new DataResponse();
601
+    }
602
+
603
+    /**
604
+     * @PasswordConfirmationRequired
605
+     * @NoAdminRequired
606
+     *
607
+     * @param string $userId
608
+     * @param string $groupid
609
+     * @return DataResponse
610
+     * @throws OCSException
611
+     */
612
+    public function removeFromGroup($userId, $groupid) {
613
+        $loggedInUser = $this->userSession->getUser();
614
+
615
+        if($groupid === null) {
616
+            throw new OCSException('', 101);
617
+        }
618
+
619
+        $group = $this->groupManager->get($groupid);
620
+        if($group === null) {
621
+            throw new OCSException('', 102);
622
+        }
623
+
624
+        $targetUser = $this->userManager->get($userId);
625
+        if($targetUser === null) {
626
+            throw new OCSException('', 103);
627
+        }
628
+
629
+        // If they're not an admin, check they are a subadmin of the group in question
630
+        $subAdminManager = $this->groupManager->getSubAdmin();
631
+        if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
632
+            throw new OCSException('', 104);
633
+        }
634
+
635
+        // Check they aren't removing themselves from 'admin' or their 'subadmin; group
636
+        if ($targetUser->getUID() === $loggedInUser->getUID()) {
637
+            if ($this->groupManager->isAdmin($loggedInUser->getUID())) {
638
+                if ($group->getGID() === 'admin') {
639
+                    throw new OCSException('Cannot remove yourself from the admin group', 105);
640
+                }
641
+            } else {
642
+                // Not an admin, so the user must be a subadmin of this group, but that is not allowed.
643
+                throw new OCSException('Cannot remove yourself from this group as you are a SubAdmin', 105);
644
+            }
645
+
646
+        } else if (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
647
+            /** @var IGroup[] $subAdminGroups */
648
+            $subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
649
+            $subAdminGroups = array_map(function (IGroup $subAdminGroup) {
650
+                return $subAdminGroup->getGID();
651
+            }, $subAdminGroups);
652
+            $userGroups = $this->groupManager->getUserGroupIds($targetUser);
653
+            $userSubAdminGroups = array_intersect($subAdminGroups, $userGroups);
654
+
655
+            if (count($userSubAdminGroups) <= 1) {
656
+                // Subadmin must not be able to remove a user from all their subadmin groups.
657
+                throw new OCSException('Cannot remove user from this group as this is the only remaining group you are a SubAdmin of', 105);
658
+            }
659
+        }
660
+
661
+        // Remove user from group
662
+        $group->removeUser($targetUser);
663
+        return new DataResponse();
664
+    }
665
+
666
+    /**
667
+     * Creates a subadmin
668
+     *
669
+     * @PasswordConfirmationRequired
670
+     *
671
+     * @param string $userId
672
+     * @param string $groupid
673
+     * @return DataResponse
674
+     * @throws OCSException
675
+     */
676
+    public function addSubAdmin($userId, $groupid) {
677
+        $group = $this->groupManager->get($groupid);
678
+        $user = $this->userManager->get($userId);
679
+
680
+        // Check if the user exists
681
+        if($user === null) {
682
+            throw new OCSException('User does not exist', 101);
683
+        }
684
+        // Check if group exists
685
+        if($group === null) {
686
+            throw new OCSException('Group does not exist',  102);
687
+        }
688
+        // Check if trying to make subadmin of admin group
689
+        if($group->getGID() === 'admin') {
690
+            throw new OCSException('Cannot create subadmins for admin group', 103);
691
+        }
692
+
693
+        $subAdminManager = $this->groupManager->getSubAdmin();
694
+
695
+        // We cannot be subadmin twice
696
+        if ($subAdminManager->isSubAdminofGroup($user, $group)) {
697
+            return new DataResponse();
698
+        }
699
+        // Go
700
+        if($subAdminManager->createSubAdmin($user, $group)) {
701
+            return new DataResponse();
702
+        } else {
703
+            throw new OCSException('Unknown error occurred', 103);
704
+        }
705
+    }
706
+
707
+    /**
708
+     * Removes a subadmin from a group
709
+     *
710
+     * @PasswordConfirmationRequired
711
+     *
712
+     * @param string $userId
713
+     * @param string $groupid
714
+     * @return DataResponse
715
+     * @throws OCSException
716
+     */
717
+    public function removeSubAdmin($userId, $groupid) {
718
+        $group = $this->groupManager->get($groupid);
719
+        $user = $this->userManager->get($userId);
720
+        $subAdminManager = $this->groupManager->getSubAdmin();
721
+
722
+        // Check if the user exists
723
+        if($user === null) {
724
+            throw new OCSException('User does not exist', 101);
725
+        }
726
+        // Check if the group exists
727
+        if($group === null) {
728
+            throw new OCSException('Group does not exist', 101);
729
+        }
730
+        // Check if they are a subadmin of this said group
731
+        if(!$subAdminManager->isSubAdminOfGroup($user, $group)) {
732
+            throw new OCSException('User is not a subadmin of this group', 102);
733
+        }
734
+
735
+        // Go
736
+        if($subAdminManager->deleteSubAdmin($user, $group)) {
737
+            return new DataResponse();
738
+        } else {
739
+            throw new OCSException('Unknown error occurred', 103);
740
+        }
741
+    }
742
+
743
+    /**
744
+     * Get the groups a user is a subadmin of
745
+     *
746
+     * @param string $userId
747
+     * @return DataResponse
748
+     * @throws OCSException
749
+     */
750
+    public function getUserSubAdminGroups($userId) {
751
+        $user = $this->userManager->get($userId);
752
+        // Check if the user exists
753
+        if($user === null) {
754
+            throw new OCSException('User does not exist', 101);
755
+        }
756
+
757
+        // Get the subadmin groups
758
+        $groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
759
+        foreach ($groups as $key => $group) {
760
+            $groups[$key] = $group->getGID();
761
+        }
762
+
763
+        if(!$groups) {
764
+            throw new OCSException('Unknown error occurred', 102);
765
+        } else {
766
+            return new DataResponse($groups);
767
+        }
768
+    }
769
+
770
+    /**
771
+     * @param string $userId
772
+     * @return array
773
+     * @throws \OCP\Files\NotFoundException
774
+     */
775
+    protected function fillStorageInfo($userId) {
776
+        try {
777
+            \OC_Util::tearDownFS();
778
+            \OC_Util::setupFS($userId);
779
+            $storage = OC_Helper::getStorageInfo('/');
780
+            $data = [
781
+                'free' => $storage['free'],
782
+                'used' => $storage['used'],
783
+                'total' => $storage['total'],
784
+                'relative' => $storage['relative'],
785
+                'quota' => $storage['quota'],
786
+            ];
787
+        } catch (NotFoundException $ex) {
788
+            $data = [];
789
+        }
790
+        return $data;
791
+    }
792
+
793
+    /**
794
+     * @NoAdminRequired
795
+     * @PasswordConfirmationRequired
796
+     *
797
+     * resend welcome message
798
+     *
799
+     * @param string $userId
800
+     * @return DataResponse
801
+     * @throws OCSException
802
+     */
803
+    public function resendWelcomeMessage($userId) {
804
+        $currentLoggedInUser = $this->userSession->getUser();
805
+
806
+        $targetUser = $this->userManager->get($userId);
807
+        if($targetUser === null) {
808
+            throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
809
+        }
810
+
811
+        // Check if admin / subadmin
812
+        $subAdminManager = $this->groupManager->getSubAdmin();
813
+        if(!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
814
+            && !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
815
+            // No rights
816
+            throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
817
+        }
818
+
819
+        $email = $targetUser->getEMailAddress();
820
+        if ($email === '' || $email === null) {
821
+            throw new OCSException('Email address not available', 101);
822
+        }
823
+        $username = $targetUser->getUID();
824
+        $lang = $this->config->getUserValue($username, 'core', 'lang', 'en');
825
+        if (!$this->l10nFactory->languageExists('settings', $lang)) {
826
+            $lang = 'en';
827
+        }
828
+
829
+        $l10n = $this->l10nFactory->get('settings', $lang);
830
+
831
+        try {
832
+            $this->newUserMailHelper->setL10N($l10n);
833
+            $emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
834
+            $this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
835
+        } catch(\Exception $e) {
836
+            $this->logger->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
837
+            throw new OCSException('Sending email failed', 102);
838
+        }
839
+
840
+        return new DataResponse();
841
+    }
842 842
 }
Please login to merge, or discard this patch.
Spacing   +52 added lines, -52 removed lines patch added patch discarded remove patch
@@ -123,7 +123,7 @@  discard block
 block discarded – undo
123 123
 		// Admin? Or SubAdmin?
124 124
 		$uid = $user->getUID();
125 125
 		$subAdminManager = $this->groupManager->getSubAdmin();
126
-		if($this->groupManager->isAdmin($uid)){
126
+		if ($this->groupManager->isAdmin($uid)) {
127 127
 			$users = $this->userManager->search($search, $limit, $offset);
128 128
 		} else if ($subAdminManager->isSubAdmin($user)) {
129 129
 			$subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
@@ -131,7 +131,7 @@  discard block
 block discarded – undo
131 131
 				$subAdminOfGroups[$key] = $group->getGID();
132 132
 			}
133 133
 
134
-			if($offset === null) {
134
+			if ($offset === null) {
135 135
 				$offset = 0;
136 136
 			}
137 137
 
@@ -165,22 +165,22 @@  discard block
 block discarded – undo
165 165
 		$isAdmin = $this->groupManager->isAdmin($user->getUID());
166 166
 		$subAdminManager = $this->groupManager->getSubAdmin();
167 167
 
168
-		if($this->userManager->userExists($userid)) {
168
+		if ($this->userManager->userExists($userid)) {
169 169
 			$this->logger->error('Failed addUser attempt: User already exists.', ['app' => 'ocs_api']);
170 170
 			throw new OCSException('User already exists', 102);
171 171
 		}
172 172
 
173
-		if(is_array($groups)) {
173
+		if (is_array($groups)) {
174 174
 			foreach ($groups as $group) {
175
-				if(!$this->groupManager->groupExists($group)) {
175
+				if (!$this->groupManager->groupExists($group)) {
176 176
 					throw new OCSException('group '.$group.' does not exist', 104);
177 177
 				}
178
-				if(!$isAdmin && !$subAdminManager->isSubAdminofGroup($user, $this->groupManager->get($group))) {
179
-					throw new OCSException('insufficient privileges for group '. $group, 105);
178
+				if (!$isAdmin && !$subAdminManager->isSubAdminofGroup($user, $this->groupManager->get($group))) {
179
+					throw new OCSException('insufficient privileges for group '.$group, 105);
180 180
 				}
181 181
 			}
182 182
 		} else {
183
-			if(!$isAdmin) {
183
+			if (!$isAdmin) {
184 184
 				throw new OCSException('no group specified (required for subadmins)', 106);
185 185
 			}
186 186
 		}
@@ -229,7 +229,7 @@  discard block
 block discarded – undo
229 229
 	public function getCurrentUser() {
230 230
 		$user = $this->userSession->getUser();
231 231
 		if ($user) {
232
-			$data =  $this->getUserData($user->getUID());
232
+			$data = $this->getUserData($user->getUID());
233 233
 			// rename "displayname" to "display-name" only for this call to keep
234 234
 			// the API stable.
235 235
 			$data['display-name'] = $data['displayname'];
@@ -255,17 +255,17 @@  discard block
 block discarded – undo
255 255
 
256 256
 		// Check if the target user exists
257 257
 		$targetUserObject = $this->userManager->get($userId);
258
-		if($targetUserObject === null) {
258
+		if ($targetUserObject === null) {
259 259
 			throw new OCSException('The requested user could not be found', \OCP\API::RESPOND_NOT_FOUND);
260 260
 		}
261 261
 
262 262
 		// Admin? Or SubAdmin?
263
-		if($this->groupManager->isAdmin($currentLoggedInUser->getUID())
263
+		if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())
264 264
 			|| $this->groupManager->getSubAdmin()->isUserAccessible($currentLoggedInUser, $targetUserObject)) {
265 265
 			$data['enabled'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'enabled', 'true');
266 266
 		} else {
267 267
 			// Check they are looking up themselves
268
-			if($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) {
268
+			if ($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) {
269 269
 				throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
270 270
 			}
271 271
 		}
@@ -311,12 +311,12 @@  discard block
 block discarded – undo
311 311
 		$currentLoggedInUser = $this->userSession->getUser();
312 312
 
313 313
 		$targetUser = $this->userManager->get($userId);
314
-		if($targetUser === null) {
314
+		if ($targetUser === null) {
315 315
 			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
316 316
 		}
317 317
 
318 318
 		$permittedFields = [];
319
-		if($targetUser->getUID() === $currentLoggedInUser->getUID()) {
319
+		if ($targetUser->getUID() === $currentLoggedInUser->getUID()) {
320 320
 			// Editing self (display, email)
321 321
 			if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
322 322
 				$permittedFields[] = 'display';
@@ -343,13 +343,13 @@  discard block
 block discarded – undo
343 343
 			}
344 344
 
345 345
 			// If admin they can edit their own quota
346
-			if($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
346
+			if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
347 347
 				$permittedFields[] = 'quota';
348 348
 			}
349 349
 		} else {
350 350
 			// Check if admin / subadmin
351 351
 			$subAdminManager = $this->groupManager->getSubAdmin();
352
-			if($subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
352
+			if ($subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
353 353
 			|| $this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
354 354
 				// They have permissions over the user
355 355
 				$permittedFields[] = 'display';
@@ -369,18 +369,18 @@  discard block
 block discarded – undo
369 369
 			}
370 370
 		}
371 371
 		// Check if permitted to edit this field
372
-		if(!in_array($key, $permittedFields)) {
372
+		if (!in_array($key, $permittedFields)) {
373 373
 			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
374 374
 		}
375 375
 		// Process the edit
376
-		switch($key) {
376
+		switch ($key) {
377 377
 			case 'display':
378 378
 			case AccountManager::PROPERTY_DISPLAYNAME:
379 379
 				$targetUser->setDisplayName($value);
380 380
 				break;
381 381
 			case 'quota':
382 382
 				$quota = $value;
383
-				if($quota !== 'none' && $quota !== 'default') {
383
+				if ($quota !== 'none' && $quota !== 'default') {
384 384
 					if (is_numeric($quota)) {
385 385
 						$quota = (float) $quota;
386 386
 					} else {
@@ -389,9 +389,9 @@  discard block
 block discarded – undo
389 389
 					if ($quota === false) {
390 390
 						throw new OCSException('Invalid quota value '.$value, 103);
391 391
 					}
392
-					if($quota === 0) {
392
+					if ($quota === 0) {
393 393
 						$quota = 'default';
394
-					}else if($quota === -1) {
394
+					} else if ($quota === -1) {
395 395
 						$quota = 'none';
396 396
 					} else {
397 397
 						$quota = \OCP\Util::humanFileSize($quota);
@@ -414,7 +414,7 @@  discard block
 block discarded – undo
414 414
 				$this->config->setUserValue($targetUser->getUID(), 'core', 'locale', $value);
415 415
 				break;
416 416
 			case AccountManager::PROPERTY_EMAIL:
417
-				if(filter_var($value, FILTER_VALIDATE_EMAIL)) {
417
+				if (filter_var($value, FILTER_VALIDATE_EMAIL)) {
418 418
 					$targetUser->setEMailAddress($value);
419 419
 				} else {
420 420
 					throw new OCSException('', 102);
@@ -450,18 +450,18 @@  discard block
 block discarded – undo
450 450
 
451 451
 		$targetUser = $this->userManager->get($userId);
452 452
 
453
-		if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
453
+		if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
454 454
 			throw new OCSException('', 101);
455 455
 		}
456 456
 
457 457
 		// If not permitted
458 458
 		$subAdminManager = $this->groupManager->getSubAdmin();
459
-		if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
459
+		if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
460 460
 			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
461 461
 		}
462 462
 
463 463
 		// Go ahead with the delete
464
-		if($targetUser->delete()) {
464
+		if ($targetUser->delete()) {
465 465
 			return new DataResponse();
466 466
 		} else {
467 467
 			throw new OCSException('', 101);
@@ -505,13 +505,13 @@  discard block
 block discarded – undo
505 505
 		$currentLoggedInUser = $this->userSession->getUser();
506 506
 
507 507
 		$targetUser = $this->userManager->get($userId);
508
-		if($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
508
+		if ($targetUser === null || $targetUser->getUID() === $currentLoggedInUser->getUID()) {
509 509
 			throw new OCSException('', 101);
510 510
 		}
511 511
 
512 512
 		// If not permitted
513 513
 		$subAdminManager = $this->groupManager->getSubAdmin();
514
-		if(!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
514
+		if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
515 515
 			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
516 516
 		}
517 517
 
@@ -532,11 +532,11 @@  discard block
 block discarded – undo
532 532
 		$loggedInUser = $this->userSession->getUser();
533 533
 
534 534
 		$targetUser = $this->userManager->get($userId);
535
-		if($targetUser === null) {
535
+		if ($targetUser === null) {
536 536
 			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
537 537
 		}
538 538
 
539
-		if($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
539
+		if ($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
540 540
 			// Self lookup or admin lookup
541 541
 			return new DataResponse([
542 542
 				'groups' => $this->groupManager->getUserGroupIds($targetUser)
@@ -545,7 +545,7 @@  discard block
 block discarded – undo
545 545
 			$subAdminManager = $this->groupManager->getSubAdmin();
546 546
 
547 547
 			// Looking up someone else
548
-			if($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
548
+			if ($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) {
549 549
 				// Return the group that the method caller is subadmin of for the user in question
550 550
 				/** @var IGroup[] $getSubAdminsGroups */
551 551
 				$getSubAdminsGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
@@ -575,16 +575,16 @@  discard block
 block discarded – undo
575 575
 	 * @throws OCSException
576 576
 	 */
577 577
 	public function addToGroup($userId, $groupid = '') {
578
-		if($groupid === '') {
578
+		if ($groupid === '') {
579 579
 			throw new OCSException('', 101);
580 580
 		}
581 581
 
582 582
 		$group = $this->groupManager->get($groupid);
583 583
 		$targetUser = $this->userManager->get($userId);
584
-		if($group === null) {
584
+		if ($group === null) {
585 585
 			throw new OCSException('', 102);
586 586
 		}
587
-		if($targetUser === null) {
587
+		if ($targetUser === null) {
588 588
 			throw new OCSException('', 103);
589 589
 		}
590 590
 
@@ -612,17 +612,17 @@  discard block
 block discarded – undo
612 612
 	public function removeFromGroup($userId, $groupid) {
613 613
 		$loggedInUser = $this->userSession->getUser();
614 614
 
615
-		if($groupid === null) {
615
+		if ($groupid === null) {
616 616
 			throw new OCSException('', 101);
617 617
 		}
618 618
 
619 619
 		$group = $this->groupManager->get($groupid);
620
-		if($group === null) {
620
+		if ($group === null) {
621 621
 			throw new OCSException('', 102);
622 622
 		}
623 623
 
624 624
 		$targetUser = $this->userManager->get($userId);
625
-		if($targetUser === null) {
625
+		if ($targetUser === null) {
626 626
 			throw new OCSException('', 103);
627 627
 		}
628 628
 
@@ -646,7 +646,7 @@  discard block
 block discarded – undo
646 646
 		} else if (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
647 647
 			/** @var IGroup[] $subAdminGroups */
648 648
 			$subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
649
-			$subAdminGroups = array_map(function (IGroup $subAdminGroup) {
649
+			$subAdminGroups = array_map(function(IGroup $subAdminGroup) {
650 650
 				return $subAdminGroup->getGID();
651 651
 			}, $subAdminGroups);
652 652
 			$userGroups = $this->groupManager->getUserGroupIds($targetUser);
@@ -678,15 +678,15 @@  discard block
 block discarded – undo
678 678
 		$user = $this->userManager->get($userId);
679 679
 
680 680
 		// Check if the user exists
681
-		if($user === null) {
681
+		if ($user === null) {
682 682
 			throw new OCSException('User does not exist', 101);
683 683
 		}
684 684
 		// Check if group exists
685
-		if($group === null) {
686
-			throw new OCSException('Group does not exist',  102);
685
+		if ($group === null) {
686
+			throw new OCSException('Group does not exist', 102);
687 687
 		}
688 688
 		// Check if trying to make subadmin of admin group
689
-		if($group->getGID() === 'admin') {
689
+		if ($group->getGID() === 'admin') {
690 690
 			throw new OCSException('Cannot create subadmins for admin group', 103);
691 691
 		}
692 692
 
@@ -697,7 +697,7 @@  discard block
 block discarded – undo
697 697
 			return new DataResponse();
698 698
 		}
699 699
 		// Go
700
-		if($subAdminManager->createSubAdmin($user, $group)) {
700
+		if ($subAdminManager->createSubAdmin($user, $group)) {
701 701
 			return new DataResponse();
702 702
 		} else {
703 703
 			throw new OCSException('Unknown error occurred', 103);
@@ -720,20 +720,20 @@  discard block
 block discarded – undo
720 720
 		$subAdminManager = $this->groupManager->getSubAdmin();
721 721
 
722 722
 		// Check if the user exists
723
-		if($user === null) {
723
+		if ($user === null) {
724 724
 			throw new OCSException('User does not exist', 101);
725 725
 		}
726 726
 		// Check if the group exists
727
-		if($group === null) {
727
+		if ($group === null) {
728 728
 			throw new OCSException('Group does not exist', 101);
729 729
 		}
730 730
 		// Check if they are a subadmin of this said group
731
-		if(!$subAdminManager->isSubAdminOfGroup($user, $group)) {
731
+		if (!$subAdminManager->isSubAdminOfGroup($user, $group)) {
732 732
 			throw new OCSException('User is not a subadmin of this group', 102);
733 733
 		}
734 734
 
735 735
 		// Go
736
-		if($subAdminManager->deleteSubAdmin($user, $group)) {
736
+		if ($subAdminManager->deleteSubAdmin($user, $group)) {
737 737
 			return new DataResponse();
738 738
 		} else {
739 739
 			throw new OCSException('Unknown error occurred', 103);
@@ -750,7 +750,7 @@  discard block
 block discarded – undo
750 750
 	public function getUserSubAdminGroups($userId) {
751 751
 		$user = $this->userManager->get($userId);
752 752
 		// Check if the user exists
753
-		if($user === null) {
753
+		if ($user === null) {
754 754
 			throw new OCSException('User does not exist', 101);
755 755
 		}
756 756
 
@@ -760,7 +760,7 @@  discard block
 block discarded – undo
760 760
 			$groups[$key] = $group->getGID();
761 761
 		}
762 762
 
763
-		if(!$groups) {
763
+		if (!$groups) {
764 764
 			throw new OCSException('Unknown error occurred', 102);
765 765
 		} else {
766 766
 			return new DataResponse($groups);
@@ -804,13 +804,13 @@  discard block
 block discarded – undo
804 804
 		$currentLoggedInUser = $this->userSession->getUser();
805 805
 
806 806
 		$targetUser = $this->userManager->get($userId);
807
-		if($targetUser === null) {
807
+		if ($targetUser === null) {
808 808
 			throw new OCSException('', \OCP\API::RESPOND_NOT_FOUND);
809 809
 		}
810 810
 
811 811
 		// Check if admin / subadmin
812 812
 		$subAdminManager = $this->groupManager->getSubAdmin();
813
-		if(!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
813
+		if (!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
814 814
 			&& !$this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
815 815
 			// No rights
816 816
 			throw new OCSException('', \OCP\API::RESPOND_UNAUTHORISED);
@@ -832,8 +832,8 @@  discard block
 block discarded – undo
832 832
 			$this->newUserMailHelper->setL10N($l10n);
833 833
 			$emailTemplate = $this->newUserMailHelper->generateTemplate($targetUser, false);
834 834
 			$this->newUserMailHelper->sendMail($targetUser, $emailTemplate);
835
-		} catch(\Exception $e) {
836
-			$this->logger->error("Can't send new user mail to $email: " . $e->getMessage(), array('app' => 'settings'));
835
+		} catch (\Exception $e) {
836
+			$this->logger->error("Can't send new user mail to $email: ".$e->getMessage(), array('app' => 'settings'));
837 837
 			throw new OCSException('Sending email failed', 102);
838 838
 		}
839 839
 
Please login to merge, or discard this patch.
lib/private/Settings/Personal/PersonalInfo.php 2 patches
Indentation   +279 added lines, -279 removed lines patch added patch discarded remove patch
@@ -40,255 +40,255 @@  discard block
 block discarded – undo
40 40
 use OCP\Settings\ISettings;
41 41
 
42 42
 class PersonalInfo implements ISettings {
43
-	/** @var IConfig */
44
-	private $config;
45
-	/** @var IUserManager */
46
-	private $userManager;
47
-	/** @var AccountManager */
48
-	private $accountManager;
49
-	/** @var IGroupManager */
50
-	private $groupManager;
51
-	/** @var IAppManager */
52
-	private $appManager;
53
-	/** @var IFactory */
54
-	private $l10nFactory;
55
-
56
-	const COMMON_LANGUAGE_CODES = [
57
-		'en', 'es', 'fr', 'de', 'de_DE', 'ja', 'ar', 'ru', 'nl', 'it',
58
-		'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko'
59
-	];
60
-
61
-	/** @var IL10N */
62
-	private $l;
63
-
64
-	/**
65
-	 * @param IConfig $config
66
-	 * @param IUserManager $userManager
67
-	 * @param IGroupManager $groupManager
68
-	 * @param AccountManager $accountManager
69
-	 * @param IFactory $l10nFactory
70
-	 * @param IL10N $l
71
-	 */
72
-	public function __construct(
73
-		IConfig $config,
74
-		IUserManager $userManager,
75
-		IGroupManager $groupManager,
76
-		AccountManager $accountManager,
77
-		IAppManager $appManager,
78
-		IFactory $l10nFactory,
79
-		IL10N $l
80
-	) {
81
-		$this->config = $config;
82
-		$this->userManager = $userManager;
83
-		$this->accountManager = $accountManager;
84
-		$this->groupManager = $groupManager;
85
-		$this->appManager = $appManager;
86
-		$this->l10nFactory = $l10nFactory;
87
-		$this->l = $l;
88
-	}
89
-
90
-	/**
91
-	 * @return TemplateResponse returns the instance with all parameters set, ready to be rendered
92
-	 * @since 9.1
93
-	 */
94
-	public function getForm() {
95
-		$federatedFileSharingEnabled = $this->appManager->isEnabledForUser('federatedfilesharing');
96
-		$lookupServerUploadEnabled = false;
97
-		if($federatedFileSharingEnabled) {
98
-			$federatedFileSharing = new Application();
99
-			$shareProvider = $federatedFileSharing->getFederatedShareProvider();
100
-			$lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled();
101
-		}
102
-
103
-		$uid = \OC_User::getUser();
104
-		$user = $this->userManager->get($uid);
105
-		$userData = $this->accountManager->getUser($user);
106
-
107
-		$storageInfo = \OC_Helper::getStorageInfo('/');
108
-		if ($storageInfo['quota'] === FileInfo::SPACE_UNLIMITED) {
109
-			$totalSpace = $this->l->t('Unlimited');
110
-		} else {
111
-			$totalSpace = \OC_Helper::humanFileSize($storageInfo['total']);
112
-		}
113
-
114
-		$languageParameters = $this->getLanguages($user);
115
-		$localeParameters = $this->getLocales($user);
116
-		$messageParameters = $this->getMessageParameters($userData);
117
-
118
-		$parameters = [
119
-			'total_space' => $totalSpace,
120
-			'usage' => \OC_Helper::humanFileSize($storageInfo['used']),
121
-			'usage_relative' => $storageInfo['relative'],
122
-			'quota' => $storageInfo['quota'],
123
-			'avatarChangeSupported' => \OC_User::canUserChangeAvatar($uid),
124
-			'lookupServerUploadEnabled' => $lookupServerUploadEnabled,
125
-			'avatarScope' => $userData[AccountManager::PROPERTY_AVATAR]['scope'],
126
-			'displayNameChangeSupported' => \OC_User::canUserChangeDisplayName($uid),
127
-			'displayName' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'],
128
-			'displayNameScope' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
129
-			'email' => $userData[AccountManager::PROPERTY_EMAIL]['value'],
130
-			'emailScope' => $userData[AccountManager::PROPERTY_EMAIL]['scope'],
131
-			'emailVerification' => $userData[AccountManager::PROPERTY_EMAIL]['verified'],
132
-			'phone' => $userData[AccountManager::PROPERTY_PHONE]['value'],
133
-			'phoneScope' => $userData[AccountManager::PROPERTY_PHONE]['scope'],
134
-			'address' => $userData[AccountManager::PROPERTY_ADDRESS]['value'],
135
-			'addressScope' => $userData[AccountManager::PROPERTY_ADDRESS]['scope'],
136
-			'website' =>  $userData[AccountManager::PROPERTY_WEBSITE]['value'],
137
-			'websiteScope' =>  $userData[AccountManager::PROPERTY_WEBSITE]['scope'],
138
-			'websiteVerification' => $userData[AccountManager::PROPERTY_WEBSITE]['verified'],
139
-			'twitter' => $userData[AccountManager::PROPERTY_TWITTER]['value'],
140
-			'twitterScope' => $userData[AccountManager::PROPERTY_TWITTER]['scope'],
141
-			'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'],
142
-			'groups' => $this->getGroups($user),
143
-			'passwordChangeSupported' => \OC_User::canUserChangePassword($uid),
144
-		] + $messageParameters + $languageParameters + $localeParameters;
145
-
146
-
147
-		return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, '');
148
-	}
149
-
150
-	/**
151
-	 * @return string the section ID, e.g. 'sharing'
152
-	 * @since 9.1
153
-	 */
154
-	public function getSection() {
155
-		return 'personal-info';
156
-	}
157
-
158
-	/**
159
-	 * @return int whether the form should be rather on the top or bottom of
160
-	 * the admin section. The forms are arranged in ascending order of the
161
-	 * priority values. It is required to return a value between 0 and 100.
162
-	 *
163
-	 * E.g.: 70
164
-	 * @since 9.1
165
-	 */
166
-	public function getPriority() {
167
-		return 10;
168
-	}
169
-
170
-	/**
171
-	 * returns a sorted list of the user's group GIDs
172
-	 *
173
-	 * @param IUser $user
174
-	 * @return array
175
-	 */
176
-	private function getGroups(IUser $user) {
177
-		$groups = array_map(
178
-			function(IGroup $group) {
179
-				return $group->getGID();
180
-			},
181
-			$this->groupManager->getUserGroups($user)
182
-		);
183
-		sort($groups);
184
-
185
-		return $groups;
186
-	}
187
-
188
-	/**
189
-	 * returns the user language, common language and other languages in an
190
-	 * associative array
191
-	 *
192
-	 * @param IUser $user
193
-	 * @return array
194
-	 */
195
-	private function getLanguages(IUser $user) {
196
-		$forceLanguage = $this->config->getSystemValue('force_language', false);
197
-		if($forceLanguage !== false) {
198
-			return [];
199
-		}
200
-
201
-		$uid = $user->getUID();
202
-
203
-		$userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
204
-		$languageCodes = $this->l10nFactory->findAvailableLanguages();
205
-
206
-		$commonLanguages = [];
207
-		$languages = [];
208
-
209
-		foreach($languageCodes as $lang) {
210
-			$l = \OC::$server->getL10N('settings', $lang);
211
-			// TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version
212
-			$potentialName = (string) $l->t('__language_name__');
213
-			if($l->getLanguageCode() === $lang && substr($potentialName, 0, 1) !== '_') {//first check if the language name is in the translation file
214
-				$ln = array('code' => $lang, 'name' => $potentialName);
215
-			} elseif ($lang === 'en') {
216
-				$ln = ['code' => $lang, 'name' => 'English (US)'];
217
-			}else{//fallback to language code
218
-				$ln=array('code'=>$lang, 'name'=>$lang);
219
-			}
220
-
221
-			// put appropriate languages into appropriate arrays, to print them sorted
222
-			// used language -> common languages -> divider -> other languages
223
-			if ($lang === $userLang) {
224
-				$userLang = $ln;
225
-			} elseif (in_array($lang, self::COMMON_LANGUAGE_CODES)) {
226
-				$commonLanguages[array_search($lang, self::COMMON_LANGUAGE_CODES)]=$ln;
227
-			} else {
228
-				$languages[]=$ln;
229
-			}
230
-		}
231
-
232
-		// if user language is not available but set somehow: show the actual code as name
233
-		if (!is_array($userLang)) {
234
-			$userLang = [
235
-				'code' => $userLang,
236
-				'name' => $userLang,
237
-			];
238
-		}
239
-
240
-		ksort($commonLanguages);
241
-
242
-		// sort now by displayed language not the iso-code
243
-		usort( $languages, function ($a, $b) {
244
-			if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) {
245
-				// If a doesn't have a name, but b does, list b before a
246
-				return 1;
247
-			}
248
-			if ($a['code'] !== $a['name'] && $b['code'] === $b['name']) {
249
-				// If a does have a name, but b doesn't, list a before b
250
-				return -1;
251
-			}
252
-			// Otherwise compare the names
253
-			return strcmp($a['name'], $b['name']);
254
-		});
255
-
256
-		return [
257
-			'activelanguage' => $userLang,
258
-			'commonlanguages' => $commonLanguages,
259
-			'languages' => $languages
260
-		];
261
-	}
262
-
263
-	private function getLocales(IUser $user) {
264
-		$forceLanguage = $this->config->getSystemValue('force_locale', false);
265
-		if($forceLanguage !== false) {
266
-			return [];
267
-		}
268
-
269
-		$uid = $user->getUID();
270
-
271
-		$userLocaleString = $this->config->getUserValue($uid, 'core', 'locale', 'en_US');
272
-
273
-		$userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
274
-
275
-		$localeData = file_get_contents(__DIR__ . '/locales.json');
276
-		$localeCodes = json_decode($localeData, true);
277
-
278
-		$userLocale = array_filter($localeCodes, function($value) use ($userLocaleString) {
279
-			return $userLocaleString === $value['code'];
280
-		});
281
-
282
-		if (count($userLocale) > 0)
283
-		{
284
-			$userLocale = reset($userLocale);
285
-		}
286
-
287
-		$localesForLanguage = array_filter($localeCodes, function($localeCode) use ($userLang) {
288
-			return 0 === strpos($localeCode['code'], $userLang);
289
-		});
290
-
291
-		/*$localesForLanguage = [];
43
+    /** @var IConfig */
44
+    private $config;
45
+    /** @var IUserManager */
46
+    private $userManager;
47
+    /** @var AccountManager */
48
+    private $accountManager;
49
+    /** @var IGroupManager */
50
+    private $groupManager;
51
+    /** @var IAppManager */
52
+    private $appManager;
53
+    /** @var IFactory */
54
+    private $l10nFactory;
55
+
56
+    const COMMON_LANGUAGE_CODES = [
57
+        'en', 'es', 'fr', 'de', 'de_DE', 'ja', 'ar', 'ru', 'nl', 'it',
58
+        'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko'
59
+    ];
60
+
61
+    /** @var IL10N */
62
+    private $l;
63
+
64
+    /**
65
+     * @param IConfig $config
66
+     * @param IUserManager $userManager
67
+     * @param IGroupManager $groupManager
68
+     * @param AccountManager $accountManager
69
+     * @param IFactory $l10nFactory
70
+     * @param IL10N $l
71
+     */
72
+    public function __construct(
73
+        IConfig $config,
74
+        IUserManager $userManager,
75
+        IGroupManager $groupManager,
76
+        AccountManager $accountManager,
77
+        IAppManager $appManager,
78
+        IFactory $l10nFactory,
79
+        IL10N $l
80
+    ) {
81
+        $this->config = $config;
82
+        $this->userManager = $userManager;
83
+        $this->accountManager = $accountManager;
84
+        $this->groupManager = $groupManager;
85
+        $this->appManager = $appManager;
86
+        $this->l10nFactory = $l10nFactory;
87
+        $this->l = $l;
88
+    }
89
+
90
+    /**
91
+     * @return TemplateResponse returns the instance with all parameters set, ready to be rendered
92
+     * @since 9.1
93
+     */
94
+    public function getForm() {
95
+        $federatedFileSharingEnabled = $this->appManager->isEnabledForUser('federatedfilesharing');
96
+        $lookupServerUploadEnabled = false;
97
+        if($federatedFileSharingEnabled) {
98
+            $federatedFileSharing = new Application();
99
+            $shareProvider = $federatedFileSharing->getFederatedShareProvider();
100
+            $lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled();
101
+        }
102
+
103
+        $uid = \OC_User::getUser();
104
+        $user = $this->userManager->get($uid);
105
+        $userData = $this->accountManager->getUser($user);
106
+
107
+        $storageInfo = \OC_Helper::getStorageInfo('/');
108
+        if ($storageInfo['quota'] === FileInfo::SPACE_UNLIMITED) {
109
+            $totalSpace = $this->l->t('Unlimited');
110
+        } else {
111
+            $totalSpace = \OC_Helper::humanFileSize($storageInfo['total']);
112
+        }
113
+
114
+        $languageParameters = $this->getLanguages($user);
115
+        $localeParameters = $this->getLocales($user);
116
+        $messageParameters = $this->getMessageParameters($userData);
117
+
118
+        $parameters = [
119
+            'total_space' => $totalSpace,
120
+            'usage' => \OC_Helper::humanFileSize($storageInfo['used']),
121
+            'usage_relative' => $storageInfo['relative'],
122
+            'quota' => $storageInfo['quota'],
123
+            'avatarChangeSupported' => \OC_User::canUserChangeAvatar($uid),
124
+            'lookupServerUploadEnabled' => $lookupServerUploadEnabled,
125
+            'avatarScope' => $userData[AccountManager::PROPERTY_AVATAR]['scope'],
126
+            'displayNameChangeSupported' => \OC_User::canUserChangeDisplayName($uid),
127
+            'displayName' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'],
128
+            'displayNameScope' => $userData[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
129
+            'email' => $userData[AccountManager::PROPERTY_EMAIL]['value'],
130
+            'emailScope' => $userData[AccountManager::PROPERTY_EMAIL]['scope'],
131
+            'emailVerification' => $userData[AccountManager::PROPERTY_EMAIL]['verified'],
132
+            'phone' => $userData[AccountManager::PROPERTY_PHONE]['value'],
133
+            'phoneScope' => $userData[AccountManager::PROPERTY_PHONE]['scope'],
134
+            'address' => $userData[AccountManager::PROPERTY_ADDRESS]['value'],
135
+            'addressScope' => $userData[AccountManager::PROPERTY_ADDRESS]['scope'],
136
+            'website' =>  $userData[AccountManager::PROPERTY_WEBSITE]['value'],
137
+            'websiteScope' =>  $userData[AccountManager::PROPERTY_WEBSITE]['scope'],
138
+            'websiteVerification' => $userData[AccountManager::PROPERTY_WEBSITE]['verified'],
139
+            'twitter' => $userData[AccountManager::PROPERTY_TWITTER]['value'],
140
+            'twitterScope' => $userData[AccountManager::PROPERTY_TWITTER]['scope'],
141
+            'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'],
142
+            'groups' => $this->getGroups($user),
143
+            'passwordChangeSupported' => \OC_User::canUserChangePassword($uid),
144
+        ] + $messageParameters + $languageParameters + $localeParameters;
145
+
146
+
147
+        return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, '');
148
+    }
149
+
150
+    /**
151
+     * @return string the section ID, e.g. 'sharing'
152
+     * @since 9.1
153
+     */
154
+    public function getSection() {
155
+        return 'personal-info';
156
+    }
157
+
158
+    /**
159
+     * @return int whether the form should be rather on the top or bottom of
160
+     * the admin section. The forms are arranged in ascending order of the
161
+     * priority values. It is required to return a value between 0 and 100.
162
+     *
163
+     * E.g.: 70
164
+     * @since 9.1
165
+     */
166
+    public function getPriority() {
167
+        return 10;
168
+    }
169
+
170
+    /**
171
+     * returns a sorted list of the user's group GIDs
172
+     *
173
+     * @param IUser $user
174
+     * @return array
175
+     */
176
+    private function getGroups(IUser $user) {
177
+        $groups = array_map(
178
+            function(IGroup $group) {
179
+                return $group->getGID();
180
+            },
181
+            $this->groupManager->getUserGroups($user)
182
+        );
183
+        sort($groups);
184
+
185
+        return $groups;
186
+    }
187
+
188
+    /**
189
+     * returns the user language, common language and other languages in an
190
+     * associative array
191
+     *
192
+     * @param IUser $user
193
+     * @return array
194
+     */
195
+    private function getLanguages(IUser $user) {
196
+        $forceLanguage = $this->config->getSystemValue('force_language', false);
197
+        if($forceLanguage !== false) {
198
+            return [];
199
+        }
200
+
201
+        $uid = $user->getUID();
202
+
203
+        $userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
204
+        $languageCodes = $this->l10nFactory->findAvailableLanguages();
205
+
206
+        $commonLanguages = [];
207
+        $languages = [];
208
+
209
+        foreach($languageCodes as $lang) {
210
+            $l = \OC::$server->getL10N('settings', $lang);
211
+            // TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version
212
+            $potentialName = (string) $l->t('__language_name__');
213
+            if($l->getLanguageCode() === $lang && substr($potentialName, 0, 1) !== '_') {//first check if the language name is in the translation file
214
+                $ln = array('code' => $lang, 'name' => $potentialName);
215
+            } elseif ($lang === 'en') {
216
+                $ln = ['code' => $lang, 'name' => 'English (US)'];
217
+            }else{//fallback to language code
218
+                $ln=array('code'=>$lang, 'name'=>$lang);
219
+            }
220
+
221
+            // put appropriate languages into appropriate arrays, to print them sorted
222
+            // used language -> common languages -> divider -> other languages
223
+            if ($lang === $userLang) {
224
+                $userLang = $ln;
225
+            } elseif (in_array($lang, self::COMMON_LANGUAGE_CODES)) {
226
+                $commonLanguages[array_search($lang, self::COMMON_LANGUAGE_CODES)]=$ln;
227
+            } else {
228
+                $languages[]=$ln;
229
+            }
230
+        }
231
+
232
+        // if user language is not available but set somehow: show the actual code as name
233
+        if (!is_array($userLang)) {
234
+            $userLang = [
235
+                'code' => $userLang,
236
+                'name' => $userLang,
237
+            ];
238
+        }
239
+
240
+        ksort($commonLanguages);
241
+
242
+        // sort now by displayed language not the iso-code
243
+        usort( $languages, function ($a, $b) {
244
+            if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) {
245
+                // If a doesn't have a name, but b does, list b before a
246
+                return 1;
247
+            }
248
+            if ($a['code'] !== $a['name'] && $b['code'] === $b['name']) {
249
+                // If a does have a name, but b doesn't, list a before b
250
+                return -1;
251
+            }
252
+            // Otherwise compare the names
253
+            return strcmp($a['name'], $b['name']);
254
+        });
255
+
256
+        return [
257
+            'activelanguage' => $userLang,
258
+            'commonlanguages' => $commonLanguages,
259
+            'languages' => $languages
260
+        ];
261
+    }
262
+
263
+    private function getLocales(IUser $user) {
264
+        $forceLanguage = $this->config->getSystemValue('force_locale', false);
265
+        if($forceLanguage !== false) {
266
+            return [];
267
+        }
268
+
269
+        $uid = $user->getUID();
270
+
271
+        $userLocaleString = $this->config->getUserValue($uid, 'core', 'locale', 'en_US');
272
+
273
+        $userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
274
+
275
+        $localeData = file_get_contents(__DIR__ . '/locales.json');
276
+        $localeCodes = json_decode($localeData, true);
277
+
278
+        $userLocale = array_filter($localeCodes, function($value) use ($userLocaleString) {
279
+            return $userLocaleString === $value['code'];
280
+        });
281
+
282
+        if (count($userLocale) > 0)
283
+        {
284
+            $userLocale = reset($userLocale);
285
+        }
286
+
287
+        $localesForLanguage = array_filter($localeCodes, function($localeCode) use ($userLang) {
288
+            return 0 === strpos($localeCode['code'], $userLang);
289
+        });
290
+
291
+        /*$localesForLanguage = [];
292 292
 
293 293
 		foreach (array_keys($localeCodes) as $localeCode) {
294 294
 			if (0 === strpos($localeCode, $userLang)) {
@@ -296,35 +296,35 @@  discard block
 block discarded – undo
296 296
 			}
297 297
 		}*/
298 298
 
299
-		return [
300
-			'activelocaleLang' => $userLocaleString,
301
-			'activelocale' => $userLocale,
302
-			'locales' => $localeCodes,
303
-			'localesforlanguage' => $localesForLanguage,
304
-		];
305
-	}
306
-
307
-	/**
308
-	 * @param array $userData
309
-	 * @return array
310
-	 */
311
-	private function getMessageParameters(array $userData) {
312
-		$needVerifyMessage = [AccountManager::PROPERTY_EMAIL, AccountManager::PROPERTY_WEBSITE, AccountManager::PROPERTY_TWITTER];
313
-		$messageParameters = [];
314
-		foreach ($needVerifyMessage as $property) {
315
-			switch ($userData[$property]['verified']) {
316
-				case AccountManager::VERIFIED:
317
-					$message = $this->l->t('Verifying');
318
-					break;
319
-				case AccountManager::VERIFICATION_IN_PROGRESS:
320
-					$message = $this->l->t('Verifying …');
321
-					break;
322
-				default:
323
-					$message = $this->l->t('Verify');
324
-			}
325
-			$messageParameters[$property . 'Message'] = $message;
326
-		}
327
-		return $messageParameters;
328
-	}
299
+        return [
300
+            'activelocaleLang' => $userLocaleString,
301
+            'activelocale' => $userLocale,
302
+            'locales' => $localeCodes,
303
+            'localesforlanguage' => $localesForLanguage,
304
+        ];
305
+    }
306
+
307
+    /**
308
+     * @param array $userData
309
+     * @return array
310
+     */
311
+    private function getMessageParameters(array $userData) {
312
+        $needVerifyMessage = [AccountManager::PROPERTY_EMAIL, AccountManager::PROPERTY_WEBSITE, AccountManager::PROPERTY_TWITTER];
313
+        $messageParameters = [];
314
+        foreach ($needVerifyMessage as $property) {
315
+            switch ($userData[$property]['verified']) {
316
+                case AccountManager::VERIFIED:
317
+                    $message = $this->l->t('Verifying');
318
+                    break;
319
+                case AccountManager::VERIFICATION_IN_PROGRESS:
320
+                    $message = $this->l->t('Verifying …');
321
+                    break;
322
+                default:
323
+                    $message = $this->l->t('Verify');
324
+            }
325
+            $messageParameters[$property . 'Message'] = $message;
326
+        }
327
+        return $messageParameters;
328
+    }
329 329
 
330 330
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -94,7 +94,7 @@  discard block
 block discarded – undo
94 94
 	public function getForm() {
95 95
 		$federatedFileSharingEnabled = $this->appManager->isEnabledForUser('federatedfilesharing');
96 96
 		$lookupServerUploadEnabled = false;
97
-		if($federatedFileSharingEnabled) {
97
+		if ($federatedFileSharingEnabled) {
98 98
 			$federatedFileSharing = new Application();
99 99
 			$shareProvider = $federatedFileSharing->getFederatedShareProvider();
100 100
 			$lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled();
@@ -194,7 +194,7 @@  discard block
 block discarded – undo
194 194
 	 */
195 195
 	private function getLanguages(IUser $user) {
196 196
 		$forceLanguage = $this->config->getSystemValue('force_language', false);
197
-		if($forceLanguage !== false) {
197
+		if ($forceLanguage !== false) {
198 198
 			return [];
199 199
 		}
200 200
 
@@ -206,16 +206,16 @@  discard block
 block discarded – undo
206 206
 		$commonLanguages = [];
207 207
 		$languages = [];
208 208
 
209
-		foreach($languageCodes as $lang) {
209
+		foreach ($languageCodes as $lang) {
210 210
 			$l = \OC::$server->getL10N('settings', $lang);
211 211
 			// TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version
212 212
 			$potentialName = (string) $l->t('__language_name__');
213
-			if($l->getLanguageCode() === $lang && substr($potentialName, 0, 1) !== '_') {//first check if the language name is in the translation file
213
+			if ($l->getLanguageCode() === $lang && substr($potentialName, 0, 1) !== '_') {//first check if the language name is in the translation file
214 214
 				$ln = array('code' => $lang, 'name' => $potentialName);
215 215
 			} elseif ($lang === 'en') {
216 216
 				$ln = ['code' => $lang, 'name' => 'English (US)'];
217
-			}else{//fallback to language code
218
-				$ln=array('code'=>$lang, 'name'=>$lang);
217
+			} else {//fallback to language code
218
+				$ln = array('code'=>$lang, 'name'=>$lang);
219 219
 			}
220 220
 
221 221
 			// put appropriate languages into appropriate arrays, to print them sorted
@@ -223,9 +223,9 @@  discard block
 block discarded – undo
223 223
 			if ($lang === $userLang) {
224 224
 				$userLang = $ln;
225 225
 			} elseif (in_array($lang, self::COMMON_LANGUAGE_CODES)) {
226
-				$commonLanguages[array_search($lang, self::COMMON_LANGUAGE_CODES)]=$ln;
226
+				$commonLanguages[array_search($lang, self::COMMON_LANGUAGE_CODES)] = $ln;
227 227
 			} else {
228
-				$languages[]=$ln;
228
+				$languages[] = $ln;
229 229
 			}
230 230
 		}
231 231
 
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
 		ksort($commonLanguages);
241 241
 
242 242
 		// sort now by displayed language not the iso-code
243
-		usort( $languages, function ($a, $b) {
243
+		usort($languages, function($a, $b) {
244 244
 			if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) {
245 245
 				// If a doesn't have a name, but b does, list b before a
246 246
 				return 1;
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
 
263 263
 	private function getLocales(IUser $user) {
264 264
 		$forceLanguage = $this->config->getSystemValue('force_locale', false);
265
-		if($forceLanguage !== false) {
265
+		if ($forceLanguage !== false) {
266 266
 			return [];
267 267
 		}
268 268
 
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
 
273 273
 		$userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage());
274 274
 
275
-		$localeData = file_get_contents(__DIR__ . '/locales.json');
275
+		$localeData = file_get_contents(__DIR__.'/locales.json');
276 276
 		$localeCodes = json_decode($localeData, true);
277 277
 
278 278
 		$userLocale = array_filter($localeCodes, function($value) use ($userLocaleString) {
@@ -322,7 +322,7 @@  discard block
 block discarded – undo
322 322
 				default:
323 323
 					$message = $this->l->t('Verify');
324 324
 			}
325
-			$messageParameters[$property . 'Message'] = $message;
325
+			$messageParameters[$property.'Message'] = $message;
326 326
 		}
327 327
 		return $messageParameters;
328 328
 	}
Please login to merge, or discard this patch.
lib/private/L10N/L10N.php 1 patch
Indentation   +202 added lines, -202 removed lines patch added patch discarded remove patch
@@ -29,206 +29,206 @@
 block discarded – undo
29 29
 
30 30
 class L10N implements IL10N {
31 31
 
32
-	/** @var IFactory */
33
-	protected $factory;
34
-
35
-	/** @var string App of this object */
36
-	protected $app;
37
-
38
-	/** @var string Language of this object */
39
-	protected $lang;
40
-
41
-	/** @var string Locale of this object */
42
-	protected $locale;
43
-
44
-	/** @var string Plural forms (string) */
45
-	private $pluralFormString = 'nplurals=2; plural=(n != 1);';
46
-
47
-	/** @var string Plural forms (function) */
48
-	private $pluralFormFunction = null;
49
-
50
-	/** @var string[] */
51
-	private $translations = [];
52
-
53
-	/**
54
-	 * @param IFactory $factory
55
-	 * @param string $app
56
-	 * @param string $lang
57
-	 * @param string $locale
58
-	 * @param array $files
59
-	 */
60
-	public function __construct(IFactory $factory, $app, $lang, $locale, array $files) {
61
-		$this->factory = $factory;
62
-		$this->app = $app;
63
-		$this->lang = $lang;
64
-		$this->locale = $locale;
65
-
66
-		$this->translations = [];
67
-		foreach ($files as $languageFile) {
68
-			$this->load($languageFile);
69
-		}
70
-	}
71
-
72
-	/**
73
-	 * The code (en, de, ...) of the language that is used for this instance
74
-	 *
75
-	 * @return string language
76
-	 */
77
-	public function getLanguageCode() {
78
-		return $this->lang;
79
-	}
80
-
81
-	/**
82
-	 * The code (en_US, fr_CA, ...) of the locale that is used for this instance
83
-	 *
84
-	 * @return string locale
85
-	 */
86
-	public function getLocaleCode() {
87
-		return $this->locale;
88
-	}
89
-
90
-	/**
91
-	 * Translating
92
-	 * @param string $text The text we need a translation for
93
-	 * @param array $parameters default:array() Parameters for sprintf
94
-	 * @return string Translation or the same text
95
-	 *
96
-	 * Returns the translation. If no translation is found, $text will be
97
-	 * returned.
98
-	 */
99
-	public function t($text, $parameters = array()) {
100
-		return (string) new \OC_L10N_String($this, $text, $parameters);
101
-	}
102
-
103
-	/**
104
-	 * Translating
105
-	 * @param string $text_singular the string to translate for exactly one object
106
-	 * @param string $text_plural the string to translate for n objects
107
-	 * @param integer $count Number of objects
108
-	 * @param array $parameters default:array() Parameters for sprintf
109
-	 * @return string Translation or the same text
110
-	 *
111
-	 * Returns the translation. If no translation is found, $text will be
112
-	 * returned. %n will be replaced with the number of objects.
113
-	 *
114
-	 * The correct plural is determined by the plural_forms-function
115
-	 * provided by the po file.
116
-	 *
117
-	 */
118
-	public function n($text_singular, $text_plural, $count, $parameters = array()) {
119
-		$identifier = "_${text_singular}_::_${text_plural}_";
120
-		if (isset($this->translations[$identifier])) {
121
-			return (string) new \OC_L10N_String($this, $identifier, $parameters, $count);
122
-		} else {
123
-			if ($count === 1) {
124
-				return (string) new \OC_L10N_String($this, $text_singular, $parameters, $count);
125
-			} else {
126
-				return (string) new \OC_L10N_String($this, $text_plural, $parameters, $count);
127
-			}
128
-		}
129
-	}
130
-
131
-	/**
132
-	 * Localization
133
-	 * @param string $type Type of localization
134
-	 * @param \DateTime|int|string $data parameters for this localization
135
-	 * @param array $options
136
-	 * @return string|int|false
137
-	 *
138
-	 * Returns the localized data.
139
-	 *
140
-	 * Implemented types:
141
-	 *  - date
142
-	 *    - Creates a date
143
-	 *    - params: timestamp (int/string)
144
-	 *  - datetime
145
-	 *    - Creates date and time
146
-	 *    - params: timestamp (int/string)
147
-	 *  - time
148
-	 *    - Creates a time
149
-	 *    - params: timestamp (int/string)
150
-	 *  - firstday: Returns the first day of the week (0 sunday - 6 saturday)
151
-	 *  - jsdate: Returns the short JS date format
152
-	 */
153
-	public function l($type, $data = null, $options = array()) {
154
-		if (null === $this->locale) {
155
-			// Use the language of the instance
156
-			$this->locale = $this->getLanguageCode();
157
-		}
158
-		if ($this->locale === 'sr@latin') {
159
-			$this->locale = 'sr_latn';
160
-		}
161
-
162
-		if ($type === 'firstday') {
163
-			return (int) Calendar::getFirstWeekday($this->locale);
164
-		}
165
-		if ($type === 'jsdate') {
166
-			return (string) Calendar::getDateFormat('short', $this->locale);
167
-		}
168
-
169
-		$value = new \DateTime();
170
-		if ($data instanceof \DateTime) {
171
-			$value = $data;
172
-		} else if (is_string($data) && !is_numeric($data)) {
173
-			$data = strtotime($data);
174
-			$value->setTimestamp($data);
175
-		} else if ($data !== null) {
176
-			$value->setTimestamp($data);
177
-		}
178
-
179
-		$options = array_merge(array('width' => 'long'), $options);
180
-		$width = $options['width'];
181
-		switch ($type) {
182
-			case 'date':
183
-				return (string) Calendar::formatDate($value, $width, $this->locale);
184
-			case 'datetime':
185
-				return (string) Calendar::formatDatetime($value, $width, $this->locale);
186
-			case 'time':
187
-				return (string) Calendar::formatTime($value, $width, $this->locale);
188
-			default:
189
-				return false;
190
-		}
191
-	}
192
-
193
-	/**
194
-	 * Returns an associative array with all translations
195
-	 *
196
-	 * Called by \OC_L10N_String
197
-	 * @return array
198
-	 */
199
-	public function getTranslations() {
200
-		return $this->translations;
201
-	}
202
-
203
-	/**
204
-	 * Returnsed function accepts the argument $n
205
-	 *
206
-	 * Called by \OC_L10N_String
207
-	 * @return string the plural form function
208
-	 */
209
-	public function getPluralFormFunction() {
210
-		if (is_null($this->pluralFormFunction)) {
211
-			$this->pluralFormFunction = $this->factory->createPluralFunction($this->pluralFormString);
212
-		}
213
-		return $this->pluralFormFunction;
214
-	}
215
-
216
-	/**
217
-	 * @param $translationFile
218
-	 * @return bool
219
-	 */
220
-	protected function load($translationFile) {
221
-		$json = json_decode(file_get_contents($translationFile), true);
222
-		if (!is_array($json)) {
223
-			$jsonError = json_last_error();
224
-			\OC::$server->getLogger()->warning("Failed to load $translationFile - json error code: $jsonError", ['app' => 'l10n']);
225
-			return false;
226
-		}
227
-
228
-		if (!empty($json['pluralForm'])) {
229
-			$this->pluralFormString = $json['pluralForm'];
230
-		}
231
-		$this->translations = array_merge($this->translations, $json['translations']);
232
-		return true;
233
-	}
32
+    /** @var IFactory */
33
+    protected $factory;
34
+
35
+    /** @var string App of this object */
36
+    protected $app;
37
+
38
+    /** @var string Language of this object */
39
+    protected $lang;
40
+
41
+    /** @var string Locale of this object */
42
+    protected $locale;
43
+
44
+    /** @var string Plural forms (string) */
45
+    private $pluralFormString = 'nplurals=2; plural=(n != 1);';
46
+
47
+    /** @var string Plural forms (function) */
48
+    private $pluralFormFunction = null;
49
+
50
+    /** @var string[] */
51
+    private $translations = [];
52
+
53
+    /**
54
+     * @param IFactory $factory
55
+     * @param string $app
56
+     * @param string $lang
57
+     * @param string $locale
58
+     * @param array $files
59
+     */
60
+    public function __construct(IFactory $factory, $app, $lang, $locale, array $files) {
61
+        $this->factory = $factory;
62
+        $this->app = $app;
63
+        $this->lang = $lang;
64
+        $this->locale = $locale;
65
+
66
+        $this->translations = [];
67
+        foreach ($files as $languageFile) {
68
+            $this->load($languageFile);
69
+        }
70
+    }
71
+
72
+    /**
73
+     * The code (en, de, ...) of the language that is used for this instance
74
+     *
75
+     * @return string language
76
+     */
77
+    public function getLanguageCode() {
78
+        return $this->lang;
79
+    }
80
+
81
+    /**
82
+     * The code (en_US, fr_CA, ...) of the locale that is used for this instance
83
+     *
84
+     * @return string locale
85
+     */
86
+    public function getLocaleCode() {
87
+        return $this->locale;
88
+    }
89
+
90
+    /**
91
+     * Translating
92
+     * @param string $text The text we need a translation for
93
+     * @param array $parameters default:array() Parameters for sprintf
94
+     * @return string Translation or the same text
95
+     *
96
+     * Returns the translation. If no translation is found, $text will be
97
+     * returned.
98
+     */
99
+    public function t($text, $parameters = array()) {
100
+        return (string) new \OC_L10N_String($this, $text, $parameters);
101
+    }
102
+
103
+    /**
104
+     * Translating
105
+     * @param string $text_singular the string to translate for exactly one object
106
+     * @param string $text_plural the string to translate for n objects
107
+     * @param integer $count Number of objects
108
+     * @param array $parameters default:array() Parameters for sprintf
109
+     * @return string Translation or the same text
110
+     *
111
+     * Returns the translation. If no translation is found, $text will be
112
+     * returned. %n will be replaced with the number of objects.
113
+     *
114
+     * The correct plural is determined by the plural_forms-function
115
+     * provided by the po file.
116
+     *
117
+     */
118
+    public function n($text_singular, $text_plural, $count, $parameters = array()) {
119
+        $identifier = "_${text_singular}_::_${text_plural}_";
120
+        if (isset($this->translations[$identifier])) {
121
+            return (string) new \OC_L10N_String($this, $identifier, $parameters, $count);
122
+        } else {
123
+            if ($count === 1) {
124
+                return (string) new \OC_L10N_String($this, $text_singular, $parameters, $count);
125
+            } else {
126
+                return (string) new \OC_L10N_String($this, $text_plural, $parameters, $count);
127
+            }
128
+        }
129
+    }
130
+
131
+    /**
132
+     * Localization
133
+     * @param string $type Type of localization
134
+     * @param \DateTime|int|string $data parameters for this localization
135
+     * @param array $options
136
+     * @return string|int|false
137
+     *
138
+     * Returns the localized data.
139
+     *
140
+     * Implemented types:
141
+     *  - date
142
+     *    - Creates a date
143
+     *    - params: timestamp (int/string)
144
+     *  - datetime
145
+     *    - Creates date and time
146
+     *    - params: timestamp (int/string)
147
+     *  - time
148
+     *    - Creates a time
149
+     *    - params: timestamp (int/string)
150
+     *  - firstday: Returns the first day of the week (0 sunday - 6 saturday)
151
+     *  - jsdate: Returns the short JS date format
152
+     */
153
+    public function l($type, $data = null, $options = array()) {
154
+        if (null === $this->locale) {
155
+            // Use the language of the instance
156
+            $this->locale = $this->getLanguageCode();
157
+        }
158
+        if ($this->locale === 'sr@latin') {
159
+            $this->locale = 'sr_latn';
160
+        }
161
+
162
+        if ($type === 'firstday') {
163
+            return (int) Calendar::getFirstWeekday($this->locale);
164
+        }
165
+        if ($type === 'jsdate') {
166
+            return (string) Calendar::getDateFormat('short', $this->locale);
167
+        }
168
+
169
+        $value = new \DateTime();
170
+        if ($data instanceof \DateTime) {
171
+            $value = $data;
172
+        } else if (is_string($data) && !is_numeric($data)) {
173
+            $data = strtotime($data);
174
+            $value->setTimestamp($data);
175
+        } else if ($data !== null) {
176
+            $value->setTimestamp($data);
177
+        }
178
+
179
+        $options = array_merge(array('width' => 'long'), $options);
180
+        $width = $options['width'];
181
+        switch ($type) {
182
+            case 'date':
183
+                return (string) Calendar::formatDate($value, $width, $this->locale);
184
+            case 'datetime':
185
+                return (string) Calendar::formatDatetime($value, $width, $this->locale);
186
+            case 'time':
187
+                return (string) Calendar::formatTime($value, $width, $this->locale);
188
+            default:
189
+                return false;
190
+        }
191
+    }
192
+
193
+    /**
194
+     * Returns an associative array with all translations
195
+     *
196
+     * Called by \OC_L10N_String
197
+     * @return array
198
+     */
199
+    public function getTranslations() {
200
+        return $this->translations;
201
+    }
202
+
203
+    /**
204
+     * Returnsed function accepts the argument $n
205
+     *
206
+     * Called by \OC_L10N_String
207
+     * @return string the plural form function
208
+     */
209
+    public function getPluralFormFunction() {
210
+        if (is_null($this->pluralFormFunction)) {
211
+            $this->pluralFormFunction = $this->factory->createPluralFunction($this->pluralFormString);
212
+        }
213
+        return $this->pluralFormFunction;
214
+    }
215
+
216
+    /**
217
+     * @param $translationFile
218
+     * @return bool
219
+     */
220
+    protected function load($translationFile) {
221
+        $json = json_decode(file_get_contents($translationFile), true);
222
+        if (!is_array($json)) {
223
+            $jsonError = json_last_error();
224
+            \OC::$server->getLogger()->warning("Failed to load $translationFile - json error code: $jsonError", ['app' => 'l10n']);
225
+            return false;
226
+        }
227
+
228
+        if (!empty($json['pluralForm'])) {
229
+            $this->pluralFormString = $json['pluralForm'];
230
+        }
231
+        $this->translations = array_merge($this->translations, $json['translations']);
232
+        return true;
233
+    }
234 234
 }
Please login to merge, or discard this patch.
lib/private/L10N/Factory.php 1 patch
Indentation   +376 added lines, -376 removed lines patch added patch discarded remove patch
@@ -40,380 +40,380 @@
 block discarded – undo
40 40
  */
41 41
 class Factory implements IFactory {
42 42
 
43
-	/** @var string */
44
-	protected $requestLanguage = '';
45
-
46
-	/**
47
-	 * cached instances
48
-	 * @var array Structure: Lang => App => \OCP\IL10N
49
-	 */
50
-	protected $instances = [];
51
-
52
-	/**
53
-	 * @var array Structure: App => string[]
54
-	 */
55
-	protected $availableLanguages = [];
56
-
57
-	/**
58
-	 * @var array Structure: string => callable
59
-	 */
60
-	protected $pluralFunctions = [];
61
-
62
-	/** @var IConfig */
63
-	protected $config;
64
-
65
-	/** @var IRequest */
66
-	protected $request;
67
-
68
-	/** @var IUserSession */
69
-	protected $userSession;
70
-
71
-	/** @var string */
72
-	protected $serverRoot;
73
-
74
-	/**
75
-	 * @param IConfig $config
76
-	 * @param IRequest $request
77
-	 * @param IUserSession $userSession
78
-	 * @param string $serverRoot
79
-	 */
80
-	public function __construct(IConfig $config,
81
-								IRequest $request,
82
-								IUserSession $userSession,
83
-								$serverRoot) {
84
-		$this->config = $config;
85
-		$this->request = $request;
86
-		$this->userSession = $userSession;
87
-		$this->serverRoot = $serverRoot;
88
-	}
89
-
90
-	/**
91
-	 * Get a language instance
92
-	 *
93
-	 * @param string $app
94
-	 * @param string|null $lang
95
-	 * @param string|null $locale
96
-	 * @return \OCP\IL10N
97
-	 */
98
-	public function get($app, $lang = null, $locale = null) {
99
-		$app = \OC_App::cleanAppId($app);
100
-		if ($lang !== null) {
101
-			$lang = str_replace(array('\0', '/', '\\', '..'), '', (string) $lang);
102
-		}
103
-
104
-		$forceLang = $this->config->getSystemValue('force_language', false);
105
-		if (is_string($forceLang)) {
106
-			$lang = $forceLang;
107
-		}
108
-
109
-		if ($lang === null || !$this->languageExists($app, $lang)) {
110
-			$lang = $this->findLanguage($app);
111
-		}
112
-
113
-		if (!isset($this->instances[$lang][$app])) {
114
-			$this->instances[$lang][$app] = new L10N(
115
-				$this, $app, $lang, $locale,
116
-				$this->getL10nFilesForApp($app, $lang)
117
-			);
118
-		}
119
-
120
-		return $this->instances[$lang][$app];
121
-	}
122
-
123
-	/**
124
-	 * Find the best language
125
-	 *
126
-	 * @param string|null $app App id or null for core
127
-	 * @return string language If nothing works it returns 'en'
128
-	 */
129
-	public function findLanguage($app = null) {
130
-		if ($this->requestLanguage !== '' && $this->languageExists($app, $this->requestLanguage)) {
131
-			return $this->requestLanguage;
132
-		}
133
-
134
-		/**
135
-		 * At this point Nextcloud might not yet be installed and thus the lookup
136
-		 * in the preferences table might fail. For this reason we need to check
137
-		 * whether the instance has already been installed
138
-		 *
139
-		 * @link https://github.com/owncloud/core/issues/21955
140
-		 */
141
-		if($this->config->getSystemValue('installed', false)) {
142
-			$userId = !is_null($this->userSession->getUser()) ? $this->userSession->getUser()->getUID() :  null;
143
-			if(!is_null($userId)) {
144
-				$userLang = $this->config->getUserValue($userId, 'core', 'lang', null);
145
-			} else {
146
-				$userLang = null;
147
-			}
148
-		} else {
149
-			$userId = null;
150
-			$userLang = null;
151
-		}
152
-
153
-		if ($userLang) {
154
-			$this->requestLanguage = $userLang;
155
-			if ($this->languageExists($app, $userLang)) {
156
-				return $userLang;
157
-			}
158
-		}
159
-
160
-		try {
161
-			// Try to get the language from the Request
162
-			$lang = $this->getLanguageFromRequest($app);
163
-			if ($userId !== null && $app === null && !$userLang) {
164
-				$this->config->setUserValue($userId, 'core', 'lang', $lang);
165
-			}
166
-			return $lang;
167
-		} catch (LanguageNotFoundException $e) {
168
-			// Finding language from request failed fall back to default language
169
-			$defaultLanguage = $this->config->getSystemValue('default_language', false);
170
-			if ($defaultLanguage !== false && $this->languageExists($app, $defaultLanguage)) {
171
-				return $defaultLanguage;
172
-			}
173
-		}
174
-
175
-		// We could not find any language so fall back to english
176
-		return 'en';
177
-	}
178
-
179
-	/**
180
-	 * Find all available languages for an app
181
-	 *
182
-	 * @param string|null $app App id or null for core
183
-	 * @return array an array of available languages
184
-	 */
185
-	public function findAvailableLanguages($app = null) {
186
-		$key = $app;
187
-		if ($key === null) {
188
-			$key = 'null';
189
-		}
190
-
191
-		// also works with null as key
192
-		if (!empty($this->availableLanguages[$key])) {
193
-			return $this->availableLanguages[$key];
194
-		}
195
-
196
-		$available = ['en']; //english is always available
197
-		$dir = $this->findL10nDir($app);
198
-		if (is_dir($dir)) {
199
-			$files = scandir($dir);
200
-			if ($files !== false) {
201
-				foreach ($files as $file) {
202
-					if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') {
203
-						$available[] = substr($file, 0, -5);
204
-					}
205
-				}
206
-			}
207
-		}
208
-
209
-		// merge with translations from theme
210
-		$theme = $this->config->getSystemValue('theme');
211
-		if (!empty($theme)) {
212
-			$themeDir = $this->serverRoot . '/themes/' . $theme . substr($dir, strlen($this->serverRoot));
213
-
214
-			if (is_dir($themeDir)) {
215
-				$files = scandir($themeDir);
216
-				if ($files !== false) {
217
-					foreach ($files as $file) {
218
-						if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') {
219
-							$available[] = substr($file, 0, -5);
220
-						}
221
-					}
222
-				}
223
-			}
224
-		}
225
-
226
-		$this->availableLanguages[$key] = $available;
227
-		return $available;
228
-	}
229
-
230
-	/**
231
-	 * @param string|null $app App id or null for core
232
-	 * @param string $lang
233
-	 * @return bool
234
-	 */
235
-	public function languageExists($app, $lang) {
236
-		if ($lang === 'en') {//english is always available
237
-			return true;
238
-		}
239
-
240
-		$languages = $this->findAvailableLanguages($app);
241
-		return array_search($lang, $languages) !== false;
242
-	}
243
-
244
-	/**
245
-	 * @param string|null $app
246
-	 * @return string
247
-	 * @throws LanguageNotFoundException
248
-	 */
249
-	private function getLanguageFromRequest($app) {
250
-		$header = $this->request->getHeader('ACCEPT_LANGUAGE');
251
-		if ($header) {
252
-			$available = $this->findAvailableLanguages($app);
253
-
254
-			// E.g. make sure that 'de' is before 'de_DE'.
255
-			sort($available);
256
-
257
-			$preferences = preg_split('/,\s*/', strtolower($header));
258
-			foreach ($preferences as $preference) {
259
-				list($preferred_language) = explode(';', $preference);
260
-				$preferred_language = str_replace('-', '_', $preferred_language);
261
-
262
-				foreach ($available as $available_language) {
263
-					if ($preferred_language === strtolower($available_language)) {
264
-						return $available_language;
265
-					}
266
-				}
267
-
268
-				// Fallback from de_De to de
269
-				foreach ($available as $available_language) {
270
-					if (substr($preferred_language, 0, 2) === $available_language) {
271
-						return $available_language;
272
-					}
273
-				}
274
-			}
275
-		}
276
-
277
-		throw new LanguageNotFoundException();
278
-	}
279
-
280
-	/**
281
-	 * Checks if $sub is a subdirectory of $parent
282
-	 *
283
-	 * @param string $sub
284
-	 * @param string $parent
285
-	 * @return bool
286
-	 */
287
-	private function isSubDirectory($sub, $parent) {
288
-		// Check whether $sub contains no ".."
289
-		if(strpos($sub, '..') !== false) {
290
-			return false;
291
-		}
292
-
293
-		// Check whether $sub is a subdirectory of $parent
294
-		if (strpos($sub, $parent) === 0) {
295
-			return true;
296
-		}
297
-
298
-		return false;
299
-	}
300
-
301
-	/**
302
-	 * Get a list of language files that should be loaded
303
-	 *
304
-	 * @param string $app
305
-	 * @param string $lang
306
-	 * @return string[]
307
-	 */
308
-	// FIXME This method is only public, until OC_L10N does not need it anymore,
309
-	// FIXME This is also the reason, why it is not in the public interface
310
-	public function getL10nFilesForApp($app, $lang) {
311
-		$languageFiles = [];
312
-
313
-		$i18nDir = $this->findL10nDir($app);
314
-		$transFile = strip_tags($i18nDir) . strip_tags($lang) . '.json';
315
-
316
-		if (($this->isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
317
-				|| $this->isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
318
-				|| $this->isSubDirectory($transFile, $this->serverRoot . '/settings/l10n/')
319
-				|| $this->isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/')
320
-			)
321
-			&& file_exists($transFile)) {
322
-			// load the translations file
323
-			$languageFiles[] = $transFile;
324
-		}
325
-
326
-		// merge with translations from theme
327
-		$theme = $this->config->getSystemValue('theme');
328
-		if (!empty($theme)) {
329
-			$transFile = $this->serverRoot . '/themes/' . $theme . substr($transFile, strlen($this->serverRoot));
330
-			if (file_exists($transFile)) {
331
-				$languageFiles[] = $transFile;
332
-			}
333
-		}
334
-
335
-		return $languageFiles;
336
-	}
337
-
338
-	/**
339
-	 * find the l10n directory
340
-	 *
341
-	 * @param string $app App id or empty string for core
342
-	 * @return string directory
343
-	 */
344
-	protected function findL10nDir($app = null) {
345
-		if (in_array($app, ['core', 'lib', 'settings'])) {
346
-			if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) {
347
-				return $this->serverRoot . '/' . $app . '/l10n/';
348
-			}
349
-		} else if ($app && \OC_App::getAppPath($app) !== false) {
350
-			// Check if the app is in the app folder
351
-			return \OC_App::getAppPath($app) . '/l10n/';
352
-		}
353
-		return $this->serverRoot . '/core/l10n/';
354
-	}
355
-
356
-
357
-	/**
358
-	 * Creates a function from the plural string
359
-	 *
360
-	 * Parts of the code is copied from Habari:
361
-	 * https://github.com/habari/system/blob/master/classes/locale.php
362
-	 * @param string $string
363
-	 * @return string
364
-	 */
365
-	public function createPluralFunction($string) {
366
-		if (isset($this->pluralFunctions[$string])) {
367
-			return $this->pluralFunctions[$string];
368
-		}
369
-
370
-		if (preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
371
-			// sanitize
372
-			$nplurals = preg_replace( '/[^0-9]/', '', $matches[1] );
373
-			$plural = preg_replace( '#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2] );
374
-
375
-			$body = str_replace(
376
-				array( 'plural', 'n', '$n$plurals', ),
377
-				array( '$plural', '$n', '$nplurals', ),
378
-				'nplurals='. $nplurals . '; plural=' . $plural
379
-			);
380
-
381
-			// add parents
382
-			// important since PHP's ternary evaluates from left to right
383
-			$body .= ';';
384
-			$res = '';
385
-			$p = 0;
386
-			for($i = 0; $i < strlen($body); $i++) {
387
-				$ch = $body[$i];
388
-				switch ( $ch ) {
389
-					case '?':
390
-						$res .= ' ? (';
391
-						$p++;
392
-						break;
393
-					case ':':
394
-						$res .= ') : (';
395
-						break;
396
-					case ';':
397
-						$res .= str_repeat( ')', $p ) . ';';
398
-						$p = 0;
399
-						break;
400
-					default:
401
-						$res .= $ch;
402
-				}
403
-			}
404
-
405
-			$body = $res . 'return ($plural>=$nplurals?$nplurals-1:$plural);';
406
-			$function = create_function('$n', $body);
407
-			$this->pluralFunctions[$string] = $function;
408
-			return $function;
409
-		} else {
410
-			// default: one plural form for all cases but n==1 (english)
411
-			$function = create_function(
412
-				'$n',
413
-				'$nplurals=2;$plural=($n==1?0:1);return ($plural>=$nplurals?$nplurals-1:$plural);'
414
-			);
415
-			$this->pluralFunctions[$string] = $function;
416
-			return $function;
417
-		}
418
-	}
43
+    /** @var string */
44
+    protected $requestLanguage = '';
45
+
46
+    /**
47
+     * cached instances
48
+     * @var array Structure: Lang => App => \OCP\IL10N
49
+     */
50
+    protected $instances = [];
51
+
52
+    /**
53
+     * @var array Structure: App => string[]
54
+     */
55
+    protected $availableLanguages = [];
56
+
57
+    /**
58
+     * @var array Structure: string => callable
59
+     */
60
+    protected $pluralFunctions = [];
61
+
62
+    /** @var IConfig */
63
+    protected $config;
64
+
65
+    /** @var IRequest */
66
+    protected $request;
67
+
68
+    /** @var IUserSession */
69
+    protected $userSession;
70
+
71
+    /** @var string */
72
+    protected $serverRoot;
73
+
74
+    /**
75
+     * @param IConfig $config
76
+     * @param IRequest $request
77
+     * @param IUserSession $userSession
78
+     * @param string $serverRoot
79
+     */
80
+    public function __construct(IConfig $config,
81
+                                IRequest $request,
82
+                                IUserSession $userSession,
83
+                                $serverRoot) {
84
+        $this->config = $config;
85
+        $this->request = $request;
86
+        $this->userSession = $userSession;
87
+        $this->serverRoot = $serverRoot;
88
+    }
89
+
90
+    /**
91
+     * Get a language instance
92
+     *
93
+     * @param string $app
94
+     * @param string|null $lang
95
+     * @param string|null $locale
96
+     * @return \OCP\IL10N
97
+     */
98
+    public function get($app, $lang = null, $locale = null) {
99
+        $app = \OC_App::cleanAppId($app);
100
+        if ($lang !== null) {
101
+            $lang = str_replace(array('\0', '/', '\\', '..'), '', (string) $lang);
102
+        }
103
+
104
+        $forceLang = $this->config->getSystemValue('force_language', false);
105
+        if (is_string($forceLang)) {
106
+            $lang = $forceLang;
107
+        }
108
+
109
+        if ($lang === null || !$this->languageExists($app, $lang)) {
110
+            $lang = $this->findLanguage($app);
111
+        }
112
+
113
+        if (!isset($this->instances[$lang][$app])) {
114
+            $this->instances[$lang][$app] = new L10N(
115
+                $this, $app, $lang, $locale,
116
+                $this->getL10nFilesForApp($app, $lang)
117
+            );
118
+        }
119
+
120
+        return $this->instances[$lang][$app];
121
+    }
122
+
123
+    /**
124
+     * Find the best language
125
+     *
126
+     * @param string|null $app App id or null for core
127
+     * @return string language If nothing works it returns 'en'
128
+     */
129
+    public function findLanguage($app = null) {
130
+        if ($this->requestLanguage !== '' && $this->languageExists($app, $this->requestLanguage)) {
131
+            return $this->requestLanguage;
132
+        }
133
+
134
+        /**
135
+         * At this point Nextcloud might not yet be installed and thus the lookup
136
+         * in the preferences table might fail. For this reason we need to check
137
+         * whether the instance has already been installed
138
+         *
139
+         * @link https://github.com/owncloud/core/issues/21955
140
+         */
141
+        if($this->config->getSystemValue('installed', false)) {
142
+            $userId = !is_null($this->userSession->getUser()) ? $this->userSession->getUser()->getUID() :  null;
143
+            if(!is_null($userId)) {
144
+                $userLang = $this->config->getUserValue($userId, 'core', 'lang', null);
145
+            } else {
146
+                $userLang = null;
147
+            }
148
+        } else {
149
+            $userId = null;
150
+            $userLang = null;
151
+        }
152
+
153
+        if ($userLang) {
154
+            $this->requestLanguage = $userLang;
155
+            if ($this->languageExists($app, $userLang)) {
156
+                return $userLang;
157
+            }
158
+        }
159
+
160
+        try {
161
+            // Try to get the language from the Request
162
+            $lang = $this->getLanguageFromRequest($app);
163
+            if ($userId !== null && $app === null && !$userLang) {
164
+                $this->config->setUserValue($userId, 'core', 'lang', $lang);
165
+            }
166
+            return $lang;
167
+        } catch (LanguageNotFoundException $e) {
168
+            // Finding language from request failed fall back to default language
169
+            $defaultLanguage = $this->config->getSystemValue('default_language', false);
170
+            if ($defaultLanguage !== false && $this->languageExists($app, $defaultLanguage)) {
171
+                return $defaultLanguage;
172
+            }
173
+        }
174
+
175
+        // We could not find any language so fall back to english
176
+        return 'en';
177
+    }
178
+
179
+    /**
180
+     * Find all available languages for an app
181
+     *
182
+     * @param string|null $app App id or null for core
183
+     * @return array an array of available languages
184
+     */
185
+    public function findAvailableLanguages($app = null) {
186
+        $key = $app;
187
+        if ($key === null) {
188
+            $key = 'null';
189
+        }
190
+
191
+        // also works with null as key
192
+        if (!empty($this->availableLanguages[$key])) {
193
+            return $this->availableLanguages[$key];
194
+        }
195
+
196
+        $available = ['en']; //english is always available
197
+        $dir = $this->findL10nDir($app);
198
+        if (is_dir($dir)) {
199
+            $files = scandir($dir);
200
+            if ($files !== false) {
201
+                foreach ($files as $file) {
202
+                    if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') {
203
+                        $available[] = substr($file, 0, -5);
204
+                    }
205
+                }
206
+            }
207
+        }
208
+
209
+        // merge with translations from theme
210
+        $theme = $this->config->getSystemValue('theme');
211
+        if (!empty($theme)) {
212
+            $themeDir = $this->serverRoot . '/themes/' . $theme . substr($dir, strlen($this->serverRoot));
213
+
214
+            if (is_dir($themeDir)) {
215
+                $files = scandir($themeDir);
216
+                if ($files !== false) {
217
+                    foreach ($files as $file) {
218
+                        if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') {
219
+                            $available[] = substr($file, 0, -5);
220
+                        }
221
+                    }
222
+                }
223
+            }
224
+        }
225
+
226
+        $this->availableLanguages[$key] = $available;
227
+        return $available;
228
+    }
229
+
230
+    /**
231
+     * @param string|null $app App id or null for core
232
+     * @param string $lang
233
+     * @return bool
234
+     */
235
+    public function languageExists($app, $lang) {
236
+        if ($lang === 'en') {//english is always available
237
+            return true;
238
+        }
239
+
240
+        $languages = $this->findAvailableLanguages($app);
241
+        return array_search($lang, $languages) !== false;
242
+    }
243
+
244
+    /**
245
+     * @param string|null $app
246
+     * @return string
247
+     * @throws LanguageNotFoundException
248
+     */
249
+    private function getLanguageFromRequest($app) {
250
+        $header = $this->request->getHeader('ACCEPT_LANGUAGE');
251
+        if ($header) {
252
+            $available = $this->findAvailableLanguages($app);
253
+
254
+            // E.g. make sure that 'de' is before 'de_DE'.
255
+            sort($available);
256
+
257
+            $preferences = preg_split('/,\s*/', strtolower($header));
258
+            foreach ($preferences as $preference) {
259
+                list($preferred_language) = explode(';', $preference);
260
+                $preferred_language = str_replace('-', '_', $preferred_language);
261
+
262
+                foreach ($available as $available_language) {
263
+                    if ($preferred_language === strtolower($available_language)) {
264
+                        return $available_language;
265
+                    }
266
+                }
267
+
268
+                // Fallback from de_De to de
269
+                foreach ($available as $available_language) {
270
+                    if (substr($preferred_language, 0, 2) === $available_language) {
271
+                        return $available_language;
272
+                    }
273
+                }
274
+            }
275
+        }
276
+
277
+        throw new LanguageNotFoundException();
278
+    }
279
+
280
+    /**
281
+     * Checks if $sub is a subdirectory of $parent
282
+     *
283
+     * @param string $sub
284
+     * @param string $parent
285
+     * @return bool
286
+     */
287
+    private function isSubDirectory($sub, $parent) {
288
+        // Check whether $sub contains no ".."
289
+        if(strpos($sub, '..') !== false) {
290
+            return false;
291
+        }
292
+
293
+        // Check whether $sub is a subdirectory of $parent
294
+        if (strpos($sub, $parent) === 0) {
295
+            return true;
296
+        }
297
+
298
+        return false;
299
+    }
300
+
301
+    /**
302
+     * Get a list of language files that should be loaded
303
+     *
304
+     * @param string $app
305
+     * @param string $lang
306
+     * @return string[]
307
+     */
308
+    // FIXME This method is only public, until OC_L10N does not need it anymore,
309
+    // FIXME This is also the reason, why it is not in the public interface
310
+    public function getL10nFilesForApp($app, $lang) {
311
+        $languageFiles = [];
312
+
313
+        $i18nDir = $this->findL10nDir($app);
314
+        $transFile = strip_tags($i18nDir) . strip_tags($lang) . '.json';
315
+
316
+        if (($this->isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
317
+                || $this->isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
318
+                || $this->isSubDirectory($transFile, $this->serverRoot . '/settings/l10n/')
319
+                || $this->isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/')
320
+            )
321
+            && file_exists($transFile)) {
322
+            // load the translations file
323
+            $languageFiles[] = $transFile;
324
+        }
325
+
326
+        // merge with translations from theme
327
+        $theme = $this->config->getSystemValue('theme');
328
+        if (!empty($theme)) {
329
+            $transFile = $this->serverRoot . '/themes/' . $theme . substr($transFile, strlen($this->serverRoot));
330
+            if (file_exists($transFile)) {
331
+                $languageFiles[] = $transFile;
332
+            }
333
+        }
334
+
335
+        return $languageFiles;
336
+    }
337
+
338
+    /**
339
+     * find the l10n directory
340
+     *
341
+     * @param string $app App id or empty string for core
342
+     * @return string directory
343
+     */
344
+    protected function findL10nDir($app = null) {
345
+        if (in_array($app, ['core', 'lib', 'settings'])) {
346
+            if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) {
347
+                return $this->serverRoot . '/' . $app . '/l10n/';
348
+            }
349
+        } else if ($app && \OC_App::getAppPath($app) !== false) {
350
+            // Check if the app is in the app folder
351
+            return \OC_App::getAppPath($app) . '/l10n/';
352
+        }
353
+        return $this->serverRoot . '/core/l10n/';
354
+    }
355
+
356
+
357
+    /**
358
+     * Creates a function from the plural string
359
+     *
360
+     * Parts of the code is copied from Habari:
361
+     * https://github.com/habari/system/blob/master/classes/locale.php
362
+     * @param string $string
363
+     * @return string
364
+     */
365
+    public function createPluralFunction($string) {
366
+        if (isset($this->pluralFunctions[$string])) {
367
+            return $this->pluralFunctions[$string];
368
+        }
369
+
370
+        if (preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
371
+            // sanitize
372
+            $nplurals = preg_replace( '/[^0-9]/', '', $matches[1] );
373
+            $plural = preg_replace( '#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2] );
374
+
375
+            $body = str_replace(
376
+                array( 'plural', 'n', '$n$plurals', ),
377
+                array( '$plural', '$n', '$nplurals', ),
378
+                'nplurals='. $nplurals . '; plural=' . $plural
379
+            );
380
+
381
+            // add parents
382
+            // important since PHP's ternary evaluates from left to right
383
+            $body .= ';';
384
+            $res = '';
385
+            $p = 0;
386
+            for($i = 0; $i < strlen($body); $i++) {
387
+                $ch = $body[$i];
388
+                switch ( $ch ) {
389
+                    case '?':
390
+                        $res .= ' ? (';
391
+                        $p++;
392
+                        break;
393
+                    case ':':
394
+                        $res .= ') : (';
395
+                        break;
396
+                    case ';':
397
+                        $res .= str_repeat( ')', $p ) . ';';
398
+                        $p = 0;
399
+                        break;
400
+                    default:
401
+                        $res .= $ch;
402
+                }
403
+            }
404
+
405
+            $body = $res . 'return ($plural>=$nplurals?$nplurals-1:$plural);';
406
+            $function = create_function('$n', $body);
407
+            $this->pluralFunctions[$string] = $function;
408
+            return $function;
409
+        } else {
410
+            // default: one plural form for all cases but n==1 (english)
411
+            $function = create_function(
412
+                '$n',
413
+                '$nplurals=2;$plural=($n==1?0:1);return ($plural>=$nplurals?$nplurals-1:$plural);'
414
+            );
415
+            $this->pluralFunctions[$string] = $function;
416
+            return $function;
417
+        }
418
+    }
419 419
 }
Please login to merge, or discard this patch.
lib/public/IL10N.php 1 patch
Indentation   +68 added lines, -68 removed lines patch added patch discarded remove patch
@@ -44,77 +44,77 @@
 block discarded – undo
44 44
  * @since 6.0.0
45 45
  */
46 46
 interface IL10N {
47
-	/**
48
-	 * Translating
49
-	 * @param string $text The text we need a translation for
50
-	 * @param array $parameters default:array() Parameters for sprintf
51
-	 * @return \OC_L10N_String Translation or the same text
52
-	 *
53
-	 * Returns the translation. If no translation is found, $text will be
54
-	 * returned.
55
-	 * @since 6.0.0
56
-	 */
57
-	public function t($text, $parameters = array());
47
+    /**
48
+     * Translating
49
+     * @param string $text The text we need a translation for
50
+     * @param array $parameters default:array() Parameters for sprintf
51
+     * @return \OC_L10N_String Translation or the same text
52
+     *
53
+     * Returns the translation. If no translation is found, $text will be
54
+     * returned.
55
+     * @since 6.0.0
56
+     */
57
+    public function t($text, $parameters = array());
58 58
 
59
-	/**
60
-	 * Translating
61
-	 * @param string $text_singular the string to translate for exactly one object
62
-	 * @param string $text_plural the string to translate for n objects
63
-	 * @param integer $count Number of objects
64
-	 * @param array $parameters default:array() Parameters for sprintf
65
-	 * @return \OC_L10N_String Translation or the same text
66
-	 *
67
-	 * Returns the translation. If no translation is found, $text will be
68
-	 * returned. %n will be replaced with the number of objects.
69
-	 *
70
-	 * The correct plural is determined by the plural_forms-function
71
-	 * provided by the po file.
72
-	 * @since 6.0.0
73
-	 *
74
-	 */
75
-	public function n($text_singular, $text_plural, $count, $parameters = array());
59
+    /**
60
+     * Translating
61
+     * @param string $text_singular the string to translate for exactly one object
62
+     * @param string $text_plural the string to translate for n objects
63
+     * @param integer $count Number of objects
64
+     * @param array $parameters default:array() Parameters for sprintf
65
+     * @return \OC_L10N_String Translation or the same text
66
+     *
67
+     * Returns the translation. If no translation is found, $text will be
68
+     * returned. %n will be replaced with the number of objects.
69
+     *
70
+     * The correct plural is determined by the plural_forms-function
71
+     * provided by the po file.
72
+     * @since 6.0.0
73
+     *
74
+     */
75
+    public function n($text_singular, $text_plural, $count, $parameters = array());
76 76
 
77
-	/**
78
-	 * Localization
79
-	 * @param string $type Type of localization
80
-	 * @param \DateTime|int|string $data parameters for this localization
81
-	 * @param array $options currently supports following options:
82
-	 * 			- 'width': handed into \Punic\Calendar::formatDate as second parameter
83
-	 * @return string|int|false
84
-	 *
85
-	 * Returns the localized data.
86
-	 *
87
-	 * Implemented types:
88
-	 *  - date
89
-	 *    - Creates a date
90
-	 *    - l10n-field: date
91
-	 *    - params: timestamp (int/string)
92
-	 *  - datetime
93
-	 *    - Creates date and time
94
-	 *    - l10n-field: datetime
95
-	 *    - params: timestamp (int/string)
96
-	 *  - time
97
-	 *    - Creates a time
98
-	 *    - l10n-field: time
99
-	 *    - params: timestamp (int/string)
100
-	 * @since 6.0.0 - parameter $options was added in 8.0.0
101
-	 */
102
-	public function l($type, $data, $options = array());
77
+    /**
78
+     * Localization
79
+     * @param string $type Type of localization
80
+     * @param \DateTime|int|string $data parameters for this localization
81
+     * @param array $options currently supports following options:
82
+     * 			- 'width': handed into \Punic\Calendar::formatDate as second parameter
83
+     * @return string|int|false
84
+     *
85
+     * Returns the localized data.
86
+     *
87
+     * Implemented types:
88
+     *  - date
89
+     *    - Creates a date
90
+     *    - l10n-field: date
91
+     *    - params: timestamp (int/string)
92
+     *  - datetime
93
+     *    - Creates date and time
94
+     *    - l10n-field: datetime
95
+     *    - params: timestamp (int/string)
96
+     *  - time
97
+     *    - Creates a time
98
+     *    - l10n-field: time
99
+     *    - params: timestamp (int/string)
100
+     * @since 6.0.0 - parameter $options was added in 8.0.0
101
+     */
102
+    public function l($type, $data, $options = array());
103 103
 
104 104
 
105
-	/**
106
-	 * The code (en, de, ...) of the language that is used for this IL10N object
107
-	 *
108
-	 * @return string language
109
-	 * @since 7.0.0
110
-	 */
111
-	public function getLanguageCode();
105
+    /**
106
+     * The code (en, de, ...) of the language that is used for this IL10N object
107
+     *
108
+     * @return string language
109
+     * @since 7.0.0
110
+     */
111
+    public function getLanguageCode();
112 112
 
113
-	/**
114
-	 * * The code (en_US, fr_CA, ...) of the locale that is used for this IL10N object
115
-	 *
116
-	 * @return string locale
117
-	 * @since 13.0.0
118
-	 */
119
-	public function getLocaleCode();
113
+    /**
114
+     * * The code (en_US, fr_CA, ...) of the locale that is used for this IL10N object
115
+     *
116
+     * @return string locale
117
+     * @since 13.0.0
118
+     */
119
+    public function getLocaleCode();
120 120
 }
Please login to merge, or discard this patch.
settings/templates/settings/personal/personal.info.php 1 patch
Spacing   +56 added lines, -56 removed lines patch added patch discarded remove patch
@@ -39,15 +39,15 @@  discard block
 block discarded – undo
39 39
 ?>
40 40
 
41 41
 <div id="quota" class="section">
42
-	<div style="width:<?php p($_['usage_relative']);?>%"
43
-		<?php if($_['usage_relative'] > 80): ?> class="quota-warning" <?php endif; ?>>
42
+	<div style="width:<?php p($_['usage_relative']); ?>%"
43
+		<?php if ($_['usage_relative'] > 80): ?> class="quota-warning" <?php endif; ?>>
44 44
 		<p id="quotatext">
45 45
 			<?php if ($_['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED): ?>
46 46
 				<?php print_unescaped($l->t('You are using <strong>%s</strong> of <strong>%s</strong>',
47
-					[$_['usage'], $_['total_space']]));?>
47
+					[$_['usage'], $_['total_space']])); ?>
48 48
 			<?php else: ?>
49 49
 				<?php print_unescaped($l->t('You are using <strong>%s</strong> of <strong>%s</strong> (<strong>%s %%</strong>)',
50
-					[$_['usage'], $_['total_space'],  $_['usage_relative']]));?>
50
+					[$_['usage'], $_['total_space'], $_['usage_relative']])); ?>
51 51
 			<?php endif ?>
52 52
 		</p>
53 53
 	</div>
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
 				</div>
82 82
 			</div>
83 83
 			<span class="icon-checkmark hidden"/>
84
-			<?php if($_['lookupServerUploadEnabled']) { ?>
84
+			<?php if ($_['lookupServerUploadEnabled']) { ?>
85 85
 				<input type="hidden" id="avatarscope" value="<?php p($_['avatarScope']) ?>">
86 86
 			<?php } ?>
87 87
 		</form>
@@ -95,14 +95,14 @@  discard block
 block discarded – undo
95 95
 					<span class="icon-password"/>
96 96
 				</h2>
97 97
 				<input type="text" id="displayname" name="displayname"
98
-					<?php if(!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
98
+					<?php if (!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
99 99
 					   value="<?php p($_['displayName']) ?>"
100 100
 					   autocomplete="on" autocapitalize="none" autocorrect="off" />
101
-				<?php if(!$_['displayNameChangeSupported']) { ?>
102
-					<span><?php if(isset($_['displayName']) && !empty($_['displayName'])) { p($_['displayName']); } else { p($l->t('No display name set')); } ?></span>
101
+				<?php if (!$_['displayNameChangeSupported']) { ?>
102
+					<span><?php if (isset($_['displayName']) && !empty($_['displayName'])) { p($_['displayName']); } else { p($l->t('No display name set')); } ?></span>
103 103
 				<?php } ?>
104 104
 				<span class="icon-checkmark hidden"/>
105
-				<?php if($_['lookupServerUploadEnabled']) { ?>
105
+				<?php if ($_['lookupServerUploadEnabled']) { ?>
106 106
 					<input type="hidden" id="displaynamescope" value="<?php p($_['displayNameScope']) ?>">
107 107
 				<?php } ?>
108 108
 			</form>
@@ -113,10 +113,10 @@  discard block
 block discarded – undo
113 113
 					<label for="email"><?php p($l->t('Email')); ?></label>
114 114
 					<span class="icon-password"/>
115 115
 				</h2>
116
-				<div class="verify <?php if ($_['email'] === ''  || $_['emailScope'] !== 'public') p('hidden'); ?>">
116
+				<div class="verify <?php if ($_['email'] === '' || $_['emailScope'] !== 'public') p('hidden'); ?>">
117 117
 					<img id="verify-email" title="<?php p($_['emailMessage']); ?>" data-status="<?php p($_['emailVerification']) ?>" src="
118 118
 				<?php
119
-					switch($_['emailVerification']) {
119
+					switch ($_['emailVerification']) {
120 120
 						case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
121 121
 							p(image_path('core', 'actions/verifying.svg'));
122 122
 							break;
@@ -129,23 +129,23 @@  discard block
 block discarded – undo
129 129
 					?>">
130 130
 				</div>
131 131
 				<input type="email" name="email" id="email" value="<?php p($_['email']); ?>"
132
-					<?php if(!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
132
+					<?php if (!$_['displayNameChangeSupported']) { print_unescaped('class="hidden"'); } ?>
133 133
 					   placeholder="<?php p($l->t('Your email address')); ?>"
134 134
 					   autocomplete="on" autocapitalize="none" autocorrect="off" />
135
-				<?php if(!$_['displayNameChangeSupported']) { ?>
136
-					<span><?php if(isset($_['email']) && !empty($_['email'])) { p($_['email']); } else { p($l->t('No email address set')); }?></span>
135
+				<?php if (!$_['displayNameChangeSupported']) { ?>
136
+					<span><?php if (isset($_['email']) && !empty($_['email'])) { p($_['email']); } else { p($l->t('No email address set')); }?></span>
137 137
 				<?php } ?>
138
-				<?php if($_['displayNameChangeSupported']) { ?>
138
+				<?php if ($_['displayNameChangeSupported']) { ?>
139 139
 					<br />
140 140
 					<em><?php p($l->t('For password reset and notifications')); ?></em>
141 141
 				<?php } ?>
142 142
 				<span class="icon-checkmark hidden"/>
143
-				<?php if($_['lookupServerUploadEnabled']) { ?>
143
+				<?php if ($_['lookupServerUploadEnabled']) { ?>
144 144
 					<input type="hidden" id="emailscope" value="<?php p($_['emailScope']) ?>">
145 145
 				<?php } ?>
146 146
 			</form>
147 147
 		</div>
148
-		<?php if($_['lookupServerUploadEnabled']) { ?>
148
+		<?php if ($_['lookupServerUploadEnabled']) { ?>
149 149
 			<div class="personal-settings-setting-box">
150 150
 				<form id="phoneform" class="section">
151 151
 					<h2>
@@ -180,10 +180,10 @@  discard block
 block discarded – undo
180 180
 						<label for="website"><?php p($l->t('Website')); ?></label>
181 181
 						<span class="icon-password"/>
182 182
 					</h2>
183
-					<div class="verify <?php if ($_['website'] === ''  || $_['websiteScope'] !== 'public') p('hidden'); ?>">
183
+					<div class="verify <?php if ($_['website'] === '' || $_['websiteScope'] !== 'public') p('hidden'); ?>">
184 184
 						<img id="verify-website" title="<?php p($_['websiteMessage']); ?>" data-status="<?php p($_['websiteVerification']) ?>" src="
185 185
 				<?php
186
-						switch($_['websiteVerification']) {
186
+						switch ($_['websiteVerification']) {
187 187
 							case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
188 188
 								p(image_path('core', 'actions/verifying.svg'));
189 189
 								break;
@@ -194,13 +194,13 @@  discard block
 block discarded – undo
194 194
 								p(image_path('core', 'actions/verify.svg'));
195 195
 						}
196 196
 						?>"
197
-							<?php if($_['websiteVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['websiteVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
197
+							<?php if ($_['websiteVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['websiteVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
198 198
 						>
199 199
 						<div class="verification-dialog popovermenu bubble menu">
200 200
 							<div class="verification-dialog-content">
201 201
 								<p class="explainVerification"></p>
202 202
 								<p class="verificationCode"></p>
203
-								<p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.'));?></p>
203
+								<p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.')); ?></p>
204 204
 							</div>
205 205
 						</div>
206 206
 					</div>
@@ -217,10 +217,10 @@  discard block
 block discarded – undo
217 217
 						<label for="twitter"><?php p($l->t('Twitter')); ?></label>
218 218
 						<span class="icon-password"/>
219 219
 					</h2>
220
-					<div class="verify <?php if ($_['twitter'] === ''  || $_['twitterScope'] !== 'public') p('hidden'); ?>">
220
+					<div class="verify <?php if ($_['twitter'] === '' || $_['twitterScope'] !== 'public') p('hidden'); ?>">
221 221
 						<img id="verify-twitter" title="<?php p($_['twitterMessage']); ?>" data-status="<?php p($_['twitterVerification']) ?>" src="
222 222
 				<?php
223
-						switch($_['twitterVerification']) {
223
+						switch ($_['twitterVerification']) {
224 224
 							case \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS:
225 225
 								p(image_path('core', 'actions/verifying.svg'));
226 226
 								break;
@@ -231,13 +231,13 @@  discard block
 block discarded – undo
231 231
 								p(image_path('core', 'actions/verify.svg'));
232 232
 						}
233 233
 						?>"
234
-							<?php if($_['twitterVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['twitterVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
234
+							<?php if ($_['twitterVerification'] === \OC\Accounts\AccountManager::VERIFICATION_IN_PROGRESS || $_['twitterVerification'] === \OC\Accounts\AccountManager::NOT_VERIFIED) print_unescaped(' class="verify-action"') ?>
235 235
 						>
236 236
 						<div class="verification-dialog popovermenu bubble menu">
237 237
 							<div class="verification-dialog-content">
238 238
 								<p class="explainVerification"></p>
239 239
 								<p class="verificationCode"></p>
240
-								<p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.'));?></p>
240
+								<p><?php p($l->t('It can take up to 24 hours before the account is displayed as verified.')); ?></p>
241 241
 							</div>
242 242
 						</div>
243 243
 					</div>
@@ -262,19 +262,19 @@  discard block
 block discarded – undo
262 262
 </div>
263 263
 
264 264
 <?php
265
-if($_['passwordChangeSupported']) {
265
+if ($_['passwordChangeSupported']) {
266 266
 	script('jquery-showpassword');
267 267
 	?>
268 268
 	<form id="passwordform" class="section">
269
-		<h2 class="inlineblock"><?php p($l->t('Password'));?></h2>
269
+		<h2 class="inlineblock"><?php p($l->t('Password')); ?></h2>
270 270
 		<div id="password-error-msg" class="msg success inlineblock" style="display: none;">Saved</div>
271 271
 		<br>
272 272
 		<label for="pass1" class="hidden-visually"><?php p($l->t('Current password')); ?>: </label>
273 273
 		<input type="password" id="pass1" name="oldpassword"
274
-			   placeholder="<?php p($l->t('Current password'));?>"
274
+			   placeholder="<?php p($l->t('Current password')); ?>"
275 275
 			   autocomplete="off" autocapitalize="none" autocorrect="off" />
276 276
 		<div class="personal-show-container">
277
-			<label for="pass2" class="hidden-visually"><?php p($l->t('New password'));?>: </label>
277
+			<label for="pass2" class="hidden-visually"><?php p($l->t('New password')); ?>: </label>
278 278
 			<input type="password" id="pass2" name="newpassword"
279 279
 				   placeholder="<?php p($l->t('New password')); ?>"
280 280
 				   data-typetoggle="#personal-show"
@@ -291,53 +291,53 @@  discard block
 block discarded – undo
291 291
 <?php if (isset($_['activelanguage'])) { ?>
292 292
 <form id="language" class="section">
293 293
 	<h2>
294
-		<label for="languageinput"><?php p($l->t('Language'));?></label>
294
+		<label for="languageinput"><?php p($l->t('Language')); ?></label>
295 295
 	</h2>
296
-	<select id="languageinput" name="lang" data-placeholder="<?php p($l->t('Language'));?>">
297
-		<option value="<?php p($_['activelanguage']['code']);?>">
298
-			<?php p($_['activelanguage']['name']);?>
296
+	<select id="languageinput" name="lang" data-placeholder="<?php p($l->t('Language')); ?>">
297
+		<option value="<?php p($_['activelanguage']['code']); ?>">
298
+			<?php p($_['activelanguage']['name']); ?>
299 299
 		</option>
300
-		<?php foreach($_['commonlanguages'] as $language):?>
301
-			<option value="<?php p($language['code']);?>">
302
-				<?php p($language['name']);?>
300
+		<?php foreach ($_['commonlanguages'] as $language):?>
301
+			<option value="<?php p($language['code']); ?>">
302
+				<?php p($language['name']); ?>
303 303
 			</option>
304
-		<?php endforeach;?>
304
+		<?php endforeach; ?>
305 305
 		<optgroup label="––––––––––"></optgroup>
306
-		<?php foreach($_['languages'] as $language):?>
307
-			<option value="<?php p($language['code']);?>">
308
-				<?php p($language['name']);?>
306
+		<?php foreach ($_['languages'] as $language):?>
307
+			<option value="<?php p($language['code']); ?>">
308
+				<?php p($language['name']); ?>
309 309
 			</option>
310
-		<?php endforeach;?>
310
+		<?php endforeach; ?>
311 311
 	</select>
312 312
 	<a href="https://www.transifex.com/nextcloud/nextcloud/"
313 313
 	   target="_blank" rel="noreferrer">
314
-		<em><?php p($l->t('Help translate'));?></em>
314
+		<em><?php p($l->t('Help translate')); ?></em>
315 315
 	</a>
316 316
 </form>
317 317
 <?php } ?>
318 318
 
319 319
 <form id="locale" class="section">
320 320
 	<h2>
321
-		<label for="localeinput"><?php p($l->t('Locale'));?></label>
321
+		<label for="localeinput"><?php p($l->t('Locale')); ?></label>
322 322
 	</h2>
323
-	<select id="localeinput" name="lang" data-placeholder="<?php p($l->t('Locale'));?>">
324
-		<option value="<?php p($_['activelocale']['code']);?>">
325
-			<?php p($_['activelocale']['name']);?>
323
+	<select id="localeinput" name="lang" data-placeholder="<?php p($l->t('Locale')); ?>">
324
+		<option value="<?php p($_['activelocale']['code']); ?>">
325
+			<?php p($_['activelocale']['name']); ?>
326 326
 		</option>
327 327
 		<optgroup label="––––––––––"></optgroup>
328
-		<?php foreach($_['localesforlanguage'] as $locale):?>
329
-			<option value="<?php p($locale['code']);?>">
330
-				<?php p($locale['name']);?>
328
+		<?php foreach ($_['localesforlanguage'] as $locale):?>
329
+			<option value="<?php p($locale['code']); ?>">
330
+				<?php p($locale['name']); ?>
331 331
 			</option>
332
-		<?php endforeach;?>
332
+		<?php endforeach; ?>
333 333
 		<optgroup label="––––––––––"></optgroup>
334
-		<option value="<?php p($_['activelocale']['code']);?>">
335
-			<?php p($_['activelocale']['name']);?>
334
+		<option value="<?php p($_['activelocale']['code']); ?>">
335
+			<?php p($_['activelocale']['name']); ?>
336 336
 		</option>
337
-		<?php foreach($_['locales'] as $locale):?>
338
-			<option value="<?php p($locale['code']);?>">
339
-				<?php p($locale['name']);?>
337
+		<?php foreach ($_['locales'] as $locale):?>
338
+			<option value="<?php p($locale['code']); ?>">
339
+				<?php p($locale['name']); ?>
340 340
 			</option>
341
-		<?php endforeach;?>
341
+		<?php endforeach; ?>
342 342
 	</select>
343 343
 </form>
344 344
\ No newline at end of file
Please login to merge, or discard this patch.