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