Passed
Push — master ( c9639f...ec07ca )
by Morris
24:32 queued 11:33
created
lib/private/App/Platform.php 1 patch
Indentation   +56 added lines, -56 removed lines patch added patch discarded remove patch
@@ -36,69 +36,69 @@
 block discarded – undo
36 36
  */
37 37
 class Platform {
38 38
 
39
-	/**
40
-	 * @param IConfig $config
41
-	 */
42
-	public function __construct(IConfig $config) {
43
-		$this->config = $config;
44
-	}
39
+    /**
40
+     * @param IConfig $config
41
+     */
42
+    public function __construct(IConfig $config) {
43
+        $this->config = $config;
44
+    }
45 45
 
46
-	/**
47
-	 * @return string
48
-	 */
49
-	public function getPhpVersion() {
50
-		return phpversion();
51
-	}
46
+    /**
47
+     * @return string
48
+     */
49
+    public function getPhpVersion() {
50
+        return phpversion();
51
+    }
52 52
 
53
-	/**
54
-	 * @return int
55
-	 */
56
-	public function getIntSize() {
57
-		return PHP_INT_SIZE;
58
-	}
53
+    /**
54
+     * @return int
55
+     */
56
+    public function getIntSize() {
57
+        return PHP_INT_SIZE;
58
+    }
59 59
 
60
-	/**
61
-	 * @return string
62
-	 */
63
-	public function getOcVersion() {
64
-		$v = \OCP\Util::getVersion();
65
-		return implode('.', $v);
66
-	}
60
+    /**
61
+     * @return string
62
+     */
63
+    public function getOcVersion() {
64
+        $v = \OCP\Util::getVersion();
65
+        return implode('.', $v);
66
+    }
67 67
 
68
-	/**
69
-	 * @return string
70
-	 */
71
-	public function getDatabase() {
72
-		$dbType = $this->config->getSystemValue('dbtype', 'sqlite');
73
-		if ($dbType === 'sqlite3') {
74
-			$dbType = 'sqlite';
75
-		}
68
+    /**
69
+     * @return string
70
+     */
71
+    public function getDatabase() {
72
+        $dbType = $this->config->getSystemValue('dbtype', 'sqlite');
73
+        if ($dbType === 'sqlite3') {
74
+            $dbType = 'sqlite';
75
+        }
76 76
 
77
-		return $dbType;
78
-	}
77
+        return $dbType;
78
+    }
79 79
 
80
-	/**
81
-	 * @return string
82
-	 */
83
-	public function getOS() {
84
-		return php_uname('s');
85
-	}
80
+    /**
81
+     * @return string
82
+     */
83
+    public function getOS() {
84
+        return php_uname('s');
85
+    }
86 86
 
87
-	/**
88
-	 * @param $command
89
-	 * @return bool
90
-	 */
91
-	public function isCommandKnown($command) {
92
-		$path = \OC_Helper::findBinaryPath($command);
93
-		return ($path !== null);
94
-	}
87
+    /**
88
+     * @param $command
89
+     * @return bool
90
+     */
91
+    public function isCommandKnown($command) {
92
+        $path = \OC_Helper::findBinaryPath($command);
93
+        return ($path !== null);
94
+    }
95 95
 
96
-	public function getLibraryVersion($name) {
97
-		$repo = new PlatformRepository();
98
-		return $repo->findLibrary($name);
99
-	}
96
+    public function getLibraryVersion($name) {
97
+        $repo = new PlatformRepository();
98
+        return $repo->findLibrary($name);
99
+    }
100 100
 
101
-	public function getArchitecture(): string {
102
-		return php_uname('m');
103
-	}
101
+    public function getArchitecture(): string {
102
+        return php_uname('m');
103
+    }
104 104
 }
Please login to merge, or discard this patch.
lib/private/App/DependencyAnalyzer.php 2 patches
Indentation   +367 added lines, -367 removed lines patch added patch discarded remove patch
@@ -35,371 +35,371 @@
 block discarded – undo
35 35
 
36 36
 class DependencyAnalyzer {
37 37
 
38
-	/** @var Platform */
39
-	private $platform;
40
-	/** @var \OCP\IL10N */
41
-	private $l;
42
-	/** @var array */
43
-	private $appInfo;
44
-
45
-	/**
46
-	 * @param Platform $platform
47
-	 * @param \OCP\IL10N $l
48
-	 */
49
-	public function __construct(Platform $platform, IL10N $l) {
50
-		$this->platform = $platform;
51
-		$this->l = $l;
52
-	}
53
-
54
-	/**
55
-	 * @param array $app
56
-	 * @returns array of missing dependencies
57
-	 */
58
-	public function analyze(array $app, bool $ignoreMax = false) {
59
-		$this->appInfo = $app;
60
-		if (isset($app['dependencies'])) {
61
-			$dependencies = $app['dependencies'];
62
-		} else {
63
-			$dependencies = [];
64
-		}
65
-
66
-		return array_merge(
67
-			$this->analyzeArchitecture($dependencies),
68
-			$this->analyzePhpVersion($dependencies),
69
-			$this->analyzeDatabases($dependencies),
70
-			$this->analyzeCommands($dependencies),
71
-			$this->analyzeLibraries($dependencies),
72
-			$this->analyzeOS($dependencies),
73
-			$this->analyzeOC($dependencies, $app, $ignoreMax)
74
-		);
75
-	}
76
-
77
-	public function isMarkedCompatible(array $app): bool {
78
-		if (isset($app['dependencies'])) {
79
-			$dependencies = $app['dependencies'];
80
-		} else {
81
-			$dependencies = [];
82
-		}
83
-
84
-		$maxVersion = $this->getMaxVersion($dependencies, $app);
85
-		if ($maxVersion === null) {
86
-			return true;
87
-		}
88
-		return !$this->compareBigger($this->platform->getOcVersion(), $maxVersion);
89
-	}
90
-
91
-	/**
92
-	 * Truncates both versions to the lowest common version, e.g.
93
-	 * 5.1.2.3 and 5.1 will be turned into 5.1 and 5.1,
94
-	 * 5.2.6.5 and 5.1 will be turned into 5.2 and 5.1
95
-	 * @param string $first
96
-	 * @param string $second
97
-	 * @return string[] first element is the first version, second element is the
98
-	 * second version
99
-	 */
100
-	private function normalizeVersions($first, $second) {
101
-		$first = explode('.', $first);
102
-		$second = explode('.', $second);
103
-
104
-		// get both arrays to the same minimum size
105
-		$length = min(count($second), count($first));
106
-		$first = array_slice($first, 0, $length);
107
-		$second = array_slice($second, 0, $length);
108
-
109
-		return [implode('.', $first), implode('.', $second)];
110
-	}
111
-
112
-	/**
113
-	 * Parameters will be normalized and then passed into version_compare
114
-	 * in the same order they are specified in the method header
115
-	 * @param string $first
116
-	 * @param string $second
117
-	 * @param string $operator
118
-	 * @return bool result similar to version_compare
119
-	 */
120
-	private function compare($first, $second, $operator) {
121
-		// we can't normalize versions if one of the given parameters is not a
122
-		// version string but null. In case one parameter is null normalization
123
-		// will therefore be skipped
124
-		if ($first !== null && $second !== null) {
125
-			list($first, $second) = $this->normalizeVersions($first, $second);
126
-		}
127
-
128
-		return version_compare($first, $second, $operator);
129
-	}
130
-
131
-	/**
132
-	 * Checks if a version is bigger than another version
133
-	 * @param string $first
134
-	 * @param string $second
135
-	 * @return bool true if the first version is bigger than the second
136
-	 */
137
-	private function compareBigger($first, $second) {
138
-		return $this->compare($first, $second, '>');
139
-	}
140
-
141
-	/**
142
-	 * Checks if a version is smaller than another version
143
-	 * @param string $first
144
-	 * @param string $second
145
-	 * @return bool true if the first version is smaller than the second
146
-	 */
147
-	private function compareSmaller($first, $second) {
148
-		return $this->compare($first, $second, '<');
149
-	}
150
-
151
-	/**
152
-	 * @param array $dependencies
153
-	 * @return array
154
-	 */
155
-	private function analyzePhpVersion(array $dependencies) {
156
-		$missing = [];
157
-		if (isset($dependencies['php']['@attributes']['min-version'])) {
158
-			$minVersion = $dependencies['php']['@attributes']['min-version'];
159
-			if ($this->compareSmaller($this->platform->getPhpVersion(), $minVersion)) {
160
-				$missing[] = (string)$this->l->t('PHP %s or higher is required.', [$minVersion]);
161
-			}
162
-		}
163
-		if (isset($dependencies['php']['@attributes']['max-version'])) {
164
-			$maxVersion = $dependencies['php']['@attributes']['max-version'];
165
-			if ($this->compareBigger($this->platform->getPhpVersion(), $maxVersion)) {
166
-				$missing[] = (string)$this->l->t('PHP with a version lower than %s is required.', [$maxVersion]);
167
-			}
168
-		}
169
-		if (isset($dependencies['php']['@attributes']['min-int-size'])) {
170
-			$intSize = $dependencies['php']['@attributes']['min-int-size'];
171
-			if ($intSize > $this->platform->getIntSize()*8) {
172
-				$missing[] = (string)$this->l->t('%sbit or higher PHP required.', [$intSize]);
173
-			}
174
-		}
175
-		return $missing;
176
-	}
177
-
178
-	private function analyzeArchitecture(array $dependencies) {
179
-		$missing = [];
180
-		if (!isset($dependencies['architecture'])) {
181
-			return $missing;
182
-		}
183
-
184
-		$supportedArchitectures = $dependencies['architecture'];
185
-		if (empty($supportedArchitectures)) {
186
-			return $missing;
187
-		}
188
-		if (!is_array($supportedArchitectures)) {
189
-			$supportedArchitectures = [$supportedArchitectures];
190
-		}
191
-		$supportedArchitectures = array_map(function ($architecture) {
192
-			return $this->getValue($architecture);
193
-		}, $supportedArchitectures);
194
-		$currentArchitecture = $this->platform->getArchitecture();
195
-		if (!in_array($currentArchitecture, $supportedArchitectures, true)) {
196
-			$missing[] = (string)$this->l->t('The following architectures are supported: %s', [implode(', ', $supportedArchitectures)]);
197
-		}
198
-		return $missing;
199
-	}
200
-
201
-	/**
202
-	 * @param array $dependencies
203
-	 * @return array
204
-	 */
205
-	private function analyzeDatabases(array $dependencies) {
206
-		$missing = [];
207
-		if (!isset($dependencies['database'])) {
208
-			return $missing;
209
-		}
210
-
211
-		$supportedDatabases = $dependencies['database'];
212
-		if (empty($supportedDatabases)) {
213
-			return $missing;
214
-		}
215
-		if (!is_array($supportedDatabases)) {
216
-			$supportedDatabases = [$supportedDatabases];
217
-		}
218
-		$supportedDatabases = array_map(function ($db) {
219
-			return $this->getValue($db);
220
-		}, $supportedDatabases);
221
-		$currentDatabase = $this->platform->getDatabase();
222
-		if (!in_array($currentDatabase, $supportedDatabases)) {
223
-			$missing[] = (string)$this->l->t('The following databases are supported: %s', [implode(', ', $supportedDatabases)]);
224
-		}
225
-		return $missing;
226
-	}
227
-
228
-	/**
229
-	 * @param array $dependencies
230
-	 * @return array
231
-	 */
232
-	private function analyzeCommands(array $dependencies) {
233
-		$missing = [];
234
-		if (!isset($dependencies['command'])) {
235
-			return $missing;
236
-		}
237
-
238
-		$commands = $dependencies['command'];
239
-		if (!is_array($commands)) {
240
-			$commands = [$commands];
241
-		}
242
-		if (isset($commands['@value'])) {
243
-			$commands = [$commands];
244
-		}
245
-		$os = $this->platform->getOS();
246
-		foreach ($commands as $command) {
247
-			if (isset($command['@attributes']['os']) && $command['@attributes']['os'] !== $os) {
248
-				continue;
249
-			}
250
-			$commandName = $this->getValue($command);
251
-			if (!$this->platform->isCommandKnown($commandName)) {
252
-				$missing[] = (string)$this->l->t('The command line tool %s could not be found', [$commandName]);
253
-			}
254
-		}
255
-		return $missing;
256
-	}
257
-
258
-	/**
259
-	 * @param array $dependencies
260
-	 * @return array
261
-	 */
262
-	private function analyzeLibraries(array $dependencies) {
263
-		$missing = [];
264
-		if (!isset($dependencies['lib'])) {
265
-			return $missing;
266
-		}
267
-
268
-		$libs = $dependencies['lib'];
269
-		if (!is_array($libs)) {
270
-			$libs = [$libs];
271
-		}
272
-		if (isset($libs['@value'])) {
273
-			$libs = [$libs];
274
-		}
275
-		foreach ($libs as $lib) {
276
-			$libName = $this->getValue($lib);
277
-			$libVersion = $this->platform->getLibraryVersion($libName);
278
-			if (is_null($libVersion)) {
279
-				$missing[] = $this->l->t('The library %s is not available.', [$libName]);
280
-				continue;
281
-			}
282
-
283
-			if (is_array($lib)) {
284
-				if (isset($lib['@attributes']['min-version'])) {
285
-					$minVersion = $lib['@attributes']['min-version'];
286
-					if ($this->compareSmaller($libVersion, $minVersion)) {
287
-						$missing[] = $this->l->t('Library %1$s with a version higher than %2$s is required - available version %3$s.',
288
-							[$libName, $minVersion, $libVersion]);
289
-					}
290
-				}
291
-				if (isset($lib['@attributes']['max-version'])) {
292
-					$maxVersion = $lib['@attributes']['max-version'];
293
-					if ($this->compareBigger($libVersion, $maxVersion)) {
294
-						$missing[] = $this->l->t('Library %1$s with a version lower than %2$s is required - available version %3$s.',
295
-							[$libName, $maxVersion, $libVersion]);
296
-					}
297
-				}
298
-			}
299
-		}
300
-		return $missing;
301
-	}
302
-
303
-	/**
304
-	 * @param array $dependencies
305
-	 * @return array
306
-	 */
307
-	private function analyzeOS(array $dependencies) {
308
-		$missing = [];
309
-		if (!isset($dependencies['os'])) {
310
-			return $missing;
311
-		}
312
-
313
-		$oss = $dependencies['os'];
314
-		if (empty($oss)) {
315
-			return $missing;
316
-		}
317
-		if (is_array($oss)) {
318
-			$oss = array_map(function ($os) {
319
-				return $this->getValue($os);
320
-			}, $oss);
321
-		} else {
322
-			$oss = [$oss];
323
-		}
324
-		$currentOS = $this->platform->getOS();
325
-		if (!in_array($currentOS, $oss)) {
326
-			$missing[] = (string)$this->l->t('The following platforms are supported: %s', [implode(', ', $oss)]);
327
-		}
328
-		return $missing;
329
-	}
330
-
331
-	/**
332
-	 * @param array $dependencies
333
-	 * @param array $appInfo
334
-	 * @return array
335
-	 */
336
-	private function analyzeOC(array $dependencies, array $appInfo, bool $ignoreMax) {
337
-		$missing = [];
338
-		$minVersion = null;
339
-		if (isset($dependencies['nextcloud']['@attributes']['min-version'])) {
340
-			$minVersion = $dependencies['nextcloud']['@attributes']['min-version'];
341
-		} elseif (isset($dependencies['owncloud']['@attributes']['min-version'])) {
342
-			$minVersion = $dependencies['owncloud']['@attributes']['min-version'];
343
-		} elseif (isset($appInfo['requiremin'])) {
344
-			$minVersion = $appInfo['requiremin'];
345
-		} elseif (isset($appInfo['require'])) {
346
-			$minVersion = $appInfo['require'];
347
-		}
348
-		$maxVersion = $this->getMaxVersion($dependencies, $appInfo);
349
-
350
-		if (!is_null($minVersion)) {
351
-			if ($this->compareSmaller($this->platform->getOcVersion(), $minVersion)) {
352
-				$missing[] = (string)$this->l->t('Server version %s or higher is required.', [$this->toVisibleVersion($minVersion)]);
353
-			}
354
-		}
355
-		if (!$ignoreMax && !is_null($maxVersion)) {
356
-			if ($this->compareBigger($this->platform->getOcVersion(), $maxVersion)) {
357
-				$missing[] = (string)$this->l->t('Server version %s or lower is required.', [$this->toVisibleVersion($maxVersion)]);
358
-			}
359
-		}
360
-		return $missing;
361
-	}
362
-
363
-	private function getMaxVersion(array $dependencies, array $appInfo): ?string {
364
-		if (isset($dependencies['nextcloud']['@attributes']['max-version'])) {
365
-			return $dependencies['nextcloud']['@attributes']['max-version'];
366
-		}
367
-		if (isset($dependencies['owncloud']['@attributes']['max-version'])) {
368
-			return $dependencies['owncloud']['@attributes']['max-version'];
369
-		}
370
-		if (isset($appInfo['requiremax'])) {
371
-			return $appInfo['requiremax'];
372
-		}
373
-
374
-		return null;
375
-	}
376
-
377
-	/**
378
-	 * Map the internal version number to the Nextcloud version
379
-	 *
380
-	 * @param string $version
381
-	 * @return string
382
-	 */
383
-	protected function toVisibleVersion($version) {
384
-		switch ($version) {
385
-			case '9.1':
386
-				return '10';
387
-			default:
388
-				if (strpos($version, '9.1.') === 0) {
389
-					$version = '10.0.' . substr($version, 4);
390
-				}
391
-				return $version;
392
-		}
393
-	}
394
-
395
-	/**
396
-	 * @param $element
397
-	 * @return mixed
398
-	 */
399
-	private function getValue($element) {
400
-		if (isset($element['@value'])) {
401
-			return $element['@value'];
402
-		}
403
-		return (string)$element;
404
-	}
38
+    /** @var Platform */
39
+    private $platform;
40
+    /** @var \OCP\IL10N */
41
+    private $l;
42
+    /** @var array */
43
+    private $appInfo;
44
+
45
+    /**
46
+     * @param Platform $platform
47
+     * @param \OCP\IL10N $l
48
+     */
49
+    public function __construct(Platform $platform, IL10N $l) {
50
+        $this->platform = $platform;
51
+        $this->l = $l;
52
+    }
53
+
54
+    /**
55
+     * @param array $app
56
+     * @returns array of missing dependencies
57
+     */
58
+    public function analyze(array $app, bool $ignoreMax = false) {
59
+        $this->appInfo = $app;
60
+        if (isset($app['dependencies'])) {
61
+            $dependencies = $app['dependencies'];
62
+        } else {
63
+            $dependencies = [];
64
+        }
65
+
66
+        return array_merge(
67
+            $this->analyzeArchitecture($dependencies),
68
+            $this->analyzePhpVersion($dependencies),
69
+            $this->analyzeDatabases($dependencies),
70
+            $this->analyzeCommands($dependencies),
71
+            $this->analyzeLibraries($dependencies),
72
+            $this->analyzeOS($dependencies),
73
+            $this->analyzeOC($dependencies, $app, $ignoreMax)
74
+        );
75
+    }
76
+
77
+    public function isMarkedCompatible(array $app): bool {
78
+        if (isset($app['dependencies'])) {
79
+            $dependencies = $app['dependencies'];
80
+        } else {
81
+            $dependencies = [];
82
+        }
83
+
84
+        $maxVersion = $this->getMaxVersion($dependencies, $app);
85
+        if ($maxVersion === null) {
86
+            return true;
87
+        }
88
+        return !$this->compareBigger($this->platform->getOcVersion(), $maxVersion);
89
+    }
90
+
91
+    /**
92
+     * Truncates both versions to the lowest common version, e.g.
93
+     * 5.1.2.3 and 5.1 will be turned into 5.1 and 5.1,
94
+     * 5.2.6.5 and 5.1 will be turned into 5.2 and 5.1
95
+     * @param string $first
96
+     * @param string $second
97
+     * @return string[] first element is the first version, second element is the
98
+     * second version
99
+     */
100
+    private function normalizeVersions($first, $second) {
101
+        $first = explode('.', $first);
102
+        $second = explode('.', $second);
103
+
104
+        // get both arrays to the same minimum size
105
+        $length = min(count($second), count($first));
106
+        $first = array_slice($first, 0, $length);
107
+        $second = array_slice($second, 0, $length);
108
+
109
+        return [implode('.', $first), implode('.', $second)];
110
+    }
111
+
112
+    /**
113
+     * Parameters will be normalized and then passed into version_compare
114
+     * in the same order they are specified in the method header
115
+     * @param string $first
116
+     * @param string $second
117
+     * @param string $operator
118
+     * @return bool result similar to version_compare
119
+     */
120
+    private function compare($first, $second, $operator) {
121
+        // we can't normalize versions if one of the given parameters is not a
122
+        // version string but null. In case one parameter is null normalization
123
+        // will therefore be skipped
124
+        if ($first !== null && $second !== null) {
125
+            list($first, $second) = $this->normalizeVersions($first, $second);
126
+        }
127
+
128
+        return version_compare($first, $second, $operator);
129
+    }
130
+
131
+    /**
132
+     * Checks if a version is bigger than another version
133
+     * @param string $first
134
+     * @param string $second
135
+     * @return bool true if the first version is bigger than the second
136
+     */
137
+    private function compareBigger($first, $second) {
138
+        return $this->compare($first, $second, '>');
139
+    }
140
+
141
+    /**
142
+     * Checks if a version is smaller than another version
143
+     * @param string $first
144
+     * @param string $second
145
+     * @return bool true if the first version is smaller than the second
146
+     */
147
+    private function compareSmaller($first, $second) {
148
+        return $this->compare($first, $second, '<');
149
+    }
150
+
151
+    /**
152
+     * @param array $dependencies
153
+     * @return array
154
+     */
155
+    private function analyzePhpVersion(array $dependencies) {
156
+        $missing = [];
157
+        if (isset($dependencies['php']['@attributes']['min-version'])) {
158
+            $minVersion = $dependencies['php']['@attributes']['min-version'];
159
+            if ($this->compareSmaller($this->platform->getPhpVersion(), $minVersion)) {
160
+                $missing[] = (string)$this->l->t('PHP %s or higher is required.', [$minVersion]);
161
+            }
162
+        }
163
+        if (isset($dependencies['php']['@attributes']['max-version'])) {
164
+            $maxVersion = $dependencies['php']['@attributes']['max-version'];
165
+            if ($this->compareBigger($this->platform->getPhpVersion(), $maxVersion)) {
166
+                $missing[] = (string)$this->l->t('PHP with a version lower than %s is required.', [$maxVersion]);
167
+            }
168
+        }
169
+        if (isset($dependencies['php']['@attributes']['min-int-size'])) {
170
+            $intSize = $dependencies['php']['@attributes']['min-int-size'];
171
+            if ($intSize > $this->platform->getIntSize()*8) {
172
+                $missing[] = (string)$this->l->t('%sbit or higher PHP required.', [$intSize]);
173
+            }
174
+        }
175
+        return $missing;
176
+    }
177
+
178
+    private function analyzeArchitecture(array $dependencies) {
179
+        $missing = [];
180
+        if (!isset($dependencies['architecture'])) {
181
+            return $missing;
182
+        }
183
+
184
+        $supportedArchitectures = $dependencies['architecture'];
185
+        if (empty($supportedArchitectures)) {
186
+            return $missing;
187
+        }
188
+        if (!is_array($supportedArchitectures)) {
189
+            $supportedArchitectures = [$supportedArchitectures];
190
+        }
191
+        $supportedArchitectures = array_map(function ($architecture) {
192
+            return $this->getValue($architecture);
193
+        }, $supportedArchitectures);
194
+        $currentArchitecture = $this->platform->getArchitecture();
195
+        if (!in_array($currentArchitecture, $supportedArchitectures, true)) {
196
+            $missing[] = (string)$this->l->t('The following architectures are supported: %s', [implode(', ', $supportedArchitectures)]);
197
+        }
198
+        return $missing;
199
+    }
200
+
201
+    /**
202
+     * @param array $dependencies
203
+     * @return array
204
+     */
205
+    private function analyzeDatabases(array $dependencies) {
206
+        $missing = [];
207
+        if (!isset($dependencies['database'])) {
208
+            return $missing;
209
+        }
210
+
211
+        $supportedDatabases = $dependencies['database'];
212
+        if (empty($supportedDatabases)) {
213
+            return $missing;
214
+        }
215
+        if (!is_array($supportedDatabases)) {
216
+            $supportedDatabases = [$supportedDatabases];
217
+        }
218
+        $supportedDatabases = array_map(function ($db) {
219
+            return $this->getValue($db);
220
+        }, $supportedDatabases);
221
+        $currentDatabase = $this->platform->getDatabase();
222
+        if (!in_array($currentDatabase, $supportedDatabases)) {
223
+            $missing[] = (string)$this->l->t('The following databases are supported: %s', [implode(', ', $supportedDatabases)]);
224
+        }
225
+        return $missing;
226
+    }
227
+
228
+    /**
229
+     * @param array $dependencies
230
+     * @return array
231
+     */
232
+    private function analyzeCommands(array $dependencies) {
233
+        $missing = [];
234
+        if (!isset($dependencies['command'])) {
235
+            return $missing;
236
+        }
237
+
238
+        $commands = $dependencies['command'];
239
+        if (!is_array($commands)) {
240
+            $commands = [$commands];
241
+        }
242
+        if (isset($commands['@value'])) {
243
+            $commands = [$commands];
244
+        }
245
+        $os = $this->platform->getOS();
246
+        foreach ($commands as $command) {
247
+            if (isset($command['@attributes']['os']) && $command['@attributes']['os'] !== $os) {
248
+                continue;
249
+            }
250
+            $commandName = $this->getValue($command);
251
+            if (!$this->platform->isCommandKnown($commandName)) {
252
+                $missing[] = (string)$this->l->t('The command line tool %s could not be found', [$commandName]);
253
+            }
254
+        }
255
+        return $missing;
256
+    }
257
+
258
+    /**
259
+     * @param array $dependencies
260
+     * @return array
261
+     */
262
+    private function analyzeLibraries(array $dependencies) {
263
+        $missing = [];
264
+        if (!isset($dependencies['lib'])) {
265
+            return $missing;
266
+        }
267
+
268
+        $libs = $dependencies['lib'];
269
+        if (!is_array($libs)) {
270
+            $libs = [$libs];
271
+        }
272
+        if (isset($libs['@value'])) {
273
+            $libs = [$libs];
274
+        }
275
+        foreach ($libs as $lib) {
276
+            $libName = $this->getValue($lib);
277
+            $libVersion = $this->platform->getLibraryVersion($libName);
278
+            if (is_null($libVersion)) {
279
+                $missing[] = $this->l->t('The library %s is not available.', [$libName]);
280
+                continue;
281
+            }
282
+
283
+            if (is_array($lib)) {
284
+                if (isset($lib['@attributes']['min-version'])) {
285
+                    $minVersion = $lib['@attributes']['min-version'];
286
+                    if ($this->compareSmaller($libVersion, $minVersion)) {
287
+                        $missing[] = $this->l->t('Library %1$s with a version higher than %2$s is required - available version %3$s.',
288
+                            [$libName, $minVersion, $libVersion]);
289
+                    }
290
+                }
291
+                if (isset($lib['@attributes']['max-version'])) {
292
+                    $maxVersion = $lib['@attributes']['max-version'];
293
+                    if ($this->compareBigger($libVersion, $maxVersion)) {
294
+                        $missing[] = $this->l->t('Library %1$s with a version lower than %2$s is required - available version %3$s.',
295
+                            [$libName, $maxVersion, $libVersion]);
296
+                    }
297
+                }
298
+            }
299
+        }
300
+        return $missing;
301
+    }
302
+
303
+    /**
304
+     * @param array $dependencies
305
+     * @return array
306
+     */
307
+    private function analyzeOS(array $dependencies) {
308
+        $missing = [];
309
+        if (!isset($dependencies['os'])) {
310
+            return $missing;
311
+        }
312
+
313
+        $oss = $dependencies['os'];
314
+        if (empty($oss)) {
315
+            return $missing;
316
+        }
317
+        if (is_array($oss)) {
318
+            $oss = array_map(function ($os) {
319
+                return $this->getValue($os);
320
+            }, $oss);
321
+        } else {
322
+            $oss = [$oss];
323
+        }
324
+        $currentOS = $this->platform->getOS();
325
+        if (!in_array($currentOS, $oss)) {
326
+            $missing[] = (string)$this->l->t('The following platforms are supported: %s', [implode(', ', $oss)]);
327
+        }
328
+        return $missing;
329
+    }
330
+
331
+    /**
332
+     * @param array $dependencies
333
+     * @param array $appInfo
334
+     * @return array
335
+     */
336
+    private function analyzeOC(array $dependencies, array $appInfo, bool $ignoreMax) {
337
+        $missing = [];
338
+        $minVersion = null;
339
+        if (isset($dependencies['nextcloud']['@attributes']['min-version'])) {
340
+            $minVersion = $dependencies['nextcloud']['@attributes']['min-version'];
341
+        } elseif (isset($dependencies['owncloud']['@attributes']['min-version'])) {
342
+            $minVersion = $dependencies['owncloud']['@attributes']['min-version'];
343
+        } elseif (isset($appInfo['requiremin'])) {
344
+            $minVersion = $appInfo['requiremin'];
345
+        } elseif (isset($appInfo['require'])) {
346
+            $minVersion = $appInfo['require'];
347
+        }
348
+        $maxVersion = $this->getMaxVersion($dependencies, $appInfo);
349
+
350
+        if (!is_null($minVersion)) {
351
+            if ($this->compareSmaller($this->platform->getOcVersion(), $minVersion)) {
352
+                $missing[] = (string)$this->l->t('Server version %s or higher is required.', [$this->toVisibleVersion($minVersion)]);
353
+            }
354
+        }
355
+        if (!$ignoreMax && !is_null($maxVersion)) {
356
+            if ($this->compareBigger($this->platform->getOcVersion(), $maxVersion)) {
357
+                $missing[] = (string)$this->l->t('Server version %s or lower is required.', [$this->toVisibleVersion($maxVersion)]);
358
+            }
359
+        }
360
+        return $missing;
361
+    }
362
+
363
+    private function getMaxVersion(array $dependencies, array $appInfo): ?string {
364
+        if (isset($dependencies['nextcloud']['@attributes']['max-version'])) {
365
+            return $dependencies['nextcloud']['@attributes']['max-version'];
366
+        }
367
+        if (isset($dependencies['owncloud']['@attributes']['max-version'])) {
368
+            return $dependencies['owncloud']['@attributes']['max-version'];
369
+        }
370
+        if (isset($appInfo['requiremax'])) {
371
+            return $appInfo['requiremax'];
372
+        }
373
+
374
+        return null;
375
+    }
376
+
377
+    /**
378
+     * Map the internal version number to the Nextcloud version
379
+     *
380
+     * @param string $version
381
+     * @return string
382
+     */
383
+    protected function toVisibleVersion($version) {
384
+        switch ($version) {
385
+            case '9.1':
386
+                return '10';
387
+            default:
388
+                if (strpos($version, '9.1.') === 0) {
389
+                    $version = '10.0.' . substr($version, 4);
390
+                }
391
+                return $version;
392
+        }
393
+    }
394
+
395
+    /**
396
+     * @param $element
397
+     * @return mixed
398
+     */
399
+    private function getValue($element) {
400
+        if (isset($element['@value'])) {
401
+            return $element['@value'];
402
+        }
403
+        return (string)$element;
404
+    }
405 405
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -157,19 +157,19 @@  discard block
 block discarded – undo
157 157
 		if (isset($dependencies['php']['@attributes']['min-version'])) {
158 158
 			$minVersion = $dependencies['php']['@attributes']['min-version'];
159 159
 			if ($this->compareSmaller($this->platform->getPhpVersion(), $minVersion)) {
160
-				$missing[] = (string)$this->l->t('PHP %s or higher is required.', [$minVersion]);
160
+				$missing[] = (string) $this->l->t('PHP %s or higher is required.', [$minVersion]);
161 161
 			}
162 162
 		}
163 163
 		if (isset($dependencies['php']['@attributes']['max-version'])) {
164 164
 			$maxVersion = $dependencies['php']['@attributes']['max-version'];
165 165
 			if ($this->compareBigger($this->platform->getPhpVersion(), $maxVersion)) {
166
-				$missing[] = (string)$this->l->t('PHP with a version lower than %s is required.', [$maxVersion]);
166
+				$missing[] = (string) $this->l->t('PHP with a version lower than %s is required.', [$maxVersion]);
167 167
 			}
168 168
 		}
169 169
 		if (isset($dependencies['php']['@attributes']['min-int-size'])) {
170 170
 			$intSize = $dependencies['php']['@attributes']['min-int-size'];
171
-			if ($intSize > $this->platform->getIntSize()*8) {
172
-				$missing[] = (string)$this->l->t('%sbit or higher PHP required.', [$intSize]);
171
+			if ($intSize > $this->platform->getIntSize() * 8) {
172
+				$missing[] = (string) $this->l->t('%sbit or higher PHP required.', [$intSize]);
173 173
 			}
174 174
 		}
175 175
 		return $missing;
@@ -188,12 +188,12 @@  discard block
 block discarded – undo
188 188
 		if (!is_array($supportedArchitectures)) {
189 189
 			$supportedArchitectures = [$supportedArchitectures];
190 190
 		}
191
-		$supportedArchitectures = array_map(function ($architecture) {
191
+		$supportedArchitectures = array_map(function($architecture) {
192 192
 			return $this->getValue($architecture);
193 193
 		}, $supportedArchitectures);
194 194
 		$currentArchitecture = $this->platform->getArchitecture();
195 195
 		if (!in_array($currentArchitecture, $supportedArchitectures, true)) {
196
-			$missing[] = (string)$this->l->t('The following architectures are supported: %s', [implode(', ', $supportedArchitectures)]);
196
+			$missing[] = (string) $this->l->t('The following architectures are supported: %s', [implode(', ', $supportedArchitectures)]);
197 197
 		}
198 198
 		return $missing;
199 199
 	}
@@ -215,12 +215,12 @@  discard block
 block discarded – undo
215 215
 		if (!is_array($supportedDatabases)) {
216 216
 			$supportedDatabases = [$supportedDatabases];
217 217
 		}
218
-		$supportedDatabases = array_map(function ($db) {
218
+		$supportedDatabases = array_map(function($db) {
219 219
 			return $this->getValue($db);
220 220
 		}, $supportedDatabases);
221 221
 		$currentDatabase = $this->platform->getDatabase();
222 222
 		if (!in_array($currentDatabase, $supportedDatabases)) {
223
-			$missing[] = (string)$this->l->t('The following databases are supported: %s', [implode(', ', $supportedDatabases)]);
223
+			$missing[] = (string) $this->l->t('The following databases are supported: %s', [implode(', ', $supportedDatabases)]);
224 224
 		}
225 225
 		return $missing;
226 226
 	}
@@ -249,7 +249,7 @@  discard block
 block discarded – undo
249 249
 			}
250 250
 			$commandName = $this->getValue($command);
251 251
 			if (!$this->platform->isCommandKnown($commandName)) {
252
-				$missing[] = (string)$this->l->t('The command line tool %s could not be found', [$commandName]);
252
+				$missing[] = (string) $this->l->t('The command line tool %s could not be found', [$commandName]);
253 253
 			}
254 254
 		}
255 255
 		return $missing;
@@ -315,7 +315,7 @@  discard block
 block discarded – undo
315 315
 			return $missing;
316 316
 		}
317 317
 		if (is_array($oss)) {
318
-			$oss = array_map(function ($os) {
318
+			$oss = array_map(function($os) {
319 319
 				return $this->getValue($os);
320 320
 			}, $oss);
321 321
 		} else {
@@ -323,7 +323,7 @@  discard block
 block discarded – undo
323 323
 		}
324 324
 		$currentOS = $this->platform->getOS();
325 325
 		if (!in_array($currentOS, $oss)) {
326
-			$missing[] = (string)$this->l->t('The following platforms are supported: %s', [implode(', ', $oss)]);
326
+			$missing[] = (string) $this->l->t('The following platforms are supported: %s', [implode(', ', $oss)]);
327 327
 		}
328 328
 		return $missing;
329 329
 	}
@@ -349,12 +349,12 @@  discard block
 block discarded – undo
349 349
 
350 350
 		if (!is_null($minVersion)) {
351 351
 			if ($this->compareSmaller($this->platform->getOcVersion(), $minVersion)) {
352
-				$missing[] = (string)$this->l->t('Server version %s or higher is required.', [$this->toVisibleVersion($minVersion)]);
352
+				$missing[] = (string) $this->l->t('Server version %s or higher is required.', [$this->toVisibleVersion($minVersion)]);
353 353
 			}
354 354
 		}
355 355
 		if (!$ignoreMax && !is_null($maxVersion)) {
356 356
 			if ($this->compareBigger($this->platform->getOcVersion(), $maxVersion)) {
357
-				$missing[] = (string)$this->l->t('Server version %s or lower is required.', [$this->toVisibleVersion($maxVersion)]);
357
+				$missing[] = (string) $this->l->t('Server version %s or lower is required.', [$this->toVisibleVersion($maxVersion)]);
358 358
 			}
359 359
 		}
360 360
 		return $missing;
@@ -386,7 +386,7 @@  discard block
 block discarded – undo
386 386
 				return '10';
387 387
 			default:
388 388
 				if (strpos($version, '9.1.') === 0) {
389
-					$version = '10.0.' . substr($version, 4);
389
+					$version = '10.0.'.substr($version, 4);
390 390
 				}
391 391
 				return $version;
392 392
 		}
@@ -400,6 +400,6 @@  discard block
 block discarded – undo
400 400
 		if (isset($element['@value'])) {
401 401
 			return $element['@value'];
402 402
 		}
403
-		return (string)$element;
403
+		return (string) $element;
404 404
 	}
405 405
 }
Please login to merge, or discard this patch.
lib/private/App/AppStore/Bundles/HubBundle.php 2 patches
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -28,24 +28,24 @@
 block discarded – undo
28 28
 namespace OC\App\AppStore\Bundles;
29 29
 
30 30
 class HubBundle extends Bundle {
31
-	public function getName() {
32
-		return $this->l10n->t('Hub bundle');
33
-	}
31
+    public function getName() {
32
+        return $this->l10n->t('Hub bundle');
33
+    }
34 34
 
35
-	public function getAppIdentifiers() {
36
-		$hubApps = [
37
-			'spreed',
38
-			'contacts',
39
-			'calendar',
40
-			'mail',
41
-		];
35
+    public function getAppIdentifiers() {
36
+        $hubApps = [
37
+            'spreed',
38
+            'contacts',
39
+            'calendar',
40
+            'mail',
41
+        ];
42 42
 
43
-		$architecture = php_uname('m');
44
-		if (PHP_OS_FAMILY === 'Linux' && in_array($architecture, ['x86_64', 'aarch64'])) {
45
-			$hubApps[] = 'richdocuments';
46
-			$hubApps[] = 'richdocumentscode' . ($architecture === 'aarch64' ? '_arm64' : '');
47
-		}
43
+        $architecture = php_uname('m');
44
+        if (PHP_OS_FAMILY === 'Linux' && in_array($architecture, ['x86_64', 'aarch64'])) {
45
+            $hubApps[] = 'richdocuments';
46
+            $hubApps[] = 'richdocumentscode' . ($architecture === 'aarch64' ? '_arm64' : '');
47
+        }
48 48
 
49
-		return $hubApps;
50
-	}
49
+        return $hubApps;
50
+    }
51 51
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -43,7 +43,7 @@
 block discarded – undo
43 43
 		$architecture = php_uname('m');
44 44
 		if (PHP_OS_FAMILY === 'Linux' && in_array($architecture, ['x86_64', 'aarch64'])) {
45 45
 			$hubApps[] = 'richdocuments';
46
-			$hubApps[] = 'richdocumentscode' . ($architecture === 'aarch64' ? '_arm64' : '');
46
+			$hubApps[] = 'richdocumentscode'.($architecture === 'aarch64' ? '_arm64' : '');
47 47
 		}
48 48
 
49 49
 		return $hubApps;
Please login to merge, or discard this patch.
lib/private/Setup.php 2 patches
Indentation   +546 added lines, -546 removed lines patch added patch discarded remove patch
@@ -64,550 +64,550 @@
 block discarded – undo
64 64
 use OCP\Security\ISecureRandom;
65 65
 
66 66
 class Setup {
67
-	/** @var SystemConfig */
68
-	protected $config;
69
-	/** @var IniGetWrapper */
70
-	protected $iniWrapper;
71
-	/** @var IL10N */
72
-	protected $l10n;
73
-	/** @var Defaults */
74
-	protected $defaults;
75
-	/** @var ILogger */
76
-	protected $logger;
77
-	/** @var ISecureRandom */
78
-	protected $random;
79
-	/** @var Installer */
80
-	protected $installer;
81
-
82
-	/**
83
-	 * @param SystemConfig $config
84
-	 * @param IniGetWrapper $iniWrapper
85
-	 * @param IL10N $l10n
86
-	 * @param Defaults $defaults
87
-	 * @param ILogger $logger
88
-	 * @param ISecureRandom $random
89
-	 * @param Installer $installer
90
-	 */
91
-	public function __construct(
92
-		SystemConfig $config,
93
-		IniGetWrapper $iniWrapper,
94
-		IL10N $l10n,
95
-		Defaults $defaults,
96
-		ILogger $logger,
97
-		ISecureRandom $random,
98
-		Installer $installer
99
-	) {
100
-		$this->config = $config;
101
-		$this->iniWrapper = $iniWrapper;
102
-		$this->l10n = $l10n;
103
-		$this->defaults = $defaults;
104
-		$this->logger = $logger;
105
-		$this->random = $random;
106
-		$this->installer = $installer;
107
-	}
108
-
109
-	protected static $dbSetupClasses = [
110
-		'mysql' => \OC\Setup\MySQL::class,
111
-		'pgsql' => \OC\Setup\PostgreSQL::class,
112
-		'oci' => \OC\Setup\OCI::class,
113
-		'sqlite' => \OC\Setup\Sqlite::class,
114
-		'sqlite3' => \OC\Setup\Sqlite::class,
115
-	];
116
-
117
-	/**
118
-	 * Wrapper around the "class_exists" PHP function to be able to mock it
119
-	 *
120
-	 * @param string $name
121
-	 * @return bool
122
-	 */
123
-	protected function class_exists($name) {
124
-		return class_exists($name);
125
-	}
126
-
127
-	/**
128
-	 * Wrapper around the "is_callable" PHP function to be able to mock it
129
-	 *
130
-	 * @param string $name
131
-	 * @return bool
132
-	 */
133
-	protected function is_callable($name) {
134
-		return is_callable($name);
135
-	}
136
-
137
-	/**
138
-	 * Wrapper around \PDO::getAvailableDrivers
139
-	 *
140
-	 * @return array
141
-	 */
142
-	protected function getAvailableDbDriversForPdo() {
143
-		return \PDO::getAvailableDrivers();
144
-	}
145
-
146
-	/**
147
-	 * Get the available and supported databases of this instance
148
-	 *
149
-	 * @param bool $allowAllDatabases
150
-	 * @return array
151
-	 * @throws Exception
152
-	 */
153
-	public function getSupportedDatabases($allowAllDatabases = false) {
154
-		$availableDatabases = [
155
-			'sqlite' => [
156
-				'type' => 'pdo',
157
-				'call' => 'sqlite',
158
-				'name' => 'SQLite',
159
-			],
160
-			'mysql' => [
161
-				'type' => 'pdo',
162
-				'call' => 'mysql',
163
-				'name' => 'MySQL/MariaDB',
164
-			],
165
-			'pgsql' => [
166
-				'type' => 'pdo',
167
-				'call' => 'pgsql',
168
-				'name' => 'PostgreSQL',
169
-			],
170
-			'oci' => [
171
-				'type' => 'function',
172
-				'call' => 'oci_connect',
173
-				'name' => 'Oracle',
174
-			],
175
-		];
176
-		if ($allowAllDatabases) {
177
-			$configuredDatabases = array_keys($availableDatabases);
178
-		} else {
179
-			$configuredDatabases = $this->config->getValue('supportedDatabases',
180
-				['sqlite', 'mysql', 'pgsql']);
181
-		}
182
-		if (!is_array($configuredDatabases)) {
183
-			throw new Exception('Supported databases are not properly configured.');
184
-		}
185
-
186
-		$supportedDatabases = [];
187
-
188
-		foreach ($configuredDatabases as $database) {
189
-			if (array_key_exists($database, $availableDatabases)) {
190
-				$working = false;
191
-				$type = $availableDatabases[$database]['type'];
192
-				$call = $availableDatabases[$database]['call'];
193
-
194
-				if ($type === 'function') {
195
-					$working = $this->is_callable($call);
196
-				} elseif ($type === 'pdo') {
197
-					$working = in_array($call, $this->getAvailableDbDriversForPdo(), true);
198
-				}
199
-				if ($working) {
200
-					$supportedDatabases[$database] = $availableDatabases[$database]['name'];
201
-				}
202
-			}
203
-		}
204
-
205
-		return $supportedDatabases;
206
-	}
207
-
208
-	/**
209
-	 * Gathers system information like database type and does
210
-	 * a few system checks.
211
-	 *
212
-	 * @return array of system info, including an "errors" value
213
-	 * in case of errors/warnings
214
-	 */
215
-	public function getSystemInfo($allowAllDatabases = false) {
216
-		$databases = $this->getSupportedDatabases($allowAllDatabases);
217
-
218
-		$dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT . '/data');
219
-
220
-		$errors = [];
221
-
222
-		// Create data directory to test whether the .htaccess works
223
-		// Notice that this is not necessarily the same data directory as the one
224
-		// that will effectively be used.
225
-		if (!file_exists($dataDir)) {
226
-			@mkdir($dataDir);
227
-		}
228
-		$htAccessWorking = true;
229
-		if (is_dir($dataDir) && is_writable($dataDir)) {
230
-			// Protect data directory here, so we can test if the protection is working
231
-			self::protectDataDirectory();
232
-
233
-			try {
234
-				$util = new \OC_Util();
235
-				$htAccessWorking = $util->isHtaccessWorking(\OC::$server->getConfig());
236
-			} catch (\OC\HintException $e) {
237
-				$errors[] = [
238
-					'error' => $e->getMessage(),
239
-					'hint' => $e->getHint(),
240
-				];
241
-				$htAccessWorking = false;
242
-			}
243
-		}
244
-
245
-		if (\OC_Util::runningOnMac()) {
246
-			$errors[] = [
247
-				'error' => $this->l10n->t(
248
-					'Mac OS X is not supported and %s will not work properly on this platform. ' .
249
-					'Use it at your own risk! ',
250
-					[$this->defaults->getName()]
251
-				),
252
-				'hint' => $this->l10n->t('For the best results, please consider using a GNU/Linux server instead.'),
253
-			];
254
-		}
255
-
256
-		if ($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
257
-			$errors[] = [
258
-				'error' => $this->l10n->t(
259
-					'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. ' .
260
-					'This will lead to problems with files over 4 GB and is highly discouraged.',
261
-					[$this->defaults->getName()]
262
-				),
263
-				'hint' => $this->l10n->t('Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP.'),
264
-			];
265
-		}
266
-
267
-		return [
268
-			'hasSQLite' => isset($databases['sqlite']),
269
-			'hasMySQL' => isset($databases['mysql']),
270
-			'hasPostgreSQL' => isset($databases['pgsql']),
271
-			'hasOracle' => isset($databases['oci']),
272
-			'databases' => $databases,
273
-			'directory' => $dataDir,
274
-			'htaccessWorking' => $htAccessWorking,
275
-			'errors' => $errors,
276
-		];
277
-	}
278
-
279
-	/**
280
-	 * @param $options
281
-	 * @return array
282
-	 */
283
-	public function install($options) {
284
-		$l = $this->l10n;
285
-
286
-		$error = [];
287
-		$dbType = $options['dbtype'];
288
-
289
-		if (empty($options['adminlogin'])) {
290
-			$error[] = $l->t('Set an admin username.');
291
-		}
292
-		if (empty($options['adminpass'])) {
293
-			$error[] = $l->t('Set an admin password.');
294
-		}
295
-		if (empty($options['directory'])) {
296
-			$options['directory'] = \OC::$SERVERROOT . "/data";
297
-		}
298
-
299
-		if (!isset(self::$dbSetupClasses[$dbType])) {
300
-			$dbType = 'sqlite';
301
-		}
302
-
303
-		$username = htmlspecialchars_decode($options['adminlogin']);
304
-		$password = htmlspecialchars_decode($options['adminpass']);
305
-		$dataDir = htmlspecialchars_decode($options['directory']);
306
-
307
-		$class = self::$dbSetupClasses[$dbType];
308
-		/** @var \OC\Setup\AbstractDatabase $dbSetup */
309
-		$dbSetup = new $class($l, $this->config, $this->logger, $this->random);
310
-		$error = array_merge($error, $dbSetup->validate($options));
311
-
312
-		// validate the data directory
313
-		if ((!is_dir($dataDir) && !mkdir($dataDir)) || !is_writable($dataDir)) {
314
-			$error[] = $l->t("Can't create or write into the data directory %s", [$dataDir]);
315
-		}
316
-
317
-		if (!empty($error)) {
318
-			return $error;
319
-		}
320
-
321
-		$request = \OC::$server->getRequest();
322
-
323
-		//no errors, good
324
-		if (isset($options['trusted_domains'])
325
-			&& is_array($options['trusted_domains'])) {
326
-			$trustedDomains = $options['trusted_domains'];
327
-		} else {
328
-			$trustedDomains = [$request->getInsecureServerHost()];
329
-		}
330
-
331
-		//use sqlite3 when available, otherwise sqlite2 will be used.
332
-		if ($dbType === 'sqlite' && class_exists('SQLite3')) {
333
-			$dbType = 'sqlite3';
334
-		}
335
-
336
-		//generate a random salt that is used to salt the local user passwords
337
-		$salt = $this->random->generate(30);
338
-		// generate a secret
339
-		$secret = $this->random->generate(48);
340
-
341
-		//write the config file
342
-		$newConfigValues = [
343
-			'passwordsalt' => $salt,
344
-			'secret' => $secret,
345
-			'trusted_domains' => $trustedDomains,
346
-			'datadirectory' => $dataDir,
347
-			'dbtype' => $dbType,
348
-			'version' => implode('.', \OCP\Util::getVersion()),
349
-		];
350
-
351
-		if ($this->config->getValue('overwrite.cli.url', null) === null) {
352
-			$newConfigValues['overwrite.cli.url'] = $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . \OC::$WEBROOT;
353
-		}
354
-
355
-		$this->config->setValues($newConfigValues);
356
-
357
-		$dbSetup->initialize($options);
358
-		try {
359
-			$dbSetup->setupDatabase($username);
360
-		} catch (\OC\DatabaseSetupException $e) {
361
-			$error[] = [
362
-				'error' => $e->getMessage(),
363
-				'hint' => $e->getHint(),
364
-			];
365
-			return $error;
366
-		} catch (Exception $e) {
367
-			$error[] = [
368
-				'error' => 'Error while trying to create admin user: ' . $e->getMessage(),
369
-				'hint' => '',
370
-			];
371
-			return $error;
372
-		}
373
-		try {
374
-			// apply necessary migrations
375
-			$dbSetup->runMigrations();
376
-		} catch (Exception $e) {
377
-			$error[] = [
378
-				'error' => 'Error while trying to initialise the database: ' . $e->getMessage(),
379
-				'hint' => '',
380
-			];
381
-			return $error;
382
-		}
383
-
384
-		//create the user and group
385
-		$user = null;
386
-		try {
387
-			$user = \OC::$server->getUserManager()->createUser($username, $password);
388
-			if (!$user) {
389
-				$error[] = "User <$username> could not be created.";
390
-			}
391
-		} catch (Exception $exception) {
392
-			$error[] = $exception->getMessage();
393
-		}
394
-
395
-		if (empty($error)) {
396
-			$config = \OC::$server->getConfig();
397
-			$config->setAppValue('core', 'installedat', microtime(true));
398
-			$config->setAppValue('core', 'lastupdatedat', microtime(true));
399
-			$config->setAppValue('core', 'vendor', $this->getVendor());
400
-
401
-			$group = \OC::$server->getGroupManager()->createGroup('admin');
402
-			if ($group instanceof IGroup) {
403
-				$group->addUser($user);
404
-			}
405
-
406
-			// Install shipped apps and specified app bundles
407
-			Installer::installShippedApps();
408
-			$bundleFetcher = new BundleFetcher(\OC::$server->getL10N('lib'));
409
-			$defaultInstallationBundles = $bundleFetcher->getDefaultInstallationBundle();
410
-			foreach ($defaultInstallationBundles as $bundle) {
411
-				try {
412
-					$this->installer->installAppBundle($bundle);
413
-				} catch (Exception $e) {
414
-				}
415
-			}
416
-
417
-			// create empty file in data dir, so we can later find
418
-			// out that this is indeed an ownCloud data directory
419
-			file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
420
-
421
-			// Update .htaccess files
422
-			self::updateHtaccess();
423
-			self::protectDataDirectory();
424
-
425
-			self::installBackgroundJobs();
426
-
427
-			//and we are done
428
-			$config->setSystemValue('installed', true);
429
-
430
-			// Create a session token for the newly created user
431
-			// The token provider requires a working db, so it's not injected on setup
432
-			/* @var $userSession User\Session */
433
-			$userSession = \OC::$server->getUserSession();
434
-			$defaultTokenProvider = \OC::$server->query(DefaultTokenProvider::class);
435
-			$userSession->setTokenProvider($defaultTokenProvider);
436
-			$userSession->login($username, $password);
437
-			$userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
438
-
439
-			$session = $userSession->getSession();
440
-			$session->set('last-password-confirm', \OC::$server->query(ITimeFactory::class)->getTime());
441
-
442
-			// Set email for admin
443
-			if (!empty($options['adminemail'])) {
444
-				$config->setUserValue($user->getUID(), 'settings', 'email', $options['adminemail']);
445
-			}
446
-		}
447
-
448
-		return $error;
449
-	}
450
-
451
-	public static function installBackgroundJobs() {
452
-		$jobList = \OC::$server->getJobList();
453
-		$jobList->add(DefaultTokenCleanupJob::class);
454
-		$jobList->add(Rotate::class);
455
-		$jobList->add(BackgroundCleanupJob::class);
456
-	}
457
-
458
-	/**
459
-	 * @return string Absolute path to htaccess
460
-	 */
461
-	private function pathToHtaccess() {
462
-		return \OC::$SERVERROOT . '/.htaccess';
463
-	}
464
-
465
-	/**
466
-	 * Find webroot from config
467
-	 *
468
-	 * @param SystemConfig $config
469
-	 * @return string
470
-	 * @throws InvalidArgumentException when invalid value for overwrite.cli.url
471
-	 */
472
-	private static function findWebRoot(SystemConfig $config): string {
473
-		// For CLI read the value from overwrite.cli.url
474
-		if (\OC::$CLI) {
475
-			$webRoot = $config->getValue('overwrite.cli.url', '');
476
-			if ($webRoot === '') {
477
-				throw new InvalidArgumentException('overwrite.cli.url is empty');
478
-			}
479
-			if (!filter_var($webRoot, FILTER_VALIDATE_URL)) {
480
-				throw new InvalidArgumentException('invalid value for overwrite.cli.url');
481
-			}
482
-			$webRoot = rtrim(parse_url($webRoot, PHP_URL_PATH), '/');
483
-		} else {
484
-			$webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/';
485
-		}
486
-
487
-		return $webRoot;
488
-	}
489
-
490
-	/**
491
-	 * Append the correct ErrorDocument path for Apache hosts
492
-	 *
493
-	 * @return bool True when success, False otherwise
494
-	 * @throws \OCP\AppFramework\QueryException
495
-	 */
496
-	public static function updateHtaccess() {
497
-		$config = \OC::$server->getSystemConfig();
498
-
499
-		try {
500
-			$webRoot = self::findWebRoot($config);
501
-		} catch (InvalidArgumentException $e) {
502
-			return false;
503
-		}
504
-
505
-		$setupHelper = new \OC\Setup(
506
-			$config,
507
-			\OC::$server->get(IniGetWrapper::class),
508
-			\OC::$server->getL10N('lib'),
509
-			\OC::$server->query(Defaults::class),
510
-			\OC::$server->getLogger(),
511
-			\OC::$server->getSecureRandom(),
512
-			\OC::$server->query(Installer::class)
513
-		);
514
-
515
-		$htaccessContent = file_get_contents($setupHelper->pathToHtaccess());
516
-		$content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n";
517
-		$htaccessContent = explode($content, $htaccessContent, 2)[0];
518
-
519
-		//custom 403 error page
520
-		$content .= "\nErrorDocument 403 " . $webRoot . '/';
521
-
522
-		//custom 404 error page
523
-		$content .= "\nErrorDocument 404 " . $webRoot . '/';
524
-
525
-		// Add rewrite rules if the RewriteBase is configured
526
-		$rewriteBase = $config->getValue('htaccess.RewriteBase', '');
527
-		if ($rewriteBase !== '') {
528
-			$content .= "\n<IfModule mod_rewrite.c>";
529
-			$content .= "\n  Options -MultiViews";
530
-			$content .= "\n  RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]";
531
-			$content .= "\n  RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]";
532
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !\\.(css|js|svg|gif|png|html|ttf|woff2?|ico|jpg|jpeg|map|webm|mp4|mp3|ogg|wav)$";
533
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$";
534
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/manifest.json$";
535
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/remote.php";
536
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/public.php";
537
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/cron.php";
538
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php";
539
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/status.php";
540
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php";
541
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php";
542
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/robots.txt";
543
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/updater/";
544
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs-provider/";
545
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocm-provider/";
546
-			$content .= "\n  RewriteCond %{REQUEST_URI} !^/\\.well-known/(acme-challenge|pki-validation)/.*";
547
-			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/richdocumentscode(_arm64)?/proxy.php$";
548
-			$content .= "\n  RewriteRule . index.php [PT,E=PATH_INFO:$1]";
549
-			$content .= "\n  RewriteBase " . $rewriteBase;
550
-			$content .= "\n  <IfModule mod_env.c>";
551
-			$content .= "\n    SetEnv front_controller_active true";
552
-			$content .= "\n    <IfModule mod_dir.c>";
553
-			$content .= "\n      DirectorySlash off";
554
-			$content .= "\n    </IfModule>";
555
-			$content .= "\n  </IfModule>";
556
-			$content .= "\n</IfModule>";
557
-		}
558
-
559
-		if ($content !== '') {
560
-			//suppress errors in case we don't have permissions for it
561
-			return (bool)@file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent . $content . "\n");
562
-		}
563
-
564
-		return false;
565
-	}
566
-
567
-	public static function protectDataDirectory() {
568
-		//Require all denied
569
-		$now = date('Y-m-d H:i:s');
570
-		$content = "# Generated by Nextcloud on $now\n";
571
-		$content .= "# Section for Apache 2.4 to 2.6\n";
572
-		$content .= "<IfModule mod_authz_core.c>\n";
573
-		$content .= "  Require all denied\n";
574
-		$content .= "</IfModule>\n";
575
-		$content .= "<IfModule mod_access_compat.c>\n";
576
-		$content .= "  Order Allow,Deny\n";
577
-		$content .= "  Deny from all\n";
578
-		$content .= "  Satisfy All\n";
579
-		$content .= "</IfModule>\n\n";
580
-		$content .= "# Section for Apache 2.2\n";
581
-		$content .= "<IfModule !mod_authz_core.c>\n";
582
-		$content .= "  <IfModule !mod_access_compat.c>\n";
583
-		$content .= "    <IfModule mod_authz_host.c>\n";
584
-		$content .= "      Order Allow,Deny\n";
585
-		$content .= "      Deny from all\n";
586
-		$content .= "    </IfModule>\n";
587
-		$content .= "    Satisfy All\n";
588
-		$content .= "  </IfModule>\n";
589
-		$content .= "</IfModule>\n\n";
590
-		$content .= "# Section for Apache 2.2 to 2.6\n";
591
-		$content .= "<IfModule mod_autoindex.c>\n";
592
-		$content .= "  IndexIgnore *\n";
593
-		$content .= "</IfModule>";
594
-
595
-		$baseDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
596
-		file_put_contents($baseDir . '/.htaccess', $content);
597
-		file_put_contents($baseDir . '/index.html', '');
598
-	}
599
-
600
-	/**
601
-	 * Return vendor from which this version was published
602
-	 *
603
-	 * @return string Get the vendor
604
-	 *
605
-	 * Copy of \OC\Updater::getVendor()
606
-	 */
607
-	private function getVendor() {
608
-		// this should really be a JSON file
609
-		require \OC::$SERVERROOT . '/version.php';
610
-		/** @var string $vendor */
611
-		return (string)$vendor;
612
-	}
67
+    /** @var SystemConfig */
68
+    protected $config;
69
+    /** @var IniGetWrapper */
70
+    protected $iniWrapper;
71
+    /** @var IL10N */
72
+    protected $l10n;
73
+    /** @var Defaults */
74
+    protected $defaults;
75
+    /** @var ILogger */
76
+    protected $logger;
77
+    /** @var ISecureRandom */
78
+    protected $random;
79
+    /** @var Installer */
80
+    protected $installer;
81
+
82
+    /**
83
+     * @param SystemConfig $config
84
+     * @param IniGetWrapper $iniWrapper
85
+     * @param IL10N $l10n
86
+     * @param Defaults $defaults
87
+     * @param ILogger $logger
88
+     * @param ISecureRandom $random
89
+     * @param Installer $installer
90
+     */
91
+    public function __construct(
92
+        SystemConfig $config,
93
+        IniGetWrapper $iniWrapper,
94
+        IL10N $l10n,
95
+        Defaults $defaults,
96
+        ILogger $logger,
97
+        ISecureRandom $random,
98
+        Installer $installer
99
+    ) {
100
+        $this->config = $config;
101
+        $this->iniWrapper = $iniWrapper;
102
+        $this->l10n = $l10n;
103
+        $this->defaults = $defaults;
104
+        $this->logger = $logger;
105
+        $this->random = $random;
106
+        $this->installer = $installer;
107
+    }
108
+
109
+    protected static $dbSetupClasses = [
110
+        'mysql' => \OC\Setup\MySQL::class,
111
+        'pgsql' => \OC\Setup\PostgreSQL::class,
112
+        'oci' => \OC\Setup\OCI::class,
113
+        'sqlite' => \OC\Setup\Sqlite::class,
114
+        'sqlite3' => \OC\Setup\Sqlite::class,
115
+    ];
116
+
117
+    /**
118
+     * Wrapper around the "class_exists" PHP function to be able to mock it
119
+     *
120
+     * @param string $name
121
+     * @return bool
122
+     */
123
+    protected function class_exists($name) {
124
+        return class_exists($name);
125
+    }
126
+
127
+    /**
128
+     * Wrapper around the "is_callable" PHP function to be able to mock it
129
+     *
130
+     * @param string $name
131
+     * @return bool
132
+     */
133
+    protected function is_callable($name) {
134
+        return is_callable($name);
135
+    }
136
+
137
+    /**
138
+     * Wrapper around \PDO::getAvailableDrivers
139
+     *
140
+     * @return array
141
+     */
142
+    protected function getAvailableDbDriversForPdo() {
143
+        return \PDO::getAvailableDrivers();
144
+    }
145
+
146
+    /**
147
+     * Get the available and supported databases of this instance
148
+     *
149
+     * @param bool $allowAllDatabases
150
+     * @return array
151
+     * @throws Exception
152
+     */
153
+    public function getSupportedDatabases($allowAllDatabases = false) {
154
+        $availableDatabases = [
155
+            'sqlite' => [
156
+                'type' => 'pdo',
157
+                'call' => 'sqlite',
158
+                'name' => 'SQLite',
159
+            ],
160
+            'mysql' => [
161
+                'type' => 'pdo',
162
+                'call' => 'mysql',
163
+                'name' => 'MySQL/MariaDB',
164
+            ],
165
+            'pgsql' => [
166
+                'type' => 'pdo',
167
+                'call' => 'pgsql',
168
+                'name' => 'PostgreSQL',
169
+            ],
170
+            'oci' => [
171
+                'type' => 'function',
172
+                'call' => 'oci_connect',
173
+                'name' => 'Oracle',
174
+            ],
175
+        ];
176
+        if ($allowAllDatabases) {
177
+            $configuredDatabases = array_keys($availableDatabases);
178
+        } else {
179
+            $configuredDatabases = $this->config->getValue('supportedDatabases',
180
+                ['sqlite', 'mysql', 'pgsql']);
181
+        }
182
+        if (!is_array($configuredDatabases)) {
183
+            throw new Exception('Supported databases are not properly configured.');
184
+        }
185
+
186
+        $supportedDatabases = [];
187
+
188
+        foreach ($configuredDatabases as $database) {
189
+            if (array_key_exists($database, $availableDatabases)) {
190
+                $working = false;
191
+                $type = $availableDatabases[$database]['type'];
192
+                $call = $availableDatabases[$database]['call'];
193
+
194
+                if ($type === 'function') {
195
+                    $working = $this->is_callable($call);
196
+                } elseif ($type === 'pdo') {
197
+                    $working = in_array($call, $this->getAvailableDbDriversForPdo(), true);
198
+                }
199
+                if ($working) {
200
+                    $supportedDatabases[$database] = $availableDatabases[$database]['name'];
201
+                }
202
+            }
203
+        }
204
+
205
+        return $supportedDatabases;
206
+    }
207
+
208
+    /**
209
+     * Gathers system information like database type and does
210
+     * a few system checks.
211
+     *
212
+     * @return array of system info, including an "errors" value
213
+     * in case of errors/warnings
214
+     */
215
+    public function getSystemInfo($allowAllDatabases = false) {
216
+        $databases = $this->getSupportedDatabases($allowAllDatabases);
217
+
218
+        $dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT . '/data');
219
+
220
+        $errors = [];
221
+
222
+        // Create data directory to test whether the .htaccess works
223
+        // Notice that this is not necessarily the same data directory as the one
224
+        // that will effectively be used.
225
+        if (!file_exists($dataDir)) {
226
+            @mkdir($dataDir);
227
+        }
228
+        $htAccessWorking = true;
229
+        if (is_dir($dataDir) && is_writable($dataDir)) {
230
+            // Protect data directory here, so we can test if the protection is working
231
+            self::protectDataDirectory();
232
+
233
+            try {
234
+                $util = new \OC_Util();
235
+                $htAccessWorking = $util->isHtaccessWorking(\OC::$server->getConfig());
236
+            } catch (\OC\HintException $e) {
237
+                $errors[] = [
238
+                    'error' => $e->getMessage(),
239
+                    'hint' => $e->getHint(),
240
+                ];
241
+                $htAccessWorking = false;
242
+            }
243
+        }
244
+
245
+        if (\OC_Util::runningOnMac()) {
246
+            $errors[] = [
247
+                'error' => $this->l10n->t(
248
+                    'Mac OS X is not supported and %s will not work properly on this platform. ' .
249
+                    'Use it at your own risk! ',
250
+                    [$this->defaults->getName()]
251
+                ),
252
+                'hint' => $this->l10n->t('For the best results, please consider using a GNU/Linux server instead.'),
253
+            ];
254
+        }
255
+
256
+        if ($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
257
+            $errors[] = [
258
+                'error' => $this->l10n->t(
259
+                    'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. ' .
260
+                    'This will lead to problems with files over 4 GB and is highly discouraged.',
261
+                    [$this->defaults->getName()]
262
+                ),
263
+                'hint' => $this->l10n->t('Please remove the open_basedir setting within your php.ini or switch to 64-bit PHP.'),
264
+            ];
265
+        }
266
+
267
+        return [
268
+            'hasSQLite' => isset($databases['sqlite']),
269
+            'hasMySQL' => isset($databases['mysql']),
270
+            'hasPostgreSQL' => isset($databases['pgsql']),
271
+            'hasOracle' => isset($databases['oci']),
272
+            'databases' => $databases,
273
+            'directory' => $dataDir,
274
+            'htaccessWorking' => $htAccessWorking,
275
+            'errors' => $errors,
276
+        ];
277
+    }
278
+
279
+    /**
280
+     * @param $options
281
+     * @return array
282
+     */
283
+    public function install($options) {
284
+        $l = $this->l10n;
285
+
286
+        $error = [];
287
+        $dbType = $options['dbtype'];
288
+
289
+        if (empty($options['adminlogin'])) {
290
+            $error[] = $l->t('Set an admin username.');
291
+        }
292
+        if (empty($options['adminpass'])) {
293
+            $error[] = $l->t('Set an admin password.');
294
+        }
295
+        if (empty($options['directory'])) {
296
+            $options['directory'] = \OC::$SERVERROOT . "/data";
297
+        }
298
+
299
+        if (!isset(self::$dbSetupClasses[$dbType])) {
300
+            $dbType = 'sqlite';
301
+        }
302
+
303
+        $username = htmlspecialchars_decode($options['adminlogin']);
304
+        $password = htmlspecialchars_decode($options['adminpass']);
305
+        $dataDir = htmlspecialchars_decode($options['directory']);
306
+
307
+        $class = self::$dbSetupClasses[$dbType];
308
+        /** @var \OC\Setup\AbstractDatabase $dbSetup */
309
+        $dbSetup = new $class($l, $this->config, $this->logger, $this->random);
310
+        $error = array_merge($error, $dbSetup->validate($options));
311
+
312
+        // validate the data directory
313
+        if ((!is_dir($dataDir) && !mkdir($dataDir)) || !is_writable($dataDir)) {
314
+            $error[] = $l->t("Can't create or write into the data directory %s", [$dataDir]);
315
+        }
316
+
317
+        if (!empty($error)) {
318
+            return $error;
319
+        }
320
+
321
+        $request = \OC::$server->getRequest();
322
+
323
+        //no errors, good
324
+        if (isset($options['trusted_domains'])
325
+            && is_array($options['trusted_domains'])) {
326
+            $trustedDomains = $options['trusted_domains'];
327
+        } else {
328
+            $trustedDomains = [$request->getInsecureServerHost()];
329
+        }
330
+
331
+        //use sqlite3 when available, otherwise sqlite2 will be used.
332
+        if ($dbType === 'sqlite' && class_exists('SQLite3')) {
333
+            $dbType = 'sqlite3';
334
+        }
335
+
336
+        //generate a random salt that is used to salt the local user passwords
337
+        $salt = $this->random->generate(30);
338
+        // generate a secret
339
+        $secret = $this->random->generate(48);
340
+
341
+        //write the config file
342
+        $newConfigValues = [
343
+            'passwordsalt' => $salt,
344
+            'secret' => $secret,
345
+            'trusted_domains' => $trustedDomains,
346
+            'datadirectory' => $dataDir,
347
+            'dbtype' => $dbType,
348
+            'version' => implode('.', \OCP\Util::getVersion()),
349
+        ];
350
+
351
+        if ($this->config->getValue('overwrite.cli.url', null) === null) {
352
+            $newConfigValues['overwrite.cli.url'] = $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . \OC::$WEBROOT;
353
+        }
354
+
355
+        $this->config->setValues($newConfigValues);
356
+
357
+        $dbSetup->initialize($options);
358
+        try {
359
+            $dbSetup->setupDatabase($username);
360
+        } catch (\OC\DatabaseSetupException $e) {
361
+            $error[] = [
362
+                'error' => $e->getMessage(),
363
+                'hint' => $e->getHint(),
364
+            ];
365
+            return $error;
366
+        } catch (Exception $e) {
367
+            $error[] = [
368
+                'error' => 'Error while trying to create admin user: ' . $e->getMessage(),
369
+                'hint' => '',
370
+            ];
371
+            return $error;
372
+        }
373
+        try {
374
+            // apply necessary migrations
375
+            $dbSetup->runMigrations();
376
+        } catch (Exception $e) {
377
+            $error[] = [
378
+                'error' => 'Error while trying to initialise the database: ' . $e->getMessage(),
379
+                'hint' => '',
380
+            ];
381
+            return $error;
382
+        }
383
+
384
+        //create the user and group
385
+        $user = null;
386
+        try {
387
+            $user = \OC::$server->getUserManager()->createUser($username, $password);
388
+            if (!$user) {
389
+                $error[] = "User <$username> could not be created.";
390
+            }
391
+        } catch (Exception $exception) {
392
+            $error[] = $exception->getMessage();
393
+        }
394
+
395
+        if (empty($error)) {
396
+            $config = \OC::$server->getConfig();
397
+            $config->setAppValue('core', 'installedat', microtime(true));
398
+            $config->setAppValue('core', 'lastupdatedat', microtime(true));
399
+            $config->setAppValue('core', 'vendor', $this->getVendor());
400
+
401
+            $group = \OC::$server->getGroupManager()->createGroup('admin');
402
+            if ($group instanceof IGroup) {
403
+                $group->addUser($user);
404
+            }
405
+
406
+            // Install shipped apps and specified app bundles
407
+            Installer::installShippedApps();
408
+            $bundleFetcher = new BundleFetcher(\OC::$server->getL10N('lib'));
409
+            $defaultInstallationBundles = $bundleFetcher->getDefaultInstallationBundle();
410
+            foreach ($defaultInstallationBundles as $bundle) {
411
+                try {
412
+                    $this->installer->installAppBundle($bundle);
413
+                } catch (Exception $e) {
414
+                }
415
+            }
416
+
417
+            // create empty file in data dir, so we can later find
418
+            // out that this is indeed an ownCloud data directory
419
+            file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
420
+
421
+            // Update .htaccess files
422
+            self::updateHtaccess();
423
+            self::protectDataDirectory();
424
+
425
+            self::installBackgroundJobs();
426
+
427
+            //and we are done
428
+            $config->setSystemValue('installed', true);
429
+
430
+            // Create a session token for the newly created user
431
+            // The token provider requires a working db, so it's not injected on setup
432
+            /* @var $userSession User\Session */
433
+            $userSession = \OC::$server->getUserSession();
434
+            $defaultTokenProvider = \OC::$server->query(DefaultTokenProvider::class);
435
+            $userSession->setTokenProvider($defaultTokenProvider);
436
+            $userSession->login($username, $password);
437
+            $userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
438
+
439
+            $session = $userSession->getSession();
440
+            $session->set('last-password-confirm', \OC::$server->query(ITimeFactory::class)->getTime());
441
+
442
+            // Set email for admin
443
+            if (!empty($options['adminemail'])) {
444
+                $config->setUserValue($user->getUID(), 'settings', 'email', $options['adminemail']);
445
+            }
446
+        }
447
+
448
+        return $error;
449
+    }
450
+
451
+    public static function installBackgroundJobs() {
452
+        $jobList = \OC::$server->getJobList();
453
+        $jobList->add(DefaultTokenCleanupJob::class);
454
+        $jobList->add(Rotate::class);
455
+        $jobList->add(BackgroundCleanupJob::class);
456
+    }
457
+
458
+    /**
459
+     * @return string Absolute path to htaccess
460
+     */
461
+    private function pathToHtaccess() {
462
+        return \OC::$SERVERROOT . '/.htaccess';
463
+    }
464
+
465
+    /**
466
+     * Find webroot from config
467
+     *
468
+     * @param SystemConfig $config
469
+     * @return string
470
+     * @throws InvalidArgumentException when invalid value for overwrite.cli.url
471
+     */
472
+    private static function findWebRoot(SystemConfig $config): string {
473
+        // For CLI read the value from overwrite.cli.url
474
+        if (\OC::$CLI) {
475
+            $webRoot = $config->getValue('overwrite.cli.url', '');
476
+            if ($webRoot === '') {
477
+                throw new InvalidArgumentException('overwrite.cli.url is empty');
478
+            }
479
+            if (!filter_var($webRoot, FILTER_VALIDATE_URL)) {
480
+                throw new InvalidArgumentException('invalid value for overwrite.cli.url');
481
+            }
482
+            $webRoot = rtrim(parse_url($webRoot, PHP_URL_PATH), '/');
483
+        } else {
484
+            $webRoot = !empty(\OC::$WEBROOT) ? \OC::$WEBROOT : '/';
485
+        }
486
+
487
+        return $webRoot;
488
+    }
489
+
490
+    /**
491
+     * Append the correct ErrorDocument path for Apache hosts
492
+     *
493
+     * @return bool True when success, False otherwise
494
+     * @throws \OCP\AppFramework\QueryException
495
+     */
496
+    public static function updateHtaccess() {
497
+        $config = \OC::$server->getSystemConfig();
498
+
499
+        try {
500
+            $webRoot = self::findWebRoot($config);
501
+        } catch (InvalidArgumentException $e) {
502
+            return false;
503
+        }
504
+
505
+        $setupHelper = new \OC\Setup(
506
+            $config,
507
+            \OC::$server->get(IniGetWrapper::class),
508
+            \OC::$server->getL10N('lib'),
509
+            \OC::$server->query(Defaults::class),
510
+            \OC::$server->getLogger(),
511
+            \OC::$server->getSecureRandom(),
512
+            \OC::$server->query(Installer::class)
513
+        );
514
+
515
+        $htaccessContent = file_get_contents($setupHelper->pathToHtaccess());
516
+        $content = "#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####\n";
517
+        $htaccessContent = explode($content, $htaccessContent, 2)[0];
518
+
519
+        //custom 403 error page
520
+        $content .= "\nErrorDocument 403 " . $webRoot . '/';
521
+
522
+        //custom 404 error page
523
+        $content .= "\nErrorDocument 404 " . $webRoot . '/';
524
+
525
+        // Add rewrite rules if the RewriteBase is configured
526
+        $rewriteBase = $config->getValue('htaccess.RewriteBase', '');
527
+        if ($rewriteBase !== '') {
528
+            $content .= "\n<IfModule mod_rewrite.c>";
529
+            $content .= "\n  Options -MultiViews";
530
+            $content .= "\n  RewriteRule ^core/js/oc.js$ index.php [PT,E=PATH_INFO:$1]";
531
+            $content .= "\n  RewriteRule ^core/preview.png$ index.php [PT,E=PATH_INFO:$1]";
532
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !\\.(css|js|svg|gif|png|html|ttf|woff2?|ico|jpg|jpeg|map|webm|mp4|mp3|ogg|wav)$";
533
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/favicon.ico$";
534
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !core/img/manifest.json$";
535
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/remote.php";
536
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/public.php";
537
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/cron.php";
538
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/core/ajax/update.php";
539
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/status.php";
540
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v1.php";
541
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs/v2.php";
542
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/robots.txt";
543
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/updater/";
544
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocs-provider/";
545
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/ocm-provider/";
546
+            $content .= "\n  RewriteCond %{REQUEST_URI} !^/\\.well-known/(acme-challenge|pki-validation)/.*";
547
+            $content .= "\n  RewriteCond %{REQUEST_FILENAME} !/richdocumentscode(_arm64)?/proxy.php$";
548
+            $content .= "\n  RewriteRule . index.php [PT,E=PATH_INFO:$1]";
549
+            $content .= "\n  RewriteBase " . $rewriteBase;
550
+            $content .= "\n  <IfModule mod_env.c>";
551
+            $content .= "\n    SetEnv front_controller_active true";
552
+            $content .= "\n    <IfModule mod_dir.c>";
553
+            $content .= "\n      DirectorySlash off";
554
+            $content .= "\n    </IfModule>";
555
+            $content .= "\n  </IfModule>";
556
+            $content .= "\n</IfModule>";
557
+        }
558
+
559
+        if ($content !== '') {
560
+            //suppress errors in case we don't have permissions for it
561
+            return (bool)@file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent . $content . "\n");
562
+        }
563
+
564
+        return false;
565
+    }
566
+
567
+    public static function protectDataDirectory() {
568
+        //Require all denied
569
+        $now = date('Y-m-d H:i:s');
570
+        $content = "# Generated by Nextcloud on $now\n";
571
+        $content .= "# Section for Apache 2.4 to 2.6\n";
572
+        $content .= "<IfModule mod_authz_core.c>\n";
573
+        $content .= "  Require all denied\n";
574
+        $content .= "</IfModule>\n";
575
+        $content .= "<IfModule mod_access_compat.c>\n";
576
+        $content .= "  Order Allow,Deny\n";
577
+        $content .= "  Deny from all\n";
578
+        $content .= "  Satisfy All\n";
579
+        $content .= "</IfModule>\n\n";
580
+        $content .= "# Section for Apache 2.2\n";
581
+        $content .= "<IfModule !mod_authz_core.c>\n";
582
+        $content .= "  <IfModule !mod_access_compat.c>\n";
583
+        $content .= "    <IfModule mod_authz_host.c>\n";
584
+        $content .= "      Order Allow,Deny\n";
585
+        $content .= "      Deny from all\n";
586
+        $content .= "    </IfModule>\n";
587
+        $content .= "    Satisfy All\n";
588
+        $content .= "  </IfModule>\n";
589
+        $content .= "</IfModule>\n\n";
590
+        $content .= "# Section for Apache 2.2 to 2.6\n";
591
+        $content .= "<IfModule mod_autoindex.c>\n";
592
+        $content .= "  IndexIgnore *\n";
593
+        $content .= "</IfModule>";
594
+
595
+        $baseDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
596
+        file_put_contents($baseDir . '/.htaccess', $content);
597
+        file_put_contents($baseDir . '/index.html', '');
598
+    }
599
+
600
+    /**
601
+     * Return vendor from which this version was published
602
+     *
603
+     * @return string Get the vendor
604
+     *
605
+     * Copy of \OC\Updater::getVendor()
606
+     */
607
+    private function getVendor() {
608
+        // this should really be a JSON file
609
+        require \OC::$SERVERROOT . '/version.php';
610
+        /** @var string $vendor */
611
+        return (string)$vendor;
612
+    }
613 613
 }
Please login to merge, or discard this patch.
Spacing   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
 	public function getSystemInfo($allowAllDatabases = false) {
216 216
 		$databases = $this->getSupportedDatabases($allowAllDatabases);
217 217
 
218
-		$dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT . '/data');
218
+		$dataDir = $this->config->getValue('datadirectory', \OC::$SERVERROOT.'/data');
219 219
 
220 220
 		$errors = [];
221 221
 
@@ -245,7 +245,7 @@  discard block
 block discarded – undo
245 245
 		if (\OC_Util::runningOnMac()) {
246 246
 			$errors[] = [
247 247
 				'error' => $this->l10n->t(
248
-					'Mac OS X is not supported and %s will not work properly on this platform. ' .
248
+					'Mac OS X is not supported and %s will not work properly on this platform. '.
249 249
 					'Use it at your own risk! ',
250 250
 					[$this->defaults->getName()]
251 251
 				),
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
 		if ($this->iniWrapper->getString('open_basedir') !== '' && PHP_INT_SIZE === 4) {
257 257
 			$errors[] = [
258 258
 				'error' => $this->l10n->t(
259
-					'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. ' .
259
+					'It seems that this %s instance is running on a 32-bit PHP environment and the open_basedir has been configured in php.ini. '.
260 260
 					'This will lead to problems with files over 4 GB and is highly discouraged.',
261 261
 					[$this->defaults->getName()]
262 262
 				),
@@ -293,7 +293,7 @@  discard block
 block discarded – undo
293 293
 			$error[] = $l->t('Set an admin password.');
294 294
 		}
295 295
 		if (empty($options['directory'])) {
296
-			$options['directory'] = \OC::$SERVERROOT . "/data";
296
+			$options['directory'] = \OC::$SERVERROOT."/data";
297 297
 		}
298 298
 
299 299
 		if (!isset(self::$dbSetupClasses[$dbType])) {
@@ -349,7 +349,7 @@  discard block
 block discarded – undo
349 349
 		];
350 350
 
351 351
 		if ($this->config->getValue('overwrite.cli.url', null) === null) {
352
-			$newConfigValues['overwrite.cli.url'] = $request->getServerProtocol() . '://' . $request->getInsecureServerHost() . \OC::$WEBROOT;
352
+			$newConfigValues['overwrite.cli.url'] = $request->getServerProtocol().'://'.$request->getInsecureServerHost().\OC::$WEBROOT;
353 353
 		}
354 354
 
355 355
 		$this->config->setValues($newConfigValues);
@@ -365,7 +365,7 @@  discard block
 block discarded – undo
365 365
 			return $error;
366 366
 		} catch (Exception $e) {
367 367
 			$error[] = [
368
-				'error' => 'Error while trying to create admin user: ' . $e->getMessage(),
368
+				'error' => 'Error while trying to create admin user: '.$e->getMessage(),
369 369
 				'hint' => '',
370 370
 			];
371 371
 			return $error;
@@ -375,7 +375,7 @@  discard block
 block discarded – undo
375 375
 			$dbSetup->runMigrations();
376 376
 		} catch (Exception $e) {
377 377
 			$error[] = [
378
-				'error' => 'Error while trying to initialise the database: ' . $e->getMessage(),
378
+				'error' => 'Error while trying to initialise the database: '.$e->getMessage(),
379 379
 				'hint' => '',
380 380
 			];
381 381
 			return $error;
@@ -416,7 +416,7 @@  discard block
 block discarded – undo
416 416
 
417 417
 			// create empty file in data dir, so we can later find
418 418
 			// out that this is indeed an ownCloud data directory
419
-			file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
419
+			file_put_contents($config->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', '');
420 420
 
421 421
 			// Update .htaccess files
422 422
 			self::updateHtaccess();
@@ -459,7 +459,7 @@  discard block
 block discarded – undo
459 459
 	 * @return string Absolute path to htaccess
460 460
 	 */
461 461
 	private function pathToHtaccess() {
462
-		return \OC::$SERVERROOT . '/.htaccess';
462
+		return \OC::$SERVERROOT.'/.htaccess';
463 463
 	}
464 464
 
465 465
 	/**
@@ -517,10 +517,10 @@  discard block
 block discarded – undo
517 517
 		$htaccessContent = explode($content, $htaccessContent, 2)[0];
518 518
 
519 519
 		//custom 403 error page
520
-		$content .= "\nErrorDocument 403 " . $webRoot . '/';
520
+		$content .= "\nErrorDocument 403 ".$webRoot.'/';
521 521
 
522 522
 		//custom 404 error page
523
-		$content .= "\nErrorDocument 404 " . $webRoot . '/';
523
+		$content .= "\nErrorDocument 404 ".$webRoot.'/';
524 524
 
525 525
 		// Add rewrite rules if the RewriteBase is configured
526 526
 		$rewriteBase = $config->getValue('htaccess.RewriteBase', '');
@@ -546,7 +546,7 @@  discard block
 block discarded – undo
546 546
 			$content .= "\n  RewriteCond %{REQUEST_URI} !^/\\.well-known/(acme-challenge|pki-validation)/.*";
547 547
 			$content .= "\n  RewriteCond %{REQUEST_FILENAME} !/richdocumentscode(_arm64)?/proxy.php$";
548 548
 			$content .= "\n  RewriteRule . index.php [PT,E=PATH_INFO:$1]";
549
-			$content .= "\n  RewriteBase " . $rewriteBase;
549
+			$content .= "\n  RewriteBase ".$rewriteBase;
550 550
 			$content .= "\n  <IfModule mod_env.c>";
551 551
 			$content .= "\n    SetEnv front_controller_active true";
552 552
 			$content .= "\n    <IfModule mod_dir.c>";
@@ -558,7 +558,7 @@  discard block
 block discarded – undo
558 558
 
559 559
 		if ($content !== '') {
560 560
 			//suppress errors in case we don't have permissions for it
561
-			return (bool)@file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent . $content . "\n");
561
+			return (bool) @file_put_contents($setupHelper->pathToHtaccess(), $htaccessContent.$content."\n");
562 562
 		}
563 563
 
564 564
 		return false;
@@ -592,9 +592,9 @@  discard block
 block discarded – undo
592 592
 		$content .= "  IndexIgnore *\n";
593 593
 		$content .= "</IfModule>";
594 594
 
595
-		$baseDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data');
596
-		file_put_contents($baseDir . '/.htaccess', $content);
597
-		file_put_contents($baseDir . '/index.html', '');
595
+		$baseDir = \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data');
596
+		file_put_contents($baseDir.'/.htaccess', $content);
597
+		file_put_contents($baseDir.'/index.html', '');
598 598
 	}
599 599
 
600 600
 	/**
@@ -606,8 +606,8 @@  discard block
 block discarded – undo
606 606
 	 */
607 607
 	private function getVendor() {
608 608
 		// this should really be a JSON file
609
-		require \OC::$SERVERROOT . '/version.php';
609
+		require \OC::$SERVERROOT.'/version.php';
610 610
 		/** @var string $vendor */
611
-		return (string)$vendor;
611
+		return (string) $vendor;
612 612
 	}
613 613
 }
Please login to merge, or discard this patch.