Completed
Push — master ( 1801e4...143145 )
by Morris
19:04 queued 02:13
created
core/Controller/WhatsNewController.php 2 patches
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -38,89 +38,89 @@
 block discarded – undo
38 38
 
39 39
 class WhatsNewController extends OCSController {
40 40
 
41
-	/** @var IConfig */
42
-	protected $config;
43
-	/** @var IUserSession */
44
-	private $userSession;
45
-	/** @var ChangesCheck */
46
-	private $whatsNewService;
47
-	/** @var IFactory */
48
-	private $langFactory;
49
-	/** @var Defaults */
50
-	private $defaults;
41
+    /** @var IConfig */
42
+    protected $config;
43
+    /** @var IUserSession */
44
+    private $userSession;
45
+    /** @var ChangesCheck */
46
+    private $whatsNewService;
47
+    /** @var IFactory */
48
+    private $langFactory;
49
+    /** @var Defaults */
50
+    private $defaults;
51 51
 
52
-	public function __construct(
53
-		string $appName,
54
-		IRequest $request,
55
-		CapabilitiesManager $capabilitiesManager,
56
-		IUserSession $userSession,
57
-		IUserManager $userManager,
58
-		Manager $keyManager,
59
-		IConfig $config,
60
-		ChangesCheck $whatsNewService,
61
-		IFactory $langFactory,
62
-		Defaults $defaults
63
-	) {
64
-		parent::__construct($appName, $request, $capabilitiesManager, $userSession, $userManager, $keyManager);
65
-		$this->config = $config;
66
-		$this->userSession = $userSession;
67
-		$this->whatsNewService = $whatsNewService;
68
-		$this->langFactory = $langFactory;
69
-		$this->defaults = $defaults;
70
-	}
52
+    public function __construct(
53
+        string $appName,
54
+        IRequest $request,
55
+        CapabilitiesManager $capabilitiesManager,
56
+        IUserSession $userSession,
57
+        IUserManager $userManager,
58
+        Manager $keyManager,
59
+        IConfig $config,
60
+        ChangesCheck $whatsNewService,
61
+        IFactory $langFactory,
62
+        Defaults $defaults
63
+    ) {
64
+        parent::__construct($appName, $request, $capabilitiesManager, $userSession, $userManager, $keyManager);
65
+        $this->config = $config;
66
+        $this->userSession = $userSession;
67
+        $this->whatsNewService = $whatsNewService;
68
+        $this->langFactory = $langFactory;
69
+        $this->defaults = $defaults;
70
+    }
71 71
 
72
-	/**
73
-	 * @NoAdminRequired
74
-	 */
75
-	public function get():DataResponse {
76
-		$user = $this->userSession->getUser();
77
-		if($user === null) {
78
-			throw new \RuntimeException("Acting user cannot be resolved");
79
-		}
80
-		$lastRead = $this->config->getUserValue($user->getUID(), 'core', 'whatsNewLastRead', 0);
81
-		$currentVersion = $this->whatsNewService->normalizeVersion($this->config->getSystemValue('version'));
72
+    /**
73
+     * @NoAdminRequired
74
+     */
75
+    public function get():DataResponse {
76
+        $user = $this->userSession->getUser();
77
+        if($user === null) {
78
+            throw new \RuntimeException("Acting user cannot be resolved");
79
+        }
80
+        $lastRead = $this->config->getUserValue($user->getUID(), 'core', 'whatsNewLastRead', 0);
81
+        $currentVersion = $this->whatsNewService->normalizeVersion($this->config->getSystemValue('version'));
82 82
 
83
-		if(version_compare($lastRead, $currentVersion, '>=')) {
84
-			return new DataResponse([], Http::STATUS_NO_CONTENT);
85
-		}
83
+        if(version_compare($lastRead, $currentVersion, '>=')) {
84
+            return new DataResponse([], Http::STATUS_NO_CONTENT);
85
+        }
86 86
 
87
-		try {
88
-			$iterator = $this->langFactory->getLanguageIterator();
89
-			$whatsNew = $this->whatsNewService->getChangesForVersion($currentVersion);
90
-			$resultData = [
91
-				'changelogURL' => $whatsNew['changelogURL'],
92
-				'product' => $this->defaults->getName(),
93
-				'version' => $currentVersion,
94
-			];
95
-			do {
96
-				$lang = $iterator->current();
97
-				if(isset($whatsNew['whatsNew'][$lang])) {
98
-					$resultData['whatsNew'] = $whatsNew['whatsNew'][$lang];
99
-					break;
100
-				}
101
-				$iterator->next();
102
-			} while ($lang !== 'en' && $iterator->valid());
103
-			return new DataResponse($resultData);
104
-		} catch (DoesNotExistException $e) {
105
-			return new DataResponse([], Http::STATUS_NO_CONTENT);
106
-		}
107
-	}
87
+        try {
88
+            $iterator = $this->langFactory->getLanguageIterator();
89
+            $whatsNew = $this->whatsNewService->getChangesForVersion($currentVersion);
90
+            $resultData = [
91
+                'changelogURL' => $whatsNew['changelogURL'],
92
+                'product' => $this->defaults->getName(),
93
+                'version' => $currentVersion,
94
+            ];
95
+            do {
96
+                $lang = $iterator->current();
97
+                if(isset($whatsNew['whatsNew'][$lang])) {
98
+                    $resultData['whatsNew'] = $whatsNew['whatsNew'][$lang];
99
+                    break;
100
+                }
101
+                $iterator->next();
102
+            } while ($lang !== 'en' && $iterator->valid());
103
+            return new DataResponse($resultData);
104
+        } catch (DoesNotExistException $e) {
105
+            return new DataResponse([], Http::STATUS_NO_CONTENT);
106
+        }
107
+    }
108 108
 
109
-	/**
110
-	 * @NoAdminRequired
111
-	 *
112
-	 * @throws \OCP\PreConditionNotMetException
113
-	 * @throws DoesNotExistException
114
-	 */
115
-	public function dismiss(string $version):DataResponse {
116
-		$user = $this->userSession->getUser();
117
-		if($user === null) {
118
-			throw new \RuntimeException("Acting user cannot be resolved");
119
-		}
120
-		$version = $this->whatsNewService->normalizeVersion($version);
121
-		// checks whether it's a valid version, throws an Exception otherwise
122
-		$this->whatsNewService->getChangesForVersion($version);
123
-		$this->config->setUserValue($user->getUID(), 'core', 'whatsNewLastRead', $version);
124
-		return new DataResponse();
125
-	}
109
+    /**
110
+     * @NoAdminRequired
111
+     *
112
+     * @throws \OCP\PreConditionNotMetException
113
+     * @throws DoesNotExistException
114
+     */
115
+    public function dismiss(string $version):DataResponse {
116
+        $user = $this->userSession->getUser();
117
+        if($user === null) {
118
+            throw new \RuntimeException("Acting user cannot be resolved");
119
+        }
120
+        $version = $this->whatsNewService->normalizeVersion($version);
121
+        // checks whether it's a valid version, throws an Exception otherwise
122
+        $this->whatsNewService->getChangesForVersion($version);
123
+        $this->config->setUserValue($user->getUID(), 'core', 'whatsNewLastRead', $version);
124
+        return new DataResponse();
125
+    }
126 126
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -74,13 +74,13 @@  discard block
 block discarded – undo
74 74
 	 */
75 75
 	public function get():DataResponse {
76 76
 		$user = $this->userSession->getUser();
77
-		if($user === null) {
77
+		if ($user === null) {
78 78
 			throw new \RuntimeException("Acting user cannot be resolved");
79 79
 		}
80 80
 		$lastRead = $this->config->getUserValue($user->getUID(), 'core', 'whatsNewLastRead', 0);
81 81
 		$currentVersion = $this->whatsNewService->normalizeVersion($this->config->getSystemValue('version'));
82 82
 
83
-		if(version_compare($lastRead, $currentVersion, '>=')) {
83
+		if (version_compare($lastRead, $currentVersion, '>=')) {
84 84
 			return new DataResponse([], Http::STATUS_NO_CONTENT);
85 85
 		}
86 86
 
@@ -94,7 +94,7 @@  discard block
 block discarded – undo
94 94
 			];
95 95
 			do {
96 96
 				$lang = $iterator->current();
97
-				if(isset($whatsNew['whatsNew'][$lang])) {
97
+				if (isset($whatsNew['whatsNew'][$lang])) {
98 98
 					$resultData['whatsNew'] = $whatsNew['whatsNew'][$lang];
99 99
 					break;
100 100
 				}
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
 	 */
115 115
 	public function dismiss(string $version):DataResponse {
116 116
 		$user = $this->userSession->getUser();
117
-		if($user === null) {
117
+		if ($user === null) {
118 118
 			throw new \RuntimeException("Acting user cannot be resolved");
119 119
 		}
120 120
 		$version = $this->whatsNewService->normalizeVersion($version);
Please login to merge, or discard this patch.
core/routes.php 1 patch
Indentation   +94 added lines, -94 removed lines patch added patch discarded remove patch
@@ -36,49 +36,49 @@  discard block
 block discarded – undo
36 36
 
37 37
 $application = new Application();
38 38
 $application->registerRoutes($this, [
39
-	'routes' => [
40
-		['name' => 'lost#email', 'url' => '/lostpassword/email', 'verb' => 'POST'],
41
-		['name' => 'lost#resetform', 'url' => '/lostpassword/reset/form/{token}/{userId}', 'verb' => 'GET'],
42
-		['name' => 'lost#setPassword', 'url' => '/lostpassword/set/{token}/{userId}', 'verb' => 'POST'],
43
-		['name' => 'user#getDisplayNames', 'url' => '/displaynames', 'verb' => 'POST'],
44
-		['name' => 'avatar#getAvatar', 'url' => '/avatar/{userId}/{size}', 'verb' => 'GET'],
45
-		['name' => 'avatar#deleteAvatar', 'url' => '/avatar/', 'verb' => 'DELETE'],
46
-		['name' => 'avatar#postCroppedAvatar', 'url' => '/avatar/cropped', 'verb' => 'POST'],
47
-		['name' => 'avatar#getTmpAvatar', 'url' => '/avatar/tmp', 'verb' => 'GET'],
48
-		['name' => 'avatar#postAvatar', 'url' => '/avatar/', 'verb' => 'POST'],
49
-		['name' => 'CSRFToken#index', 'url' => '/csrftoken', 'verb' => 'GET'],
50
-		['name' => 'login#tryLogin', 'url' => '/login', 'verb' => 'POST'],
51
-		['name' => 'login#confirmPassword', 'url' => '/login/confirm', 'verb' => 'POST'],
52
-		['name' => 'login#showLoginForm', 'url' => '/login', 'verb' => 'GET'],
53
-		['name' => 'login#logout', 'url' => '/logout', 'verb' => 'GET'],
54
-		['name' => 'ClientFlowLogin#showAuthPickerPage', 'url' => '/login/flow', 'verb' => 'GET'],
55
-		['name' => 'ClientFlowLogin#redirectPage', 'url' => '/login/flow/redirect', 'verb' => 'GET'],
56
-		['name' => 'ClientFlowLogin#generateAppPassword', 'url' => '/login/flow', 'verb' => 'POST'],
57
-		['name' => 'ClientFlowLogin#grantPage', 'url' => '/login/flow/grant', 'verb' => 'GET'],
58
-		['name' => 'TwoFactorChallenge#selectChallenge', 'url' => '/login/selectchallenge', 'verb' => 'GET'],
59
-		['name' => 'TwoFactorChallenge#showChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'GET'],
60
-		['name' => 'TwoFactorChallenge#solveChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'POST'],
61
-		['name' => 'OCJS#getConfig', 'url' => '/core/js/oc.js', 'verb' => 'GET'],
62
-		['name' => 'Preview#getPreviewByFileId', 'url' => '/core/preview', 'verb' => 'GET'],
63
-		['name' => 'Preview#getPreview', 'url' => '/core/preview.png', 'verb' => 'GET'],
64
-		['name' => 'Css#getCss', 'url' => '/css/{appName}/{fileName}', 'verb' => 'GET'],
65
-		['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'],
66
-		['name' => 'contactsMenu#index', 'url' => '/contactsmenu/contacts', 'verb' => 'POST'],
67
-		['name' => 'contactsMenu#findOne', 'url' => '/contactsmenu/findOne', 'verb' => 'POST'],
68
-		['name' => 'WalledGarden#get', 'url' => '/204', 'verb' => 'GET'],
69
-		['name' => 'Search#search', 'url' => '/core/search', 'verb' => 'GET'],
70
-	],
71
-	'ocs' => [
72
-		['root' => '/cloud', 'name' => 'OCS#getCapabilities', 'url' => '/capabilities', 'verb' => 'GET'],
73
-		['root' => '', 'name' => 'OCS#getConfig', 'url' => '/config', 'verb' => 'GET'],
74
-		['root' => '/person', 'name' => 'OCS#personCheck', 'url' => '/check', 'verb' => 'POST'],
75
-		['root' => '/identityproof', 'name' => 'OCS#getIdentityProof', 'url' => '/key/{cloudId}', 'verb' => 'GET'],
76
-		['root' => '/core', 'name' => 'Navigation#getAppsNavigation', 'url' => '/navigation/apps', 'verb' => 'GET'],
77
-		['root' => '/core', 'name' => 'Navigation#getSettingsNavigation', 'url' => '/navigation/settings', 'verb' => 'GET'],
78
-		['root' => '/core', 'name' => 'AutoComplete#get', 'url' => '/autocomplete/get', 'verb' => 'GET'],
79
-		['root' => '/core', 'name' => 'WhatsNew#get', 'url' => '/whatsnew', 'verb' => 'GET'],
80
-		['root' => '/core', 'name' => 'WhatsNew#dismiss', 'url' => '/whatsnew', 'verb' => 'POST'],
81
-	],
39
+    'routes' => [
40
+        ['name' => 'lost#email', 'url' => '/lostpassword/email', 'verb' => 'POST'],
41
+        ['name' => 'lost#resetform', 'url' => '/lostpassword/reset/form/{token}/{userId}', 'verb' => 'GET'],
42
+        ['name' => 'lost#setPassword', 'url' => '/lostpassword/set/{token}/{userId}', 'verb' => 'POST'],
43
+        ['name' => 'user#getDisplayNames', 'url' => '/displaynames', 'verb' => 'POST'],
44
+        ['name' => 'avatar#getAvatar', 'url' => '/avatar/{userId}/{size}', 'verb' => 'GET'],
45
+        ['name' => 'avatar#deleteAvatar', 'url' => '/avatar/', 'verb' => 'DELETE'],
46
+        ['name' => 'avatar#postCroppedAvatar', 'url' => '/avatar/cropped', 'verb' => 'POST'],
47
+        ['name' => 'avatar#getTmpAvatar', 'url' => '/avatar/tmp', 'verb' => 'GET'],
48
+        ['name' => 'avatar#postAvatar', 'url' => '/avatar/', 'verb' => 'POST'],
49
+        ['name' => 'CSRFToken#index', 'url' => '/csrftoken', 'verb' => 'GET'],
50
+        ['name' => 'login#tryLogin', 'url' => '/login', 'verb' => 'POST'],
51
+        ['name' => 'login#confirmPassword', 'url' => '/login/confirm', 'verb' => 'POST'],
52
+        ['name' => 'login#showLoginForm', 'url' => '/login', 'verb' => 'GET'],
53
+        ['name' => 'login#logout', 'url' => '/logout', 'verb' => 'GET'],
54
+        ['name' => 'ClientFlowLogin#showAuthPickerPage', 'url' => '/login/flow', 'verb' => 'GET'],
55
+        ['name' => 'ClientFlowLogin#redirectPage', 'url' => '/login/flow/redirect', 'verb' => 'GET'],
56
+        ['name' => 'ClientFlowLogin#generateAppPassword', 'url' => '/login/flow', 'verb' => 'POST'],
57
+        ['name' => 'ClientFlowLogin#grantPage', 'url' => '/login/flow/grant', 'verb' => 'GET'],
58
+        ['name' => 'TwoFactorChallenge#selectChallenge', 'url' => '/login/selectchallenge', 'verb' => 'GET'],
59
+        ['name' => 'TwoFactorChallenge#showChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'GET'],
60
+        ['name' => 'TwoFactorChallenge#solveChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'POST'],
61
+        ['name' => 'OCJS#getConfig', 'url' => '/core/js/oc.js', 'verb' => 'GET'],
62
+        ['name' => 'Preview#getPreviewByFileId', 'url' => '/core/preview', 'verb' => 'GET'],
63
+        ['name' => 'Preview#getPreview', 'url' => '/core/preview.png', 'verb' => 'GET'],
64
+        ['name' => 'Css#getCss', 'url' => '/css/{appName}/{fileName}', 'verb' => 'GET'],
65
+        ['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'],
66
+        ['name' => 'contactsMenu#index', 'url' => '/contactsmenu/contacts', 'verb' => 'POST'],
67
+        ['name' => 'contactsMenu#findOne', 'url' => '/contactsmenu/findOne', 'verb' => 'POST'],
68
+        ['name' => 'WalledGarden#get', 'url' => '/204', 'verb' => 'GET'],
69
+        ['name' => 'Search#search', 'url' => '/core/search', 'verb' => 'GET'],
70
+    ],
71
+    'ocs' => [
72
+        ['root' => '/cloud', 'name' => 'OCS#getCapabilities', 'url' => '/capabilities', 'verb' => 'GET'],
73
+        ['root' => '', 'name' => 'OCS#getConfig', 'url' => '/config', 'verb' => 'GET'],
74
+        ['root' => '/person', 'name' => 'OCS#personCheck', 'url' => '/check', 'verb' => 'POST'],
75
+        ['root' => '/identityproof', 'name' => 'OCS#getIdentityProof', 'url' => '/key/{cloudId}', 'verb' => 'GET'],
76
+        ['root' => '/core', 'name' => 'Navigation#getAppsNavigation', 'url' => '/navigation/apps', 'verb' => 'GET'],
77
+        ['root' => '/core', 'name' => 'Navigation#getSettingsNavigation', 'url' => '/navigation/settings', 'verb' => 'GET'],
78
+        ['root' => '/core', 'name' => 'AutoComplete#get', 'url' => '/autocomplete/get', 'verb' => 'GET'],
79
+        ['root' => '/core', 'name' => 'WhatsNew#get', 'url' => '/whatsnew', 'verb' => 'GET'],
80
+        ['root' => '/core', 'name' => 'WhatsNew#dismiss', 'url' => '/whatsnew', 'verb' => 'POST'],
81
+    ],
82 82
 ]);
83 83
 
84 84
 // Post installation check
@@ -87,12 +87,12 @@  discard block
 block discarded – undo
87 87
 // Core ajax actions
88 88
 // Routing
89 89
 $this->create('core_ajax_update', '/core/ajax/update.php')
90
-	->actionInclude('core/ajax/update.php');
90
+    ->actionInclude('core/ajax/update.php');
91 91
 
92 92
 // File routes
93 93
 $this->create('files.viewcontroller.showFile', '/f/{fileid}')->action(function($urlParams) {
94
-	$app = new \OCA\Files\AppInfo\Application($urlParams);
95
-	$app->dispatch('ViewController', 'index');
94
+    $app = new \OCA\Files\AppInfo\Application($urlParams);
95
+    $app->dispatch('ViewController', 'index');
96 96
 });
97 97
 
98 98
 // Call routes
@@ -101,12 +101,12 @@  discard block
 block discarded – undo
101 101
  * @suppress PhanUndeclaredClassMethod
102 102
  */
103 103
 $this->create('spreed.pagecontroller.showCall', '/call/{token}')->action(function($urlParams) {
104
-	if (class_exists(\OCA\Spreed\AppInfo\Application::class, false)) {
105
-		$app = new \OCA\Spreed\AppInfo\Application($urlParams);
106
-		$app->dispatch('PageController', 'index');
107
-	} else {
108
-		throw new \OC\HintException('App spreed is not enabled');
109
-	}
104
+    if (class_exists(\OCA\Spreed\AppInfo\Application::class, false)) {
105
+        $app = new \OCA\Spreed\AppInfo\Application($urlParams);
106
+        $app->dispatch('PageController', 'index');
107
+    } else {
108
+        throw new \OC\HintException('App spreed is not enabled');
109
+    }
110 110
 });
111 111
 
112 112
 // OCM routes
@@ -115,12 +115,12 @@  discard block
 block discarded – undo
115 115
  * @suppress PhanUndeclaredClassMethod
116 116
  */
117 117
 $this->create('cloud_federation_api.requesthandlercontroller.addShare', '/ocm/shares')->post()->action(function($urlParams) {
118
-	if (class_exists(\OCA\CloudFederationAPI\AppInfo\Application::class, false)) {
119
-		$app = new \OCA\CloudFederationAPI\AppInfo\Application($urlParams);
120
-		$app->dispatch('RequestHandlerController', 'addShare');
121
-	} else {
122
-		throw new \OC\HintException('Cloud Federation API not enabled');
123
-	}
118
+    if (class_exists(\OCA\CloudFederationAPI\AppInfo\Application::class, false)) {
119
+        $app = new \OCA\CloudFederationAPI\AppInfo\Application($urlParams);
120
+        $app->dispatch('RequestHandlerController', 'addShare');
121
+    } else {
122
+        throw new \OC\HintException('Cloud Federation API not enabled');
123
+    }
124 124
 });
125 125
 
126 126
 /**
@@ -128,53 +128,53 @@  discard block
 block discarded – undo
128 128
  * @suppress PhanUndeclaredClassMethod
129 129
  */
130 130
 $this->create('cloud_federation_api.requesthandlercontroller.receiveNotification', '/ocm/notifications')->post()->action(function($urlParams) {
131
-	if (class_exists(\OCA\CloudFederationAPI\AppInfo\Application::class, false)) {
132
-		$app = new \OCA\CloudFederationAPI\AppInfo\Application($urlParams);
133
-		$app->dispatch('RequestHandlerController', 'receiveNotification');
134
-	} else {
135
-		throw new \OC\HintException('Cloud Federation API not enabled');
136
-	}
131
+    if (class_exists(\OCA\CloudFederationAPI\AppInfo\Application::class, false)) {
132
+        $app = new \OCA\CloudFederationAPI\AppInfo\Application($urlParams);
133
+        $app->dispatch('RequestHandlerController', 'receiveNotification');
134
+    } else {
135
+        throw new \OC\HintException('Cloud Federation API not enabled');
136
+    }
137 137
 });
138 138
 
139 139
 
140 140
 // Sharing routes
141 141
 $this->create('files_sharing.sharecontroller.showShare', '/s/{token}')->action(function($urlParams) {
142
-	if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
143
-		$app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
144
-		$app->dispatch('ShareController', 'showShare');
145
-	} else {
146
-		throw new \OC\HintException('App file sharing is not enabled');
147
-	}
142
+    if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
143
+        $app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
144
+        $app->dispatch('ShareController', 'showShare');
145
+    } else {
146
+        throw new \OC\HintException('App file sharing is not enabled');
147
+    }
148 148
 });
149 149
 $this->create('files_sharing.sharecontroller.authenticate', '/s/{token}/authenticate/{redirect}')->post()->action(function($urlParams) {
150
-	if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
151
-		$app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
152
-		$app->dispatch('ShareController', 'authenticate');
153
-	} else {
154
-		throw new \OC\HintException('App file sharing is not enabled');
155
-	}
150
+    if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
151
+        $app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
152
+        $app->dispatch('ShareController', 'authenticate');
153
+    } else {
154
+        throw new \OC\HintException('App file sharing is not enabled');
155
+    }
156 156
 });
157 157
 $this->create('files_sharing.sharecontroller.showAuthenticate', '/s/{token}/authenticate/{redirect}')->get()->action(function($urlParams) {
158
-	if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
159
-		$app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
160
-		$app->dispatch('ShareController', 'showAuthenticate');
161
-	} else {
162
-		throw new \OC\HintException('App file sharing is not enabled');
163
-	}
158
+    if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
159
+        $app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
160
+        $app->dispatch('ShareController', 'showAuthenticate');
161
+    } else {
162
+        throw new \OC\HintException('App file sharing is not enabled');
163
+    }
164 164
 });
165 165
 $this->create('files_sharing.sharecontroller.downloadShare', '/s/{token}/download')->get()->action(function($urlParams) {
166
-	if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
167
-		$app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
168
-		$app->dispatch('ShareController', 'downloadShare');
169
-	} else {
170
-		throw new \OC\HintException('App file sharing is not enabled');
171
-	}
166
+    if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
167
+        $app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
168
+        $app->dispatch('ShareController', 'downloadShare');
169
+    } else {
170
+        throw new \OC\HintException('App file sharing is not enabled');
171
+    }
172 172
 });
173 173
 $this->create('files_sharing.publicpreview.directLink', '/s/{token}/preview')->get()->action(function($urlParams) {
174
-	if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
175
-		$app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
176
-		$app->dispatch('PublicPreviewController', 'directLink');
177
-	} else {
178
-		throw new \OC\HintException('App file sharing is not enabled');
179
-	}
174
+    if (class_exists(\OCA\Files_Sharing\AppInfo\Application::class, false)) {
175
+        $app = new \OCA\Files_Sharing\AppInfo\Application($urlParams);
176
+        $app->dispatch('PublicPreviewController', 'directLink');
177
+    } else {
178
+        throw new \OC\HintException('App file sharing is not enabled');
179
+    }
180 180
 });
Please login to merge, or discard this patch.
lib/public/L10N/ILanguageIterator.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -44,31 +44,31 @@
 block discarded – undo
44 44
  */
45 45
 interface ILanguageIterator extends \Iterator {
46 46
 
47
-	/**
48
-	 * Return the current element
49
-	 *
50
-	 * @since 14.0.0
51
-	 */
52
-	public function current(): string;
47
+    /**
48
+     * Return the current element
49
+     *
50
+     * @since 14.0.0
51
+     */
52
+    public function current(): string;
53 53
 
54
-	/**
55
-	 * Move forward to next element
56
-	 *
57
-	 * @since 14.0.0
58
-	 */
59
-	public function next();
54
+    /**
55
+     * Move forward to next element
56
+     *
57
+     * @since 14.0.0
58
+     */
59
+    public function next();
60 60
 
61
-	/**
62
-	 * Return the key of the current element
63
-	 *
64
-	 * @since 14.0.0
65
-	 */
66
-	public function key():int;
61
+    /**
62
+     * Return the key of the current element
63
+     *
64
+     * @since 14.0.0
65
+     */
66
+    public function key():int;
67 67
 
68
-	/**
69
-	 * Checks if current position is valid
70
-	 *
71
-	 * @since 14.0.0
72
-	 */
73
-	public function valid():bool;
68
+    /**
69
+     * Checks if current position is valid
70
+     *
71
+     * @since 14.0.0
72
+     */
73
+    public function valid():bool;
74 74
 }
Please login to merge, or discard this patch.
lib/public/L10N/IFactory.php 1 patch
Indentation   +72 added lines, -72 removed lines patch added patch discarded remove patch
@@ -27,84 +27,84 @@
 block discarded – undo
27 27
  * @since 8.2.0
28 28
  */
29 29
 interface IFactory {
30
-	/**
31
-	 * Get a language instance
32
-	 *
33
-	 * @param string $app
34
-	 * @param string|null $lang
35
-	 * @return \OCP\IL10N
36
-	 * @since 8.2.0
37
-	 */
38
-	public function get($app, $lang = null);
30
+    /**
31
+     * Get a language instance
32
+     *
33
+     * @param string $app
34
+     * @param string|null $lang
35
+     * @return \OCP\IL10N
36
+     * @since 8.2.0
37
+     */
38
+    public function get($app, $lang = null);
39 39
 
40
-	/**
41
-	 * Find the best language
42
-	 *
43
-	 * @param string|null $app App id or null for core
44
-	 * @return string language If nothing works it returns 'en'
45
-	 * @since 9.0.0
46
-	 */
47
-	public function findLanguage($app = null);
40
+    /**
41
+     * Find the best language
42
+     *
43
+     * @param string|null $app App id or null for core
44
+     * @return string language If nothing works it returns 'en'
45
+     * @since 9.0.0
46
+     */
47
+    public function findLanguage($app = null);
48 48
 
49
-	/**
50
-	 * @param string|null $lang user language as default locale
51
-	 * @return string locale If nothing works it returns 'en_US'
52
-	 * @since 14.0.0
53
-	 */
54
-	public function findLocale($lang = null);
49
+    /**
50
+     * @param string|null $lang user language as default locale
51
+     * @return string locale If nothing works it returns 'en_US'
52
+     * @since 14.0.0
53
+     */
54
+    public function findLocale($lang = null);
55 55
 
56
-	/**
57
-	 * Find all available languages for an app
58
-	 *
59
-	 * @param string|null $app App id or null for core
60
-	 * @return string[] an array of available languages
61
-	 * @since 9.0.0
62
-	 */
63
-	public function findAvailableLanguages($app = null);
56
+    /**
57
+     * Find all available languages for an app
58
+     *
59
+     * @param string|null $app App id or null for core
60
+     * @return string[] an array of available languages
61
+     * @since 9.0.0
62
+     */
63
+    public function findAvailableLanguages($app = null);
64 64
 
65
-	/**
66
-	 * @return array an array of available
67
-	 * @since 14.0.0
68
-	 */
69
-	public function findAvailableLocales();
65
+    /**
66
+     * @return array an array of available
67
+     * @since 14.0.0
68
+     */
69
+    public function findAvailableLocales();
70 70
 
71
-	/**
72
-	 * @param string|null $app App id or null for core
73
-	 * @param string $lang
74
-	 * @return bool
75
-	 * @since 9.0.0
76
-	 */
77
-	public function languageExists($app, $lang);
71
+    /**
72
+     * @param string|null $app App id or null for core
73
+     * @param string $lang
74
+     * @return bool
75
+     * @since 9.0.0
76
+     */
77
+    public function languageExists($app, $lang);
78 78
 
79
-	/**
80
-	 * @param string $locale
81
-	 * @return bool
82
-	 * @since 14.0.0
83
-	 */
84
-	public function localeExists($locale);
79
+    /**
80
+     * @param string $locale
81
+     * @return bool
82
+     * @since 14.0.0
83
+     */
84
+    public function localeExists($locale);
85 85
 
86
-	/**
87
-	 * Creates a function from the plural string
88
-	 *
89
-	 * @param string $string
90
-	 * @return string Unique function name
91
-	 * @since 14.0.0
92
-	 */
93
-	public function createPluralFunction($string);
86
+    /**
87
+     * Creates a function from the plural string
88
+     *
89
+     * @param string $string
90
+     * @return string Unique function name
91
+     * @since 14.0.0
92
+     */
93
+    public function createPluralFunction($string);
94 94
 
95
-	/**
96
-	 * iterate through language settings (if provided) in this order:
97
-	 * 1. returns the forced language or:
98
-	 * 2. if applicable, the trunk of 1 (e.g. "fu" instead of "fu_BAR"
99
-	 * 3. returns the user language or:
100
-	 * 4. if applicable, the trunk of 3
101
-	 * 5. returns the system default language or:
102
-	 * 6. if applicable, the trunk of 5
103
-	 * 7+∞. returns 'en'
104
-	 *
105
-	 * Hint: in most cases findLanguage() suits you fine
106
-	 *
107
-	 * @since 14.0.0
108
-	 */
109
-	public function getLanguageIterator(IUser $user = null): ILanguageIterator;
95
+    /**
96
+     * iterate through language settings (if provided) in this order:
97
+     * 1. returns the forced language or:
98
+     * 2. if applicable, the trunk of 1 (e.g. "fu" instead of "fu_BAR"
99
+     * 3. returns the user language or:
100
+     * 4. if applicable, the trunk of 3
101
+     * 5. returns the system default language or:
102
+     * 6. if applicable, the trunk of 5
103
+     * 7+∞. returns 'en'
104
+     *
105
+     * Hint: in most cases findLanguage() suits you fine
106
+     *
107
+     * @since 14.0.0
108
+     */
109
+    public function getLanguageIterator(IUser $user = null): ILanguageIterator;
110 110
 }
Please login to merge, or discard this patch.
lib/private/L10N/Factory.php 2 patches
Indentation   +577 added lines, -577 removed lines patch added patch discarded remove patch
@@ -42,581 +42,581 @@
 block discarded – undo
42 42
  */
43 43
 class Factory implements IFactory {
44 44
 
45
-	/** @var string */
46
-	protected $requestLanguage = '';
47
-
48
-	/**
49
-	 * cached instances
50
-	 * @var array Structure: Lang => App => \OCP\IL10N
51
-	 */
52
-	protected $instances = [];
53
-
54
-	/**
55
-	 * @var array Structure: App => string[]
56
-	 */
57
-	protected $availableLanguages = [];
58
-
59
-	/**
60
-	 * @var array
61
-	 */
62
-	protected $availableLocales = [];
63
-
64
-	/**
65
-	 * @var array Structure: string => callable
66
-	 */
67
-	protected $pluralFunctions = [];
68
-
69
-	const COMMON_LANGUAGE_CODES = [
70
-		'en', 'es', 'fr', 'de', 'de_DE', 'ja', 'ar', 'ru', 'nl', 'it',
71
-		'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko'
72
-	];
73
-
74
-	/** @var IConfig */
75
-	protected $config;
76
-
77
-	/** @var IRequest */
78
-	protected $request;
79
-
80
-	/** @var IUserSession */
81
-	protected $userSession;
82
-
83
-	/** @var string */
84
-	protected $serverRoot;
85
-
86
-	/**
87
-	 * @param IConfig $config
88
-	 * @param IRequest $request
89
-	 * @param IUserSession $userSession
90
-	 * @param string $serverRoot
91
-	 */
92
-	public function __construct(IConfig $config,
93
-								IRequest $request,
94
-								IUserSession $userSession,
95
-								$serverRoot) {
96
-		$this->config = $config;
97
-		$this->request = $request;
98
-		$this->userSession = $userSession;
99
-		$this->serverRoot = $serverRoot;
100
-	}
101
-
102
-	/**
103
-	 * Get a language instance
104
-	 *
105
-	 * @param string $app
106
-	 * @param string|null $lang
107
-	 * @param string|null $locale
108
-	 * @return \OCP\IL10N
109
-	 */
110
-	public function get($app, $lang = null, $locale = null) {
111
-		$app = \OC_App::cleanAppId($app);
112
-		if ($lang !== null) {
113
-			$lang = str_replace(array('\0', '/', '\\', '..'), '', (string) $lang);
114
-		}
115
-
116
-		$forceLang = $this->config->getSystemValue('force_language', false);
117
-		if (is_string($forceLang)) {
118
-			$lang = $forceLang;
119
-		}
120
-
121
-		$forceLocale = $this->config->getSystemValue('force_locale', false);
122
-		if (is_string($forceLocale)) {
123
-			$locale = $forceLocale;
124
-		}
125
-
126
-		if ($lang === null || !$this->languageExists($app, $lang)) {
127
-			$lang = $this->findLanguage($app);
128
-		}
129
-
130
-		if ($locale === null || !$this->localeExists($locale)) {
131
-			$locale = $this->findLocale($lang);
132
-		}
133
-
134
-		if (!isset($this->instances[$lang][$app])) {
135
-			$this->instances[$lang][$app] = new L10N(
136
-				$this, $app, $lang, $locale,
137
-				$this->getL10nFilesForApp($app, $lang)
138
-			);
139
-		}
140
-
141
-		return $this->instances[$lang][$app];
142
-	}
143
-
144
-	/**
145
-	 * Find the best language
146
-	 *
147
-	 * @param string|null $app App id or null for core
148
-	 * @return string language If nothing works it returns 'en'
149
-	 */
150
-	public function findLanguage($app = null) {
151
-		$forceLang = $this->config->getSystemValue('force_language', false);
152
-		if (is_string($forceLang)) {
153
-			$this->requestLanguage = $forceLang;
154
-		}
155
-
156
-		if ($this->requestLanguage !== '' && $this->languageExists($app, $this->requestLanguage)) {
157
-			return $this->requestLanguage;
158
-		}
159
-
160
-		/**
161
-		 * At this point Nextcloud might not yet be installed and thus the lookup
162
-		 * in the preferences table might fail. For this reason we need to check
163
-		 * whether the instance has already been installed
164
-		 *
165
-		 * @link https://github.com/owncloud/core/issues/21955
166
-		 */
167
-		if ($this->config->getSystemValue('installed', false)) {
168
-			$userId = !is_null($this->userSession->getUser()) ? $this->userSession->getUser()->getUID() :  null;
169
-			if (!is_null($userId)) {
170
-				$userLang = $this->config->getUserValue($userId, 'core', 'lang', null);
171
-			} else {
172
-				$userLang = null;
173
-			}
174
-		} else {
175
-			$userId = null;
176
-			$userLang = null;
177
-		}
178
-
179
-		if ($userLang) {
180
-			$this->requestLanguage = $userLang;
181
-			if ($this->languageExists($app, $userLang)) {
182
-				return $userLang;
183
-			}
184
-		}
185
-
186
-		try {
187
-			// Try to get the language from the Request
188
-			$lang = $this->getLanguageFromRequest($app);
189
-			if ($userId !== null && $app === null && !$userLang) {
190
-				$this->config->setUserValue($userId, 'core', 'lang', $lang);
191
-			}
192
-			return $lang;
193
-		} catch (LanguageNotFoundException $e) {
194
-			// Finding language from request failed fall back to default language
195
-			$defaultLanguage = $this->config->getSystemValue('default_language', false);
196
-			if ($defaultLanguage !== false && $this->languageExists($app, $defaultLanguage)) {
197
-				return $defaultLanguage;
198
-			}
199
-		}
200
-
201
-		// We could not find any language so fall back to english
202
-		return 'en';
203
-	}
204
-
205
-	/**
206
-	 * find the best locale
207
-	 *
208
-	 * @param string $lang
209
-	 * @return null|string
210
-	 */
211
-	public function findLocale($lang = null) {
212
-		$forceLocale = $this->config->getSystemValue('force_locale', false);
213
-		if (is_string($forceLocale) && $this->localeExists($forceLocale)) {
214
-			return $forceLocale;
215
-		}
216
-
217
-		if ($this->config->getSystemValue('installed', false)) {
218
-			$userId = null !== $this->userSession->getUser() ? $this->userSession->getUser()->getUID() :  null;
219
-			$userLocale = null;
220
-			if (null !== $userId) {
221
-				$userLocale = $this->config->getUserValue($userId, 'core', 'locale', null);
222
-			}
223
-		} else {
224
-			$userId = null;
225
-			$userLocale = null;
226
-		}
227
-
228
-		if ($userLocale && $this->localeExists($userLocale)) {
229
-			return $userLocale;
230
-		}
231
-
232
-		// Default : use system default locale
233
-		$defaultLocale = $this->config->getSystemValue('default_locale', false);
234
-		if ($defaultLocale !== false && $this->localeExists($defaultLocale)) {
235
-			return $defaultLocale;
236
-		}
237
-
238
-		// If no user locale set, use lang as locale
239
-		if (null !== $lang && $this->localeExists($lang)) {
240
-			return $lang;
241
-		}
242
-
243
-		// At last, return USA
244
-		return 'en_US';
245
-	}
246
-
247
-	/**
248
-	 * Find all available languages for an app
249
-	 *
250
-	 * @param string|null $app App id or null for core
251
-	 * @return array an array of available languages
252
-	 */
253
-	public function findAvailableLanguages($app = null) {
254
-		$key = $app;
255
-		if ($key === null) {
256
-			$key = 'null';
257
-		}
258
-
259
-		// also works with null as key
260
-		if (!empty($this->availableLanguages[$key])) {
261
-			return $this->availableLanguages[$key];
262
-		}
263
-
264
-		$available = ['en']; //english is always available
265
-		$dir = $this->findL10nDir($app);
266
-		if (is_dir($dir)) {
267
-			$files = scandir($dir);
268
-			if ($files !== false) {
269
-				foreach ($files as $file) {
270
-					if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') {
271
-						$available[] = substr($file, 0, -5);
272
-					}
273
-				}
274
-			}
275
-		}
276
-
277
-		// merge with translations from theme
278
-		$theme = $this->config->getSystemValue('theme');
279
-		if (!empty($theme)) {
280
-			$themeDir = $this->serverRoot . '/themes/' . $theme . substr($dir, strlen($this->serverRoot));
281
-
282
-			if (is_dir($themeDir)) {
283
-				$files = scandir($themeDir);
284
-				if ($files !== false) {
285
-					foreach ($files as $file) {
286
-						if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') {
287
-							$available[] = substr($file, 0, -5);
288
-						}
289
-					}
290
-				}
291
-			}
292
-		}
293
-
294
-		$this->availableLanguages[$key] = $available;
295
-		return $available;
296
-	}
297
-
298
-	/**
299
-	 * @return array|mixed
300
-	 */
301
-	public function findAvailableLocales() {
302
-		if (!empty($this->availableLocales)) {
303
-			return $this->availableLocales;
304
-		}
305
-
306
-		$localeData = file_get_contents(\OC::$SERVERROOT . '/resources/locales.json');
307
-		$this->availableLocales = \json_decode($localeData, true);
308
-
309
-		return $this->availableLocales;
310
-	}
311
-
312
-	/**
313
-	 * @param string|null $app App id or null for core
314
-	 * @param string $lang
315
-	 * @return bool
316
-	 */
317
-	public function languageExists($app, $lang) {
318
-		if ($lang === 'en') {//english is always available
319
-			return true;
320
-		}
321
-
322
-		$languages = $this->findAvailableLanguages($app);
323
-		return array_search($lang, $languages) !== false;
324
-	}
325
-
326
-	public function getLanguageIterator(IUser $user = null): ILanguageIterator {
327
-		$user = $user ?? $this->userSession->getUser();
328
-		if($user === null) {
329
-			throw new \RuntimeException('Failed to get an IUser instance');
330
-		}
331
-		return new LanguageIterator($user, $this->config);
332
-	}
333
-
334
-	/**
335
-	 * @param string $locale
336
-	 * @return bool
337
-	 */
338
-	public function localeExists($locale) {
339
-		if ($locale === 'en') { //english is always available
340
-			return true;
341
-		}
342
-
343
-		$locales = $this->findAvailableLocales();
344
-		$userLocale = array_filter($locales, function($value) use ($locale) {
345
-			return $locale === $value['code'];
346
-		});
347
-
348
-		return !empty($userLocale);
349
-	}
350
-
351
-	/**
352
-	 * @param string|null $app
353
-	 * @return string
354
-	 * @throws LanguageNotFoundException
355
-	 */
356
-	private function getLanguageFromRequest($app) {
357
-		$header = $this->request->getHeader('ACCEPT_LANGUAGE');
358
-		if ($header !== '') {
359
-			$available = $this->findAvailableLanguages($app);
360
-
361
-			// E.g. make sure that 'de' is before 'de_DE'.
362
-			sort($available);
363
-
364
-			$preferences = preg_split('/,\s*/', strtolower($header));
365
-			foreach ($preferences as $preference) {
366
-				list($preferred_language) = explode(';', $preference);
367
-				$preferred_language = str_replace('-', '_', $preferred_language);
368
-
369
-				foreach ($available as $available_language) {
370
-					if ($preferred_language === strtolower($available_language)) {
371
-						return $this->respectDefaultLanguage($app, $available_language);
372
-					}
373
-				}
374
-
375
-				// Fallback from de_De to de
376
-				foreach ($available as $available_language) {
377
-					if (substr($preferred_language, 0, 2) === $available_language) {
378
-						return $available_language;
379
-					}
380
-				}
381
-			}
382
-		}
383
-
384
-		throw new LanguageNotFoundException();
385
-	}
386
-
387
-	/**
388
-	 * if default language is set to de_DE (formal German) this should be
389
-	 * preferred to 'de' (non-formal German) if possible
390
-	 *
391
-	 * @param string|null $app
392
-	 * @param string $lang
393
-	 * @return string
394
-	 */
395
-	protected function respectDefaultLanguage($app, $lang) {
396
-		$result = $lang;
397
-		$defaultLanguage = $this->config->getSystemValue('default_language', false);
398
-
399
-		// use formal version of german ("Sie" instead of "Du") if the default
400
-		// language is set to 'de_DE' if possible
401
-		if (is_string($defaultLanguage) &&
402
-			strtolower($lang) === 'de' &&
403
-			strtolower($defaultLanguage) === 'de_de' &&
404
-			$this->languageExists($app, 'de_DE')
405
-		) {
406
-			$result = 'de_DE';
407
-		}
408
-
409
-		return $result;
410
-	}
411
-
412
-	/**
413
-	 * Checks if $sub is a subdirectory of $parent
414
-	 *
415
-	 * @param string $sub
416
-	 * @param string $parent
417
-	 * @return bool
418
-	 */
419
-	private function isSubDirectory($sub, $parent) {
420
-		// Check whether $sub contains no ".."
421
-		if (strpos($sub, '..') !== false) {
422
-			return false;
423
-		}
424
-
425
-		// Check whether $sub is a subdirectory of $parent
426
-		if (strpos($sub, $parent) === 0) {
427
-			return true;
428
-		}
429
-
430
-		return false;
431
-	}
432
-
433
-	/**
434
-	 * Get a list of language files that should be loaded
435
-	 *
436
-	 * @param string $app
437
-	 * @param string $lang
438
-	 * @return string[]
439
-	 */
440
-	// FIXME This method is only public, until OC_L10N does not need it anymore,
441
-	// FIXME This is also the reason, why it is not in the public interface
442
-	public function getL10nFilesForApp($app, $lang) {
443
-		$languageFiles = [];
444
-
445
-		$i18nDir = $this->findL10nDir($app);
446
-		$transFile = strip_tags($i18nDir) . strip_tags($lang) . '.json';
447
-
448
-		if (($this->isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
449
-				|| $this->isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
450
-				|| $this->isSubDirectory($transFile, $this->serverRoot . '/settings/l10n/')
451
-				|| $this->isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/')
452
-			)
453
-			&& file_exists($transFile)) {
454
-			// load the translations file
455
-			$languageFiles[] = $transFile;
456
-		}
457
-
458
-		// merge with translations from theme
459
-		$theme = $this->config->getSystemValue('theme');
460
-		if (!empty($theme)) {
461
-			$transFile = $this->serverRoot . '/themes/' . $theme . substr($transFile, strlen($this->serverRoot));
462
-			if (file_exists($transFile)) {
463
-				$languageFiles[] = $transFile;
464
-			}
465
-		}
466
-
467
-		return $languageFiles;
468
-	}
469
-
470
-	/**
471
-	 * find the l10n directory
472
-	 *
473
-	 * @param string $app App id or empty string for core
474
-	 * @return string directory
475
-	 */
476
-	protected function findL10nDir($app = null) {
477
-		if (in_array($app, ['core', 'lib', 'settings'])) {
478
-			if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) {
479
-				return $this->serverRoot . '/' . $app . '/l10n/';
480
-			}
481
-		} else if ($app && \OC_App::getAppPath($app) !== false) {
482
-			// Check if the app is in the app folder
483
-			return \OC_App::getAppPath($app) . '/l10n/';
484
-		}
485
-		return $this->serverRoot . '/core/l10n/';
486
-	}
487
-
488
-
489
-	/**
490
-	 * Creates a function from the plural string
491
-	 *
492
-	 * Parts of the code is copied from Habari:
493
-	 * https://github.com/habari/system/blob/master/classes/locale.php
494
-	 * @param string $string
495
-	 * @return string
496
-	 */
497
-	public function createPluralFunction($string) {
498
-		if (isset($this->pluralFunctions[$string])) {
499
-			return $this->pluralFunctions[$string];
500
-		}
501
-
502
-		if (preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
503
-			// sanitize
504
-			$nplurals = preg_replace( '/[^0-9]/', '', $matches[1] );
505
-			$plural = preg_replace( '#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2] );
506
-
507
-			$body = str_replace(
508
-				array( 'plural', 'n', '$n$plurals', ),
509
-				array( '$plural', '$n', '$nplurals', ),
510
-				'nplurals='. $nplurals . '; plural=' . $plural
511
-			);
512
-
513
-			// add parents
514
-			// important since PHP's ternary evaluates from left to right
515
-			$body .= ';';
516
-			$res = '';
517
-			$p = 0;
518
-			$length = strlen($body);
519
-			for($i = 0; $i < $length; $i++) {
520
-				$ch = $body[$i];
521
-				switch ( $ch ) {
522
-					case '?':
523
-						$res .= ' ? (';
524
-						$p++;
525
-						break;
526
-					case ':':
527
-						$res .= ') : (';
528
-						break;
529
-					case ';':
530
-						$res .= str_repeat( ')', $p ) . ';';
531
-						$p = 0;
532
-						break;
533
-					default:
534
-						$res .= $ch;
535
-				}
536
-			}
537
-
538
-			$body = $res . 'return ($plural>=$nplurals?$nplurals-1:$plural);';
539
-			$function = create_function('$n', $body);
540
-			$this->pluralFunctions[$string] = $function;
541
-			return $function;
542
-		} else {
543
-			// default: one plural form for all cases but n==1 (english)
544
-			$function = create_function(
545
-				'$n',
546
-				'$nplurals=2;$plural=($n==1?0:1);return ($plural>=$nplurals?$nplurals-1:$plural);'
547
-			);
548
-			$this->pluralFunctions[$string] = $function;
549
-			return $function;
550
-		}
551
-	}
552
-
553
-	/**
554
-	 * returns the common language and other languages in an
555
-	 * associative array
556
-	 *
557
-	 * @return array
558
-	 */
559
-	public function getLanguages() {
560
-		$forceLanguage = $this->config->getSystemValue('force_language', false);
561
-		if ($forceLanguage !== false) {
562
-			return [];
563
-		}
564
-
565
-		$languageCodes = $this->findAvailableLanguages();
566
-
567
-		$commonLanguages = [];
568
-		$languages = [];
569
-
570
-		foreach($languageCodes as $lang) {
571
-			$l = $this->get('lib', $lang);
572
-			// TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version
573
-			$potentialName = (string) $l->t('__language_name__');
574
-			if ($l->getLanguageCode() === $lang && $potentialName[0] !== '_') {//first check if the language name is in the translation file
575
-				$ln = array(
576
-					'code' => $lang,
577
-					'name' => $potentialName
578
-				);
579
-			} else if ($lang === 'en') {
580
-				$ln = array(
581
-					'code' => $lang,
582
-					'name' => 'English (US)'
583
-				);
584
-			} else {//fallback to language code
585
-				$ln = array(
586
-					'code' => $lang,
587
-					'name' => $lang
588
-				);
589
-			}
590
-
591
-			// put appropriate languages into appropriate arrays, to print them sorted
592
-			// common languages -> divider -> other languages
593
-			if (in_array($lang, self::COMMON_LANGUAGE_CODES)) {
594
-				$commonLanguages[array_search($lang, self::COMMON_LANGUAGE_CODES)] = $ln;
595
-			} else {
596
-				$languages[] = $ln;
597
-			}
598
-		}
599
-
600
-		ksort($commonLanguages);
601
-
602
-		// sort now by displayed language not the iso-code
603
-		usort( $languages, function ($a, $b) {
604
-			if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) {
605
-				// If a doesn't have a name, but b does, list b before a
606
-				return 1;
607
-			}
608
-			if ($a['code'] !== $a['name'] && $b['code'] === $b['name']) {
609
-				// If a does have a name, but b doesn't, list a before b
610
-				return -1;
611
-			}
612
-			// Otherwise compare the names
613
-			return strcmp($a['name'], $b['name']);
614
-		});
615
-
616
-		return [
617
-			// reset indexes
618
-			'commonlanguages' => array_values($commonLanguages),
619
-			'languages' => $languages
620
-		];
621
-	}
45
+    /** @var string */
46
+    protected $requestLanguage = '';
47
+
48
+    /**
49
+     * cached instances
50
+     * @var array Structure: Lang => App => \OCP\IL10N
51
+     */
52
+    protected $instances = [];
53
+
54
+    /**
55
+     * @var array Structure: App => string[]
56
+     */
57
+    protected $availableLanguages = [];
58
+
59
+    /**
60
+     * @var array
61
+     */
62
+    protected $availableLocales = [];
63
+
64
+    /**
65
+     * @var array Structure: string => callable
66
+     */
67
+    protected $pluralFunctions = [];
68
+
69
+    const COMMON_LANGUAGE_CODES = [
70
+        'en', 'es', 'fr', 'de', 'de_DE', 'ja', 'ar', 'ru', 'nl', 'it',
71
+        'pt_BR', 'pt_PT', 'da', 'fi_FI', 'nb_NO', 'sv', 'tr', 'zh_CN', 'ko'
72
+    ];
73
+
74
+    /** @var IConfig */
75
+    protected $config;
76
+
77
+    /** @var IRequest */
78
+    protected $request;
79
+
80
+    /** @var IUserSession */
81
+    protected $userSession;
82
+
83
+    /** @var string */
84
+    protected $serverRoot;
85
+
86
+    /**
87
+     * @param IConfig $config
88
+     * @param IRequest $request
89
+     * @param IUserSession $userSession
90
+     * @param string $serverRoot
91
+     */
92
+    public function __construct(IConfig $config,
93
+                                IRequest $request,
94
+                                IUserSession $userSession,
95
+                                $serverRoot) {
96
+        $this->config = $config;
97
+        $this->request = $request;
98
+        $this->userSession = $userSession;
99
+        $this->serverRoot = $serverRoot;
100
+    }
101
+
102
+    /**
103
+     * Get a language instance
104
+     *
105
+     * @param string $app
106
+     * @param string|null $lang
107
+     * @param string|null $locale
108
+     * @return \OCP\IL10N
109
+     */
110
+    public function get($app, $lang = null, $locale = null) {
111
+        $app = \OC_App::cleanAppId($app);
112
+        if ($lang !== null) {
113
+            $lang = str_replace(array('\0', '/', '\\', '..'), '', (string) $lang);
114
+        }
115
+
116
+        $forceLang = $this->config->getSystemValue('force_language', false);
117
+        if (is_string($forceLang)) {
118
+            $lang = $forceLang;
119
+        }
120
+
121
+        $forceLocale = $this->config->getSystemValue('force_locale', false);
122
+        if (is_string($forceLocale)) {
123
+            $locale = $forceLocale;
124
+        }
125
+
126
+        if ($lang === null || !$this->languageExists($app, $lang)) {
127
+            $lang = $this->findLanguage($app);
128
+        }
129
+
130
+        if ($locale === null || !$this->localeExists($locale)) {
131
+            $locale = $this->findLocale($lang);
132
+        }
133
+
134
+        if (!isset($this->instances[$lang][$app])) {
135
+            $this->instances[$lang][$app] = new L10N(
136
+                $this, $app, $lang, $locale,
137
+                $this->getL10nFilesForApp($app, $lang)
138
+            );
139
+        }
140
+
141
+        return $this->instances[$lang][$app];
142
+    }
143
+
144
+    /**
145
+     * Find the best language
146
+     *
147
+     * @param string|null $app App id or null for core
148
+     * @return string language If nothing works it returns 'en'
149
+     */
150
+    public function findLanguage($app = null) {
151
+        $forceLang = $this->config->getSystemValue('force_language', false);
152
+        if (is_string($forceLang)) {
153
+            $this->requestLanguage = $forceLang;
154
+        }
155
+
156
+        if ($this->requestLanguage !== '' && $this->languageExists($app, $this->requestLanguage)) {
157
+            return $this->requestLanguage;
158
+        }
159
+
160
+        /**
161
+         * At this point Nextcloud might not yet be installed and thus the lookup
162
+         * in the preferences table might fail. For this reason we need to check
163
+         * whether the instance has already been installed
164
+         *
165
+         * @link https://github.com/owncloud/core/issues/21955
166
+         */
167
+        if ($this->config->getSystemValue('installed', false)) {
168
+            $userId = !is_null($this->userSession->getUser()) ? $this->userSession->getUser()->getUID() :  null;
169
+            if (!is_null($userId)) {
170
+                $userLang = $this->config->getUserValue($userId, 'core', 'lang', null);
171
+            } else {
172
+                $userLang = null;
173
+            }
174
+        } else {
175
+            $userId = null;
176
+            $userLang = null;
177
+        }
178
+
179
+        if ($userLang) {
180
+            $this->requestLanguage = $userLang;
181
+            if ($this->languageExists($app, $userLang)) {
182
+                return $userLang;
183
+            }
184
+        }
185
+
186
+        try {
187
+            // Try to get the language from the Request
188
+            $lang = $this->getLanguageFromRequest($app);
189
+            if ($userId !== null && $app === null && !$userLang) {
190
+                $this->config->setUserValue($userId, 'core', 'lang', $lang);
191
+            }
192
+            return $lang;
193
+        } catch (LanguageNotFoundException $e) {
194
+            // Finding language from request failed fall back to default language
195
+            $defaultLanguage = $this->config->getSystemValue('default_language', false);
196
+            if ($defaultLanguage !== false && $this->languageExists($app, $defaultLanguage)) {
197
+                return $defaultLanguage;
198
+            }
199
+        }
200
+
201
+        // We could not find any language so fall back to english
202
+        return 'en';
203
+    }
204
+
205
+    /**
206
+     * find the best locale
207
+     *
208
+     * @param string $lang
209
+     * @return null|string
210
+     */
211
+    public function findLocale($lang = null) {
212
+        $forceLocale = $this->config->getSystemValue('force_locale', false);
213
+        if (is_string($forceLocale) && $this->localeExists($forceLocale)) {
214
+            return $forceLocale;
215
+        }
216
+
217
+        if ($this->config->getSystemValue('installed', false)) {
218
+            $userId = null !== $this->userSession->getUser() ? $this->userSession->getUser()->getUID() :  null;
219
+            $userLocale = null;
220
+            if (null !== $userId) {
221
+                $userLocale = $this->config->getUserValue($userId, 'core', 'locale', null);
222
+            }
223
+        } else {
224
+            $userId = null;
225
+            $userLocale = null;
226
+        }
227
+
228
+        if ($userLocale && $this->localeExists($userLocale)) {
229
+            return $userLocale;
230
+        }
231
+
232
+        // Default : use system default locale
233
+        $defaultLocale = $this->config->getSystemValue('default_locale', false);
234
+        if ($defaultLocale !== false && $this->localeExists($defaultLocale)) {
235
+            return $defaultLocale;
236
+        }
237
+
238
+        // If no user locale set, use lang as locale
239
+        if (null !== $lang && $this->localeExists($lang)) {
240
+            return $lang;
241
+        }
242
+
243
+        // At last, return USA
244
+        return 'en_US';
245
+    }
246
+
247
+    /**
248
+     * Find all available languages for an app
249
+     *
250
+     * @param string|null $app App id or null for core
251
+     * @return array an array of available languages
252
+     */
253
+    public function findAvailableLanguages($app = null) {
254
+        $key = $app;
255
+        if ($key === null) {
256
+            $key = 'null';
257
+        }
258
+
259
+        // also works with null as key
260
+        if (!empty($this->availableLanguages[$key])) {
261
+            return $this->availableLanguages[$key];
262
+        }
263
+
264
+        $available = ['en']; //english is always available
265
+        $dir = $this->findL10nDir($app);
266
+        if (is_dir($dir)) {
267
+            $files = scandir($dir);
268
+            if ($files !== false) {
269
+                foreach ($files as $file) {
270
+                    if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') {
271
+                        $available[] = substr($file, 0, -5);
272
+                    }
273
+                }
274
+            }
275
+        }
276
+
277
+        // merge with translations from theme
278
+        $theme = $this->config->getSystemValue('theme');
279
+        if (!empty($theme)) {
280
+            $themeDir = $this->serverRoot . '/themes/' . $theme . substr($dir, strlen($this->serverRoot));
281
+
282
+            if (is_dir($themeDir)) {
283
+                $files = scandir($themeDir);
284
+                if ($files !== false) {
285
+                    foreach ($files as $file) {
286
+                        if (substr($file, -5) === '.json' && substr($file, 0, 4) !== 'l10n') {
287
+                            $available[] = substr($file, 0, -5);
288
+                        }
289
+                    }
290
+                }
291
+            }
292
+        }
293
+
294
+        $this->availableLanguages[$key] = $available;
295
+        return $available;
296
+    }
297
+
298
+    /**
299
+     * @return array|mixed
300
+     */
301
+    public function findAvailableLocales() {
302
+        if (!empty($this->availableLocales)) {
303
+            return $this->availableLocales;
304
+        }
305
+
306
+        $localeData = file_get_contents(\OC::$SERVERROOT . '/resources/locales.json');
307
+        $this->availableLocales = \json_decode($localeData, true);
308
+
309
+        return $this->availableLocales;
310
+    }
311
+
312
+    /**
313
+     * @param string|null $app App id or null for core
314
+     * @param string $lang
315
+     * @return bool
316
+     */
317
+    public function languageExists($app, $lang) {
318
+        if ($lang === 'en') {//english is always available
319
+            return true;
320
+        }
321
+
322
+        $languages = $this->findAvailableLanguages($app);
323
+        return array_search($lang, $languages) !== false;
324
+    }
325
+
326
+    public function getLanguageIterator(IUser $user = null): ILanguageIterator {
327
+        $user = $user ?? $this->userSession->getUser();
328
+        if($user === null) {
329
+            throw new \RuntimeException('Failed to get an IUser instance');
330
+        }
331
+        return new LanguageIterator($user, $this->config);
332
+    }
333
+
334
+    /**
335
+     * @param string $locale
336
+     * @return bool
337
+     */
338
+    public function localeExists($locale) {
339
+        if ($locale === 'en') { //english is always available
340
+            return true;
341
+        }
342
+
343
+        $locales = $this->findAvailableLocales();
344
+        $userLocale = array_filter($locales, function($value) use ($locale) {
345
+            return $locale === $value['code'];
346
+        });
347
+
348
+        return !empty($userLocale);
349
+    }
350
+
351
+    /**
352
+     * @param string|null $app
353
+     * @return string
354
+     * @throws LanguageNotFoundException
355
+     */
356
+    private function getLanguageFromRequest($app) {
357
+        $header = $this->request->getHeader('ACCEPT_LANGUAGE');
358
+        if ($header !== '') {
359
+            $available = $this->findAvailableLanguages($app);
360
+
361
+            // E.g. make sure that 'de' is before 'de_DE'.
362
+            sort($available);
363
+
364
+            $preferences = preg_split('/,\s*/', strtolower($header));
365
+            foreach ($preferences as $preference) {
366
+                list($preferred_language) = explode(';', $preference);
367
+                $preferred_language = str_replace('-', '_', $preferred_language);
368
+
369
+                foreach ($available as $available_language) {
370
+                    if ($preferred_language === strtolower($available_language)) {
371
+                        return $this->respectDefaultLanguage($app, $available_language);
372
+                    }
373
+                }
374
+
375
+                // Fallback from de_De to de
376
+                foreach ($available as $available_language) {
377
+                    if (substr($preferred_language, 0, 2) === $available_language) {
378
+                        return $available_language;
379
+                    }
380
+                }
381
+            }
382
+        }
383
+
384
+        throw new LanguageNotFoundException();
385
+    }
386
+
387
+    /**
388
+     * if default language is set to de_DE (formal German) this should be
389
+     * preferred to 'de' (non-formal German) if possible
390
+     *
391
+     * @param string|null $app
392
+     * @param string $lang
393
+     * @return string
394
+     */
395
+    protected function respectDefaultLanguage($app, $lang) {
396
+        $result = $lang;
397
+        $defaultLanguage = $this->config->getSystemValue('default_language', false);
398
+
399
+        // use formal version of german ("Sie" instead of "Du") if the default
400
+        // language is set to 'de_DE' if possible
401
+        if (is_string($defaultLanguage) &&
402
+            strtolower($lang) === 'de' &&
403
+            strtolower($defaultLanguage) === 'de_de' &&
404
+            $this->languageExists($app, 'de_DE')
405
+        ) {
406
+            $result = 'de_DE';
407
+        }
408
+
409
+        return $result;
410
+    }
411
+
412
+    /**
413
+     * Checks if $sub is a subdirectory of $parent
414
+     *
415
+     * @param string $sub
416
+     * @param string $parent
417
+     * @return bool
418
+     */
419
+    private function isSubDirectory($sub, $parent) {
420
+        // Check whether $sub contains no ".."
421
+        if (strpos($sub, '..') !== false) {
422
+            return false;
423
+        }
424
+
425
+        // Check whether $sub is a subdirectory of $parent
426
+        if (strpos($sub, $parent) === 0) {
427
+            return true;
428
+        }
429
+
430
+        return false;
431
+    }
432
+
433
+    /**
434
+     * Get a list of language files that should be loaded
435
+     *
436
+     * @param string $app
437
+     * @param string $lang
438
+     * @return string[]
439
+     */
440
+    // FIXME This method is only public, until OC_L10N does not need it anymore,
441
+    // FIXME This is also the reason, why it is not in the public interface
442
+    public function getL10nFilesForApp($app, $lang) {
443
+        $languageFiles = [];
444
+
445
+        $i18nDir = $this->findL10nDir($app);
446
+        $transFile = strip_tags($i18nDir) . strip_tags($lang) . '.json';
447
+
448
+        if (($this->isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
449
+                || $this->isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
450
+                || $this->isSubDirectory($transFile, $this->serverRoot . '/settings/l10n/')
451
+                || $this->isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/')
452
+            )
453
+            && file_exists($transFile)) {
454
+            // load the translations file
455
+            $languageFiles[] = $transFile;
456
+        }
457
+
458
+        // merge with translations from theme
459
+        $theme = $this->config->getSystemValue('theme');
460
+        if (!empty($theme)) {
461
+            $transFile = $this->serverRoot . '/themes/' . $theme . substr($transFile, strlen($this->serverRoot));
462
+            if (file_exists($transFile)) {
463
+                $languageFiles[] = $transFile;
464
+            }
465
+        }
466
+
467
+        return $languageFiles;
468
+    }
469
+
470
+    /**
471
+     * find the l10n directory
472
+     *
473
+     * @param string $app App id or empty string for core
474
+     * @return string directory
475
+     */
476
+    protected function findL10nDir($app = null) {
477
+        if (in_array($app, ['core', 'lib', 'settings'])) {
478
+            if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) {
479
+                return $this->serverRoot . '/' . $app . '/l10n/';
480
+            }
481
+        } else if ($app && \OC_App::getAppPath($app) !== false) {
482
+            // Check if the app is in the app folder
483
+            return \OC_App::getAppPath($app) . '/l10n/';
484
+        }
485
+        return $this->serverRoot . '/core/l10n/';
486
+    }
487
+
488
+
489
+    /**
490
+     * Creates a function from the plural string
491
+     *
492
+     * Parts of the code is copied from Habari:
493
+     * https://github.com/habari/system/blob/master/classes/locale.php
494
+     * @param string $string
495
+     * @return string
496
+     */
497
+    public function createPluralFunction($string) {
498
+        if (isset($this->pluralFunctions[$string])) {
499
+            return $this->pluralFunctions[$string];
500
+        }
501
+
502
+        if (preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
503
+            // sanitize
504
+            $nplurals = preg_replace( '/[^0-9]/', '', $matches[1] );
505
+            $plural = preg_replace( '#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2] );
506
+
507
+            $body = str_replace(
508
+                array( 'plural', 'n', '$n$plurals', ),
509
+                array( '$plural', '$n', '$nplurals', ),
510
+                'nplurals='. $nplurals . '; plural=' . $plural
511
+            );
512
+
513
+            // add parents
514
+            // important since PHP's ternary evaluates from left to right
515
+            $body .= ';';
516
+            $res = '';
517
+            $p = 0;
518
+            $length = strlen($body);
519
+            for($i = 0; $i < $length; $i++) {
520
+                $ch = $body[$i];
521
+                switch ( $ch ) {
522
+                    case '?':
523
+                        $res .= ' ? (';
524
+                        $p++;
525
+                        break;
526
+                    case ':':
527
+                        $res .= ') : (';
528
+                        break;
529
+                    case ';':
530
+                        $res .= str_repeat( ')', $p ) . ';';
531
+                        $p = 0;
532
+                        break;
533
+                    default:
534
+                        $res .= $ch;
535
+                }
536
+            }
537
+
538
+            $body = $res . 'return ($plural>=$nplurals?$nplurals-1:$plural);';
539
+            $function = create_function('$n', $body);
540
+            $this->pluralFunctions[$string] = $function;
541
+            return $function;
542
+        } else {
543
+            // default: one plural form for all cases but n==1 (english)
544
+            $function = create_function(
545
+                '$n',
546
+                '$nplurals=2;$plural=($n==1?0:1);return ($plural>=$nplurals?$nplurals-1:$plural);'
547
+            );
548
+            $this->pluralFunctions[$string] = $function;
549
+            return $function;
550
+        }
551
+    }
552
+
553
+    /**
554
+     * returns the common language and other languages in an
555
+     * associative array
556
+     *
557
+     * @return array
558
+     */
559
+    public function getLanguages() {
560
+        $forceLanguage = $this->config->getSystemValue('force_language', false);
561
+        if ($forceLanguage !== false) {
562
+            return [];
563
+        }
564
+
565
+        $languageCodes = $this->findAvailableLanguages();
566
+
567
+        $commonLanguages = [];
568
+        $languages = [];
569
+
570
+        foreach($languageCodes as $lang) {
571
+            $l = $this->get('lib', $lang);
572
+            // TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version
573
+            $potentialName = (string) $l->t('__language_name__');
574
+            if ($l->getLanguageCode() === $lang && $potentialName[0] !== '_') {//first check if the language name is in the translation file
575
+                $ln = array(
576
+                    'code' => $lang,
577
+                    'name' => $potentialName
578
+                );
579
+            } else if ($lang === 'en') {
580
+                $ln = array(
581
+                    'code' => $lang,
582
+                    'name' => 'English (US)'
583
+                );
584
+            } else {//fallback to language code
585
+                $ln = array(
586
+                    'code' => $lang,
587
+                    'name' => $lang
588
+                );
589
+            }
590
+
591
+            // put appropriate languages into appropriate arrays, to print them sorted
592
+            // common languages -> divider -> other languages
593
+            if (in_array($lang, self::COMMON_LANGUAGE_CODES)) {
594
+                $commonLanguages[array_search($lang, self::COMMON_LANGUAGE_CODES)] = $ln;
595
+            } else {
596
+                $languages[] = $ln;
597
+            }
598
+        }
599
+
600
+        ksort($commonLanguages);
601
+
602
+        // sort now by displayed language not the iso-code
603
+        usort( $languages, function ($a, $b) {
604
+            if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) {
605
+                // If a doesn't have a name, but b does, list b before a
606
+                return 1;
607
+            }
608
+            if ($a['code'] !== $a['name'] && $b['code'] === $b['name']) {
609
+                // If a does have a name, but b doesn't, list a before b
610
+                return -1;
611
+            }
612
+            // Otherwise compare the names
613
+            return strcmp($a['name'], $b['name']);
614
+        });
615
+
616
+        return [
617
+            // reset indexes
618
+            'commonlanguages' => array_values($commonLanguages),
619
+            'languages' => $languages
620
+        ];
621
+    }
622 622
 }
Please login to merge, or discard this patch.
Spacing   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -165,7 +165,7 @@  discard block
 block discarded – undo
165 165
 		 * @link https://github.com/owncloud/core/issues/21955
166 166
 		 */
167 167
 		if ($this->config->getSystemValue('installed', false)) {
168
-			$userId = !is_null($this->userSession->getUser()) ? $this->userSession->getUser()->getUID() :  null;
168
+			$userId = !is_null($this->userSession->getUser()) ? $this->userSession->getUser()->getUID() : null;
169 169
 			if (!is_null($userId)) {
170 170
 				$userLang = $this->config->getUserValue($userId, 'core', 'lang', null);
171 171
 			} else {
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
 		}
216 216
 
217 217
 		if ($this->config->getSystemValue('installed', false)) {
218
-			$userId = null !== $this->userSession->getUser() ? $this->userSession->getUser()->getUID() :  null;
218
+			$userId = null !== $this->userSession->getUser() ? $this->userSession->getUser()->getUID() : null;
219 219
 			$userLocale = null;
220 220
 			if (null !== $userId) {
221 221
 				$userLocale = $this->config->getUserValue($userId, 'core', 'locale', null);
@@ -277,7 +277,7 @@  discard block
 block discarded – undo
277 277
 		// merge with translations from theme
278 278
 		$theme = $this->config->getSystemValue('theme');
279 279
 		if (!empty($theme)) {
280
-			$themeDir = $this->serverRoot . '/themes/' . $theme . substr($dir, strlen($this->serverRoot));
280
+			$themeDir = $this->serverRoot.'/themes/'.$theme.substr($dir, strlen($this->serverRoot));
281 281
 
282 282
 			if (is_dir($themeDir)) {
283 283
 				$files = scandir($themeDir);
@@ -303,7 +303,7 @@  discard block
 block discarded – undo
303 303
 			return $this->availableLocales;
304 304
 		}
305 305
 
306
-		$localeData = file_get_contents(\OC::$SERVERROOT . '/resources/locales.json');
306
+		$localeData = file_get_contents(\OC::$SERVERROOT.'/resources/locales.json');
307 307
 		$this->availableLocales = \json_decode($localeData, true);
308 308
 
309 309
 		return $this->availableLocales;
@@ -325,7 +325,7 @@  discard block
 block discarded – undo
325 325
 
326 326
 	public function getLanguageIterator(IUser $user = null): ILanguageIterator {
327 327
 		$user = $user ?? $this->userSession->getUser();
328
-		if($user === null) {
328
+		if ($user === null) {
329 329
 			throw new \RuntimeException('Failed to get an IUser instance');
330 330
 		}
331 331
 		return new LanguageIterator($user, $this->config);
@@ -443,12 +443,12 @@  discard block
 block discarded – undo
443 443
 		$languageFiles = [];
444 444
 
445 445
 		$i18nDir = $this->findL10nDir($app);
446
-		$transFile = strip_tags($i18nDir) . strip_tags($lang) . '.json';
446
+		$transFile = strip_tags($i18nDir).strip_tags($lang).'.json';
447 447
 
448
-		if (($this->isSubDirectory($transFile, $this->serverRoot . '/core/l10n/')
449
-				|| $this->isSubDirectory($transFile, $this->serverRoot . '/lib/l10n/')
450
-				|| $this->isSubDirectory($transFile, $this->serverRoot . '/settings/l10n/')
451
-				|| $this->isSubDirectory($transFile, \OC_App::getAppPath($app) . '/l10n/')
448
+		if (($this->isSubDirectory($transFile, $this->serverRoot.'/core/l10n/')
449
+				|| $this->isSubDirectory($transFile, $this->serverRoot.'/lib/l10n/')
450
+				|| $this->isSubDirectory($transFile, $this->serverRoot.'/settings/l10n/')
451
+				|| $this->isSubDirectory($transFile, \OC_App::getAppPath($app).'/l10n/')
452 452
 			)
453 453
 			&& file_exists($transFile)) {
454 454
 			// load the translations file
@@ -458,7 +458,7 @@  discard block
 block discarded – undo
458 458
 		// merge with translations from theme
459 459
 		$theme = $this->config->getSystemValue('theme');
460 460
 		if (!empty($theme)) {
461
-			$transFile = $this->serverRoot . '/themes/' . $theme . substr($transFile, strlen($this->serverRoot));
461
+			$transFile = $this->serverRoot.'/themes/'.$theme.substr($transFile, strlen($this->serverRoot));
462 462
 			if (file_exists($transFile)) {
463 463
 				$languageFiles[] = $transFile;
464 464
 			}
@@ -475,14 +475,14 @@  discard block
 block discarded – undo
475 475
 	 */
476 476
 	protected function findL10nDir($app = null) {
477 477
 		if (in_array($app, ['core', 'lib', 'settings'])) {
478
-			if (file_exists($this->serverRoot . '/' . $app . '/l10n/')) {
479
-				return $this->serverRoot . '/' . $app . '/l10n/';
478
+			if (file_exists($this->serverRoot.'/'.$app.'/l10n/')) {
479
+				return $this->serverRoot.'/'.$app.'/l10n/';
480 480
 			}
481 481
 		} else if ($app && \OC_App::getAppPath($app) !== false) {
482 482
 			// Check if the app is in the app folder
483
-			return \OC_App::getAppPath($app) . '/l10n/';
483
+			return \OC_App::getAppPath($app).'/l10n/';
484 484
 		}
485
-		return $this->serverRoot . '/core/l10n/';
485
+		return $this->serverRoot.'/core/l10n/';
486 486
 	}
487 487
 
488 488
 
@@ -499,15 +499,15 @@  discard block
 block discarded – undo
499 499
 			return $this->pluralFunctions[$string];
500 500
 		}
501 501
 
502
-		if (preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
502
+		if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
503 503
 			// sanitize
504
-			$nplurals = preg_replace( '/[^0-9]/', '', $matches[1] );
505
-			$plural = preg_replace( '#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2] );
504
+			$nplurals = preg_replace('/[^0-9]/', '', $matches[1]);
505
+			$plural = preg_replace('#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2]);
506 506
 
507 507
 			$body = str_replace(
508
-				array( 'plural', 'n', '$n$plurals', ),
509
-				array( '$plural', '$n', '$nplurals', ),
510
-				'nplurals='. $nplurals . '; plural=' . $plural
508
+				array('plural', 'n', '$n$plurals',),
509
+				array('$plural', '$n', '$nplurals',),
510
+				'nplurals='.$nplurals.'; plural='.$plural
511 511
 			);
512 512
 
513 513
 			// add parents
@@ -516,9 +516,9 @@  discard block
 block discarded – undo
516 516
 			$res = '';
517 517
 			$p = 0;
518 518
 			$length = strlen($body);
519
-			for($i = 0; $i < $length; $i++) {
519
+			for ($i = 0; $i < $length; $i++) {
520 520
 				$ch = $body[$i];
521
-				switch ( $ch ) {
521
+				switch ($ch) {
522 522
 					case '?':
523 523
 						$res .= ' ? (';
524 524
 						$p++;
@@ -527,7 +527,7 @@  discard block
 block discarded – undo
527 527
 						$res .= ') : (';
528 528
 						break;
529 529
 					case ';':
530
-						$res .= str_repeat( ')', $p ) . ';';
530
+						$res .= str_repeat(')', $p).';';
531 531
 						$p = 0;
532 532
 						break;
533 533
 					default:
@@ -535,7 +535,7 @@  discard block
 block discarded – undo
535 535
 				}
536 536
 			}
537 537
 
538
-			$body = $res . 'return ($plural>=$nplurals?$nplurals-1:$plural);';
538
+			$body = $res.'return ($plural>=$nplurals?$nplurals-1:$plural);';
539 539
 			$function = create_function('$n', $body);
540 540
 			$this->pluralFunctions[$string] = $function;
541 541
 			return $function;
@@ -567,7 +567,7 @@  discard block
 block discarded – undo
567 567
 		$commonLanguages = [];
568 568
 		$languages = [];
569 569
 
570
-		foreach($languageCodes as $lang) {
570
+		foreach ($languageCodes as $lang) {
571 571
 			$l = $this->get('lib', $lang);
572 572
 			// TRANSLATORS this is the language name for the language switcher in the personal settings and should be the localized version
573 573
 			$potentialName = (string) $l->t('__language_name__');
@@ -600,7 +600,7 @@  discard block
 block discarded – undo
600 600
 		ksort($commonLanguages);
601 601
 
602 602
 		// sort now by displayed language not the iso-code
603
-		usort( $languages, function ($a, $b) {
603
+		usort($languages, function($a, $b) {
604 604
 			if ($a['code'] === $a['name'] && $b['code'] !== $b['name']) {
605 605
 				// If a doesn't have a name, but b does, list b before a
606 606
 				return 1;
Please login to merge, or discard this patch.
lib/private/L10N/LanguageIterator.php 2 patches
Indentation   +98 added lines, -98 removed lines patch added patch discarded remove patch
@@ -29,109 +29,109 @@
 block discarded – undo
29 29
 use OCP\L10N\ILanguageIterator;
30 30
 
31 31
 class LanguageIterator implements ILanguageIterator {
32
-	private $i = 0;
33
-	/** @var IConfig */
34
-	private $config;
35
-	/** @var IUser */
36
-	private $user;
32
+    private $i = 0;
33
+    /** @var IConfig */
34
+    private $config;
35
+    /** @var IUser */
36
+    private $user;
37 37
 
38
-	public function __construct(IUser $user, IConfig $config) {
39
-		$this->config = $config;
40
-		$this->user = $user;
41
-	}
38
+    public function __construct(IUser $user, IConfig $config) {
39
+        $this->config = $config;
40
+        $this->user = $user;
41
+    }
42 42
 
43
-	/**
44
-	 * Rewind the Iterator to the first element
45
-	 */
46
-	public function rewind() {
47
-		$this->i = 0;
48
-	}
43
+    /**
44
+     * Rewind the Iterator to the first element
45
+     */
46
+    public function rewind() {
47
+        $this->i = 0;
48
+    }
49 49
 
50
-	/**
51
-	 * Return the current element
52
-	 *
53
-	 * @since 14.0.0
54
-	 */
55
-	public function current(): string {
56
-		switch($this->i) {
57
-			/** @noinspection PhpMissingBreakStatementInspection */
58
-			case 0:
59
-				$forcedLang = $this->config->getSystemValue('force_language', false);
60
-				if(is_string($forcedLang)) {
61
-					return $forcedLang;
62
-				}
63
-				$this->next();
64
-			/** @noinspection PhpMissingBreakStatementInspection */
65
-			case 1:
66
-				$forcedLang = $this->config->getSystemValue('force_language', false);
67
-				if(is_string($forcedLang)
68
-					&& ($truncated = $this->getTruncatedLanguage($forcedLang)) !== $forcedLang
69
-				) {
70
-					return $truncated;
71
-				}
72
-				$this->next();
73
-			/** @noinspection PhpMissingBreakStatementInspection */
74
-			case 2:
75
-				$userLang = $this->config->getUserValue($this->user->getUID(), 'core', 'lang', null);
76
-				if(is_string($userLang)) {
77
-					return $userLang;
78
-				}
79
-				$this->next();
80
-			/** @noinspection PhpMissingBreakStatementInspection */
81
-			case 3:
82
-				$userLang = $this->config->getUserValue($this->user->getUID(), 'core', 'lang', null);
83
-				if(is_string($userLang)
84
-					&& ($truncated = $this->getTruncatedLanguage($userLang)) !== $userLang
85
-				) {
86
-					return $truncated;
87
-				}
88
-				$this->next();
89
-			case 4:
90
-				return $this->config->getSystemValue('default_language', 'en');
91
-			/** @noinspection PhpMissingBreakStatementInspection */
92
-			case 5:
93
-				$defaultLang = $this->config->getSystemValue('default_language', 'en');
94
-				if(($truncated = $this->getTruncatedLanguage($defaultLang)) !== $defaultLang) {
95
-					return $truncated;
96
-				}
97
-				$this->next();
98
-			default:
99
-				return 'en';
100
-		}
101
-	}
50
+    /**
51
+     * Return the current element
52
+     *
53
+     * @since 14.0.0
54
+     */
55
+    public function current(): string {
56
+        switch($this->i) {
57
+            /** @noinspection PhpMissingBreakStatementInspection */
58
+            case 0:
59
+                $forcedLang = $this->config->getSystemValue('force_language', false);
60
+                if(is_string($forcedLang)) {
61
+                    return $forcedLang;
62
+                }
63
+                $this->next();
64
+            /** @noinspection PhpMissingBreakStatementInspection */
65
+            case 1:
66
+                $forcedLang = $this->config->getSystemValue('force_language', false);
67
+                if(is_string($forcedLang)
68
+                    && ($truncated = $this->getTruncatedLanguage($forcedLang)) !== $forcedLang
69
+                ) {
70
+                    return $truncated;
71
+                }
72
+                $this->next();
73
+            /** @noinspection PhpMissingBreakStatementInspection */
74
+            case 2:
75
+                $userLang = $this->config->getUserValue($this->user->getUID(), 'core', 'lang', null);
76
+                if(is_string($userLang)) {
77
+                    return $userLang;
78
+                }
79
+                $this->next();
80
+            /** @noinspection PhpMissingBreakStatementInspection */
81
+            case 3:
82
+                $userLang = $this->config->getUserValue($this->user->getUID(), 'core', 'lang', null);
83
+                if(is_string($userLang)
84
+                    && ($truncated = $this->getTruncatedLanguage($userLang)) !== $userLang
85
+                ) {
86
+                    return $truncated;
87
+                }
88
+                $this->next();
89
+            case 4:
90
+                return $this->config->getSystemValue('default_language', 'en');
91
+            /** @noinspection PhpMissingBreakStatementInspection */
92
+            case 5:
93
+                $defaultLang = $this->config->getSystemValue('default_language', 'en');
94
+                if(($truncated = $this->getTruncatedLanguage($defaultLang)) !== $defaultLang) {
95
+                    return $truncated;
96
+                }
97
+                $this->next();
98
+            default:
99
+                return 'en';
100
+        }
101
+    }
102 102
 
103
-	/**
104
-	 * Move forward to next element
105
-	 *
106
-	 * @since 14.0.0
107
-	 */
108
-	public function next() {
109
-		++$this->i;
110
-	}
103
+    /**
104
+     * Move forward to next element
105
+     *
106
+     * @since 14.0.0
107
+     */
108
+    public function next() {
109
+        ++$this->i;
110
+    }
111 111
 
112
-	/**
113
-	 * Return the key of the current element
114
-	 *
115
-	 * @since 14.0.0
116
-	 */
117
-	public function key(): int {
118
-		return $this->i;
119
-	}
112
+    /**
113
+     * Return the key of the current element
114
+     *
115
+     * @since 14.0.0
116
+     */
117
+    public function key(): int {
118
+        return $this->i;
119
+    }
120 120
 
121
-	/**
122
-	 * Checks if current position is valid
123
-	 *
124
-	 * @since 14.0.0
125
-	 */
126
-	public function valid(): bool {
127
-		return $this->i <= 6;
128
-	}
121
+    /**
122
+     * Checks if current position is valid
123
+     *
124
+     * @since 14.0.0
125
+     */
126
+    public function valid(): bool {
127
+        return $this->i <= 6;
128
+    }
129 129
 
130
-	protected function getTruncatedLanguage(string $lang):string {
131
-		$pos = strpos($lang, '_');
132
-		if($pos !== false) {
133
-			$lang = substr($lang, 0, $pos);
134
-		}
135
-		return $lang;
136
-	}
130
+    protected function getTruncatedLanguage(string $lang):string {
131
+        $pos = strpos($lang, '_');
132
+        if($pos !== false) {
133
+            $lang = substr($lang, 0, $pos);
134
+        }
135
+        return $lang;
136
+    }
137 137
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -53,18 +53,18 @@  discard block
 block discarded – undo
53 53
 	 * @since 14.0.0
54 54
 	 */
55 55
 	public function current(): string {
56
-		switch($this->i) {
56
+		switch ($this->i) {
57 57
 			/** @noinspection PhpMissingBreakStatementInspection */
58 58
 			case 0:
59 59
 				$forcedLang = $this->config->getSystemValue('force_language', false);
60
-				if(is_string($forcedLang)) {
60
+				if (is_string($forcedLang)) {
61 61
 					return $forcedLang;
62 62
 				}
63 63
 				$this->next();
64 64
 			/** @noinspection PhpMissingBreakStatementInspection */
65 65
 			case 1:
66 66
 				$forcedLang = $this->config->getSystemValue('force_language', false);
67
-				if(is_string($forcedLang)
67
+				if (is_string($forcedLang)
68 68
 					&& ($truncated = $this->getTruncatedLanguage($forcedLang)) !== $forcedLang
69 69
 				) {
70 70
 					return $truncated;
@@ -73,14 +73,14 @@  discard block
 block discarded – undo
73 73
 			/** @noinspection PhpMissingBreakStatementInspection */
74 74
 			case 2:
75 75
 				$userLang = $this->config->getUserValue($this->user->getUID(), 'core', 'lang', null);
76
-				if(is_string($userLang)) {
76
+				if (is_string($userLang)) {
77 77
 					return $userLang;
78 78
 				}
79 79
 				$this->next();
80 80
 			/** @noinspection PhpMissingBreakStatementInspection */
81 81
 			case 3:
82 82
 				$userLang = $this->config->getUserValue($this->user->getUID(), 'core', 'lang', null);
83
-				if(is_string($userLang)
83
+				if (is_string($userLang)
84 84
 					&& ($truncated = $this->getTruncatedLanguage($userLang)) !== $userLang
85 85
 				) {
86 86
 					return $truncated;
@@ -91,7 +91,7 @@  discard block
 block discarded – undo
91 91
 			/** @noinspection PhpMissingBreakStatementInspection */
92 92
 			case 5:
93 93
 				$defaultLang = $this->config->getSystemValue('default_language', 'en');
94
-				if(($truncated = $this->getTruncatedLanguage($defaultLang)) !== $defaultLang) {
94
+				if (($truncated = $this->getTruncatedLanguage($defaultLang)) !== $defaultLang) {
95 95
 					return $truncated;
96 96
 				}
97 97
 				$this->next();
@@ -129,7 +129,7 @@  discard block
 block discarded – undo
129 129
 
130 130
 	protected function getTruncatedLanguage(string $lang):string {
131 131
 		$pos = strpos($lang, '_');
132
-		if($pos !== false) {
132
+		if ($pos !== false) {
133 133
 			$lang = substr($lang, 0, $pos);
134 134
 		}
135 135
 		return $lang;
Please login to merge, or discard this patch.
lib/private/Updater/ChangesCheck.php 2 patches
Indentation   +133 added lines, -133 removed lines patch added patch discarded remove patch
@@ -30,137 +30,137 @@
 block discarded – undo
30 30
 use OCP\ILogger;
31 31
 
32 32
 class ChangesCheck {
33
-	/** @var IClientService */
34
-	protected $clientService;
35
-	/** @var ChangesMapper */
36
-	private $mapper;
37
-	/** @var ILogger */
38
-	private $logger;
39
-
40
-	const RESPONSE_NO_CONTENT = 0;
41
-	const RESPONSE_USE_CACHE = 1;
42
-	const RESPONSE_HAS_CONTENT = 2;
43
-
44
-	public function __construct(IClientService $clientService, ChangesMapper $mapper, ILogger $logger) {
45
-		$this->clientService = $clientService;
46
-		$this->mapper = $mapper;
47
-		$this->logger = $logger;
48
-	}
49
-
50
-	/**
51
-	 * @throws DoesNotExistException
52
-	 */
53
-	public function getChangesForVersion(string $version): array {
54
-		$version = $this->normalizeVersion($version);
55
-		$changesInfo = $this->mapper->getChanges($version);
56
-		return json_decode($changesInfo->getData(), true);
57
-	}
58
-
59
-	/**
60
-	 * @throws \Exception
61
-	 */
62
-	public function check(string $uri, string $version): array {
63
-		try {
64
-			$version = $this->normalizeVersion($version);
65
-			$changesInfo = $this->mapper->getChanges($version);
66
-			if($changesInfo->getLastCheck() + 1800 > time()) {
67
-				return json_decode($changesInfo->getData(), true);
68
-			}
69
-		} catch (DoesNotExistException $e) {
70
-			$changesInfo = new ChangesResult();
71
-		}
72
-
73
-		$response = $this->queryChangesServer($uri, $changesInfo);
74
-
75
-		switch($this->evaluateResponse($response)) {
76
-			case self::RESPONSE_NO_CONTENT:
77
-				return [];
78
-			case self::RESPONSE_USE_CACHE:
79
-				return json_decode($changesInfo->getData(), true);
80
-			case self::RESPONSE_HAS_CONTENT:
81
-			default:
82
-				$data = $this->extractData($response->getBody());
83
-				$changesInfo->setData(json_encode($data));
84
-				$changesInfo->setEtag($response->getHeader('Etag'));
85
-				$this->cacheResult($changesInfo, $version);
86
-
87
-				return $data;
88
-		}
89
-	}
90
-
91
-	protected function evaluateResponse(IResponse $response): int {
92
-		if($response->getStatusCode() === 304) {
93
-			return self::RESPONSE_USE_CACHE;
94
-		} else if($response->getStatusCode() === 404) {
95
-			return self::RESPONSE_NO_CONTENT;
96
-		} else if($response->getStatusCode() === 200) {
97
-			return self::RESPONSE_HAS_CONTENT;
98
-		}
99
-		$this->logger->debug('Unexpected return code {code} from changelog server', [
100
-			'app' => 'core',
101
-			'code' => $response->getStatusCode(),
102
-		]);
103
-		return self::RESPONSE_NO_CONTENT;
104
-	}
105
-
106
-	protected function cacheResult(ChangesResult $entry, string $version) {
107
-		if($entry->getVersion() === $version) {
108
-			$this->mapper->update($entry);
109
-		} else {
110
-			$entry->setVersion($version);
111
-			$this->mapper->insert($entry);
112
-		}
113
-	}
114
-
115
-	/**
116
-	 * @throws \Exception
117
-	 */
118
-	protected function queryChangesServer(string $uri, ChangesResult $entry): IResponse {
119
-		$headers = [];
120
-		if($entry->getEtag() !== '') {
121
-			$headers['If-None-Match'] = [$entry->getEtag()];
122
-		}
123
-
124
-		$entry->setLastCheck(time());
125
-		$client = $this->clientService->newClient();
126
-		return $client->get($uri, [
127
-			'headers' => $headers,
128
-		]);
129
-	}
130
-
131
-	protected function extractData($body):array {
132
-		$data = [];
133
-		if ($body) {
134
-			$loadEntities = libxml_disable_entity_loader(true);
135
-			$xml = @simplexml_load_string($body);
136
-			libxml_disable_entity_loader($loadEntities);
137
-			if ($xml !== false) {
138
-				$data['changelogURL'] = (string)$xml->changelog['href'];
139
-				$data['whatsNew'] = [];
140
-				foreach($xml->whatsNew as $infoSet) {
141
-					$data['whatsNew'][(string)$infoSet['lang']] = [
142
-						'regular' => (array)$infoSet->regular->item,
143
-						'admin' => (array)$infoSet->admin->item,
144
-					];
145
-				}
146
-			} else {
147
-				libxml_clear_errors();
148
-			}
149
-		}
150
-		return $data;
151
-	}
152
-
153
-	/**
154
-	 * returns a x.y.z form of the provided version. Extra numbers will be
155
-	 * omitted, missing ones added as zeros.
156
-	 */
157
-	public function normalizeVersion(string $version): string {
158
-		$versionNumbers = array_slice(explode('.', $version), 0, 3);
159
-		$versionNumbers[0] = $versionNumbers[0] ?: '0'; // deal with empty input
160
-		while(count($versionNumbers) < 3) {
161
-			// changelog server expects x.y.z, pad 0 if it is too short
162
-			$versionNumbers[] = 0;
163
-		}
164
-		return implode('.', $versionNumbers);
165
-	}
33
+    /** @var IClientService */
34
+    protected $clientService;
35
+    /** @var ChangesMapper */
36
+    private $mapper;
37
+    /** @var ILogger */
38
+    private $logger;
39
+
40
+    const RESPONSE_NO_CONTENT = 0;
41
+    const RESPONSE_USE_CACHE = 1;
42
+    const RESPONSE_HAS_CONTENT = 2;
43
+
44
+    public function __construct(IClientService $clientService, ChangesMapper $mapper, ILogger $logger) {
45
+        $this->clientService = $clientService;
46
+        $this->mapper = $mapper;
47
+        $this->logger = $logger;
48
+    }
49
+
50
+    /**
51
+     * @throws DoesNotExistException
52
+     */
53
+    public function getChangesForVersion(string $version): array {
54
+        $version = $this->normalizeVersion($version);
55
+        $changesInfo = $this->mapper->getChanges($version);
56
+        return json_decode($changesInfo->getData(), true);
57
+    }
58
+
59
+    /**
60
+     * @throws \Exception
61
+     */
62
+    public function check(string $uri, string $version): array {
63
+        try {
64
+            $version = $this->normalizeVersion($version);
65
+            $changesInfo = $this->mapper->getChanges($version);
66
+            if($changesInfo->getLastCheck() + 1800 > time()) {
67
+                return json_decode($changesInfo->getData(), true);
68
+            }
69
+        } catch (DoesNotExistException $e) {
70
+            $changesInfo = new ChangesResult();
71
+        }
72
+
73
+        $response = $this->queryChangesServer($uri, $changesInfo);
74
+
75
+        switch($this->evaluateResponse($response)) {
76
+            case self::RESPONSE_NO_CONTENT:
77
+                return [];
78
+            case self::RESPONSE_USE_CACHE:
79
+                return json_decode($changesInfo->getData(), true);
80
+            case self::RESPONSE_HAS_CONTENT:
81
+            default:
82
+                $data = $this->extractData($response->getBody());
83
+                $changesInfo->setData(json_encode($data));
84
+                $changesInfo->setEtag($response->getHeader('Etag'));
85
+                $this->cacheResult($changesInfo, $version);
86
+
87
+                return $data;
88
+        }
89
+    }
90
+
91
+    protected function evaluateResponse(IResponse $response): int {
92
+        if($response->getStatusCode() === 304) {
93
+            return self::RESPONSE_USE_CACHE;
94
+        } else if($response->getStatusCode() === 404) {
95
+            return self::RESPONSE_NO_CONTENT;
96
+        } else if($response->getStatusCode() === 200) {
97
+            return self::RESPONSE_HAS_CONTENT;
98
+        }
99
+        $this->logger->debug('Unexpected return code {code} from changelog server', [
100
+            'app' => 'core',
101
+            'code' => $response->getStatusCode(),
102
+        ]);
103
+        return self::RESPONSE_NO_CONTENT;
104
+    }
105
+
106
+    protected function cacheResult(ChangesResult $entry, string $version) {
107
+        if($entry->getVersion() === $version) {
108
+            $this->mapper->update($entry);
109
+        } else {
110
+            $entry->setVersion($version);
111
+            $this->mapper->insert($entry);
112
+        }
113
+    }
114
+
115
+    /**
116
+     * @throws \Exception
117
+     */
118
+    protected function queryChangesServer(string $uri, ChangesResult $entry): IResponse {
119
+        $headers = [];
120
+        if($entry->getEtag() !== '') {
121
+            $headers['If-None-Match'] = [$entry->getEtag()];
122
+        }
123
+
124
+        $entry->setLastCheck(time());
125
+        $client = $this->clientService->newClient();
126
+        return $client->get($uri, [
127
+            'headers' => $headers,
128
+        ]);
129
+    }
130
+
131
+    protected function extractData($body):array {
132
+        $data = [];
133
+        if ($body) {
134
+            $loadEntities = libxml_disable_entity_loader(true);
135
+            $xml = @simplexml_load_string($body);
136
+            libxml_disable_entity_loader($loadEntities);
137
+            if ($xml !== false) {
138
+                $data['changelogURL'] = (string)$xml->changelog['href'];
139
+                $data['whatsNew'] = [];
140
+                foreach($xml->whatsNew as $infoSet) {
141
+                    $data['whatsNew'][(string)$infoSet['lang']] = [
142
+                        'regular' => (array)$infoSet->regular->item,
143
+                        'admin' => (array)$infoSet->admin->item,
144
+                    ];
145
+                }
146
+            } else {
147
+                libxml_clear_errors();
148
+            }
149
+        }
150
+        return $data;
151
+    }
152
+
153
+    /**
154
+     * returns a x.y.z form of the provided version. Extra numbers will be
155
+     * omitted, missing ones added as zeros.
156
+     */
157
+    public function normalizeVersion(string $version): string {
158
+        $versionNumbers = array_slice(explode('.', $version), 0, 3);
159
+        $versionNumbers[0] = $versionNumbers[0] ?: '0'; // deal with empty input
160
+        while(count($versionNumbers) < 3) {
161
+            // changelog server expects x.y.z, pad 0 if it is too short
162
+            $versionNumbers[] = 0;
163
+        }
164
+        return implode('.', $versionNumbers);
165
+    }
166 166
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -63,7 +63,7 @@  discard block
 block discarded – undo
63 63
 		try {
64 64
 			$version = $this->normalizeVersion($version);
65 65
 			$changesInfo = $this->mapper->getChanges($version);
66
-			if($changesInfo->getLastCheck() + 1800 > time()) {
66
+			if ($changesInfo->getLastCheck() + 1800 > time()) {
67 67
 				return json_decode($changesInfo->getData(), true);
68 68
 			}
69 69
 		} catch (DoesNotExistException $e) {
@@ -72,7 +72,7 @@  discard block
 block discarded – undo
72 72
 
73 73
 		$response = $this->queryChangesServer($uri, $changesInfo);
74 74
 
75
-		switch($this->evaluateResponse($response)) {
75
+		switch ($this->evaluateResponse($response)) {
76 76
 			case self::RESPONSE_NO_CONTENT:
77 77
 				return [];
78 78
 			case self::RESPONSE_USE_CACHE:
@@ -89,11 +89,11 @@  discard block
 block discarded – undo
89 89
 	}
90 90
 
91 91
 	protected function evaluateResponse(IResponse $response): int {
92
-		if($response->getStatusCode() === 304) {
92
+		if ($response->getStatusCode() === 304) {
93 93
 			return self::RESPONSE_USE_CACHE;
94
-		} else if($response->getStatusCode() === 404) {
94
+		} else if ($response->getStatusCode() === 404) {
95 95
 			return self::RESPONSE_NO_CONTENT;
96
-		} else if($response->getStatusCode() === 200) {
96
+		} else if ($response->getStatusCode() === 200) {
97 97
 			return self::RESPONSE_HAS_CONTENT;
98 98
 		}
99 99
 		$this->logger->debug('Unexpected return code {code} from changelog server', [
@@ -104,7 +104,7 @@  discard block
 block discarded – undo
104 104
 	}
105 105
 
106 106
 	protected function cacheResult(ChangesResult $entry, string $version) {
107
-		if($entry->getVersion() === $version) {
107
+		if ($entry->getVersion() === $version) {
108 108
 			$this->mapper->update($entry);
109 109
 		} else {
110 110
 			$entry->setVersion($version);
@@ -117,7 +117,7 @@  discard block
 block discarded – undo
117 117
 	 */
118 118
 	protected function queryChangesServer(string $uri, ChangesResult $entry): IResponse {
119 119
 		$headers = [];
120
-		if($entry->getEtag() !== '') {
120
+		if ($entry->getEtag() !== '') {
121 121
 			$headers['If-None-Match'] = [$entry->getEtag()];
122 122
 		}
123 123
 
@@ -135,12 +135,12 @@  discard block
 block discarded – undo
135 135
 			$xml = @simplexml_load_string($body);
136 136
 			libxml_disable_entity_loader($loadEntities);
137 137
 			if ($xml !== false) {
138
-				$data['changelogURL'] = (string)$xml->changelog['href'];
138
+				$data['changelogURL'] = (string) $xml->changelog['href'];
139 139
 				$data['whatsNew'] = [];
140
-				foreach($xml->whatsNew as $infoSet) {
141
-					$data['whatsNew'][(string)$infoSet['lang']] = [
142
-						'regular' => (array)$infoSet->regular->item,
143
-						'admin' => (array)$infoSet->admin->item,
140
+				foreach ($xml->whatsNew as $infoSet) {
141
+					$data['whatsNew'][(string) $infoSet['lang']] = [
142
+						'regular' => (array) $infoSet->regular->item,
143
+						'admin' => (array) $infoSet->admin->item,
144 144
 					];
145 145
 				}
146 146
 			} else {
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
 	public function normalizeVersion(string $version): string {
158 158
 		$versionNumbers = array_slice(explode('.', $version), 0, 3);
159 159
 		$versionNumbers[0] = $versionNumbers[0] ?: '0'; // deal with empty input
160
-		while(count($versionNumbers) < 3) {
160
+		while (count($versionNumbers) < 3) {
161 161
 			// changelog server expects x.y.z, pad 0 if it is too short
162 162
 			$versionNumbers[] = 0;
163 163
 		}
Please login to merge, or discard this patch.
apps/updatenotification/lib/Settings/Admin.php 2 patches
Indentation   +134 added lines, -134 removed lines patch added patch discarded remove patch
@@ -37,138 +37,138 @@
 block discarded – undo
37 37
 use OCP\Util;
38 38
 
39 39
 class Admin implements ISettings {
40
-	/** @var IConfig */
41
-	private $config;
42
-	/** @var UpdateChecker */
43
-	private $updateChecker;
44
-	/** @var IGroupManager */
45
-	private $groupManager;
46
-	/** @var IDateTimeFormatter */
47
-	private $dateTimeFormatter;
48
-	/** @var IUserSession */
49
-	private $session;
50
-	/** @var IFactory */
51
-	private $l10nFactory;
52
-
53
-	public function __construct(
54
-		IConfig $config,
55
-		UpdateChecker $updateChecker,
56
-		IGroupManager $groupManager,
57
-		IDateTimeFormatter $dateTimeFormatter,
58
-		IUserSession $session,
59
-		IFactory $l10nFactory
60
-	) {
61
-		$this->config = $config;
62
-		$this->updateChecker = $updateChecker;
63
-		$this->groupManager = $groupManager;
64
-		$this->dateTimeFormatter = $dateTimeFormatter;
65
-		$this->session = $session;
66
-		$this->l10nFactory = $l10nFactory;
67
-	}
68
-
69
-	/**
70
-	 * @return TemplateResponse
71
-	 */
72
-	public function getForm(): TemplateResponse {
73
-		$lastUpdateCheckTimestamp = $this->config->getAppValue('core', 'lastupdatedat');
74
-		$lastUpdateCheck = $this->dateTimeFormatter->formatDateTime($lastUpdateCheckTimestamp);
75
-
76
-		$channels = [
77
-			'daily',
78
-			'beta',
79
-			'stable',
80
-			'production',
81
-		];
82
-		$currentChannel = Util::getChannel();
83
-		if ($currentChannel === 'git') {
84
-			$channels[] = 'git';
85
-		}
86
-
87
-		$updateState = $this->updateChecker->getUpdateState();
88
-
89
-		$notifyGroups = json_decode($this->config->getAppValue('updatenotification', 'notify_groups', '["admin"]'), true);
90
-
91
-		$defaultUpdateServerURL = 'https://updates.nextcloud.com/updater_server/';
92
-		$updateServerURL = $this->config->getSystemValue('updater.server.url', $defaultUpdateServerURL);
93
-
94
-		$params = [
95
-			'isNewVersionAvailable' => !empty($updateState['updateAvailable']),
96
-			'isUpdateChecked' => $lastUpdateCheckTimestamp > 0,
97
-			'lastChecked' => $lastUpdateCheck,
98
-			'currentChannel' => $currentChannel,
99
-			'channels' => $channels,
100
-			'newVersionString' => empty($updateState['updateVersion']) ? '' : $updateState['updateVersion'],
101
-			'downloadLink' => empty($updateState['downloadLink']) ? '' : $updateState['downloadLink'],
102
-			'changes' => $this->filterChanges($updateState['changes'] ?? []),
103
-			'updaterEnabled' => empty($updateState['updaterEnabled']) ? false : $updateState['updaterEnabled'],
104
-			'versionIsEol' => empty($updateState['versionIsEol']) ? false : $updateState['versionIsEol'],
105
-			'isDefaultUpdateServerURL' => $updateServerURL === $defaultUpdateServerURL,
106
-			'updateServerURL' => $updateServerURL,
107
-			'notifyGroups' => $this->getSelectedGroups($notifyGroups),
108
-		];
109
-
110
-		$params = [
111
-			'json' => json_encode($params),
112
-		];
113
-
114
-		return new TemplateResponse('updatenotification', 'admin', $params, '');
115
-	}
116
-
117
-	protected function filterChanges(array $changes) {
118
-		$filtered = [];
119
-		if(isset($changes['changelogURL'])) {
120
-			$filtered['changelogURL'] = $changes['changelogURL'];
121
-		}
122
-		if(!isset($changes['whatsNew'])) {
123
-			return $filtered;
124
-		}
125
-
126
-		$iterator = $this->l10nFactory->getLanguageIterator();
127
-		do {
128
-			$lang = $iterator->current();
129
-			if(isset($changes['whatsNew'][$lang])) {
130
-				return $filtered['whatsNew'][$lang];
131
-			}
132
-			$iterator->next();
133
-		} while($lang !== 'en' && $iterator->valid());
134
-
135
-		return $filtered;
136
-	}
137
-
138
-	/**
139
-	 * @param array $groupIds
140
-	 * @return array
141
-	 */
142
-	protected function getSelectedGroups(array $groupIds): array {
143
-		$result = [];
144
-		foreach ($groupIds as $groupId) {
145
-			$group = $this->groupManager->get($groupId);
146
-
147
-			if ($group === null) {
148
-				continue;
149
-			}
150
-
151
-			$result[] = ['value' => $group->getGID(), 'label' => $group->getDisplayName()];
152
-		}
153
-
154
-		return $result;
155
-	}
156
-
157
-	/**
158
-	 * @return string the section ID, e.g. 'sharing'
159
-	 */
160
-	public function getSection(): string {
161
-		return 'overview';
162
-	}
163
-
164
-	/**
165
-	 * @return int whether the form should be rather on the top or bottom of
166
-	 * the admin section. The forms are arranged in ascending order of the
167
-	 * priority values. It is required to return a value between 0 and 100.
168
-	 *
169
-	 * E.g.: 70
170
-	 */
171
-	public function getPriority(): int {
172
-		return 11;
173
-	}
40
+    /** @var IConfig */
41
+    private $config;
42
+    /** @var UpdateChecker */
43
+    private $updateChecker;
44
+    /** @var IGroupManager */
45
+    private $groupManager;
46
+    /** @var IDateTimeFormatter */
47
+    private $dateTimeFormatter;
48
+    /** @var IUserSession */
49
+    private $session;
50
+    /** @var IFactory */
51
+    private $l10nFactory;
52
+
53
+    public function __construct(
54
+        IConfig $config,
55
+        UpdateChecker $updateChecker,
56
+        IGroupManager $groupManager,
57
+        IDateTimeFormatter $dateTimeFormatter,
58
+        IUserSession $session,
59
+        IFactory $l10nFactory
60
+    ) {
61
+        $this->config = $config;
62
+        $this->updateChecker = $updateChecker;
63
+        $this->groupManager = $groupManager;
64
+        $this->dateTimeFormatter = $dateTimeFormatter;
65
+        $this->session = $session;
66
+        $this->l10nFactory = $l10nFactory;
67
+    }
68
+
69
+    /**
70
+     * @return TemplateResponse
71
+     */
72
+    public function getForm(): TemplateResponse {
73
+        $lastUpdateCheckTimestamp = $this->config->getAppValue('core', 'lastupdatedat');
74
+        $lastUpdateCheck = $this->dateTimeFormatter->formatDateTime($lastUpdateCheckTimestamp);
75
+
76
+        $channels = [
77
+            'daily',
78
+            'beta',
79
+            'stable',
80
+            'production',
81
+        ];
82
+        $currentChannel = Util::getChannel();
83
+        if ($currentChannel === 'git') {
84
+            $channels[] = 'git';
85
+        }
86
+
87
+        $updateState = $this->updateChecker->getUpdateState();
88
+
89
+        $notifyGroups = json_decode($this->config->getAppValue('updatenotification', 'notify_groups', '["admin"]'), true);
90
+
91
+        $defaultUpdateServerURL = 'https://updates.nextcloud.com/updater_server/';
92
+        $updateServerURL = $this->config->getSystemValue('updater.server.url', $defaultUpdateServerURL);
93
+
94
+        $params = [
95
+            'isNewVersionAvailable' => !empty($updateState['updateAvailable']),
96
+            'isUpdateChecked' => $lastUpdateCheckTimestamp > 0,
97
+            'lastChecked' => $lastUpdateCheck,
98
+            'currentChannel' => $currentChannel,
99
+            'channels' => $channels,
100
+            'newVersionString' => empty($updateState['updateVersion']) ? '' : $updateState['updateVersion'],
101
+            'downloadLink' => empty($updateState['downloadLink']) ? '' : $updateState['downloadLink'],
102
+            'changes' => $this->filterChanges($updateState['changes'] ?? []),
103
+            'updaterEnabled' => empty($updateState['updaterEnabled']) ? false : $updateState['updaterEnabled'],
104
+            'versionIsEol' => empty($updateState['versionIsEol']) ? false : $updateState['versionIsEol'],
105
+            'isDefaultUpdateServerURL' => $updateServerURL === $defaultUpdateServerURL,
106
+            'updateServerURL' => $updateServerURL,
107
+            'notifyGroups' => $this->getSelectedGroups($notifyGroups),
108
+        ];
109
+
110
+        $params = [
111
+            'json' => json_encode($params),
112
+        ];
113
+
114
+        return new TemplateResponse('updatenotification', 'admin', $params, '');
115
+    }
116
+
117
+    protected function filterChanges(array $changes) {
118
+        $filtered = [];
119
+        if(isset($changes['changelogURL'])) {
120
+            $filtered['changelogURL'] = $changes['changelogURL'];
121
+        }
122
+        if(!isset($changes['whatsNew'])) {
123
+            return $filtered;
124
+        }
125
+
126
+        $iterator = $this->l10nFactory->getLanguageIterator();
127
+        do {
128
+            $lang = $iterator->current();
129
+            if(isset($changes['whatsNew'][$lang])) {
130
+                return $filtered['whatsNew'][$lang];
131
+            }
132
+            $iterator->next();
133
+        } while($lang !== 'en' && $iterator->valid());
134
+
135
+        return $filtered;
136
+    }
137
+
138
+    /**
139
+     * @param array $groupIds
140
+     * @return array
141
+     */
142
+    protected function getSelectedGroups(array $groupIds): array {
143
+        $result = [];
144
+        foreach ($groupIds as $groupId) {
145
+            $group = $this->groupManager->get($groupId);
146
+
147
+            if ($group === null) {
148
+                continue;
149
+            }
150
+
151
+            $result[] = ['value' => $group->getGID(), 'label' => $group->getDisplayName()];
152
+        }
153
+
154
+        return $result;
155
+    }
156
+
157
+    /**
158
+     * @return string the section ID, e.g. 'sharing'
159
+     */
160
+    public function getSection(): string {
161
+        return 'overview';
162
+    }
163
+
164
+    /**
165
+     * @return int whether the form should be rather on the top or bottom of
166
+     * the admin section. The forms are arranged in ascending order of the
167
+     * priority values. It is required to return a value between 0 and 100.
168
+     *
169
+     * E.g.: 70
170
+     */
171
+    public function getPriority(): int {
172
+        return 11;
173
+    }
174 174
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -116,21 +116,21 @@
 block discarded – undo
116 116
 
117 117
 	protected function filterChanges(array $changes) {
118 118
 		$filtered = [];
119
-		if(isset($changes['changelogURL'])) {
119
+		if (isset($changes['changelogURL'])) {
120 120
 			$filtered['changelogURL'] = $changes['changelogURL'];
121 121
 		}
122
-		if(!isset($changes['whatsNew'])) {
122
+		if (!isset($changes['whatsNew'])) {
123 123
 			return $filtered;
124 124
 		}
125 125
 
126 126
 		$iterator = $this->l10nFactory->getLanguageIterator();
127 127
 		do {
128 128
 			$lang = $iterator->current();
129
-			if(isset($changes['whatsNew'][$lang])) {
129
+			if (isset($changes['whatsNew'][$lang])) {
130 130
 				return $filtered['whatsNew'][$lang];
131 131
 			}
132 132
 			$iterator->next();
133
-		} while($lang !== 'en' && $iterator->valid());
133
+		} while ($lang !== 'en' && $iterator->valid());
134 134
 
135 135
 		return $filtered;
136 136
 	}
Please login to merge, or discard this patch.