Passed
Push — master ( 62403d...0c3e2f )
by Joas
14:50 queued 14s
created
lib/private/Config.php 1 patch
Indentation   +202 added lines, -202 removed lines patch added patch discarded remove patch
@@ -42,232 +42,232 @@
 block discarded – undo
42 42
  */
43 43
 class Config {
44 44
 
45
-	const ENV_PREFIX = 'NC_';
45
+    const ENV_PREFIX = 'NC_';
46 46
 
47
-	/** @var array Associative array ($key => $value) */
48
-	protected $cache = [];
49
-	/** @var string */
50
-	protected $configDir;
51
-	/** @var string */
52
-	protected $configFilePath;
53
-	/** @var string */
54
-	protected $configFileName;
47
+    /** @var array Associative array ($key => $value) */
48
+    protected $cache = [];
49
+    /** @var string */
50
+    protected $configDir;
51
+    /** @var string */
52
+    protected $configFilePath;
53
+    /** @var string */
54
+    protected $configFileName;
55 55
 
56
-	/**
57
-	 * @param string $configDir Path to the config dir, needs to end with '/'
58
-	 * @param string $fileName (Optional) Name of the config file. Defaults to config.php
59
-	 */
60
-	public function __construct($configDir, $fileName = 'config.php') {
61
-		$this->configDir = $configDir;
62
-		$this->configFilePath = $this->configDir.$fileName;
63
-		$this->configFileName = $fileName;
64
-		$this->readData();
65
-	}
56
+    /**
57
+     * @param string $configDir Path to the config dir, needs to end with '/'
58
+     * @param string $fileName (Optional) Name of the config file. Defaults to config.php
59
+     */
60
+    public function __construct($configDir, $fileName = 'config.php') {
61
+        $this->configDir = $configDir;
62
+        $this->configFilePath = $this->configDir.$fileName;
63
+        $this->configFileName = $fileName;
64
+        $this->readData();
65
+    }
66 66
 
67
-	/**
68
-	 * Lists all available config keys
69
-	 *
70
-	 * Please note that it does not return the values.
71
-	 *
72
-	 * @return array an array of key names
73
-	 */
74
-	public function getKeys() {
75
-		return array_keys($this->cache);
76
-	}
67
+    /**
68
+     * Lists all available config keys
69
+     *
70
+     * Please note that it does not return the values.
71
+     *
72
+     * @return array an array of key names
73
+     */
74
+    public function getKeys() {
75
+        return array_keys($this->cache);
76
+    }
77 77
 
78
-	/**
79
-	 * Returns a config value
80
-	 *
81
-	 * gets its value from an `NC_` prefixed environment variable
82
-	 * if it doesn't exist from config.php
83
-	 * if this doesn't exist either, it will return the given `$default`
84
-	 *
85
-	 * @param string $key key
86
-	 * @param mixed $default = null default value
87
-	 * @return mixed the value or $default
88
-	 */
89
-	public function getValue($key, $default = null) {
90
-		$envValue = getenv(self::ENV_PREFIX . $key);
91
-		if ($envValue !== false) {
92
-			return $envValue;
93
-		}
78
+    /**
79
+     * Returns a config value
80
+     *
81
+     * gets its value from an `NC_` prefixed environment variable
82
+     * if it doesn't exist from config.php
83
+     * if this doesn't exist either, it will return the given `$default`
84
+     *
85
+     * @param string $key key
86
+     * @param mixed $default = null default value
87
+     * @return mixed the value or $default
88
+     */
89
+    public function getValue($key, $default = null) {
90
+        $envValue = getenv(self::ENV_PREFIX . $key);
91
+        if ($envValue !== false) {
92
+            return $envValue;
93
+        }
94 94
 
95
-		if (isset($this->cache[$key])) {
96
-			return $this->cache[$key];
97
-		}
95
+        if (isset($this->cache[$key])) {
96
+            return $this->cache[$key];
97
+        }
98 98
 
99
-		return $default;
100
-	}
99
+        return $default;
100
+    }
101 101
 
102
-	/**
103
-	 * Sets and deletes values and writes the config.php
104
-	 *
105
-	 * @param array $configs Associative array with `key => value` pairs
106
-	 *                       If value is null, the config key will be deleted
107
-	 */
108
-	public function setValues(array $configs) {
109
-		$needsUpdate = false;
110
-		foreach ($configs as $key => $value) {
111
-			if ($value !== null) {
112
-				$needsUpdate |= $this->set($key, $value);
113
-			} else {
114
-				$needsUpdate |= $this->delete($key);
115
-			}
116
-		}
102
+    /**
103
+     * Sets and deletes values and writes the config.php
104
+     *
105
+     * @param array $configs Associative array with `key => value` pairs
106
+     *                       If value is null, the config key will be deleted
107
+     */
108
+    public function setValues(array $configs) {
109
+        $needsUpdate = false;
110
+        foreach ($configs as $key => $value) {
111
+            if ($value !== null) {
112
+                $needsUpdate |= $this->set($key, $value);
113
+            } else {
114
+                $needsUpdate |= $this->delete($key);
115
+            }
116
+        }
117 117
 
118
-		if ($needsUpdate) {
119
-			// Write changes
120
-			$this->writeData();
121
-		}
122
-	}
118
+        if ($needsUpdate) {
119
+            // Write changes
120
+            $this->writeData();
121
+        }
122
+    }
123 123
 
124
-	/**
125
-	 * Sets the value and writes it to config.php if required
126
-	 *
127
-	 * @param string $key key
128
-	 * @param mixed $value value
129
-	 */
130
-	public function setValue($key, $value) {
131
-		if ($this->set($key, $value)) {
132
-			// Write changes
133
-			$this->writeData();
134
-		}
135
-	}
124
+    /**
125
+     * Sets the value and writes it to config.php if required
126
+     *
127
+     * @param string $key key
128
+     * @param mixed $value value
129
+     */
130
+    public function setValue($key, $value) {
131
+        if ($this->set($key, $value)) {
132
+            // Write changes
133
+            $this->writeData();
134
+        }
135
+    }
136 136
 
137
-	/**
138
-	 * This function sets the value
139
-	 *
140
-	 * @param string $key key
141
-	 * @param mixed $value value
142
-	 * @return bool True if the file needs to be updated, false otherwise
143
-	 */
144
-	protected function set($key, $value) {
145
-		if (!isset($this->cache[$key]) || $this->cache[$key] !== $value) {
146
-			// Add change
147
-			$this->cache[$key] = $value;
148
-			return true;
149
-		}
137
+    /**
138
+     * This function sets the value
139
+     *
140
+     * @param string $key key
141
+     * @param mixed $value value
142
+     * @return bool True if the file needs to be updated, false otherwise
143
+     */
144
+    protected function set($key, $value) {
145
+        if (!isset($this->cache[$key]) || $this->cache[$key] !== $value) {
146
+            // Add change
147
+            $this->cache[$key] = $value;
148
+            return true;
149
+        }
150 150
 
151
-		return false;
152
-	}
151
+        return false;
152
+    }
153 153
 
154
-	/**
155
-	 * Removes a key from the config and removes it from config.php if required
156
-	 * @param string $key
157
-	 */
158
-	public function deleteKey($key) {
159
-		if ($this->delete($key)) {
160
-			// Write changes
161
-			$this->writeData();
162
-		}
163
-	}
154
+    /**
155
+     * Removes a key from the config and removes it from config.php if required
156
+     * @param string $key
157
+     */
158
+    public function deleteKey($key) {
159
+        if ($this->delete($key)) {
160
+            // Write changes
161
+            $this->writeData();
162
+        }
163
+    }
164 164
 
165
-	/**
166
-	 * This function removes a key from the config
167
-	 *
168
-	 * @param string $key
169
-	 * @return bool True if the file needs to be updated, false otherwise
170
-	 */
171
-	protected function delete($key) {
172
-		if (isset($this->cache[$key])) {
173
-			// Delete key from cache
174
-			unset($this->cache[$key]);
175
-			return true;
176
-		}
177
-		return false;
178
-	}
165
+    /**
166
+     * This function removes a key from the config
167
+     *
168
+     * @param string $key
169
+     * @return bool True if the file needs to be updated, false otherwise
170
+     */
171
+    protected function delete($key) {
172
+        if (isset($this->cache[$key])) {
173
+            // Delete key from cache
174
+            unset($this->cache[$key]);
175
+            return true;
176
+        }
177
+        return false;
178
+    }
179 179
 
180
-	/**
181
-	 * Loads the config file
182
-	 *
183
-	 * Reads the config file and saves it to the cache
184
-	 *
185
-	 * @throws \Exception If no lock could be acquired or the config file has not been found
186
-	 */
187
-	private function readData() {
188
-		// Default config should always get loaded
189
-		$configFiles = [$this->configFilePath];
180
+    /**
181
+     * Loads the config file
182
+     *
183
+     * Reads the config file and saves it to the cache
184
+     *
185
+     * @throws \Exception If no lock could be acquired or the config file has not been found
186
+     */
187
+    private function readData() {
188
+        // Default config should always get loaded
189
+        $configFiles = [$this->configFilePath];
190 190
 
191
-		// Add all files in the config dir ending with the same file name
192
-		$extra = glob($this->configDir.'*.'.$this->configFileName);
193
-		if (is_array($extra)) {
194
-			natsort($extra);
195
-			$configFiles = array_merge($configFiles, $extra);
196
-		}
191
+        // Add all files in the config dir ending with the same file name
192
+        $extra = glob($this->configDir.'*.'.$this->configFileName);
193
+        if (is_array($extra)) {
194
+            natsort($extra);
195
+            $configFiles = array_merge($configFiles, $extra);
196
+        }
197 197
 
198
-		// Include file and merge config
199
-		foreach ($configFiles as $file) {
200
-			$fileExistsAndIsReadable = file_exists($file) && is_readable($file);
201
-			$filePointer = $fileExistsAndIsReadable ? fopen($file, 'r') : false;
202
-			if($file === $this->configFilePath &&
203
-				$filePointer === false) {
204
-				// Opening the main config might not be possible, e.g. if the wrong
205
-				// permissions are set (likely on a new installation)
206
-				continue;
207
-			}
198
+        // Include file and merge config
199
+        foreach ($configFiles as $file) {
200
+            $fileExistsAndIsReadable = file_exists($file) && is_readable($file);
201
+            $filePointer = $fileExistsAndIsReadable ? fopen($file, 'r') : false;
202
+            if($file === $this->configFilePath &&
203
+                $filePointer === false) {
204
+                // Opening the main config might not be possible, e.g. if the wrong
205
+                // permissions are set (likely on a new installation)
206
+                continue;
207
+            }
208 208
 
209
-			// Try to acquire a file lock
210
-			if(!flock($filePointer, LOCK_SH)) {
211
-				throw new \Exception(sprintf('Could not acquire a shared lock on the config file %s', $file));
212
-			}
209
+            // Try to acquire a file lock
210
+            if(!flock($filePointer, LOCK_SH)) {
211
+                throw new \Exception(sprintf('Could not acquire a shared lock on the config file %s', $file));
212
+            }
213 213
 
214
-			unset($CONFIG);
215
-			include $file;
216
-			if(isset($CONFIG) && is_array($CONFIG)) {
217
-				$this->cache = array_merge($this->cache, $CONFIG);
218
-			}
214
+            unset($CONFIG);
215
+            include $file;
216
+            if(isset($CONFIG) && is_array($CONFIG)) {
217
+                $this->cache = array_merge($this->cache, $CONFIG);
218
+            }
219 219
 
220
-			// Close the file pointer and release the lock
221
-			flock($filePointer, LOCK_UN);
222
-			fclose($filePointer);
223
-		}
224
-	}
220
+            // Close the file pointer and release the lock
221
+            flock($filePointer, LOCK_UN);
222
+            fclose($filePointer);
223
+        }
224
+    }
225 225
 
226
-	/**
227
-	 * Writes the config file
228
-	 *
229
-	 * Saves the config to the config file.
230
-	 *
231
-	 * @throws HintException If the config file cannot be written to
232
-	 * @throws \Exception If no file lock can be acquired
233
-	 */
234
-	private function writeData() {
235
-		// Create a php file ...
236
-		$content = "<?php\n";
237
-		$content .= '$CONFIG = ';
238
-		$content .= var_export($this->cache, true);
239
-		$content .= ";\n";
226
+    /**
227
+     * Writes the config file
228
+     *
229
+     * Saves the config to the config file.
230
+     *
231
+     * @throws HintException If the config file cannot be written to
232
+     * @throws \Exception If no file lock can be acquired
233
+     */
234
+    private function writeData() {
235
+        // Create a php file ...
236
+        $content = "<?php\n";
237
+        $content .= '$CONFIG = ';
238
+        $content .= var_export($this->cache, true);
239
+        $content .= ";\n";
240 240
 
241
-		touch ($this->configFilePath);
242
-		$filePointer = fopen($this->configFilePath, 'r+');
241
+        touch ($this->configFilePath);
242
+        $filePointer = fopen($this->configFilePath, 'r+');
243 243
 
244
-		// Prevent others not to read the config
245
-		chmod($this->configFilePath, 0640);
244
+        // Prevent others not to read the config
245
+        chmod($this->configFilePath, 0640);
246 246
 
247
-		// File does not exist, this can happen when doing a fresh install
248
-		if(!is_resource ($filePointer)) {
249
-			// TODO fix this via DI once it is very clear that this doesn't cause side effects due to initialization order
250
-			// currently this breaks app routes but also could have other side effects especially during setup and exception handling
251
-			$url = \OC::$server->getURLGenerator()->linkToDocs('admin-dir_permissions');
252
-			throw new HintException(
253
-				"Can't write into config directory!",
254
-				'This can usually be fixed by giving the webserver write access to the config directory. See ' . $url);
255
-		}
247
+        // File does not exist, this can happen when doing a fresh install
248
+        if(!is_resource ($filePointer)) {
249
+            // TODO fix this via DI once it is very clear that this doesn't cause side effects due to initialization order
250
+            // currently this breaks app routes but also could have other side effects especially during setup and exception handling
251
+            $url = \OC::$server->getURLGenerator()->linkToDocs('admin-dir_permissions');
252
+            throw new HintException(
253
+                "Can't write into config directory!",
254
+                'This can usually be fixed by giving the webserver write access to the config directory. See ' . $url);
255
+        }
256 256
 
257
-		// Try to acquire a file lock
258
-		if(!flock($filePointer, LOCK_EX)) {
259
-			throw new \Exception(sprintf('Could not acquire an exclusive lock on the config file %s', $this->configFilePath));
260
-		}
257
+        // Try to acquire a file lock
258
+        if(!flock($filePointer, LOCK_EX)) {
259
+            throw new \Exception(sprintf('Could not acquire an exclusive lock on the config file %s', $this->configFilePath));
260
+        }
261 261
 
262
-		// Write the config and release the lock
263
-		ftruncate ($filePointer, 0);
264
-		fwrite($filePointer, $content);
265
-		fflush($filePointer);
266
-		flock($filePointer, LOCK_UN);
267
-		fclose($filePointer);
262
+        // Write the config and release the lock
263
+        ftruncate ($filePointer, 0);
264
+        fwrite($filePointer, $content);
265
+        fflush($filePointer);
266
+        flock($filePointer, LOCK_UN);
267
+        fclose($filePointer);
268 268
 
269
-		if (function_exists('opcache_invalidate')) {
270
-			@opcache_invalidate($this->configFilePath, true);
271
-		}
272
-	}
269
+        if (function_exists('opcache_invalidate')) {
270
+            @opcache_invalidate($this->configFilePath, true);
271
+        }
272
+    }
273 273
 }
Please login to merge, or discard this patch.
lib/private/Setup/AbstractDatabase.php 1 patch
Indentation   +104 added lines, -104 removed lines patch added patch discarded remove patch
@@ -38,118 +38,118 @@
 block discarded – undo
38 38
 
39 39
 abstract class AbstractDatabase {
40 40
 
41
-	/** @var IL10N */
42
-	protected $trans;
43
-	/** @var string */
44
-	protected $dbUser;
45
-	/** @var string */
46
-	protected $dbPassword;
47
-	/** @var string */
48
-	protected $dbName;
49
-	/** @var string */
50
-	protected $dbHost;
51
-	/** @var string */
52
-	protected $dbPort;
53
-	/** @var string */
54
-	protected $tablePrefix;
55
-	/** @var SystemConfig */
56
-	protected $config;
57
-	/** @var ILogger */
58
-	protected $logger;
59
-	/** @var ISecureRandom */
60
-	protected $random;
41
+    /** @var IL10N */
42
+    protected $trans;
43
+    /** @var string */
44
+    protected $dbUser;
45
+    /** @var string */
46
+    protected $dbPassword;
47
+    /** @var string */
48
+    protected $dbName;
49
+    /** @var string */
50
+    protected $dbHost;
51
+    /** @var string */
52
+    protected $dbPort;
53
+    /** @var string */
54
+    protected $tablePrefix;
55
+    /** @var SystemConfig */
56
+    protected $config;
57
+    /** @var ILogger */
58
+    protected $logger;
59
+    /** @var ISecureRandom */
60
+    protected $random;
61 61
 
62
-	public function __construct(IL10N $trans, SystemConfig $config, ILogger $logger, ISecureRandom $random) {
63
-		$this->trans = $trans;
64
-		$this->config = $config;
65
-		$this->logger = $logger;
66
-		$this->random = $random;
67
-	}
62
+    public function __construct(IL10N $trans, SystemConfig $config, ILogger $logger, ISecureRandom $random) {
63
+        $this->trans = $trans;
64
+        $this->config = $config;
65
+        $this->logger = $logger;
66
+        $this->random = $random;
67
+    }
68 68
 
69
-	public function validate($config) {
70
-		$errors = [];
71
-		if(empty($config['dbuser']) && empty($config['dbname'])) {
72
-			$errors[] = $this->trans->t("%s enter the database username and name.", [$this->dbprettyname]);
73
-		} else if(empty($config['dbuser'])) {
74
-			$errors[] = $this->trans->t("%s enter the database username.", [$this->dbprettyname]);
75
-		} else if(empty($config['dbname'])) {
76
-			$errors[] = $this->trans->t("%s enter the database name.", [$this->dbprettyname]);
77
-		}
78
-		if(substr_count($config['dbname'], '.') >= 1) {
79
-			$errors[] = $this->trans->t("%s you may not use dots in the database name", [$this->dbprettyname]);
80
-		}
81
-		return $errors;
82
-	}
69
+    public function validate($config) {
70
+        $errors = [];
71
+        if(empty($config['dbuser']) && empty($config['dbname'])) {
72
+            $errors[] = $this->trans->t("%s enter the database username and name.", [$this->dbprettyname]);
73
+        } else if(empty($config['dbuser'])) {
74
+            $errors[] = $this->trans->t("%s enter the database username.", [$this->dbprettyname]);
75
+        } else if(empty($config['dbname'])) {
76
+            $errors[] = $this->trans->t("%s enter the database name.", [$this->dbprettyname]);
77
+        }
78
+        if(substr_count($config['dbname'], '.') >= 1) {
79
+            $errors[] = $this->trans->t("%s you may not use dots in the database name", [$this->dbprettyname]);
80
+        }
81
+        return $errors;
82
+    }
83 83
 
84
-	public function initialize($config) {
85
-		$dbUser = $config['dbuser'];
86
-		$dbPass = $config['dbpass'];
87
-		$dbName = $config['dbname'];
88
-		$dbHost = !empty($config['dbhost']) ? $config['dbhost'] : 'localhost';
89
-		$dbPort = !empty($config['dbport']) ? $config['dbport'] : '';
90
-		$dbTablePrefix = isset($config['dbtableprefix']) ? $config['dbtableprefix'] : 'oc_';
84
+    public function initialize($config) {
85
+        $dbUser = $config['dbuser'];
86
+        $dbPass = $config['dbpass'];
87
+        $dbName = $config['dbname'];
88
+        $dbHost = !empty($config['dbhost']) ? $config['dbhost'] : 'localhost';
89
+        $dbPort = !empty($config['dbport']) ? $config['dbport'] : '';
90
+        $dbTablePrefix = isset($config['dbtableprefix']) ? $config['dbtableprefix'] : 'oc_';
91 91
 
92
-		$this->config->setValues([
93
-			'dbname'		=> $dbName,
94
-			'dbhost'		=> $dbHost,
95
-			'dbport' => $dbPort,
96
-			'dbtableprefix'	=> $dbTablePrefix,
97
-		]);
92
+        $this->config->setValues([
93
+            'dbname'		=> $dbName,
94
+            'dbhost'		=> $dbHost,
95
+            'dbport' => $dbPort,
96
+            'dbtableprefix'	=> $dbTablePrefix,
97
+        ]);
98 98
 
99
-		$this->dbUser = $dbUser;
100
-		$this->dbPassword = $dbPass;
101
-		$this->dbName = $dbName;
102
-		$this->dbHost = $dbHost;
103
-		$this->dbPort = $dbPort;
104
-		$this->tablePrefix = $dbTablePrefix;
105
-	}
99
+        $this->dbUser = $dbUser;
100
+        $this->dbPassword = $dbPass;
101
+        $this->dbName = $dbName;
102
+        $this->dbHost = $dbHost;
103
+        $this->dbPort = $dbPort;
104
+        $this->tablePrefix = $dbTablePrefix;
105
+    }
106 106
 
107
-	/**
108
-	 * @param array $configOverwrite
109
-	 * @return \OC\DB\Connection
110
-	 */
111
-	protected function connect(array $configOverwrite = []) {
112
-		$connectionParams = [
113
-			'host' => $this->dbHost,
114
-			'user' => $this->dbUser,
115
-			'password' => $this->dbPassword,
116
-			'tablePrefix' => $this->tablePrefix,
117
-			'dbname' => $this->dbName
118
-		];
107
+    /**
108
+     * @param array $configOverwrite
109
+     * @return \OC\DB\Connection
110
+     */
111
+    protected function connect(array $configOverwrite = []) {
112
+        $connectionParams = [
113
+            'host' => $this->dbHost,
114
+            'user' => $this->dbUser,
115
+            'password' => $this->dbPassword,
116
+            'tablePrefix' => $this->tablePrefix,
117
+            'dbname' => $this->dbName
118
+        ];
119 119
 
120
-		// adding port support through installer
121
-		if (!empty($this->dbPort)) {
122
-			if (ctype_digit($this->dbPort)) {
123
-				$connectionParams['port'] = $this->dbPort;
124
-			} else {
125
-				$connectionParams['unix_socket'] = $this->dbPort;
126
-			}
127
-		} else if (strpos($this->dbHost, ':')) {
128
-			// Host variable may carry a port or socket.
129
-			list($host, $portOrSocket) = explode(':', $this->dbHost, 2);
130
-			if (ctype_digit($portOrSocket)) {
131
-				$connectionParams['port'] = $portOrSocket;
132
-			} else {
133
-				$connectionParams['unix_socket'] = $portOrSocket;
134
-			}
135
-			$connectionParams['host'] = $host;
136
-		}
120
+        // adding port support through installer
121
+        if (!empty($this->dbPort)) {
122
+            if (ctype_digit($this->dbPort)) {
123
+                $connectionParams['port'] = $this->dbPort;
124
+            } else {
125
+                $connectionParams['unix_socket'] = $this->dbPort;
126
+            }
127
+        } else if (strpos($this->dbHost, ':')) {
128
+            // Host variable may carry a port or socket.
129
+            list($host, $portOrSocket) = explode(':', $this->dbHost, 2);
130
+            if (ctype_digit($portOrSocket)) {
131
+                $connectionParams['port'] = $portOrSocket;
132
+            } else {
133
+                $connectionParams['unix_socket'] = $portOrSocket;
134
+            }
135
+            $connectionParams['host'] = $host;
136
+        }
137 137
 
138
-		$connectionParams = array_merge($connectionParams, $configOverwrite);
139
-		$cf = new ConnectionFactory($this->config);
140
-		return $cf->getConnection($this->config->getValue('dbtype', 'sqlite'), $connectionParams);
141
-	}
138
+        $connectionParams = array_merge($connectionParams, $configOverwrite);
139
+        $cf = new ConnectionFactory($this->config);
140
+        return $cf->getConnection($this->config->getValue('dbtype', 'sqlite'), $connectionParams);
141
+    }
142 142
 
143
-	/**
144
-	 * @param string $userName
145
-	 */
146
-	abstract public function setupDatabase($userName);
143
+    /**
144
+     * @param string $userName
145
+     */
146
+    abstract public function setupDatabase($userName);
147 147
 
148
-	public function runMigrations() {
149
-		if (!is_dir(\OC::$SERVERROOT."/core/Migrations")) {
150
-			return;
151
-		}
152
-		$ms = new MigrationService('core', \OC::$server->getDatabaseConnection());
153
-		$ms->migrate();
154
-	}
148
+    public function runMigrations() {
149
+        if (!is_dir(\OC::$SERVERROOT."/core/Migrations")) {
150
+            return;
151
+        }
152
+        $ms = new MigrationService('core', \OC::$server->getDatabaseConnection());
153
+        $ms->migrate();
154
+    }
155 155
 }
Please login to merge, or discard this patch.
lib/private/Setup/Sqlite.php 1 patch
Indentation   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -26,14 +26,14 @@  discard block
 block discarded – undo
26 26
 use OC\DB\ConnectionFactory;
27 27
 
28 28
 class Sqlite extends AbstractDatabase {
29
-	public $dbprettyname = 'Sqlite';
29
+    public $dbprettyname = 'Sqlite';
30 30
 
31
-	public function validate($config) {
32
-		return [];
33
-	}
31
+    public function validate($config) {
32
+        return [];
33
+    }
34 34
 
35
-	public function initialize($config) {
36
-		/*
35
+    public function initialize($config) {
36
+        /*
37 37
 		 * Web: When using web based installer its not possible to set dbname
38 38
 		 * or dbtableprefix. Defaults used from ConnectionFactory and dbtype = 'sqlite'
39 39
 		 * is written to config.php.
@@ -44,32 +44,32 @@  discard block
 block discarded – undo
44 44
 		 * in connection factory configuration is obtained from config.php.
45 45
 		 */
46 46
 
47
-		$this->dbName = empty($config['dbname'])
48
-			? ConnectionFactory::DEFAULT_DBNAME
49
-			: $config['dbname'];
47
+        $this->dbName = empty($config['dbname'])
48
+            ? ConnectionFactory::DEFAULT_DBNAME
49
+            : $config['dbname'];
50 50
 
51
-		$this->tablePrefix = empty($config['dbtableprefix'])
52
-			? ConnectionFactory::DEFAULT_DBTABLEPREFIX
53
-			: $config['dbtableprefix'];
51
+        $this->tablePrefix = empty($config['dbtableprefix'])
52
+            ? ConnectionFactory::DEFAULT_DBTABLEPREFIX
53
+            : $config['dbtableprefix'];
54 54
 
55
-		if ($this->dbName !== ConnectionFactory::DEFAULT_DBNAME) {
56
-			$this->config->setValue('dbname', $this->dbName);
57
-		}
55
+        if ($this->dbName !== ConnectionFactory::DEFAULT_DBNAME) {
56
+            $this->config->setValue('dbname', $this->dbName);
57
+        }
58 58
 
59
-		if ($this->tablePrefix !== ConnectionFactory::DEFAULT_DBTABLEPREFIX) {
60
-			$this->config->setValue('dbtableprefix', $this->tablePrefix);
61
-		}
62
-	}
59
+        if ($this->tablePrefix !== ConnectionFactory::DEFAULT_DBTABLEPREFIX) {
60
+            $this->config->setValue('dbtableprefix', $this->tablePrefix);
61
+        }
62
+    }
63 63
 
64
-	public function setupDatabase($username) {
65
-		$datadir = $this->config->getValue(
66
-			'datadirectory',
67
-			\OC::$SERVERROOT . '/data'
68
-		);
64
+    public function setupDatabase($username) {
65
+        $datadir = $this->config->getValue(
66
+            'datadirectory',
67
+            \OC::$SERVERROOT . '/data'
68
+        );
69 69
 
70
-		$sqliteFile = $datadir . '/' . $this->dbName . 'db';
71
-		if (file_exists($sqliteFile)) {
72
-			unlink($sqliteFile);
73
-		}
74
-	}
70
+        $sqliteFile = $datadir . '/' . $this->dbName . 'db';
71
+        if (file_exists($sqliteFile)) {
72
+            unlink($sqliteFile);
73
+        }
74
+    }
75 75
 }
Please login to merge, or discard this patch.
lib/private/Setup/OCI.php 1 patch
Indentation   +70 added lines, -70 removed lines patch added patch discarded remove patch
@@ -31,81 +31,81 @@
 block discarded – undo
31 31
 namespace OC\Setup;
32 32
 
33 33
 class OCI extends AbstractDatabase {
34
-	public $dbprettyname = 'Oracle';
34
+    public $dbprettyname = 'Oracle';
35 35
 
36
-	protected $dbtablespace;
36
+    protected $dbtablespace;
37 37
 
38
-	public function initialize($config) {
39
-		parent::initialize($config);
40
-		if (array_key_exists('dbtablespace', $config)) {
41
-			$this->dbtablespace = $config['dbtablespace'];
42
-		} else {
43
-			$this->dbtablespace = 'USERS';
44
-		}
45
-		// allow empty hostname for oracle
46
-		$this->dbHost = $config['dbhost'];
38
+    public function initialize($config) {
39
+        parent::initialize($config);
40
+        if (array_key_exists('dbtablespace', $config)) {
41
+            $this->dbtablespace = $config['dbtablespace'];
42
+        } else {
43
+            $this->dbtablespace = 'USERS';
44
+        }
45
+        // allow empty hostname for oracle
46
+        $this->dbHost = $config['dbhost'];
47 47
 
48
-		$this->config->setValues([
49
-			'dbhost' => $this->dbHost,
50
-			'dbtablespace' => $this->dbtablespace,
51
-		]);
52
-	}
48
+        $this->config->setValues([
49
+            'dbhost' => $this->dbHost,
50
+            'dbtablespace' => $this->dbtablespace,
51
+        ]);
52
+    }
53 53
 
54
-	public function validate($config) {
55
-		$errors = [];
56
-		if (empty($config['dbuser']) && empty($config['dbname'])) {
57
-			$errors[] = $this->trans->t("%s enter the database username and name.", [$this->dbprettyname]);
58
-		} else if (empty($config['dbuser'])) {
59
-			$errors[] = $this->trans->t("%s enter the database username.", [$this->dbprettyname]);
60
-		} else if (empty($config['dbname'])) {
61
-			$errors[] = $this->trans->t("%s enter the database name.", [$this->dbprettyname]);
62
-		}
63
-		return $errors;
64
-	}
54
+    public function validate($config) {
55
+        $errors = [];
56
+        if (empty($config['dbuser']) && empty($config['dbname'])) {
57
+            $errors[] = $this->trans->t("%s enter the database username and name.", [$this->dbprettyname]);
58
+        } else if (empty($config['dbuser'])) {
59
+            $errors[] = $this->trans->t("%s enter the database username.", [$this->dbprettyname]);
60
+        } else if (empty($config['dbname'])) {
61
+            $errors[] = $this->trans->t("%s enter the database name.", [$this->dbprettyname]);
62
+        }
63
+        return $errors;
64
+    }
65 65
 
66
-	public function setupDatabase($username) {
67
-		try {
68
-			$this->connect();
69
-		} catch (\Exception $e) {
70
-			$errorMessage = $this->getLastError();
71
-			if ($errorMessage) {
72
-				throw new \OC\DatabaseSetupException($this->trans->t('Oracle connection could not be established'),
73
-					$errorMessage . ' Check environment: ORACLE_HOME=' . getenv('ORACLE_HOME')
74
-					. ' ORACLE_SID=' . getenv('ORACLE_SID')
75
-					. ' LD_LIBRARY_PATH=' . getenv('LD_LIBRARY_PATH')
76
-					. ' NLS_LANG=' . getenv('NLS_LANG')
77
-					. ' tnsnames.ora is ' . (is_readable(getenv('ORACLE_HOME') . '/network/admin/tnsnames.ora') ? '' : 'not ') . 'readable');
78
-			}
79
-			throw new \OC\DatabaseSetupException($this->trans->t('Oracle username and/or password not valid'),
80
-				'Check environment: ORACLE_HOME=' . getenv('ORACLE_HOME')
81
-				. ' ORACLE_SID=' . getenv('ORACLE_SID')
82
-				. ' LD_LIBRARY_PATH=' . getenv('LD_LIBRARY_PATH')
83
-				. ' NLS_LANG=' . getenv('NLS_LANG')
84
-				. ' tnsnames.ora is ' . (is_readable(getenv('ORACLE_HOME') . '/network/admin/tnsnames.ora') ? '' : 'not ') . 'readable');
85
-		}
66
+    public function setupDatabase($username) {
67
+        try {
68
+            $this->connect();
69
+        } catch (\Exception $e) {
70
+            $errorMessage = $this->getLastError();
71
+            if ($errorMessage) {
72
+                throw new \OC\DatabaseSetupException($this->trans->t('Oracle connection could not be established'),
73
+                    $errorMessage . ' Check environment: ORACLE_HOME=' . getenv('ORACLE_HOME')
74
+                    . ' ORACLE_SID=' . getenv('ORACLE_SID')
75
+                    . ' LD_LIBRARY_PATH=' . getenv('LD_LIBRARY_PATH')
76
+                    . ' NLS_LANG=' . getenv('NLS_LANG')
77
+                    . ' tnsnames.ora is ' . (is_readable(getenv('ORACLE_HOME') . '/network/admin/tnsnames.ora') ? '' : 'not ') . 'readable');
78
+            }
79
+            throw new \OC\DatabaseSetupException($this->trans->t('Oracle username and/or password not valid'),
80
+                'Check environment: ORACLE_HOME=' . getenv('ORACLE_HOME')
81
+                . ' ORACLE_SID=' . getenv('ORACLE_SID')
82
+                . ' LD_LIBRARY_PATH=' . getenv('LD_LIBRARY_PATH')
83
+                . ' NLS_LANG=' . getenv('NLS_LANG')
84
+                . ' tnsnames.ora is ' . (is_readable(getenv('ORACLE_HOME') . '/network/admin/tnsnames.ora') ? '' : 'not ') . 'readable');
85
+        }
86 86
 
87
-		$this->config->setValues([
88
-			'dbuser' => $this->dbUser,
89
-			'dbname' => $this->dbName,
90
-			'dbpassword' => $this->dbPassword,
91
-		]);
92
-	}
87
+        $this->config->setValues([
88
+            'dbuser' => $this->dbUser,
89
+            'dbname' => $this->dbName,
90
+            'dbpassword' => $this->dbPassword,
91
+        ]);
92
+    }
93 93
 
94
-	/**
95
-	 * @param resource $connection
96
-	 * @return string
97
-	 */
98
-	protected function getLastError($connection = null) {
99
-		if ($connection) {
100
-			$error = oci_error($connection);
101
-		} else {
102
-			$error = oci_error();
103
-		}
104
-		foreach (['message', 'code'] as $key) {
105
-			if (isset($error[$key])) {
106
-				return $error[$key];
107
-			}
108
-		}
109
-		return '';
110
-	}
94
+    /**
95
+     * @param resource $connection
96
+     * @return string
97
+     */
98
+    protected function getLastError($connection = null) {
99
+        if ($connection) {
100
+            $error = oci_error($connection);
101
+        } else {
102
+            $error = oci_error();
103
+        }
104
+        foreach (['message', 'code'] as $key) {
105
+            if (isset($error[$key])) {
106
+                return $error[$key];
107
+            }
108
+        }
109
+        return '';
110
+    }
111 111
 }
Please login to merge, or discard this patch.
lib/private/Repair.php 1 patch
Indentation   +174 added lines, -174 removed lines patch added patch discarded remove patch
@@ -68,178 +68,178 @@
 block discarded – undo
68 68
 
69 69
 class Repair implements IOutput {
70 70
 
71
-	/** @var IRepairStep[] */
72
-	private $repairSteps;
73
-
74
-	/** @var EventDispatcherInterface */
75
-	private $dispatcher;
76
-
77
-	/** @var string */
78
-	private $currentStep;
79
-
80
-	/**
81
-	 * Creates a new repair step runner
82
-	 *
83
-	 * @param IRepairStep[] $repairSteps array of RepairStep instances
84
-	 * @param EventDispatcherInterface $dispatcher
85
-	 */
86
-	public function __construct(array $repairSteps, EventDispatcherInterface $dispatcher) {
87
-		$this->repairSteps = $repairSteps;
88
-		$this->dispatcher  = $dispatcher;
89
-	}
90
-
91
-	/**
92
-	 * Run a series of repair steps for common problems
93
-	 */
94
-	public function run() {
95
-		if (count($this->repairSteps) === 0) {
96
-			$this->emit('\OC\Repair', 'info', ['No repair steps available']);
97
-
98
-			return;
99
-		}
100
-		// run each repair step
101
-		foreach ($this->repairSteps as $step) {
102
-			$this->currentStep = $step->getName();
103
-			$this->emit('\OC\Repair', 'step', [$this->currentStep]);
104
-			$step->run($this);
105
-		}
106
-	}
107
-
108
-	/**
109
-	 * Add repair step
110
-	 *
111
-	 * @param IRepairStep|string $repairStep repair step
112
-	 * @throws \Exception
113
-	 */
114
-	public function addStep($repairStep) {
115
-		if (is_string($repairStep)) {
116
-			try {
117
-				$s = \OC::$server->query($repairStep);
118
-			} catch (QueryException $e) {
119
-				if (class_exists($repairStep)) {
120
-					$s = new $repairStep();
121
-				} else {
122
-					throw new \Exception("Repair step '$repairStep' is unknown");
123
-				}
124
-			}
125
-
126
-			if ($s instanceof IRepairStep) {
127
-				$this->repairSteps[] = $s;
128
-			} else {
129
-				throw new \Exception("Repair step '$repairStep' is not of type \\OCP\\Migration\\IRepairStep");
130
-			}
131
-		} else {
132
-			$this->repairSteps[] = $repairStep;
133
-		}
134
-	}
135
-
136
-	/**
137
-	 * Returns the default repair steps to be run on the
138
-	 * command line or after an upgrade.
139
-	 *
140
-	 * @return IRepairStep[]
141
-	 */
142
-	public static function getRepairSteps() {
143
-		return [
144
-			new Collation(\OC::$server->getConfig(), \OC::$server->getLogger(), \OC::$server->getDatabaseConnection(), false),
145
-			new RepairMimeTypes(\OC::$server->getConfig()),
146
-			new CleanTags(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager()),
147
-			new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
148
-			new MoveUpdaterStepFile(\OC::$server->getConfig()),
149
-			new FixMountStorages(\OC::$server->getDatabaseConnection()),
150
-			new AddLogRotateJob(\OC::$server->getJobList()),
151
-			new ClearFrontendCaches(\OC::$server->getMemCacheFactory(), \OC::$server->query(SCSSCacher::class), \OC::$server->query(JSCombiner::class)),
152
-			new ClearGeneratedAvatarCache(\OC::$server->getConfig(), \OC::$server->query(AvatarManager::class)),
153
-			new AddPreviewBackgroundCleanupJob(\OC::$server->getJobList()),
154
-			new AddCleanupUpdaterBackupsJob(\OC::$server->getJobList()),
155
-			new CleanupCardDAVPhotoCache(\OC::$server->getConfig(), \OC::$server->getAppDataDir('dav-photocache'), \OC::$server->getLogger()),
156
-			new AddClenupLoginFlowV2BackgroundJob(\OC::$server->getJobList()),
157
-			new RemoveLinkShares(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig(), \OC::$server->getGroupManager(), \OC::$server->getNotificationManager(), \OC::$server->query(ITimeFactory::class)),
158
-			new ClearCollectionsAccessCache(\OC::$server->getConfig(), \OC::$server->query(IManager::class)),
159
-			\OC::$server->query(SwitchUpdateChannel::class),
160
-			\OC::$server->query(SetEnterpriseLogo::class),
161
-			\OC::$server->query(ResetGeneratedAvatarFlag::class),
162
-		];
163
-	}
164
-
165
-	/**
166
-	 * Returns expensive repair steps to be run on the
167
-	 * command line with a special option.
168
-	 *
169
-	 * @return IRepairStep[]
170
-	 */
171
-	public static function getExpensiveRepairSteps() {
172
-		return [
173
-			new OldGroupMembershipShares(\OC::$server->getDatabaseConnection(), \OC::$server->getGroupManager())
174
-		];
175
-	}
176
-
177
-	/**
178
-	 * Returns the repair steps to be run before an
179
-	 * upgrade.
180
-	 *
181
-	 * @return IRepairStep[]
182
-	 */
183
-	public static function getBeforeUpgradeRepairSteps() {
184
-		$connection = \OC::$server->getDatabaseConnection();
185
-		$config     = \OC::$server->getConfig();
186
-		$steps      = [
187
-			new Collation(\OC::$server->getConfig(), \OC::$server->getLogger(), $connection, true),
188
-			new SqliteAutoincrement($connection),
189
-			new SaveAccountsTableData($connection, $config),
190
-			new DropAccountTermsTable($connection)
191
-		];
192
-
193
-		return $steps;
194
-	}
195
-
196
-	/**
197
-	 * @param string $scope
198
-	 * @param string $method
199
-	 * @param array $arguments
200
-	 */
201
-	public function emit($scope, $method, array $arguments = []) {
202
-		if (!is_null($this->dispatcher)) {
203
-			$this->dispatcher->dispatch("$scope::$method",
204
-				new GenericEvent("$scope::$method", $arguments));
205
-		}
206
-	}
207
-
208
-	public function info($string) {
209
-		// for now just emit as we did in the past
210
-		$this->emit('\OC\Repair', 'info', [$string]);
211
-	}
212
-
213
-	/**
214
-	 * @param string $message
215
-	 */
216
-	public function warning($message) {
217
-		// for now just emit as we did in the past
218
-		$this->emit('\OC\Repair', 'warning', [$message]);
219
-	}
220
-
221
-	/**
222
-	 * @param int $max
223
-	 */
224
-	public function startProgress($max = 0) {
225
-		// for now just emit as we did in the past
226
-		$this->emit('\OC\Repair', 'startProgress', [$max, $this->currentStep]);
227
-	}
228
-
229
-	/**
230
-	 * @param int $step
231
-	 * @param string $description
232
-	 */
233
-	public function advance($step = 1, $description = '') {
234
-		// for now just emit as we did in the past
235
-		$this->emit('\OC\Repair', 'advance', [$step, $description]);
236
-	}
237
-
238
-	/**
239
-	 * @param int $max
240
-	 */
241
-	public function finishProgress() {
242
-		// for now just emit as we did in the past
243
-		$this->emit('\OC\Repair', 'finishProgress', []);
244
-	}
71
+    /** @var IRepairStep[] */
72
+    private $repairSteps;
73
+
74
+    /** @var EventDispatcherInterface */
75
+    private $dispatcher;
76
+
77
+    /** @var string */
78
+    private $currentStep;
79
+
80
+    /**
81
+     * Creates a new repair step runner
82
+     *
83
+     * @param IRepairStep[] $repairSteps array of RepairStep instances
84
+     * @param EventDispatcherInterface $dispatcher
85
+     */
86
+    public function __construct(array $repairSteps, EventDispatcherInterface $dispatcher) {
87
+        $this->repairSteps = $repairSteps;
88
+        $this->dispatcher  = $dispatcher;
89
+    }
90
+
91
+    /**
92
+     * Run a series of repair steps for common problems
93
+     */
94
+    public function run() {
95
+        if (count($this->repairSteps) === 0) {
96
+            $this->emit('\OC\Repair', 'info', ['No repair steps available']);
97
+
98
+            return;
99
+        }
100
+        // run each repair step
101
+        foreach ($this->repairSteps as $step) {
102
+            $this->currentStep = $step->getName();
103
+            $this->emit('\OC\Repair', 'step', [$this->currentStep]);
104
+            $step->run($this);
105
+        }
106
+    }
107
+
108
+    /**
109
+     * Add repair step
110
+     *
111
+     * @param IRepairStep|string $repairStep repair step
112
+     * @throws \Exception
113
+     */
114
+    public function addStep($repairStep) {
115
+        if (is_string($repairStep)) {
116
+            try {
117
+                $s = \OC::$server->query($repairStep);
118
+            } catch (QueryException $e) {
119
+                if (class_exists($repairStep)) {
120
+                    $s = new $repairStep();
121
+                } else {
122
+                    throw new \Exception("Repair step '$repairStep' is unknown");
123
+                }
124
+            }
125
+
126
+            if ($s instanceof IRepairStep) {
127
+                $this->repairSteps[] = $s;
128
+            } else {
129
+                throw new \Exception("Repair step '$repairStep' is not of type \\OCP\\Migration\\IRepairStep");
130
+            }
131
+        } else {
132
+            $this->repairSteps[] = $repairStep;
133
+        }
134
+    }
135
+
136
+    /**
137
+     * Returns the default repair steps to be run on the
138
+     * command line or after an upgrade.
139
+     *
140
+     * @return IRepairStep[]
141
+     */
142
+    public static function getRepairSteps() {
143
+        return [
144
+            new Collation(\OC::$server->getConfig(), \OC::$server->getLogger(), \OC::$server->getDatabaseConnection(), false),
145
+            new RepairMimeTypes(\OC::$server->getConfig()),
146
+            new CleanTags(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager()),
147
+            new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
148
+            new MoveUpdaterStepFile(\OC::$server->getConfig()),
149
+            new FixMountStorages(\OC::$server->getDatabaseConnection()),
150
+            new AddLogRotateJob(\OC::$server->getJobList()),
151
+            new ClearFrontendCaches(\OC::$server->getMemCacheFactory(), \OC::$server->query(SCSSCacher::class), \OC::$server->query(JSCombiner::class)),
152
+            new ClearGeneratedAvatarCache(\OC::$server->getConfig(), \OC::$server->query(AvatarManager::class)),
153
+            new AddPreviewBackgroundCleanupJob(\OC::$server->getJobList()),
154
+            new AddCleanupUpdaterBackupsJob(\OC::$server->getJobList()),
155
+            new CleanupCardDAVPhotoCache(\OC::$server->getConfig(), \OC::$server->getAppDataDir('dav-photocache'), \OC::$server->getLogger()),
156
+            new AddClenupLoginFlowV2BackgroundJob(\OC::$server->getJobList()),
157
+            new RemoveLinkShares(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig(), \OC::$server->getGroupManager(), \OC::$server->getNotificationManager(), \OC::$server->query(ITimeFactory::class)),
158
+            new ClearCollectionsAccessCache(\OC::$server->getConfig(), \OC::$server->query(IManager::class)),
159
+            \OC::$server->query(SwitchUpdateChannel::class),
160
+            \OC::$server->query(SetEnterpriseLogo::class),
161
+            \OC::$server->query(ResetGeneratedAvatarFlag::class),
162
+        ];
163
+    }
164
+
165
+    /**
166
+     * Returns expensive repair steps to be run on the
167
+     * command line with a special option.
168
+     *
169
+     * @return IRepairStep[]
170
+     */
171
+    public static function getExpensiveRepairSteps() {
172
+        return [
173
+            new OldGroupMembershipShares(\OC::$server->getDatabaseConnection(), \OC::$server->getGroupManager())
174
+        ];
175
+    }
176
+
177
+    /**
178
+     * Returns the repair steps to be run before an
179
+     * upgrade.
180
+     *
181
+     * @return IRepairStep[]
182
+     */
183
+    public static function getBeforeUpgradeRepairSteps() {
184
+        $connection = \OC::$server->getDatabaseConnection();
185
+        $config     = \OC::$server->getConfig();
186
+        $steps      = [
187
+            new Collation(\OC::$server->getConfig(), \OC::$server->getLogger(), $connection, true),
188
+            new SqliteAutoincrement($connection),
189
+            new SaveAccountsTableData($connection, $config),
190
+            new DropAccountTermsTable($connection)
191
+        ];
192
+
193
+        return $steps;
194
+    }
195
+
196
+    /**
197
+     * @param string $scope
198
+     * @param string $method
199
+     * @param array $arguments
200
+     */
201
+    public function emit($scope, $method, array $arguments = []) {
202
+        if (!is_null($this->dispatcher)) {
203
+            $this->dispatcher->dispatch("$scope::$method",
204
+                new GenericEvent("$scope::$method", $arguments));
205
+        }
206
+    }
207
+
208
+    public function info($string) {
209
+        // for now just emit as we did in the past
210
+        $this->emit('\OC\Repair', 'info', [$string]);
211
+    }
212
+
213
+    /**
214
+     * @param string $message
215
+     */
216
+    public function warning($message) {
217
+        // for now just emit as we did in the past
218
+        $this->emit('\OC\Repair', 'warning', [$message]);
219
+    }
220
+
221
+    /**
222
+     * @param int $max
223
+     */
224
+    public function startProgress($max = 0) {
225
+        // for now just emit as we did in the past
226
+        $this->emit('\OC\Repair', 'startProgress', [$max, $this->currentStep]);
227
+    }
228
+
229
+    /**
230
+     * @param int $step
231
+     * @param string $description
232
+     */
233
+    public function advance($step = 1, $description = '') {
234
+        // for now just emit as we did in the past
235
+        $this->emit('\OC\Repair', 'advance', [$step, $description]);
236
+    }
237
+
238
+    /**
239
+     * @param int $max
240
+     */
241
+    public function finishProgress() {
242
+        // for now just emit as we did in the past
243
+        $this->emit('\OC\Repair', 'finishProgress', []);
244
+    }
245 245
 }
Please login to merge, or discard this patch.
lib/private/AppFramework/DependencyInjection/DIContainer.php 1 patch
Indentation   +350 added lines, -350 removed lines patch added patch discarded remove patch
@@ -69,354 +69,354 @@
 block discarded – undo
69 69
 
70 70
 class DIContainer extends SimpleContainer implements IAppContainer {
71 71
 
72
-	/**
73
-	 * @var array
74
-	 */
75
-	private $middleWares = [];
76
-
77
-	/** @var ServerContainer */
78
-	private $server;
79
-
80
-	/**
81
-	 * Put your class dependencies in here
82
-	 * @param string $appName the name of the app
83
-	 * @param array $urlParams
84
-	 * @param ServerContainer|null $server
85
-	 */
86
-	public function __construct($appName, $urlParams = [], ServerContainer $server = null){
87
-		parent::__construct();
88
-		$this['AppName'] = $appName;
89
-		$this['urlParams'] = $urlParams;
90
-
91
-		$this->registerAlias('Request', IRequest::class);
92
-
93
-		/** @var \OC\ServerContainer $server */
94
-		if ($server === null) {
95
-			$server = \OC::$server;
96
-		}
97
-		$this->server = $server;
98
-		$this->server->registerAppContainer($appName, $this);
99
-
100
-		// aliases
101
-		$this->registerAlias('appName', 'AppName');
102
-		$this->registerAlias('webRoot', 'WebRoot');
103
-		$this->registerAlias('userId', 'UserId');
104
-
105
-		/**
106
-		 * Core services
107
-		 */
108
-		$this->registerService(IOutput::class, function(){
109
-			return new Output($this->getServer()->getWebRoot());
110
-		});
111
-
112
-		$this->registerService(Folder::class, function() {
113
-			return $this->getServer()->getUserFolder();
114
-		});
115
-
116
-		$this->registerService(IAppData::class, function (SimpleContainer $c) {
117
-			return $this->getServer()->getAppDataDir($c->query('AppName'));
118
-		});
119
-
120
-		$this->registerService(IL10N::class, function($c) {
121
-			return $this->getServer()->getL10N($c->query('AppName'));
122
-		});
123
-
124
-		// Log wrapper
125
-		$this->registerService(ILogger::class, function ($c) {
126
-			return new OC\AppFramework\Logger($this->server->query(ILogger::class), $c->query('AppName'));
127
-		});
128
-
129
-		$this->registerService(IServerContainer::class, function () {
130
-			return $this->getServer();
131
-		});
132
-		$this->registerAlias('ServerContainer', IServerContainer::class);
133
-
134
-		$this->registerService(\OCP\WorkflowEngine\IManager::class, function ($c) {
135
-			return $c->query(Manager::class);
136
-		});
137
-
138
-		$this->registerService(\OCP\AppFramework\IAppContainer::class, function ($c) {
139
-			return $c;
140
-		});
141
-
142
-		// commonly used attributes
143
-		$this->registerService('UserId', function ($c) {
144
-			return $c->query(IUserSession::class)->getSession()->get('user_id');
145
-		});
146
-
147
-		$this->registerService('WebRoot', function ($c) {
148
-			return $c->query('ServerContainer')->getWebRoot();
149
-		});
150
-
151
-		$this->registerService('OC_Defaults', function ($c) {
152
-			return $c->getServer()->getThemingDefaults();
153
-		});
154
-
155
-		$this->registerService(IConfig::class, function ($c) {
156
-			return $c->query(OC\GlobalScale\Config::class);
157
-		});
158
-
159
-		$this->registerService('Protocol', function($c){
160
-			/** @var \OC\Server $server */
161
-			$server = $c->query('ServerContainer');
162
-			$protocol = $server->getRequest()->getHttpProtocol();
163
-			return new Http($_SERVER, $protocol);
164
-		});
165
-
166
-		$this->registerService('Dispatcher', function($c) {
167
-			return new Dispatcher(
168
-				$c['Protocol'],
169
-				$c['MiddlewareDispatcher'],
170
-				$c->query(IControllerMethodReflector::class),
171
-				$c['Request']
172
-			);
173
-		});
174
-
175
-		/**
176
-		 * App Framework default arguments
177
-		 */
178
-		$this->registerParameter('corsMethods', 'PUT, POST, GET, DELETE, PATCH');
179
-		$this->registerParameter('corsAllowedHeaders', 'Authorization, Content-Type, Accept');
180
-		$this->registerParameter('corsMaxAge', 1728000);
181
-
182
-		/**
183
-		 * Middleware
184
-		 */
185
-		$this->registerService('MiddlewareDispatcher', function(SimpleContainer $c) {
186
-			$server =  $this->getServer();
187
-
188
-			$dispatcher = new MiddlewareDispatcher();
189
-			$dispatcher->registerMiddleware(
190
-				$c->query(OC\AppFramework\Middleware\Security\ReloadExecutionMiddleware::class)
191
-			);
192
-
193
-			$dispatcher->registerMiddleware(
194
-				new OC\AppFramework\Middleware\Security\SameSiteCookieMiddleware(
195
-					$c->query(IRequest::class),
196
-					$c->query(IControllerMethodReflector::class)
197
-				)
198
-			);
199
-			$dispatcher->registerMiddleware(
200
-				new CORSMiddleware(
201
-					$c->query(IRequest::class),
202
-					$c->query(IControllerMethodReflector::class),
203
-					$c->query(IUserSession::class),
204
-					$c->query(OC\Security\Bruteforce\Throttler::class)
205
-				)
206
-			);
207
-			$dispatcher->registerMiddleware(
208
-				new OCSMiddleware(
209
-					$c->query(IRequest::class)
210
-				)
211
-			);
212
-
213
-			$securityMiddleware = new SecurityMiddleware(
214
-				$c->query(IRequest::class),
215
-				$c->query(IControllerMethodReflector::class),
216
-				$c->query(INavigationManager::class),
217
-				$c->query(IURLGenerator::class),
218
-				$server->getLogger(),
219
-				$c['AppName'],
220
-				$server->getUserSession()->isLoggedIn(),
221
-				$server->getGroupManager()->isAdmin($this->getUserId()),
222
-				$server->getUserSession()->getUser() !== null && $server->query(ISubAdmin::class)->isSubAdmin($server->getUserSession()->getUser()),
223
-				$server->getAppManager(),
224
-				$server->getL10N('lib')
225
-			);
226
-			$dispatcher->registerMiddleware($securityMiddleware);
227
-			$dispatcher->registerMiddleware(
228
-				new OC\AppFramework\Middleware\Security\CSPMiddleware(
229
-					$server->query(OC\Security\CSP\ContentSecurityPolicyManager::class),
230
-					$server->query(OC\Security\CSP\ContentSecurityPolicyNonceManager::class),
231
-					$server->query(OC\Security\CSRF\CsrfTokenManager::class)
232
-				)
233
-			);
234
-			$dispatcher->registerMiddleware(
235
-				$server->query(OC\AppFramework\Middleware\Security\FeaturePolicyMiddleware::class)
236
-			);
237
-			$dispatcher->registerMiddleware(
238
-				new OC\AppFramework\Middleware\Security\PasswordConfirmationMiddleware(
239
-					$c->query(IControllerMethodReflector::class),
240
-					$c->query(ISession::class),
241
-					$c->query(IUserSession::class),
242
-					$c->query(ITimeFactory::class)
243
-				)
244
-			);
245
-			$dispatcher->registerMiddleware(
246
-				new TwoFactorMiddleware(
247
-					$c->query(OC\Authentication\TwoFactorAuth\Manager::class),
248
-					$c->query(IUserSession::class),
249
-					$c->query(ISession::class),
250
-					$c->query(IURLGenerator::class),
251
-					$c->query(IControllerMethodReflector::class),
252
-					$c->query(IRequest::class)
253
-				)
254
-			);
255
-			$dispatcher->registerMiddleware(
256
-				new OC\AppFramework\Middleware\Security\BruteForceMiddleware(
257
-					$c->query(IControllerMethodReflector::class),
258
-					$c->query(OC\Security\Bruteforce\Throttler::class),
259
-					$c->query(IRequest::class)
260
-				)
261
-			);
262
-			$dispatcher->registerMiddleware(
263
-				new RateLimitingMiddleware(
264
-					$c->query(IRequest::class),
265
-					$c->query(IUserSession::class),
266
-					$c->query(IControllerMethodReflector::class),
267
-					$c->query(OC\Security\RateLimiting\Limiter::class)
268
-				)
269
-			);
270
-			$dispatcher->registerMiddleware(
271
-				new OC\AppFramework\Middleware\PublicShare\PublicShareMiddleware(
272
-					$c->query(IRequest::class),
273
-					$c->query(ISession::class),
274
-					$c->query(\OCP\IConfig::class)
275
-				)
276
-			);
277
-			$dispatcher->registerMiddleware(
278
-				$c->query(\OC\AppFramework\Middleware\AdditionalScriptsMiddleware::class)
279
-			);
280
-
281
-			foreach($this->middleWares as $middleWare) {
282
-				$dispatcher->registerMiddleware($c->query($middleWare));
283
-			}
284
-
285
-			$dispatcher->registerMiddleware(
286
-				new SessionMiddleware(
287
-					$c->query(IControllerMethodReflector::class),
288
-					$c->query(ISession::class)
289
-				)
290
-			);
291
-			return $dispatcher;
292
-		});
293
-
294
-		$this->registerAlias(\OCP\Collaboration\Resources\IProviderManager::class, OC\Collaboration\Resources\ProviderManager::class);
295
-		$this->registerAlias(\OCP\Collaboration\Resources\IManager::class, OC\Collaboration\Resources\Manager::class);
296
-	}
297
-
298
-	/**
299
-	 * @return \OCP\IServerContainer
300
-	 */
301
-	public function getServer()
302
-	{
303
-		return $this->server;
304
-	}
305
-
306
-	/**
307
-	 * @param string $middleWare
308
-	 * @return boolean|null
309
-	 */
310
-	public function registerMiddleWare($middleWare) {
311
-		if (in_array($middleWare, $this->middleWares, true) !== false) {
312
-			return false;
313
-		}
314
-		$this->middleWares[] = $middleWare;
315
-	}
316
-
317
-	/**
318
-	 * used to return the appname of the set application
319
-	 * @return string the name of your application
320
-	 */
321
-	public function getAppName() {
322
-		return $this->query('AppName');
323
-	}
324
-
325
-	/**
326
-	 * @deprecated use IUserSession->isLoggedIn()
327
-	 * @return boolean
328
-	 */
329
-	public function isLoggedIn() {
330
-		return \OC::$server->getUserSession()->isLoggedIn();
331
-	}
332
-
333
-	/**
334
-	 * @deprecated use IGroupManager->isAdmin($userId)
335
-	 * @return boolean
336
-	 */
337
-	public function isAdminUser() {
338
-		$uid = $this->getUserId();
339
-		return \OC_User::isAdminUser($uid);
340
-	}
341
-
342
-	private function getUserId() {
343
-		return $this->getServer()->getSession()->get('user_id');
344
-	}
345
-
346
-	/**
347
-	 * @deprecated use the ILogger instead
348
-	 * @param string $message
349
-	 * @param string $level
350
-	 * @return mixed
351
-	 */
352
-	public function log($message, $level) {
353
-		switch($level){
354
-			case 'debug':
355
-				$level = ILogger::DEBUG;
356
-				break;
357
-			case 'info':
358
-				$level = ILogger::INFO;
359
-				break;
360
-			case 'warn':
361
-				$level = ILogger::WARN;
362
-				break;
363
-			case 'fatal':
364
-				$level = ILogger::FATAL;
365
-				break;
366
-			default:
367
-				$level = ILogger::ERROR;
368
-				break;
369
-		}
370
-		\OCP\Util::writeLog($this->getAppName(), $message, $level);
371
-	}
372
-
373
-	/**
374
-	 * Register a capability
375
-	 *
376
-	 * @param string $serviceName e.g. 'OCA\Files\Capabilities'
377
-	 */
378
-	public function registerCapability($serviceName) {
379
-		$this->query('OC\CapabilitiesManager')->registerCapability(function() use ($serviceName) {
380
-			return $this->query($serviceName);
381
-		});
382
-	}
383
-
384
-	public function query(string $name, bool $autoload = true) {
385
-		try {
386
-			return $this->queryNoFallback($name);
387
-		} catch (QueryException $firstException) {
388
-			try {
389
-				return $this->getServer()->query($name, $autoload);
390
-			} catch (QueryException $secondException) {
391
-				if ($firstException->getCode() === 1) {
392
-					throw $secondException;
393
-				}
394
-				throw $firstException;
395
-			}
396
-		}
397
-	}
398
-
399
-	/**
400
-	 * @param string $name
401
-	 * @return mixed
402
-	 * @throws QueryException if the query could not be resolved
403
-	 */
404
-	public function queryNoFallback($name) {
405
-		$name = $this->sanitizeName($name);
406
-
407
-		if ($this->offsetExists($name)) {
408
-			return parent::query($name);
409
-		} else {
410
-			if ($this['AppName'] === 'settings' && strpos($name, 'OC\\Settings\\') === 0) {
411
-				return parent::query($name);
412
-			} else if ($this['AppName'] === 'core' && strpos($name, 'OC\\Core\\') === 0) {
413
-				return parent::query($name);
414
-			} else if (strpos($name, \OC\AppFramework\App::buildAppNamespace($this['AppName']) . '\\') === 0) {
415
-				return parent::query($name);
416
-			}
417
-		}
418
-
419
-		throw new QueryException('Could not resolve ' . $name . '!' .
420
-			' Class can not be instantiated', 1);
421
-	}
72
+    /**
73
+     * @var array
74
+     */
75
+    private $middleWares = [];
76
+
77
+    /** @var ServerContainer */
78
+    private $server;
79
+
80
+    /**
81
+     * Put your class dependencies in here
82
+     * @param string $appName the name of the app
83
+     * @param array $urlParams
84
+     * @param ServerContainer|null $server
85
+     */
86
+    public function __construct($appName, $urlParams = [], ServerContainer $server = null){
87
+        parent::__construct();
88
+        $this['AppName'] = $appName;
89
+        $this['urlParams'] = $urlParams;
90
+
91
+        $this->registerAlias('Request', IRequest::class);
92
+
93
+        /** @var \OC\ServerContainer $server */
94
+        if ($server === null) {
95
+            $server = \OC::$server;
96
+        }
97
+        $this->server = $server;
98
+        $this->server->registerAppContainer($appName, $this);
99
+
100
+        // aliases
101
+        $this->registerAlias('appName', 'AppName');
102
+        $this->registerAlias('webRoot', 'WebRoot');
103
+        $this->registerAlias('userId', 'UserId');
104
+
105
+        /**
106
+         * Core services
107
+         */
108
+        $this->registerService(IOutput::class, function(){
109
+            return new Output($this->getServer()->getWebRoot());
110
+        });
111
+
112
+        $this->registerService(Folder::class, function() {
113
+            return $this->getServer()->getUserFolder();
114
+        });
115
+
116
+        $this->registerService(IAppData::class, function (SimpleContainer $c) {
117
+            return $this->getServer()->getAppDataDir($c->query('AppName'));
118
+        });
119
+
120
+        $this->registerService(IL10N::class, function($c) {
121
+            return $this->getServer()->getL10N($c->query('AppName'));
122
+        });
123
+
124
+        // Log wrapper
125
+        $this->registerService(ILogger::class, function ($c) {
126
+            return new OC\AppFramework\Logger($this->server->query(ILogger::class), $c->query('AppName'));
127
+        });
128
+
129
+        $this->registerService(IServerContainer::class, function () {
130
+            return $this->getServer();
131
+        });
132
+        $this->registerAlias('ServerContainer', IServerContainer::class);
133
+
134
+        $this->registerService(\OCP\WorkflowEngine\IManager::class, function ($c) {
135
+            return $c->query(Manager::class);
136
+        });
137
+
138
+        $this->registerService(\OCP\AppFramework\IAppContainer::class, function ($c) {
139
+            return $c;
140
+        });
141
+
142
+        // commonly used attributes
143
+        $this->registerService('UserId', function ($c) {
144
+            return $c->query(IUserSession::class)->getSession()->get('user_id');
145
+        });
146
+
147
+        $this->registerService('WebRoot', function ($c) {
148
+            return $c->query('ServerContainer')->getWebRoot();
149
+        });
150
+
151
+        $this->registerService('OC_Defaults', function ($c) {
152
+            return $c->getServer()->getThemingDefaults();
153
+        });
154
+
155
+        $this->registerService(IConfig::class, function ($c) {
156
+            return $c->query(OC\GlobalScale\Config::class);
157
+        });
158
+
159
+        $this->registerService('Protocol', function($c){
160
+            /** @var \OC\Server $server */
161
+            $server = $c->query('ServerContainer');
162
+            $protocol = $server->getRequest()->getHttpProtocol();
163
+            return new Http($_SERVER, $protocol);
164
+        });
165
+
166
+        $this->registerService('Dispatcher', function($c) {
167
+            return new Dispatcher(
168
+                $c['Protocol'],
169
+                $c['MiddlewareDispatcher'],
170
+                $c->query(IControllerMethodReflector::class),
171
+                $c['Request']
172
+            );
173
+        });
174
+
175
+        /**
176
+         * App Framework default arguments
177
+         */
178
+        $this->registerParameter('corsMethods', 'PUT, POST, GET, DELETE, PATCH');
179
+        $this->registerParameter('corsAllowedHeaders', 'Authorization, Content-Type, Accept');
180
+        $this->registerParameter('corsMaxAge', 1728000);
181
+
182
+        /**
183
+         * Middleware
184
+         */
185
+        $this->registerService('MiddlewareDispatcher', function(SimpleContainer $c) {
186
+            $server =  $this->getServer();
187
+
188
+            $dispatcher = new MiddlewareDispatcher();
189
+            $dispatcher->registerMiddleware(
190
+                $c->query(OC\AppFramework\Middleware\Security\ReloadExecutionMiddleware::class)
191
+            );
192
+
193
+            $dispatcher->registerMiddleware(
194
+                new OC\AppFramework\Middleware\Security\SameSiteCookieMiddleware(
195
+                    $c->query(IRequest::class),
196
+                    $c->query(IControllerMethodReflector::class)
197
+                )
198
+            );
199
+            $dispatcher->registerMiddleware(
200
+                new CORSMiddleware(
201
+                    $c->query(IRequest::class),
202
+                    $c->query(IControllerMethodReflector::class),
203
+                    $c->query(IUserSession::class),
204
+                    $c->query(OC\Security\Bruteforce\Throttler::class)
205
+                )
206
+            );
207
+            $dispatcher->registerMiddleware(
208
+                new OCSMiddleware(
209
+                    $c->query(IRequest::class)
210
+                )
211
+            );
212
+
213
+            $securityMiddleware = new SecurityMiddleware(
214
+                $c->query(IRequest::class),
215
+                $c->query(IControllerMethodReflector::class),
216
+                $c->query(INavigationManager::class),
217
+                $c->query(IURLGenerator::class),
218
+                $server->getLogger(),
219
+                $c['AppName'],
220
+                $server->getUserSession()->isLoggedIn(),
221
+                $server->getGroupManager()->isAdmin($this->getUserId()),
222
+                $server->getUserSession()->getUser() !== null && $server->query(ISubAdmin::class)->isSubAdmin($server->getUserSession()->getUser()),
223
+                $server->getAppManager(),
224
+                $server->getL10N('lib')
225
+            );
226
+            $dispatcher->registerMiddleware($securityMiddleware);
227
+            $dispatcher->registerMiddleware(
228
+                new OC\AppFramework\Middleware\Security\CSPMiddleware(
229
+                    $server->query(OC\Security\CSP\ContentSecurityPolicyManager::class),
230
+                    $server->query(OC\Security\CSP\ContentSecurityPolicyNonceManager::class),
231
+                    $server->query(OC\Security\CSRF\CsrfTokenManager::class)
232
+                )
233
+            );
234
+            $dispatcher->registerMiddleware(
235
+                $server->query(OC\AppFramework\Middleware\Security\FeaturePolicyMiddleware::class)
236
+            );
237
+            $dispatcher->registerMiddleware(
238
+                new OC\AppFramework\Middleware\Security\PasswordConfirmationMiddleware(
239
+                    $c->query(IControllerMethodReflector::class),
240
+                    $c->query(ISession::class),
241
+                    $c->query(IUserSession::class),
242
+                    $c->query(ITimeFactory::class)
243
+                )
244
+            );
245
+            $dispatcher->registerMiddleware(
246
+                new TwoFactorMiddleware(
247
+                    $c->query(OC\Authentication\TwoFactorAuth\Manager::class),
248
+                    $c->query(IUserSession::class),
249
+                    $c->query(ISession::class),
250
+                    $c->query(IURLGenerator::class),
251
+                    $c->query(IControllerMethodReflector::class),
252
+                    $c->query(IRequest::class)
253
+                )
254
+            );
255
+            $dispatcher->registerMiddleware(
256
+                new OC\AppFramework\Middleware\Security\BruteForceMiddleware(
257
+                    $c->query(IControllerMethodReflector::class),
258
+                    $c->query(OC\Security\Bruteforce\Throttler::class),
259
+                    $c->query(IRequest::class)
260
+                )
261
+            );
262
+            $dispatcher->registerMiddleware(
263
+                new RateLimitingMiddleware(
264
+                    $c->query(IRequest::class),
265
+                    $c->query(IUserSession::class),
266
+                    $c->query(IControllerMethodReflector::class),
267
+                    $c->query(OC\Security\RateLimiting\Limiter::class)
268
+                )
269
+            );
270
+            $dispatcher->registerMiddleware(
271
+                new OC\AppFramework\Middleware\PublicShare\PublicShareMiddleware(
272
+                    $c->query(IRequest::class),
273
+                    $c->query(ISession::class),
274
+                    $c->query(\OCP\IConfig::class)
275
+                )
276
+            );
277
+            $dispatcher->registerMiddleware(
278
+                $c->query(\OC\AppFramework\Middleware\AdditionalScriptsMiddleware::class)
279
+            );
280
+
281
+            foreach($this->middleWares as $middleWare) {
282
+                $dispatcher->registerMiddleware($c->query($middleWare));
283
+            }
284
+
285
+            $dispatcher->registerMiddleware(
286
+                new SessionMiddleware(
287
+                    $c->query(IControllerMethodReflector::class),
288
+                    $c->query(ISession::class)
289
+                )
290
+            );
291
+            return $dispatcher;
292
+        });
293
+
294
+        $this->registerAlias(\OCP\Collaboration\Resources\IProviderManager::class, OC\Collaboration\Resources\ProviderManager::class);
295
+        $this->registerAlias(\OCP\Collaboration\Resources\IManager::class, OC\Collaboration\Resources\Manager::class);
296
+    }
297
+
298
+    /**
299
+     * @return \OCP\IServerContainer
300
+     */
301
+    public function getServer()
302
+    {
303
+        return $this->server;
304
+    }
305
+
306
+    /**
307
+     * @param string $middleWare
308
+     * @return boolean|null
309
+     */
310
+    public function registerMiddleWare($middleWare) {
311
+        if (in_array($middleWare, $this->middleWares, true) !== false) {
312
+            return false;
313
+        }
314
+        $this->middleWares[] = $middleWare;
315
+    }
316
+
317
+    /**
318
+     * used to return the appname of the set application
319
+     * @return string the name of your application
320
+     */
321
+    public function getAppName() {
322
+        return $this->query('AppName');
323
+    }
324
+
325
+    /**
326
+     * @deprecated use IUserSession->isLoggedIn()
327
+     * @return boolean
328
+     */
329
+    public function isLoggedIn() {
330
+        return \OC::$server->getUserSession()->isLoggedIn();
331
+    }
332
+
333
+    /**
334
+     * @deprecated use IGroupManager->isAdmin($userId)
335
+     * @return boolean
336
+     */
337
+    public function isAdminUser() {
338
+        $uid = $this->getUserId();
339
+        return \OC_User::isAdminUser($uid);
340
+    }
341
+
342
+    private function getUserId() {
343
+        return $this->getServer()->getSession()->get('user_id');
344
+    }
345
+
346
+    /**
347
+     * @deprecated use the ILogger instead
348
+     * @param string $message
349
+     * @param string $level
350
+     * @return mixed
351
+     */
352
+    public function log($message, $level) {
353
+        switch($level){
354
+            case 'debug':
355
+                $level = ILogger::DEBUG;
356
+                break;
357
+            case 'info':
358
+                $level = ILogger::INFO;
359
+                break;
360
+            case 'warn':
361
+                $level = ILogger::WARN;
362
+                break;
363
+            case 'fatal':
364
+                $level = ILogger::FATAL;
365
+                break;
366
+            default:
367
+                $level = ILogger::ERROR;
368
+                break;
369
+        }
370
+        \OCP\Util::writeLog($this->getAppName(), $message, $level);
371
+    }
372
+
373
+    /**
374
+     * Register a capability
375
+     *
376
+     * @param string $serviceName e.g. 'OCA\Files\Capabilities'
377
+     */
378
+    public function registerCapability($serviceName) {
379
+        $this->query('OC\CapabilitiesManager')->registerCapability(function() use ($serviceName) {
380
+            return $this->query($serviceName);
381
+        });
382
+    }
383
+
384
+    public function query(string $name, bool $autoload = true) {
385
+        try {
386
+            return $this->queryNoFallback($name);
387
+        } catch (QueryException $firstException) {
388
+            try {
389
+                return $this->getServer()->query($name, $autoload);
390
+            } catch (QueryException $secondException) {
391
+                if ($firstException->getCode() === 1) {
392
+                    throw $secondException;
393
+                }
394
+                throw $firstException;
395
+            }
396
+        }
397
+    }
398
+
399
+    /**
400
+     * @param string $name
401
+     * @return mixed
402
+     * @throws QueryException if the query could not be resolved
403
+     */
404
+    public function queryNoFallback($name) {
405
+        $name = $this->sanitizeName($name);
406
+
407
+        if ($this->offsetExists($name)) {
408
+            return parent::query($name);
409
+        } else {
410
+            if ($this['AppName'] === 'settings' && strpos($name, 'OC\\Settings\\') === 0) {
411
+                return parent::query($name);
412
+            } else if ($this['AppName'] === 'core' && strpos($name, 'OC\\Core\\') === 0) {
413
+                return parent::query($name);
414
+            } else if (strpos($name, \OC\AppFramework\App::buildAppNamespace($this['AppName']) . '\\') === 0) {
415
+                return parent::query($name);
416
+            }
417
+        }
418
+
419
+        throw new QueryException('Could not resolve ' . $name . '!' .
420
+            ' Class can not be instantiated', 1);
421
+    }
422 422
 }
Please login to merge, or discard this patch.
lib/private/AppFramework/Http.php 1 patch
Indentation   +115 added lines, -115 removed lines patch added patch discarded remove patch
@@ -33,121 +33,121 @@
 block discarded – undo
33 33
 
34 34
 class Http extends BaseHttp {
35 35
 
36
-	private $server;
37
-	private $protocolVersion;
38
-	protected $headers;
39
-
40
-	/**
41
-	 * @param array $server $_SERVER
42
-	 * @param string $protocolVersion the http version to use defaults to HTTP/1.1
43
-	 */
44
-	public function __construct($server, $protocolVersion='HTTP/1.1') {
45
-		$this->server = $server;
46
-		$this->protocolVersion = $protocolVersion;
47
-
48
-		$this->headers = [
49
-			self::STATUS_CONTINUE => 'Continue',
50
-			self::STATUS_SWITCHING_PROTOCOLS => 'Switching Protocols',
51
-			self::STATUS_PROCESSING => 'Processing',
52
-			self::STATUS_OK => 'OK',
53
-			self::STATUS_CREATED => 'Created',
54
-			self::STATUS_ACCEPTED => 'Accepted',
55
-			self::STATUS_NON_AUTHORATIVE_INFORMATION => 'Non-Authorative Information',
56
-			self::STATUS_NO_CONTENT => 'No Content',
57
-			self::STATUS_RESET_CONTENT => 'Reset Content',
58
-			self::STATUS_PARTIAL_CONTENT => 'Partial Content',
59
-			self::STATUS_MULTI_STATUS => 'Multi-Status', // RFC 4918
60
-			self::STATUS_ALREADY_REPORTED => 'Already Reported', // RFC 5842
61
-			self::STATUS_IM_USED => 'IM Used', // RFC 3229
62
-			self::STATUS_MULTIPLE_CHOICES => 'Multiple Choices',
63
-			self::STATUS_MOVED_PERMANENTLY => 'Moved Permanently',
64
-			self::STATUS_FOUND => 'Found',
65
-			self::STATUS_SEE_OTHER => 'See Other',
66
-			self::STATUS_NOT_MODIFIED => 'Not Modified',
67
-			self::STATUS_USE_PROXY => 'Use Proxy',
68
-			self::STATUS_RESERVED => 'Reserved',
69
-			self::STATUS_TEMPORARY_REDIRECT => 'Temporary Redirect',
70
-			self::STATUS_BAD_REQUEST => 'Bad request',
71
-			self::STATUS_UNAUTHORIZED => 'Unauthorized',
72
-			self::STATUS_PAYMENT_REQUIRED => 'Payment Required',
73
-			self::STATUS_FORBIDDEN => 'Forbidden',
74
-			self::STATUS_NOT_FOUND => 'Not Found',
75
-			self::STATUS_METHOD_NOT_ALLOWED => 'Method Not Allowed',
76
-			self::STATUS_NOT_ACCEPTABLE => 'Not Acceptable',
77
-			self::STATUS_PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required',
78
-			self::STATUS_REQUEST_TIMEOUT => 'Request Timeout',
79
-			self::STATUS_CONFLICT => 'Conflict',
80
-			self::STATUS_GONE => 'Gone',
81
-			self::STATUS_LENGTH_REQUIRED => 'Length Required',
82
-			self::STATUS_PRECONDITION_FAILED => 'Precondition failed',
83
-			self::STATUS_REQUEST_ENTITY_TOO_LARGE => 'Request Entity Too Large',
84
-			self::STATUS_REQUEST_URI_TOO_LONG => 'Request-URI Too Long',
85
-			self::STATUS_UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type',
86
-			self::STATUS_REQUEST_RANGE_NOT_SATISFIABLE => 'Requested Range Not Satisfiable',
87
-			self::STATUS_EXPECTATION_FAILED => 'Expectation Failed',
88
-			self::STATUS_IM_A_TEAPOT => 'I\'m a teapot', // RFC 2324
89
-			self::STATUS_UNPROCESSABLE_ENTITY => 'Unprocessable Entity', // RFC 4918
90
-			self::STATUS_LOCKED => 'Locked', // RFC 4918
91
-			self::STATUS_FAILED_DEPENDENCY => 'Failed Dependency', // RFC 4918
92
-			self::STATUS_UPGRADE_REQUIRED => 'Upgrade required',
93
-			self::STATUS_PRECONDITION_REQUIRED => 'Precondition required', // draft-nottingham-http-new-status
94
-			self::STATUS_TOO_MANY_REQUESTS => 'Too Many Requests', // draft-nottingham-http-new-status
95
-			self::STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE => 'Request Header Fields Too Large', // draft-nottingham-http-new-status
96
-			self::STATUS_INTERNAL_SERVER_ERROR => 'Internal Server Error',
97
-			self::STATUS_NOT_IMPLEMENTED => 'Not Implemented',
98
-			self::STATUS_BAD_GATEWAY => 'Bad Gateway',
99
-			self::STATUS_SERVICE_UNAVAILABLE => 'Service Unavailable',
100
-			self::STATUS_GATEWAY_TIMEOUT => 'Gateway Timeout',
101
-			self::STATUS_HTTP_VERSION_NOT_SUPPORTED => 'HTTP Version not supported',
102
-			self::STATUS_VARIANT_ALSO_NEGOTIATES => 'Variant Also Negotiates',
103
-			self::STATUS_INSUFFICIENT_STORAGE => 'Insufficient Storage', // RFC 4918
104
-			self::STATUS_LOOP_DETECTED => 'Loop Detected', // RFC 5842
105
-			self::STATUS_BANDWIDTH_LIMIT_EXCEEDED => 'Bandwidth Limit Exceeded', // non-standard
106
-			self::STATUS_NOT_EXTENDED => 'Not extended',
107
-			self::STATUS_NETWORK_AUTHENTICATION_REQUIRED => 'Network Authentication Required', // draft-nottingham-http-new-status
108
-		];
109
-	}
110
-
111
-
112
-	/**
113
-	 * Gets the correct header
114
-	 * @param int Http::CONSTANT $status the constant from the Http class
115
-	 * @param \DateTime $lastModified formatted last modified date
116
-	 * @param string $ETag the etag
117
-	 * @return string
118
-	 */
119
-	public function getStatusHeader($status, \DateTime $lastModified=null, 
120
-	                                $ETag=null) {
121
-
122
-		if(!is_null($lastModified)) {
123
-			$lastModified = $lastModified->format(\DateTime::RFC2822);
124
-		}
125
-
126
-		// if etag or lastmodified have not changed, return a not modified
127
-		if ((isset($this->server['HTTP_IF_NONE_MATCH'])
128
-			&& trim(trim($this->server['HTTP_IF_NONE_MATCH']), '"') === (string)$ETag)
129
-
130
-			||
131
-
132
-			(isset($this->server['HTTP_IF_MODIFIED_SINCE'])
133
-			&& trim($this->server['HTTP_IF_MODIFIED_SINCE']) === 
134
-				$lastModified)) {
135
-
136
-			$status = self::STATUS_NOT_MODIFIED;
137
-		}
138
-
139
-		// we have one change currently for the http 1.0 header that differs
140
-		// from 1.1: STATUS_TEMPORARY_REDIRECT should be STATUS_FOUND
141
-		// if this differs any more, we want to create childclasses for this
142
-		if($status === self::STATUS_TEMPORARY_REDIRECT 
143
-			&& $this->protocolVersion === 'HTTP/1.0') {
144
-
145
-			$status = self::STATUS_FOUND;
146
-		}
147
-
148
-		return $this->protocolVersion . ' ' . $status . ' ' . 
149
-			$this->headers[$status];
150
-	}
36
+    private $server;
37
+    private $protocolVersion;
38
+    protected $headers;
39
+
40
+    /**
41
+     * @param array $server $_SERVER
42
+     * @param string $protocolVersion the http version to use defaults to HTTP/1.1
43
+     */
44
+    public function __construct($server, $protocolVersion='HTTP/1.1') {
45
+        $this->server = $server;
46
+        $this->protocolVersion = $protocolVersion;
47
+
48
+        $this->headers = [
49
+            self::STATUS_CONTINUE => 'Continue',
50
+            self::STATUS_SWITCHING_PROTOCOLS => 'Switching Protocols',
51
+            self::STATUS_PROCESSING => 'Processing',
52
+            self::STATUS_OK => 'OK',
53
+            self::STATUS_CREATED => 'Created',
54
+            self::STATUS_ACCEPTED => 'Accepted',
55
+            self::STATUS_NON_AUTHORATIVE_INFORMATION => 'Non-Authorative Information',
56
+            self::STATUS_NO_CONTENT => 'No Content',
57
+            self::STATUS_RESET_CONTENT => 'Reset Content',
58
+            self::STATUS_PARTIAL_CONTENT => 'Partial Content',
59
+            self::STATUS_MULTI_STATUS => 'Multi-Status', // RFC 4918
60
+            self::STATUS_ALREADY_REPORTED => 'Already Reported', // RFC 5842
61
+            self::STATUS_IM_USED => 'IM Used', // RFC 3229
62
+            self::STATUS_MULTIPLE_CHOICES => 'Multiple Choices',
63
+            self::STATUS_MOVED_PERMANENTLY => 'Moved Permanently',
64
+            self::STATUS_FOUND => 'Found',
65
+            self::STATUS_SEE_OTHER => 'See Other',
66
+            self::STATUS_NOT_MODIFIED => 'Not Modified',
67
+            self::STATUS_USE_PROXY => 'Use Proxy',
68
+            self::STATUS_RESERVED => 'Reserved',
69
+            self::STATUS_TEMPORARY_REDIRECT => 'Temporary Redirect',
70
+            self::STATUS_BAD_REQUEST => 'Bad request',
71
+            self::STATUS_UNAUTHORIZED => 'Unauthorized',
72
+            self::STATUS_PAYMENT_REQUIRED => 'Payment Required',
73
+            self::STATUS_FORBIDDEN => 'Forbidden',
74
+            self::STATUS_NOT_FOUND => 'Not Found',
75
+            self::STATUS_METHOD_NOT_ALLOWED => 'Method Not Allowed',
76
+            self::STATUS_NOT_ACCEPTABLE => 'Not Acceptable',
77
+            self::STATUS_PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required',
78
+            self::STATUS_REQUEST_TIMEOUT => 'Request Timeout',
79
+            self::STATUS_CONFLICT => 'Conflict',
80
+            self::STATUS_GONE => 'Gone',
81
+            self::STATUS_LENGTH_REQUIRED => 'Length Required',
82
+            self::STATUS_PRECONDITION_FAILED => 'Precondition failed',
83
+            self::STATUS_REQUEST_ENTITY_TOO_LARGE => 'Request Entity Too Large',
84
+            self::STATUS_REQUEST_URI_TOO_LONG => 'Request-URI Too Long',
85
+            self::STATUS_UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type',
86
+            self::STATUS_REQUEST_RANGE_NOT_SATISFIABLE => 'Requested Range Not Satisfiable',
87
+            self::STATUS_EXPECTATION_FAILED => 'Expectation Failed',
88
+            self::STATUS_IM_A_TEAPOT => 'I\'m a teapot', // RFC 2324
89
+            self::STATUS_UNPROCESSABLE_ENTITY => 'Unprocessable Entity', // RFC 4918
90
+            self::STATUS_LOCKED => 'Locked', // RFC 4918
91
+            self::STATUS_FAILED_DEPENDENCY => 'Failed Dependency', // RFC 4918
92
+            self::STATUS_UPGRADE_REQUIRED => 'Upgrade required',
93
+            self::STATUS_PRECONDITION_REQUIRED => 'Precondition required', // draft-nottingham-http-new-status
94
+            self::STATUS_TOO_MANY_REQUESTS => 'Too Many Requests', // draft-nottingham-http-new-status
95
+            self::STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE => 'Request Header Fields Too Large', // draft-nottingham-http-new-status
96
+            self::STATUS_INTERNAL_SERVER_ERROR => 'Internal Server Error',
97
+            self::STATUS_NOT_IMPLEMENTED => 'Not Implemented',
98
+            self::STATUS_BAD_GATEWAY => 'Bad Gateway',
99
+            self::STATUS_SERVICE_UNAVAILABLE => 'Service Unavailable',
100
+            self::STATUS_GATEWAY_TIMEOUT => 'Gateway Timeout',
101
+            self::STATUS_HTTP_VERSION_NOT_SUPPORTED => 'HTTP Version not supported',
102
+            self::STATUS_VARIANT_ALSO_NEGOTIATES => 'Variant Also Negotiates',
103
+            self::STATUS_INSUFFICIENT_STORAGE => 'Insufficient Storage', // RFC 4918
104
+            self::STATUS_LOOP_DETECTED => 'Loop Detected', // RFC 5842
105
+            self::STATUS_BANDWIDTH_LIMIT_EXCEEDED => 'Bandwidth Limit Exceeded', // non-standard
106
+            self::STATUS_NOT_EXTENDED => 'Not extended',
107
+            self::STATUS_NETWORK_AUTHENTICATION_REQUIRED => 'Network Authentication Required', // draft-nottingham-http-new-status
108
+        ];
109
+    }
110
+
111
+
112
+    /**
113
+     * Gets the correct header
114
+     * @param int Http::CONSTANT $status the constant from the Http class
115
+     * @param \DateTime $lastModified formatted last modified date
116
+     * @param string $ETag the etag
117
+     * @return string
118
+     */
119
+    public function getStatusHeader($status, \DateTime $lastModified=null, 
120
+                                    $ETag=null) {
121
+
122
+        if(!is_null($lastModified)) {
123
+            $lastModified = $lastModified->format(\DateTime::RFC2822);
124
+        }
125
+
126
+        // if etag or lastmodified have not changed, return a not modified
127
+        if ((isset($this->server['HTTP_IF_NONE_MATCH'])
128
+            && trim(trim($this->server['HTTP_IF_NONE_MATCH']), '"') === (string)$ETag)
129
+
130
+            ||
131
+
132
+            (isset($this->server['HTTP_IF_MODIFIED_SINCE'])
133
+            && trim($this->server['HTTP_IF_MODIFIED_SINCE']) === 
134
+                $lastModified)) {
135
+
136
+            $status = self::STATUS_NOT_MODIFIED;
137
+        }
138
+
139
+        // we have one change currently for the http 1.0 header that differs
140
+        // from 1.1: STATUS_TEMPORARY_REDIRECT should be STATUS_FOUND
141
+        // if this differs any more, we want to create childclasses for this
142
+        if($status === self::STATUS_TEMPORARY_REDIRECT 
143
+            && $this->protocolVersion === 'HTTP/1.0') {
144
+
145
+            $status = self::STATUS_FOUND;
146
+        }
147
+
148
+        return $this->protocolVersion . ' ' . $status . ' ' . 
149
+            $this->headers[$status];
150
+    }
151 151
 
152 152
 
153 153
 }
Please login to merge, or discard this patch.
lib/private/App/AppManager.php 1 patch
Indentation   +537 added lines, -537 removed lines patch added patch discarded remove patch
@@ -52,541 +52,541 @@
 block discarded – undo
52 52
 
53 53
 class AppManager implements IAppManager {
54 54
 
55
-	/**
56
-	 * Apps with these types can not be enabled for certain groups only
57
-	 * @var string[]
58
-	 */
59
-	protected $protectedAppTypes = [
60
-		'filesystem',
61
-		'prelogin',
62
-		'authentication',
63
-		'logging',
64
-		'prevent_group_restriction',
65
-	];
66
-
67
-	/** @var IUserSession */
68
-	private $userSession;
69
-
70
-	/** @var IConfig */
71
-	private $config;
72
-
73
-	/** @var AppConfig */
74
-	private $appConfig;
75
-
76
-	/** @var IGroupManager */
77
-	private $groupManager;
78
-
79
-	/** @var ICacheFactory */
80
-	private $memCacheFactory;
81
-
82
-	/** @var EventDispatcherInterface */
83
-	private $dispatcher;
84
-
85
-	/** @var ILogger */
86
-	private $logger;
87
-
88
-	/** @var string[] $appId => $enabled */
89
-	private $installedAppsCache;
90
-
91
-	/** @var string[] */
92
-	private $shippedApps;
93
-
94
-	/** @var string[] */
95
-	private $alwaysEnabled;
96
-
97
-	/** @var array */
98
-	private $appInfos = [];
99
-
100
-	/** @var array */
101
-	private $appVersions = [];
102
-
103
-	/** @var array */
104
-	private $autoDisabledApps = [];
105
-
106
-	/**
107
-	 * @param IUserSession $userSession
108
-	 * @param IConfig $config
109
-	 * @param AppConfig $appConfig
110
-	 * @param IGroupManager $groupManager
111
-	 * @param ICacheFactory $memCacheFactory
112
-	 * @param EventDispatcherInterface $dispatcher
113
-	 */
114
-	public function __construct(IUserSession $userSession,
115
-								IConfig $config,
116
-								AppConfig $appConfig,
117
-								IGroupManager $groupManager,
118
-								ICacheFactory $memCacheFactory,
119
-								EventDispatcherInterface $dispatcher,
120
-								ILogger $logger) {
121
-		$this->userSession = $userSession;
122
-		$this->config = $config;
123
-		$this->appConfig = $appConfig;
124
-		$this->groupManager = $groupManager;
125
-		$this->memCacheFactory = $memCacheFactory;
126
-		$this->dispatcher = $dispatcher;
127
-		$this->logger = $logger;
128
-	}
129
-
130
-	/**
131
-	 * @return string[] $appId => $enabled
132
-	 */
133
-	private function getInstalledAppsValues() {
134
-		if (!$this->installedAppsCache) {
135
-			$values = $this->appConfig->getValues(false, 'enabled');
136
-
137
-			$alwaysEnabledApps = $this->getAlwaysEnabledApps();
138
-			foreach($alwaysEnabledApps as $appId) {
139
-				$values[$appId] = 'yes';
140
-			}
141
-
142
-			$this->installedAppsCache = array_filter($values, function ($value) {
143
-				return $value !== 'no';
144
-			});
145
-			ksort($this->installedAppsCache);
146
-		}
147
-		return $this->installedAppsCache;
148
-	}
149
-
150
-	/**
151
-	 * List all installed apps
152
-	 *
153
-	 * @return string[]
154
-	 */
155
-	public function getInstalledApps() {
156
-		return array_keys($this->getInstalledAppsValues());
157
-	}
158
-
159
-	/**
160
-	 * List all apps enabled for a user
161
-	 *
162
-	 * @param \OCP\IUser $user
163
-	 * @return string[]
164
-	 */
165
-	public function getEnabledAppsForUser(IUser $user) {
166
-		$apps = $this->getInstalledAppsValues();
167
-		$appsForUser = array_filter($apps, function ($enabled) use ($user) {
168
-			return $this->checkAppForUser($enabled, $user);
169
-		});
170
-		return array_keys($appsForUser);
171
-	}
172
-
173
-	/**
174
-	 * @param \OCP\IGroup $group
175
-	 * @return array
176
-	 */
177
-	public function getEnabledAppsForGroup(IGroup $group): array {
178
-		$apps = $this->getInstalledAppsValues();
179
-		$appsForGroups = array_filter($apps, function ($enabled) use ($group) {
180
-			return $this->checkAppForGroups($enabled, $group);
181
-		});
182
-		return array_keys($appsForGroups);
183
-	}
184
-
185
-	/**
186
-	 * @return array
187
-	 */
188
-	public function getAutoDisabledApps(): array {
189
-		return $this->autoDisabledApps;
190
-	}
191
-
192
-	/**
193
-	 * @param string $appId
194
-	 * @return array
195
-	 */
196
-	public function getAppRestriction(string $appId): array {
197
-		$values = $this->getInstalledAppsValues();
198
-
199
-		if (!isset($values[$appId])) {
200
-			return [];
201
-		}
202
-
203
-		if ($values[$appId] === 'yes' || $values[$appId] === 'no') {
204
-			return [];
205
-		}
206
-		return json_decode($values[$appId]);
207
-	}
208
-
209
-
210
-	/**
211
-	 * Check if an app is enabled for user
212
-	 *
213
-	 * @param string $appId
214
-	 * @param \OCP\IUser $user (optional) if not defined, the currently logged in user will be used
215
-	 * @return bool
216
-	 */
217
-	public function isEnabledForUser($appId, $user = null) {
218
-		if ($this->isAlwaysEnabled($appId)) {
219
-			return true;
220
-		}
221
-		if ($user === null) {
222
-			$user = $this->userSession->getUser();
223
-		}
224
-		$installedApps = $this->getInstalledAppsValues();
225
-		if (isset($installedApps[$appId])) {
226
-			return $this->checkAppForUser($installedApps[$appId], $user);
227
-		} else {
228
-			return false;
229
-		}
230
-	}
231
-
232
-	/**
233
-	 * @param string $enabled
234
-	 * @param IUser $user
235
-	 * @return bool
236
-	 */
237
-	private function checkAppForUser($enabled, $user) {
238
-		if ($enabled === 'yes') {
239
-			return true;
240
-		} elseif ($user === null) {
241
-			return false;
242
-		} else {
243
-			if(empty($enabled)){
244
-				return false;
245
-			}
246
-
247
-			$groupIds = json_decode($enabled);
248
-
249
-			if (!is_array($groupIds)) {
250
-				$jsonError = json_last_error();
251
-				$this->logger->warning('AppManger::checkAppForUser - can\'t decode group IDs: ' . print_r($enabled, true) . ' - json error code: ' . $jsonError, ['app' => 'lib']);
252
-				return false;
253
-			}
254
-
255
-			$userGroups = $this->groupManager->getUserGroupIds($user);
256
-			foreach ($userGroups as $groupId) {
257
-				if (in_array($groupId, $groupIds, true)) {
258
-					return true;
259
-				}
260
-			}
261
-			return false;
262
-		}
263
-	}
264
-
265
-	/**
266
-	 * @param string $enabled
267
-	 * @param IGroup $group
268
-	 * @return bool
269
-	 */
270
-	private function checkAppForGroups(string $enabled, IGroup $group): bool {
271
-		if ($enabled === 'yes') {
272
-			return true;
273
-		} elseif ($group === null) {
274
-			return false;
275
-		} else {
276
-			if (empty($enabled)) {
277
-				return false;
278
-			}
279
-
280
-			$groupIds = json_decode($enabled);
281
-
282
-			if (!is_array($groupIds)) {
283
-				$jsonError = json_last_error();
284
-				$this->logger->warning('AppManger::checkAppForUser - can\'t decode group IDs: ' . print_r($enabled, true) . ' - json error code: ' . $jsonError, ['app' => 'lib']);
285
-				return false;
286
-			}
287
-
288
-			return in_array($group->getGID(), $groupIds);
289
-		}
290
-	}
291
-
292
-	/**
293
-	 * Check if an app is enabled in the instance
294
-	 *
295
-	 * Notice: This actually checks if the app is enabled and not only if it is installed.
296
-	 *
297
-	 * @param string $appId
298
-	 * @param \OCP\IGroup[]|String[] $groups
299
-	 * @return bool
300
-	 */
301
-	public function isInstalled($appId) {
302
-		$installedApps = $this->getInstalledAppsValues();
303
-		return isset($installedApps[$appId]);
304
-	}
305
-
306
-	public function ignoreNextcloudRequirementForApp(string $appId): void {
307
-		$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
308
-		if (!in_array($appId, $ignoreMaxApps, true)) {
309
-			$ignoreMaxApps[] = $appId;
310
-			$this->config->setSystemValue('app_install_overwrite', $ignoreMaxApps);
311
-		}
312
-	}
313
-
314
-	/**
315
-	 * Enable an app for every user
316
-	 *
317
-	 * @param string $appId
318
-	 * @param bool $forceEnable
319
-	 * @throws AppPathNotFoundException
320
-	 */
321
-	public function enableApp(string $appId, bool $forceEnable = false): void {
322
-		// Check if app exists
323
-		$this->getAppPath($appId);
324
-
325
-		if ($forceEnable) {
326
-			$this->ignoreNextcloudRequirementForApp($appId);
327
-		}
328
-
329
-		$this->installedAppsCache[$appId] = 'yes';
330
-		$this->appConfig->setValue($appId, 'enabled', 'yes');
331
-		$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE, new ManagerEvent(
332
-			ManagerEvent::EVENT_APP_ENABLE, $appId
333
-		));
334
-		$this->clearAppsCache();
335
-	}
336
-
337
-	/**
338
-	 * Whether a list of types contains a protected app type
339
-	 *
340
-	 * @param string[] $types
341
-	 * @return bool
342
-	 */
343
-	public function hasProtectedAppType($types) {
344
-		if (empty($types)) {
345
-			return false;
346
-		}
347
-
348
-		$protectedTypes = array_intersect($this->protectedAppTypes, $types);
349
-		return !empty($protectedTypes);
350
-	}
351
-
352
-	/**
353
-	 * Enable an app only for specific groups
354
-	 *
355
-	 * @param string $appId
356
-	 * @param \OCP\IGroup[] $groups
357
-	 * @param bool $forceEnable
358
-	 * @throws \InvalidArgumentException if app can't be enabled for groups
359
-	 * @throws AppPathNotFoundException
360
-	 */
361
-	public function enableAppForGroups(string $appId, array $groups, bool $forceEnable = false): void {
362
-		// Check if app exists
363
-		$this->getAppPath($appId);
364
-
365
-		$info = $this->getAppInfo($appId);
366
-		if (!empty($info['types']) && $this->hasProtectedAppType($info['types'])) {
367
-			throw new \InvalidArgumentException("$appId can't be enabled for groups.");
368
-		}
369
-
370
-		if ($forceEnable) {
371
-			$this->ignoreNextcloudRequirementForApp($appId);
372
-		}
373
-
374
-		$groupIds = array_map(function ($group) {
375
-			/** @var \OCP\IGroup $group */
376
-			return ($group instanceof IGroup)
377
-				? $group->getGID()
378
-				: $group;
379
-		}, $groups);
380
-
381
-		$this->installedAppsCache[$appId] = json_encode($groupIds);
382
-		$this->appConfig->setValue($appId, 'enabled', json_encode($groupIds));
383
-		$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, new ManagerEvent(
384
-			ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, $appId, $groups
385
-		));
386
-		$this->clearAppsCache();
387
-
388
-	}
389
-
390
-	/**
391
-	 * Disable an app for every user
392
-	 *
393
-	 * @param string $appId
394
-	 * @param bool $automaticDisabled
395
-	 * @throws \Exception if app can't be disabled
396
-	 */
397
-	public function disableApp($appId, $automaticDisabled = false) {
398
-		if ($this->isAlwaysEnabled($appId)) {
399
-			throw new \Exception("$appId can't be disabled.");
400
-		}
401
-
402
-		if ($automaticDisabled) {
403
-			$this->autoDisabledApps[] = $appId;
404
-		}
405
-
406
-		unset($this->installedAppsCache[$appId]);
407
-		$this->appConfig->setValue($appId, 'enabled', 'no');
408
-
409
-		// run uninstall steps
410
-		$appData = $this->getAppInfo($appId);
411
-		if (!is_null($appData)) {
412
-			\OC_App::executeRepairSteps($appId, $appData['repair-steps']['uninstall']);
413
-		}
414
-
415
-		$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_DISABLE, new ManagerEvent(
416
-			ManagerEvent::EVENT_APP_DISABLE, $appId
417
-		));
418
-		$this->clearAppsCache();
419
-	}
420
-
421
-	/**
422
-	 * Get the directory for the given app.
423
-	 *
424
-	 * @param string $appId
425
-	 * @return string
426
-	 * @throws AppPathNotFoundException if app folder can't be found
427
-	 */
428
-	public function getAppPath($appId) {
429
-		$appPath = \OC_App::getAppPath($appId);
430
-		if($appPath === false) {
431
-			throw new AppPathNotFoundException('Could not find path for ' . $appId);
432
-		}
433
-		return $appPath;
434
-	}
435
-
436
-	/**
437
-	 * Get the web path for the given app.
438
-	 *
439
-	 * @param string $appId
440
-	 * @return string
441
-	 * @throws AppPathNotFoundException if app path can't be found
442
-	 */
443
-	public function getAppWebPath(string $appId): string {
444
-		$appWebPath = \OC_App::getAppWebPath($appId);
445
-		if($appWebPath === false) {
446
-			throw new AppPathNotFoundException('Could not find web path for ' . $appId);
447
-		}
448
-		return $appWebPath;
449
-	}
450
-
451
-	/**
452
-	 * Clear the cached list of apps when enabling/disabling an app
453
-	 */
454
-	public function clearAppsCache() {
455
-		$settingsMemCache = $this->memCacheFactory->createDistributed('settings');
456
-		$settingsMemCache->clear('listApps');
457
-		$this->appInfos = [];
458
-	}
459
-
460
-	/**
461
-	 * Returns a list of apps that need upgrade
462
-	 *
463
-	 * @param string $version Nextcloud version as array of version components
464
-	 * @return array list of app info from apps that need an upgrade
465
-	 *
466
-	 * @internal
467
-	 */
468
-	public function getAppsNeedingUpgrade($version) {
469
-		$appsToUpgrade = [];
470
-		$apps = $this->getInstalledApps();
471
-		foreach ($apps as $appId) {
472
-			$appInfo = $this->getAppInfo($appId);
473
-			$appDbVersion = $this->appConfig->getValue($appId, 'installed_version');
474
-			if ($appDbVersion
475
-				&& isset($appInfo['version'])
476
-				&& version_compare($appInfo['version'], $appDbVersion, '>')
477
-				&& \OC_App::isAppCompatible($version, $appInfo)
478
-			) {
479
-				$appsToUpgrade[] = $appInfo;
480
-			}
481
-		}
482
-
483
-		return $appsToUpgrade;
484
-	}
485
-
486
-	/**
487
-	 * Returns the app information from "appinfo/info.xml".
488
-	 *
489
-	 * @param string $appId app id
490
-	 *
491
-	 * @param bool $path
492
-	 * @param null $lang
493
-	 * @return array|null app info
494
-	 */
495
-	public function getAppInfo(string $appId, bool $path = false, $lang = null) {
496
-		if ($path) {
497
-			$file = $appId;
498
-		} else {
499
-			if ($lang === null && isset($this->appInfos[$appId])) {
500
-				return $this->appInfos[$appId];
501
-			}
502
-			try {
503
-				$appPath = $this->getAppPath($appId);
504
-			} catch (AppPathNotFoundException $e) {
505
-				return null;
506
-			}
507
-			$file = $appPath . '/appinfo/info.xml';
508
-		}
509
-
510
-		$parser = new InfoParser($this->memCacheFactory->createLocal('core.appinfo'));
511
-		$data = $parser->parse($file);
512
-
513
-		if (is_array($data)) {
514
-			$data = \OC_App::parseAppInfo($data, $lang);
515
-		}
516
-
517
-		if ($lang === null) {
518
-			$this->appInfos[$appId] = $data;
519
-		}
520
-
521
-		return $data;
522
-	}
523
-
524
-	public function getAppVersion(string $appId, bool $useCache = true): string {
525
-		if(!$useCache || !isset($this->appVersions[$appId])) {
526
-			$appInfo = $this->getAppInfo($appId);
527
-			$this->appVersions[$appId] = ($appInfo !== null && isset($appInfo['version'])) ? $appInfo['version'] : '0';
528
-		}
529
-		return $this->appVersions[$appId];
530
-	}
531
-
532
-	/**
533
-	 * Returns a list of apps incompatible with the given version
534
-	 *
535
-	 * @param string $version Nextcloud version as array of version components
536
-	 *
537
-	 * @return array list of app info from incompatible apps
538
-	 *
539
-	 * @internal
540
-	 */
541
-	public function getIncompatibleApps(string $version): array {
542
-		$apps = $this->getInstalledApps();
543
-		$incompatibleApps = [];
544
-		foreach ($apps as $appId) {
545
-			$info = $this->getAppInfo($appId);
546
-			if ($info === null) {
547
-				$incompatibleApps[] = ['id' => $appId];
548
-			} else if (!\OC_App::isAppCompatible($version, $info)) {
549
-				$incompatibleApps[] = $info;
550
-			}
551
-		}
552
-		return $incompatibleApps;
553
-	}
554
-
555
-	/**
556
-	 * @inheritdoc
557
-	 * In case you change this method, also change \OC\App\CodeChecker\InfoChecker::isShipped()
558
-	 */
559
-	public function isShipped($appId) {
560
-		$this->loadShippedJson();
561
-		return in_array($appId, $this->shippedApps, true);
562
-	}
563
-
564
-	private function isAlwaysEnabled($appId) {
565
-		$alwaysEnabled = $this->getAlwaysEnabledApps();
566
-		return in_array($appId, $alwaysEnabled, true);
567
-	}
568
-
569
-	/**
570
-	 * In case you change this method, also change \OC\App\CodeChecker\InfoChecker::loadShippedJson()
571
-	 * @throws \Exception
572
-	 */
573
-	private function loadShippedJson() {
574
-		if ($this->shippedApps === null) {
575
-			$shippedJson = \OC::$SERVERROOT . '/core/shipped.json';
576
-			if (!file_exists($shippedJson)) {
577
-				throw new \Exception("File not found: $shippedJson");
578
-			}
579
-			$content = json_decode(file_get_contents($shippedJson), true);
580
-			$this->shippedApps = $content['shippedApps'];
581
-			$this->alwaysEnabled = $content['alwaysEnabled'];
582
-		}
583
-	}
584
-
585
-	/**
586
-	 * @inheritdoc
587
-	 */
588
-	public function getAlwaysEnabledApps() {
589
-		$this->loadShippedJson();
590
-		return $this->alwaysEnabled;
591
-	}
55
+    /**
56
+     * Apps with these types can not be enabled for certain groups only
57
+     * @var string[]
58
+     */
59
+    protected $protectedAppTypes = [
60
+        'filesystem',
61
+        'prelogin',
62
+        'authentication',
63
+        'logging',
64
+        'prevent_group_restriction',
65
+    ];
66
+
67
+    /** @var IUserSession */
68
+    private $userSession;
69
+
70
+    /** @var IConfig */
71
+    private $config;
72
+
73
+    /** @var AppConfig */
74
+    private $appConfig;
75
+
76
+    /** @var IGroupManager */
77
+    private $groupManager;
78
+
79
+    /** @var ICacheFactory */
80
+    private $memCacheFactory;
81
+
82
+    /** @var EventDispatcherInterface */
83
+    private $dispatcher;
84
+
85
+    /** @var ILogger */
86
+    private $logger;
87
+
88
+    /** @var string[] $appId => $enabled */
89
+    private $installedAppsCache;
90
+
91
+    /** @var string[] */
92
+    private $shippedApps;
93
+
94
+    /** @var string[] */
95
+    private $alwaysEnabled;
96
+
97
+    /** @var array */
98
+    private $appInfos = [];
99
+
100
+    /** @var array */
101
+    private $appVersions = [];
102
+
103
+    /** @var array */
104
+    private $autoDisabledApps = [];
105
+
106
+    /**
107
+     * @param IUserSession $userSession
108
+     * @param IConfig $config
109
+     * @param AppConfig $appConfig
110
+     * @param IGroupManager $groupManager
111
+     * @param ICacheFactory $memCacheFactory
112
+     * @param EventDispatcherInterface $dispatcher
113
+     */
114
+    public function __construct(IUserSession $userSession,
115
+                                IConfig $config,
116
+                                AppConfig $appConfig,
117
+                                IGroupManager $groupManager,
118
+                                ICacheFactory $memCacheFactory,
119
+                                EventDispatcherInterface $dispatcher,
120
+                                ILogger $logger) {
121
+        $this->userSession = $userSession;
122
+        $this->config = $config;
123
+        $this->appConfig = $appConfig;
124
+        $this->groupManager = $groupManager;
125
+        $this->memCacheFactory = $memCacheFactory;
126
+        $this->dispatcher = $dispatcher;
127
+        $this->logger = $logger;
128
+    }
129
+
130
+    /**
131
+     * @return string[] $appId => $enabled
132
+     */
133
+    private function getInstalledAppsValues() {
134
+        if (!$this->installedAppsCache) {
135
+            $values = $this->appConfig->getValues(false, 'enabled');
136
+
137
+            $alwaysEnabledApps = $this->getAlwaysEnabledApps();
138
+            foreach($alwaysEnabledApps as $appId) {
139
+                $values[$appId] = 'yes';
140
+            }
141
+
142
+            $this->installedAppsCache = array_filter($values, function ($value) {
143
+                return $value !== 'no';
144
+            });
145
+            ksort($this->installedAppsCache);
146
+        }
147
+        return $this->installedAppsCache;
148
+    }
149
+
150
+    /**
151
+     * List all installed apps
152
+     *
153
+     * @return string[]
154
+     */
155
+    public function getInstalledApps() {
156
+        return array_keys($this->getInstalledAppsValues());
157
+    }
158
+
159
+    /**
160
+     * List all apps enabled for a user
161
+     *
162
+     * @param \OCP\IUser $user
163
+     * @return string[]
164
+     */
165
+    public function getEnabledAppsForUser(IUser $user) {
166
+        $apps = $this->getInstalledAppsValues();
167
+        $appsForUser = array_filter($apps, function ($enabled) use ($user) {
168
+            return $this->checkAppForUser($enabled, $user);
169
+        });
170
+        return array_keys($appsForUser);
171
+    }
172
+
173
+    /**
174
+     * @param \OCP\IGroup $group
175
+     * @return array
176
+     */
177
+    public function getEnabledAppsForGroup(IGroup $group): array {
178
+        $apps = $this->getInstalledAppsValues();
179
+        $appsForGroups = array_filter($apps, function ($enabled) use ($group) {
180
+            return $this->checkAppForGroups($enabled, $group);
181
+        });
182
+        return array_keys($appsForGroups);
183
+    }
184
+
185
+    /**
186
+     * @return array
187
+     */
188
+    public function getAutoDisabledApps(): array {
189
+        return $this->autoDisabledApps;
190
+    }
191
+
192
+    /**
193
+     * @param string $appId
194
+     * @return array
195
+     */
196
+    public function getAppRestriction(string $appId): array {
197
+        $values = $this->getInstalledAppsValues();
198
+
199
+        if (!isset($values[$appId])) {
200
+            return [];
201
+        }
202
+
203
+        if ($values[$appId] === 'yes' || $values[$appId] === 'no') {
204
+            return [];
205
+        }
206
+        return json_decode($values[$appId]);
207
+    }
208
+
209
+
210
+    /**
211
+     * Check if an app is enabled for user
212
+     *
213
+     * @param string $appId
214
+     * @param \OCP\IUser $user (optional) if not defined, the currently logged in user will be used
215
+     * @return bool
216
+     */
217
+    public function isEnabledForUser($appId, $user = null) {
218
+        if ($this->isAlwaysEnabled($appId)) {
219
+            return true;
220
+        }
221
+        if ($user === null) {
222
+            $user = $this->userSession->getUser();
223
+        }
224
+        $installedApps = $this->getInstalledAppsValues();
225
+        if (isset($installedApps[$appId])) {
226
+            return $this->checkAppForUser($installedApps[$appId], $user);
227
+        } else {
228
+            return false;
229
+        }
230
+    }
231
+
232
+    /**
233
+     * @param string $enabled
234
+     * @param IUser $user
235
+     * @return bool
236
+     */
237
+    private function checkAppForUser($enabled, $user) {
238
+        if ($enabled === 'yes') {
239
+            return true;
240
+        } elseif ($user === null) {
241
+            return false;
242
+        } else {
243
+            if(empty($enabled)){
244
+                return false;
245
+            }
246
+
247
+            $groupIds = json_decode($enabled);
248
+
249
+            if (!is_array($groupIds)) {
250
+                $jsonError = json_last_error();
251
+                $this->logger->warning('AppManger::checkAppForUser - can\'t decode group IDs: ' . print_r($enabled, true) . ' - json error code: ' . $jsonError, ['app' => 'lib']);
252
+                return false;
253
+            }
254
+
255
+            $userGroups = $this->groupManager->getUserGroupIds($user);
256
+            foreach ($userGroups as $groupId) {
257
+                if (in_array($groupId, $groupIds, true)) {
258
+                    return true;
259
+                }
260
+            }
261
+            return false;
262
+        }
263
+    }
264
+
265
+    /**
266
+     * @param string $enabled
267
+     * @param IGroup $group
268
+     * @return bool
269
+     */
270
+    private function checkAppForGroups(string $enabled, IGroup $group): bool {
271
+        if ($enabled === 'yes') {
272
+            return true;
273
+        } elseif ($group === null) {
274
+            return false;
275
+        } else {
276
+            if (empty($enabled)) {
277
+                return false;
278
+            }
279
+
280
+            $groupIds = json_decode($enabled);
281
+
282
+            if (!is_array($groupIds)) {
283
+                $jsonError = json_last_error();
284
+                $this->logger->warning('AppManger::checkAppForUser - can\'t decode group IDs: ' . print_r($enabled, true) . ' - json error code: ' . $jsonError, ['app' => 'lib']);
285
+                return false;
286
+            }
287
+
288
+            return in_array($group->getGID(), $groupIds);
289
+        }
290
+    }
291
+
292
+    /**
293
+     * Check if an app is enabled in the instance
294
+     *
295
+     * Notice: This actually checks if the app is enabled and not only if it is installed.
296
+     *
297
+     * @param string $appId
298
+     * @param \OCP\IGroup[]|String[] $groups
299
+     * @return bool
300
+     */
301
+    public function isInstalled($appId) {
302
+        $installedApps = $this->getInstalledAppsValues();
303
+        return isset($installedApps[$appId]);
304
+    }
305
+
306
+    public function ignoreNextcloudRequirementForApp(string $appId): void {
307
+        $ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
308
+        if (!in_array($appId, $ignoreMaxApps, true)) {
309
+            $ignoreMaxApps[] = $appId;
310
+            $this->config->setSystemValue('app_install_overwrite', $ignoreMaxApps);
311
+        }
312
+    }
313
+
314
+    /**
315
+     * Enable an app for every user
316
+     *
317
+     * @param string $appId
318
+     * @param bool $forceEnable
319
+     * @throws AppPathNotFoundException
320
+     */
321
+    public function enableApp(string $appId, bool $forceEnable = false): void {
322
+        // Check if app exists
323
+        $this->getAppPath($appId);
324
+
325
+        if ($forceEnable) {
326
+            $this->ignoreNextcloudRequirementForApp($appId);
327
+        }
328
+
329
+        $this->installedAppsCache[$appId] = 'yes';
330
+        $this->appConfig->setValue($appId, 'enabled', 'yes');
331
+        $this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE, new ManagerEvent(
332
+            ManagerEvent::EVENT_APP_ENABLE, $appId
333
+        ));
334
+        $this->clearAppsCache();
335
+    }
336
+
337
+    /**
338
+     * Whether a list of types contains a protected app type
339
+     *
340
+     * @param string[] $types
341
+     * @return bool
342
+     */
343
+    public function hasProtectedAppType($types) {
344
+        if (empty($types)) {
345
+            return false;
346
+        }
347
+
348
+        $protectedTypes = array_intersect($this->protectedAppTypes, $types);
349
+        return !empty($protectedTypes);
350
+    }
351
+
352
+    /**
353
+     * Enable an app only for specific groups
354
+     *
355
+     * @param string $appId
356
+     * @param \OCP\IGroup[] $groups
357
+     * @param bool $forceEnable
358
+     * @throws \InvalidArgumentException if app can't be enabled for groups
359
+     * @throws AppPathNotFoundException
360
+     */
361
+    public function enableAppForGroups(string $appId, array $groups, bool $forceEnable = false): void {
362
+        // Check if app exists
363
+        $this->getAppPath($appId);
364
+
365
+        $info = $this->getAppInfo($appId);
366
+        if (!empty($info['types']) && $this->hasProtectedAppType($info['types'])) {
367
+            throw new \InvalidArgumentException("$appId can't be enabled for groups.");
368
+        }
369
+
370
+        if ($forceEnable) {
371
+            $this->ignoreNextcloudRequirementForApp($appId);
372
+        }
373
+
374
+        $groupIds = array_map(function ($group) {
375
+            /** @var \OCP\IGroup $group */
376
+            return ($group instanceof IGroup)
377
+                ? $group->getGID()
378
+                : $group;
379
+        }, $groups);
380
+
381
+        $this->installedAppsCache[$appId] = json_encode($groupIds);
382
+        $this->appConfig->setValue($appId, 'enabled', json_encode($groupIds));
383
+        $this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, new ManagerEvent(
384
+            ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, $appId, $groups
385
+        ));
386
+        $this->clearAppsCache();
387
+
388
+    }
389
+
390
+    /**
391
+     * Disable an app for every user
392
+     *
393
+     * @param string $appId
394
+     * @param bool $automaticDisabled
395
+     * @throws \Exception if app can't be disabled
396
+     */
397
+    public function disableApp($appId, $automaticDisabled = false) {
398
+        if ($this->isAlwaysEnabled($appId)) {
399
+            throw new \Exception("$appId can't be disabled.");
400
+        }
401
+
402
+        if ($automaticDisabled) {
403
+            $this->autoDisabledApps[] = $appId;
404
+        }
405
+
406
+        unset($this->installedAppsCache[$appId]);
407
+        $this->appConfig->setValue($appId, 'enabled', 'no');
408
+
409
+        // run uninstall steps
410
+        $appData = $this->getAppInfo($appId);
411
+        if (!is_null($appData)) {
412
+            \OC_App::executeRepairSteps($appId, $appData['repair-steps']['uninstall']);
413
+        }
414
+
415
+        $this->dispatcher->dispatch(ManagerEvent::EVENT_APP_DISABLE, new ManagerEvent(
416
+            ManagerEvent::EVENT_APP_DISABLE, $appId
417
+        ));
418
+        $this->clearAppsCache();
419
+    }
420
+
421
+    /**
422
+     * Get the directory for the given app.
423
+     *
424
+     * @param string $appId
425
+     * @return string
426
+     * @throws AppPathNotFoundException if app folder can't be found
427
+     */
428
+    public function getAppPath($appId) {
429
+        $appPath = \OC_App::getAppPath($appId);
430
+        if($appPath === false) {
431
+            throw new AppPathNotFoundException('Could not find path for ' . $appId);
432
+        }
433
+        return $appPath;
434
+    }
435
+
436
+    /**
437
+     * Get the web path for the given app.
438
+     *
439
+     * @param string $appId
440
+     * @return string
441
+     * @throws AppPathNotFoundException if app path can't be found
442
+     */
443
+    public function getAppWebPath(string $appId): string {
444
+        $appWebPath = \OC_App::getAppWebPath($appId);
445
+        if($appWebPath === false) {
446
+            throw new AppPathNotFoundException('Could not find web path for ' . $appId);
447
+        }
448
+        return $appWebPath;
449
+    }
450
+
451
+    /**
452
+     * Clear the cached list of apps when enabling/disabling an app
453
+     */
454
+    public function clearAppsCache() {
455
+        $settingsMemCache = $this->memCacheFactory->createDistributed('settings');
456
+        $settingsMemCache->clear('listApps');
457
+        $this->appInfos = [];
458
+    }
459
+
460
+    /**
461
+     * Returns a list of apps that need upgrade
462
+     *
463
+     * @param string $version Nextcloud version as array of version components
464
+     * @return array list of app info from apps that need an upgrade
465
+     *
466
+     * @internal
467
+     */
468
+    public function getAppsNeedingUpgrade($version) {
469
+        $appsToUpgrade = [];
470
+        $apps = $this->getInstalledApps();
471
+        foreach ($apps as $appId) {
472
+            $appInfo = $this->getAppInfo($appId);
473
+            $appDbVersion = $this->appConfig->getValue($appId, 'installed_version');
474
+            if ($appDbVersion
475
+                && isset($appInfo['version'])
476
+                && version_compare($appInfo['version'], $appDbVersion, '>')
477
+                && \OC_App::isAppCompatible($version, $appInfo)
478
+            ) {
479
+                $appsToUpgrade[] = $appInfo;
480
+            }
481
+        }
482
+
483
+        return $appsToUpgrade;
484
+    }
485
+
486
+    /**
487
+     * Returns the app information from "appinfo/info.xml".
488
+     *
489
+     * @param string $appId app id
490
+     *
491
+     * @param bool $path
492
+     * @param null $lang
493
+     * @return array|null app info
494
+     */
495
+    public function getAppInfo(string $appId, bool $path = false, $lang = null) {
496
+        if ($path) {
497
+            $file = $appId;
498
+        } else {
499
+            if ($lang === null && isset($this->appInfos[$appId])) {
500
+                return $this->appInfos[$appId];
501
+            }
502
+            try {
503
+                $appPath = $this->getAppPath($appId);
504
+            } catch (AppPathNotFoundException $e) {
505
+                return null;
506
+            }
507
+            $file = $appPath . '/appinfo/info.xml';
508
+        }
509
+
510
+        $parser = new InfoParser($this->memCacheFactory->createLocal('core.appinfo'));
511
+        $data = $parser->parse($file);
512
+
513
+        if (is_array($data)) {
514
+            $data = \OC_App::parseAppInfo($data, $lang);
515
+        }
516
+
517
+        if ($lang === null) {
518
+            $this->appInfos[$appId] = $data;
519
+        }
520
+
521
+        return $data;
522
+    }
523
+
524
+    public function getAppVersion(string $appId, bool $useCache = true): string {
525
+        if(!$useCache || !isset($this->appVersions[$appId])) {
526
+            $appInfo = $this->getAppInfo($appId);
527
+            $this->appVersions[$appId] = ($appInfo !== null && isset($appInfo['version'])) ? $appInfo['version'] : '0';
528
+        }
529
+        return $this->appVersions[$appId];
530
+    }
531
+
532
+    /**
533
+     * Returns a list of apps incompatible with the given version
534
+     *
535
+     * @param string $version Nextcloud version as array of version components
536
+     *
537
+     * @return array list of app info from incompatible apps
538
+     *
539
+     * @internal
540
+     */
541
+    public function getIncompatibleApps(string $version): array {
542
+        $apps = $this->getInstalledApps();
543
+        $incompatibleApps = [];
544
+        foreach ($apps as $appId) {
545
+            $info = $this->getAppInfo($appId);
546
+            if ($info === null) {
547
+                $incompatibleApps[] = ['id' => $appId];
548
+            } else if (!\OC_App::isAppCompatible($version, $info)) {
549
+                $incompatibleApps[] = $info;
550
+            }
551
+        }
552
+        return $incompatibleApps;
553
+    }
554
+
555
+    /**
556
+     * @inheritdoc
557
+     * In case you change this method, also change \OC\App\CodeChecker\InfoChecker::isShipped()
558
+     */
559
+    public function isShipped($appId) {
560
+        $this->loadShippedJson();
561
+        return in_array($appId, $this->shippedApps, true);
562
+    }
563
+
564
+    private function isAlwaysEnabled($appId) {
565
+        $alwaysEnabled = $this->getAlwaysEnabledApps();
566
+        return in_array($appId, $alwaysEnabled, true);
567
+    }
568
+
569
+    /**
570
+     * In case you change this method, also change \OC\App\CodeChecker\InfoChecker::loadShippedJson()
571
+     * @throws \Exception
572
+     */
573
+    private function loadShippedJson() {
574
+        if ($this->shippedApps === null) {
575
+            $shippedJson = \OC::$SERVERROOT . '/core/shipped.json';
576
+            if (!file_exists($shippedJson)) {
577
+                throw new \Exception("File not found: $shippedJson");
578
+            }
579
+            $content = json_decode(file_get_contents($shippedJson), true);
580
+            $this->shippedApps = $content['shippedApps'];
581
+            $this->alwaysEnabled = $content['alwaysEnabled'];
582
+        }
583
+    }
584
+
585
+    /**
586
+     * @inheritdoc
587
+     */
588
+    public function getAlwaysEnabledApps() {
589
+        $this->loadShippedJson();
590
+        return $this->alwaysEnabled;
591
+    }
592 592
 }
Please login to merge, or discard this patch.
lib/private/App/DependencyAnalyzer.php 1 patch
Indentation   +343 added lines, -343 removed lines patch added patch discarded remove patch
@@ -34,347 +34,347 @@
 block discarded – undo
34 34
 
35 35
 class DependencyAnalyzer {
36 36
 
37
-	/** @var Platform */
38
-	private $platform;
39
-	/** @var \OCP\IL10N */
40
-	private $l;
41
-	/** @var array */
42
-	private $appInfo;
43
-
44
-	/**
45
-	 * @param Platform $platform
46
-	 * @param \OCP\IL10N $l
47
-	 */
48
-	public function __construct(Platform $platform, IL10N $l) {
49
-		$this->platform = $platform;
50
-		$this->l = $l;
51
-	}
52
-
53
-	/**
54
-	 * @param array $app
55
-	 * @returns array of missing dependencies
56
-	 */
57
-	public function analyze(array $app, bool $ignoreMax = false) {
58
-		$this->appInfo = $app;
59
-		if (isset($app['dependencies'])) {
60
-			$dependencies = $app['dependencies'];
61
-		} else {
62
-			$dependencies = [];
63
-		}
64
-
65
-		return array_merge(
66
-			$this->analyzePhpVersion($dependencies),
67
-			$this->analyzeDatabases($dependencies),
68
-			$this->analyzeCommands($dependencies),
69
-			$this->analyzeLibraries($dependencies),
70
-			$this->analyzeOS($dependencies),
71
-			$this->analyzeOC($dependencies, $app, $ignoreMax)
72
-		);
73
-	}
74
-
75
-	public function isMarkedCompatible(array $app): bool {
76
-		if (isset($app['dependencies'])) {
77
-			$dependencies = $app['dependencies'];
78
-		} else {
79
-			$dependencies = [];
80
-		}
81
-
82
-		$maxVersion = $this->getMaxVersion($dependencies, $app);
83
-		if ($maxVersion === null) {
84
-			return true;
85
-		}
86
-		return !$this->compareBigger($this->platform->getOcVersion(), $maxVersion);
87
-	}
88
-
89
-	/**
90
-	 * Truncates both versions to the lowest common version, e.g.
91
-	 * 5.1.2.3 and 5.1 will be turned into 5.1 and 5.1,
92
-	 * 5.2.6.5 and 5.1 will be turned into 5.2 and 5.1
93
-	 * @param string $first
94
-	 * @param string $second
95
-	 * @return string[] first element is the first version, second element is the
96
-	 * second version
97
-	 */
98
-	private function normalizeVersions($first, $second) {
99
-		$first = explode('.', $first);
100
-		$second = explode('.', $second);
101
-
102
-		// get both arrays to the same minimum size
103
-		$length = min(count($second), count($first));
104
-		$first = array_slice($first, 0, $length);
105
-		$second = array_slice($second, 0, $length);
106
-
107
-		return [implode('.', $first), implode('.', $second)];
108
-	}
109
-
110
-	/**
111
-	 * Parameters will be normalized and then passed into version_compare
112
-	 * in the same order they are specified in the method header
113
-	 * @param string $first
114
-	 * @param string $second
115
-	 * @param string $operator
116
-	 * @return bool result similar to version_compare
117
-	 */
118
-	private function compare($first, $second, $operator) {
119
-		// we can't normalize versions if one of the given parameters is not a
120
-		// version string but null. In case one parameter is null normalization
121
-		// will therefore be skipped
122
-		if ($first !== null && $second !== null) {
123
-			list($first, $second) = $this->normalizeVersions($first, $second);
124
-		}
125
-
126
-		return version_compare($first, $second, $operator);
127
-	}
128
-
129
-	/**
130
-	 * Checks if a version is bigger than another version
131
-	 * @param string $first
132
-	 * @param string $second
133
-	 * @return bool true if the first version is bigger than the second
134
-	 */
135
-	private function compareBigger($first, $second) {
136
-		return $this->compare($first, $second, '>');
137
-	}
138
-
139
-	/**
140
-	 * Checks if a version is smaller than another version
141
-	 * @param string $first
142
-	 * @param string $second
143
-	 * @return bool true if the first version is smaller than the second
144
-	 */
145
-	private function compareSmaller($first, $second) {
146
-		return $this->compare($first, $second, '<');
147
-	}
148
-
149
-	/**
150
-	 * @param array $dependencies
151
-	 * @return array
152
-	 */
153
-	private function analyzePhpVersion(array $dependencies) {
154
-		$missing = [];
155
-		if (isset($dependencies['php']['@attributes']['min-version'])) {
156
-			$minVersion = $dependencies['php']['@attributes']['min-version'];
157
-			if ($this->compareSmaller($this->platform->getPhpVersion(), $minVersion)) {
158
-				$missing[] = (string)$this->l->t('PHP %s or higher is required.', [$minVersion]);
159
-			}
160
-		}
161
-		if (isset($dependencies['php']['@attributes']['max-version'])) {
162
-			$maxVersion = $dependencies['php']['@attributes']['max-version'];
163
-			if ($this->compareBigger($this->platform->getPhpVersion(), $maxVersion)) {
164
-				$missing[] = (string)$this->l->t('PHP with a version lower than %s is required.', [$maxVersion]);
165
-			}
166
-		}
167
-		if (isset($dependencies['php']['@attributes']['min-int-size'])) {
168
-			$intSize = $dependencies['php']['@attributes']['min-int-size'];
169
-			if ($intSize > $this->platform->getIntSize()*8) {
170
-				$missing[] = (string)$this->l->t('%sbit or higher PHP required.', [$intSize]);
171
-			}
172
-		}
173
-		return $missing;
174
-	}
175
-
176
-	/**
177
-	 * @param array $dependencies
178
-	 * @return array
179
-	 */
180
-	private function analyzeDatabases(array $dependencies) {
181
-		$missing = [];
182
-		if (!isset($dependencies['database'])) {
183
-			return $missing;
184
-		}
185
-
186
-		$supportedDatabases = $dependencies['database'];
187
-		if (empty($supportedDatabases)) {
188
-			return $missing;
189
-		}
190
-		if (!is_array($supportedDatabases)) {
191
-			$supportedDatabases = [$supportedDatabases];
192
-		}
193
-		$supportedDatabases = array_map(function ($db) {
194
-			return $this->getValue($db);
195
-		}, $supportedDatabases);
196
-		$currentDatabase = $this->platform->getDatabase();
197
-		if (!in_array($currentDatabase, $supportedDatabases)) {
198
-			$missing[] = (string)$this->l->t('Following databases are supported: %s', [implode(', ', $supportedDatabases)]);
199
-		}
200
-		return $missing;
201
-	}
202
-
203
-	/**
204
-	 * @param array $dependencies
205
-	 * @return array
206
-	 */
207
-	private function analyzeCommands(array $dependencies) {
208
-		$missing = [];
209
-		if (!isset($dependencies['command'])) {
210
-			return $missing;
211
-		}
212
-
213
-		$commands = $dependencies['command'];
214
-		if (!is_array($commands)) {
215
-			$commands = [$commands];
216
-		}
217
-		if (isset($commands['@value'])) {
218
-			$commands = [$commands];
219
-		}
220
-		$os = $this->platform->getOS();
221
-		foreach ($commands as $command) {
222
-			if (isset($command['@attributes']['os']) && $command['@attributes']['os'] !== $os) {
223
-				continue;
224
-			}
225
-			$commandName = $this->getValue($command);
226
-			if (!$this->platform->isCommandKnown($commandName)) {
227
-				$missing[] = (string)$this->l->t('The command line tool %s could not be found', [$commandName]);
228
-			}
229
-		}
230
-		return $missing;
231
-	}
232
-
233
-	/**
234
-	 * @param array $dependencies
235
-	 * @return array
236
-	 */
237
-	private function analyzeLibraries(array $dependencies) {
238
-		$missing = [];
239
-		if (!isset($dependencies['lib'])) {
240
-			return $missing;
241
-		}
242
-
243
-		$libs = $dependencies['lib'];
244
-		if (!is_array($libs)) {
245
-			$libs = [$libs];
246
-		}
247
-		if (isset($libs['@value'])) {
248
-			$libs = [$libs];
249
-		}
250
-		foreach ($libs as $lib) {
251
-			$libName = $this->getValue($lib);
252
-			$libVersion = $this->platform->getLibraryVersion($libName);
253
-			if (is_null($libVersion)) {
254
-				$missing[] = $this->l->t('The library %s is not available.', [$libName]);
255
-				continue;
256
-			}
257
-
258
-			if (is_array($lib)) {
259
-				if (isset($lib['@attributes']['min-version'])) {
260
-					$minVersion = $lib['@attributes']['min-version'];
261
-					if ($this->compareSmaller($libVersion, $minVersion)) {
262
-						$missing[] = $this->l->t('Library %1$s with a version higher than %2$s is required - available version %3$s.',
263
-							[$libName, $minVersion, $libVersion]);
264
-					}
265
-				}
266
-				if (isset($lib['@attributes']['max-version'])) {
267
-					$maxVersion = $lib['@attributes']['max-version'];
268
-					if ($this->compareBigger($libVersion, $maxVersion)) {
269
-						$missing[] = $this->l->t('Library %1$s with a version lower than %2$s is required - available version %3$s.',
270
-							[$libName, $maxVersion, $libVersion]);
271
-					}
272
-				}
273
-			}
274
-		}
275
-		return $missing;
276
-	}
277
-
278
-	/**
279
-	 * @param array $dependencies
280
-	 * @return array
281
-	 */
282
-	private function analyzeOS(array $dependencies) {
283
-		$missing = [];
284
-		if (!isset($dependencies['os'])) {
285
-			return $missing;
286
-		}
287
-
288
-		$oss = $dependencies['os'];
289
-		if (empty($oss)) {
290
-			return $missing;
291
-		}
292
-		if (is_array($oss)) {
293
-			$oss = array_map(function ($os) {
294
-				return $this->getValue($os);
295
-			}, $oss);
296
-		} else {
297
-			$oss = [$oss];
298
-		}
299
-		$currentOS = $this->platform->getOS();
300
-		if (!in_array($currentOS, $oss)) {
301
-			$missing[] = (string)$this->l->t('Following platforms are supported: %s', [implode(', ', $oss)]);
302
-		}
303
-		return $missing;
304
-	}
305
-
306
-	/**
307
-	 * @param array $dependencies
308
-	 * @param array $appInfo
309
-	 * @return array
310
-	 */
311
-	private function analyzeOC(array $dependencies, array $appInfo, bool $ignoreMax) {
312
-		$missing = [];
313
-		$minVersion = null;
314
-		if (isset($dependencies['nextcloud']['@attributes']['min-version'])) {
315
-			$minVersion = $dependencies['nextcloud']['@attributes']['min-version'];
316
-		} elseif (isset($dependencies['owncloud']['@attributes']['min-version'])) {
317
-			$minVersion = $dependencies['owncloud']['@attributes']['min-version'];
318
-		} elseif (isset($appInfo['requiremin'])) {
319
-			$minVersion = $appInfo['requiremin'];
320
-		} elseif (isset($appInfo['require'])) {
321
-			$minVersion = $appInfo['require'];
322
-		}
323
-		$maxVersion = $this->getMaxVersion($dependencies, $appInfo);
324
-
325
-		if (!is_null($minVersion)) {
326
-			if ($this->compareSmaller($this->platform->getOcVersion(), $minVersion)) {
327
-				$missing[] = (string)$this->l->t('Server version %s or higher is required.', [$this->toVisibleVersion($minVersion)]);
328
-			}
329
-		}
330
-		if (!$ignoreMax && !is_null($maxVersion)) {
331
-			if ($this->compareBigger($this->platform->getOcVersion(), $maxVersion)) {
332
-				$missing[] = (string)$this->l->t('Server version %s or lower is required.', [$this->toVisibleVersion($maxVersion)]);
333
-			}
334
-		}
335
-		return $missing;
336
-	}
337
-
338
-	private function getMaxVersion(array $dependencies, array $appInfo): ?string {
339
-		if (isset($dependencies['nextcloud']['@attributes']['max-version'])) {
340
-			return $dependencies['nextcloud']['@attributes']['max-version'];
341
-		}
342
-		if (isset($dependencies['owncloud']['@attributes']['max-version'])) {
343
-			return $dependencies['owncloud']['@attributes']['max-version'];
344
-		}
345
-		if (isset($appInfo['requiremax'])) {
346
-			return $appInfo['requiremax'];
347
-		}
348
-
349
-		return null;
350
-	}
351
-
352
-	/**
353
-	 * Map the internal version number to the Nextcloud version
354
-	 *
355
-	 * @param string $version
356
-	 * @return string
357
-	 */
358
-	protected function toVisibleVersion($version) {
359
-		switch ($version) {
360
-			case '9.1':
361
-				return '10';
362
-			default:
363
-				if (strpos($version, '9.1.') === 0) {
364
-					$version = '10.0.' . substr($version, 4);
365
-				}
366
-				return $version;
367
-		}
368
-	}
369
-
370
-	/**
371
-	 * @param $element
372
-	 * @return mixed
373
-	 */
374
-	private function getValue($element) {
375
-		if (isset($element['@value'])) {
376
-			return $element['@value'];
377
-		}
378
-		return (string)$element;
379
-	}
37
+    /** @var Platform */
38
+    private $platform;
39
+    /** @var \OCP\IL10N */
40
+    private $l;
41
+    /** @var array */
42
+    private $appInfo;
43
+
44
+    /**
45
+     * @param Platform $platform
46
+     * @param \OCP\IL10N $l
47
+     */
48
+    public function __construct(Platform $platform, IL10N $l) {
49
+        $this->platform = $platform;
50
+        $this->l = $l;
51
+    }
52
+
53
+    /**
54
+     * @param array $app
55
+     * @returns array of missing dependencies
56
+     */
57
+    public function analyze(array $app, bool $ignoreMax = false) {
58
+        $this->appInfo = $app;
59
+        if (isset($app['dependencies'])) {
60
+            $dependencies = $app['dependencies'];
61
+        } else {
62
+            $dependencies = [];
63
+        }
64
+
65
+        return array_merge(
66
+            $this->analyzePhpVersion($dependencies),
67
+            $this->analyzeDatabases($dependencies),
68
+            $this->analyzeCommands($dependencies),
69
+            $this->analyzeLibraries($dependencies),
70
+            $this->analyzeOS($dependencies),
71
+            $this->analyzeOC($dependencies, $app, $ignoreMax)
72
+        );
73
+    }
74
+
75
+    public function isMarkedCompatible(array $app): bool {
76
+        if (isset($app['dependencies'])) {
77
+            $dependencies = $app['dependencies'];
78
+        } else {
79
+            $dependencies = [];
80
+        }
81
+
82
+        $maxVersion = $this->getMaxVersion($dependencies, $app);
83
+        if ($maxVersion === null) {
84
+            return true;
85
+        }
86
+        return !$this->compareBigger($this->platform->getOcVersion(), $maxVersion);
87
+    }
88
+
89
+    /**
90
+     * Truncates both versions to the lowest common version, e.g.
91
+     * 5.1.2.3 and 5.1 will be turned into 5.1 and 5.1,
92
+     * 5.2.6.5 and 5.1 will be turned into 5.2 and 5.1
93
+     * @param string $first
94
+     * @param string $second
95
+     * @return string[] first element is the first version, second element is the
96
+     * second version
97
+     */
98
+    private function normalizeVersions($first, $second) {
99
+        $first = explode('.', $first);
100
+        $second = explode('.', $second);
101
+
102
+        // get both arrays to the same minimum size
103
+        $length = min(count($second), count($first));
104
+        $first = array_slice($first, 0, $length);
105
+        $second = array_slice($second, 0, $length);
106
+
107
+        return [implode('.', $first), implode('.', $second)];
108
+    }
109
+
110
+    /**
111
+     * Parameters will be normalized and then passed into version_compare
112
+     * in the same order they are specified in the method header
113
+     * @param string $first
114
+     * @param string $second
115
+     * @param string $operator
116
+     * @return bool result similar to version_compare
117
+     */
118
+    private function compare($first, $second, $operator) {
119
+        // we can't normalize versions if one of the given parameters is not a
120
+        // version string but null. In case one parameter is null normalization
121
+        // will therefore be skipped
122
+        if ($first !== null && $second !== null) {
123
+            list($first, $second) = $this->normalizeVersions($first, $second);
124
+        }
125
+
126
+        return version_compare($first, $second, $operator);
127
+    }
128
+
129
+    /**
130
+     * Checks if a version is bigger than another version
131
+     * @param string $first
132
+     * @param string $second
133
+     * @return bool true if the first version is bigger than the second
134
+     */
135
+    private function compareBigger($first, $second) {
136
+        return $this->compare($first, $second, '>');
137
+    }
138
+
139
+    /**
140
+     * Checks if a version is smaller than another version
141
+     * @param string $first
142
+     * @param string $second
143
+     * @return bool true if the first version is smaller than the second
144
+     */
145
+    private function compareSmaller($first, $second) {
146
+        return $this->compare($first, $second, '<');
147
+    }
148
+
149
+    /**
150
+     * @param array $dependencies
151
+     * @return array
152
+     */
153
+    private function analyzePhpVersion(array $dependencies) {
154
+        $missing = [];
155
+        if (isset($dependencies['php']['@attributes']['min-version'])) {
156
+            $minVersion = $dependencies['php']['@attributes']['min-version'];
157
+            if ($this->compareSmaller($this->platform->getPhpVersion(), $minVersion)) {
158
+                $missing[] = (string)$this->l->t('PHP %s or higher is required.', [$minVersion]);
159
+            }
160
+        }
161
+        if (isset($dependencies['php']['@attributes']['max-version'])) {
162
+            $maxVersion = $dependencies['php']['@attributes']['max-version'];
163
+            if ($this->compareBigger($this->platform->getPhpVersion(), $maxVersion)) {
164
+                $missing[] = (string)$this->l->t('PHP with a version lower than %s is required.', [$maxVersion]);
165
+            }
166
+        }
167
+        if (isset($dependencies['php']['@attributes']['min-int-size'])) {
168
+            $intSize = $dependencies['php']['@attributes']['min-int-size'];
169
+            if ($intSize > $this->platform->getIntSize()*8) {
170
+                $missing[] = (string)$this->l->t('%sbit or higher PHP required.', [$intSize]);
171
+            }
172
+        }
173
+        return $missing;
174
+    }
175
+
176
+    /**
177
+     * @param array $dependencies
178
+     * @return array
179
+     */
180
+    private function analyzeDatabases(array $dependencies) {
181
+        $missing = [];
182
+        if (!isset($dependencies['database'])) {
183
+            return $missing;
184
+        }
185
+
186
+        $supportedDatabases = $dependencies['database'];
187
+        if (empty($supportedDatabases)) {
188
+            return $missing;
189
+        }
190
+        if (!is_array($supportedDatabases)) {
191
+            $supportedDatabases = [$supportedDatabases];
192
+        }
193
+        $supportedDatabases = array_map(function ($db) {
194
+            return $this->getValue($db);
195
+        }, $supportedDatabases);
196
+        $currentDatabase = $this->platform->getDatabase();
197
+        if (!in_array($currentDatabase, $supportedDatabases)) {
198
+            $missing[] = (string)$this->l->t('Following databases are supported: %s', [implode(', ', $supportedDatabases)]);
199
+        }
200
+        return $missing;
201
+    }
202
+
203
+    /**
204
+     * @param array $dependencies
205
+     * @return array
206
+     */
207
+    private function analyzeCommands(array $dependencies) {
208
+        $missing = [];
209
+        if (!isset($dependencies['command'])) {
210
+            return $missing;
211
+        }
212
+
213
+        $commands = $dependencies['command'];
214
+        if (!is_array($commands)) {
215
+            $commands = [$commands];
216
+        }
217
+        if (isset($commands['@value'])) {
218
+            $commands = [$commands];
219
+        }
220
+        $os = $this->platform->getOS();
221
+        foreach ($commands as $command) {
222
+            if (isset($command['@attributes']['os']) && $command['@attributes']['os'] !== $os) {
223
+                continue;
224
+            }
225
+            $commandName = $this->getValue($command);
226
+            if (!$this->platform->isCommandKnown($commandName)) {
227
+                $missing[] = (string)$this->l->t('The command line tool %s could not be found', [$commandName]);
228
+            }
229
+        }
230
+        return $missing;
231
+    }
232
+
233
+    /**
234
+     * @param array $dependencies
235
+     * @return array
236
+     */
237
+    private function analyzeLibraries(array $dependencies) {
238
+        $missing = [];
239
+        if (!isset($dependencies['lib'])) {
240
+            return $missing;
241
+        }
242
+
243
+        $libs = $dependencies['lib'];
244
+        if (!is_array($libs)) {
245
+            $libs = [$libs];
246
+        }
247
+        if (isset($libs['@value'])) {
248
+            $libs = [$libs];
249
+        }
250
+        foreach ($libs as $lib) {
251
+            $libName = $this->getValue($lib);
252
+            $libVersion = $this->platform->getLibraryVersion($libName);
253
+            if (is_null($libVersion)) {
254
+                $missing[] = $this->l->t('The library %s is not available.', [$libName]);
255
+                continue;
256
+            }
257
+
258
+            if (is_array($lib)) {
259
+                if (isset($lib['@attributes']['min-version'])) {
260
+                    $minVersion = $lib['@attributes']['min-version'];
261
+                    if ($this->compareSmaller($libVersion, $minVersion)) {
262
+                        $missing[] = $this->l->t('Library %1$s with a version higher than %2$s is required - available version %3$s.',
263
+                            [$libName, $minVersion, $libVersion]);
264
+                    }
265
+                }
266
+                if (isset($lib['@attributes']['max-version'])) {
267
+                    $maxVersion = $lib['@attributes']['max-version'];
268
+                    if ($this->compareBigger($libVersion, $maxVersion)) {
269
+                        $missing[] = $this->l->t('Library %1$s with a version lower than %2$s is required - available version %3$s.',
270
+                            [$libName, $maxVersion, $libVersion]);
271
+                    }
272
+                }
273
+            }
274
+        }
275
+        return $missing;
276
+    }
277
+
278
+    /**
279
+     * @param array $dependencies
280
+     * @return array
281
+     */
282
+    private function analyzeOS(array $dependencies) {
283
+        $missing = [];
284
+        if (!isset($dependencies['os'])) {
285
+            return $missing;
286
+        }
287
+
288
+        $oss = $dependencies['os'];
289
+        if (empty($oss)) {
290
+            return $missing;
291
+        }
292
+        if (is_array($oss)) {
293
+            $oss = array_map(function ($os) {
294
+                return $this->getValue($os);
295
+            }, $oss);
296
+        } else {
297
+            $oss = [$oss];
298
+        }
299
+        $currentOS = $this->platform->getOS();
300
+        if (!in_array($currentOS, $oss)) {
301
+            $missing[] = (string)$this->l->t('Following platforms are supported: %s', [implode(', ', $oss)]);
302
+        }
303
+        return $missing;
304
+    }
305
+
306
+    /**
307
+     * @param array $dependencies
308
+     * @param array $appInfo
309
+     * @return array
310
+     */
311
+    private function analyzeOC(array $dependencies, array $appInfo, bool $ignoreMax) {
312
+        $missing = [];
313
+        $minVersion = null;
314
+        if (isset($dependencies['nextcloud']['@attributes']['min-version'])) {
315
+            $minVersion = $dependencies['nextcloud']['@attributes']['min-version'];
316
+        } elseif (isset($dependencies['owncloud']['@attributes']['min-version'])) {
317
+            $minVersion = $dependencies['owncloud']['@attributes']['min-version'];
318
+        } elseif (isset($appInfo['requiremin'])) {
319
+            $minVersion = $appInfo['requiremin'];
320
+        } elseif (isset($appInfo['require'])) {
321
+            $minVersion = $appInfo['require'];
322
+        }
323
+        $maxVersion = $this->getMaxVersion($dependencies, $appInfo);
324
+
325
+        if (!is_null($minVersion)) {
326
+            if ($this->compareSmaller($this->platform->getOcVersion(), $minVersion)) {
327
+                $missing[] = (string)$this->l->t('Server version %s or higher is required.', [$this->toVisibleVersion($minVersion)]);
328
+            }
329
+        }
330
+        if (!$ignoreMax && !is_null($maxVersion)) {
331
+            if ($this->compareBigger($this->platform->getOcVersion(), $maxVersion)) {
332
+                $missing[] = (string)$this->l->t('Server version %s or lower is required.', [$this->toVisibleVersion($maxVersion)]);
333
+            }
334
+        }
335
+        return $missing;
336
+    }
337
+
338
+    private function getMaxVersion(array $dependencies, array $appInfo): ?string {
339
+        if (isset($dependencies['nextcloud']['@attributes']['max-version'])) {
340
+            return $dependencies['nextcloud']['@attributes']['max-version'];
341
+        }
342
+        if (isset($dependencies['owncloud']['@attributes']['max-version'])) {
343
+            return $dependencies['owncloud']['@attributes']['max-version'];
344
+        }
345
+        if (isset($appInfo['requiremax'])) {
346
+            return $appInfo['requiremax'];
347
+        }
348
+
349
+        return null;
350
+    }
351
+
352
+    /**
353
+     * Map the internal version number to the Nextcloud version
354
+     *
355
+     * @param string $version
356
+     * @return string
357
+     */
358
+    protected function toVisibleVersion($version) {
359
+        switch ($version) {
360
+            case '9.1':
361
+                return '10';
362
+            default:
363
+                if (strpos($version, '9.1.') === 0) {
364
+                    $version = '10.0.' . substr($version, 4);
365
+                }
366
+                return $version;
367
+        }
368
+    }
369
+
370
+    /**
371
+     * @param $element
372
+     * @return mixed
373
+     */
374
+    private function getValue($element) {
375
+        if (isset($element['@value'])) {
376
+            return $element['@value'];
377
+        }
378
+        return (string)$element;
379
+    }
380 380
 }
Please login to merge, or discard this patch.