Completed
Push — master ( fab951...c2b1bd )
by Joas
102:02 queued 82:49
created
lib/private/Security/CertificateManager.php 2 patches
Indentation   +248 added lines, -248 removed lines patch added patch discarded remove patch
@@ -38,253 +38,253 @@
 block discarded – undo
38 38
  * Manage trusted certificates for users
39 39
  */
40 40
 class CertificateManager implements ICertificateManager {
41
-	/**
42
-	 * @var string
43
-	 */
44
-	protected $uid;
45
-
46
-	/**
47
-	 * @var \OC\Files\View
48
-	 */
49
-	protected $view;
50
-
51
-	/**
52
-	 * @var IConfig
53
-	 */
54
-	protected $config;
55
-
56
-	/**
57
-	 * @var ILogger
58
-	 */
59
-	protected $logger;
60
-
61
-	/** @var ISecureRandom */
62
-	protected $random;
63
-
64
-	/**
65
-	 * @param string $uid
66
-	 * @param \OC\Files\View $view relative to data/
67
-	 * @param IConfig $config
68
-	 * @param ILogger $logger
69
-	 * @param ISecureRandom $random
70
-	 */
71
-	public function __construct($uid,
72
-								\OC\Files\View $view,
73
-								IConfig $config,
74
-								ILogger $logger,
75
-								ISecureRandom $random) {
76
-		$this->uid = $uid;
77
-		$this->view = $view;
78
-		$this->config = $config;
79
-		$this->logger = $logger;
80
-		$this->random = $random;
81
-	}
82
-
83
-	/**
84
-	 * Returns all certificates trusted by the user
85
-	 *
86
-	 * @return \OCP\ICertificate[]
87
-	 */
88
-	public function listCertificates() {
89
-
90
-		if (!$this->config->getSystemValue('installed', false)) {
91
-			return array();
92
-		}
93
-
94
-		$path = $this->getPathToCertificates() . 'uploads/';
95
-		if (!$this->view->is_dir($path)) {
96
-			return array();
97
-		}
98
-		$result = array();
99
-		$handle = $this->view->opendir($path);
100
-		if (!is_resource($handle)) {
101
-			return array();
102
-		}
103
-		while (false !== ($file = readdir($handle))) {
104
-			if ($file != '.' && $file != '..') {
105
-				try {
106
-					$result[] = new Certificate($this->view->file_get_contents($path . $file), $file);
107
-				} catch (\Exception $e) {
108
-				}
109
-			}
110
-		}
111
-		closedir($handle);
112
-		return $result;
113
-	}
114
-
115
-	/**
116
-	 * create the certificate bundle of all trusted certificated
117
-	 */
118
-	public function createCertificateBundle() {
119
-		$path = $this->getPathToCertificates();
120
-		$certs = $this->listCertificates();
121
-
122
-		if (!$this->view->file_exists($path)) {
123
-			$this->view->mkdir($path);
124
-		}
125
-
126
-		$defaultCertificates = file_get_contents(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
127
-		if (strlen($defaultCertificates) < 1024) { // sanity check to verify that we have some content for our bundle
128
-			// log as exception so we have a stacktrace
129
-			$this->logger->logException(new \Exception('Shipped ca-bundle is empty, refusing to create certificate bundle'));
130
-			return;
131
-		}
132
-
133
-		$certPath = $path . 'rootcerts.crt';
134
-		$tmpPath = $certPath . '.tmp' . $this->random->generate(10, ISecureRandom::CHAR_DIGITS);
135
-		$fhCerts = $this->view->fopen($tmpPath, 'w');
136
-
137
-		// Write user certificates
138
-		foreach ($certs as $cert) {
139
-			$file = $path . '/uploads/' . $cert->getName();
140
-			$data = $this->view->file_get_contents($file);
141
-			if (strpos($data, 'BEGIN CERTIFICATE')) {
142
-				fwrite($fhCerts, $data);
143
-				fwrite($fhCerts, "\r\n");
144
-			}
145
-		}
146
-
147
-		// Append the default certificates
148
-		fwrite($fhCerts, $defaultCertificates);
149
-
150
-		// Append the system certificate bundle
151
-		$systemBundle = $this->getCertificateBundle(null);
152
-		if ($systemBundle !== $certPath && $this->view->file_exists($systemBundle)) {
153
-			$systemCertificates = $this->view->file_get_contents($systemBundle);
154
-			fwrite($fhCerts, $systemCertificates);
155
-		}
156
-
157
-		fclose($fhCerts);
158
-
159
-		$this->view->rename($tmpPath, $certPath);
160
-	}
161
-
162
-	/**
163
-	 * Save the certificate and re-generate the certificate bundle
164
-	 *
165
-	 * @param string $certificate the certificate data
166
-	 * @param string $name the filename for the certificate
167
-	 * @return \OCP\ICertificate
168
-	 * @throws \Exception If the certificate could not get added
169
-	 */
170
-	public function addCertificate($certificate, $name) {
171
-		if (!Filesystem::isValidPath($name) or Filesystem::isFileBlacklisted($name)) {
172
-			throw new \Exception('Filename is not valid');
173
-		}
174
-
175
-		$dir = $this->getPathToCertificates() . 'uploads/';
176
-		if (!$this->view->file_exists($dir)) {
177
-			$this->view->mkdir($dir);
178
-		}
179
-
180
-		try {
181
-			$file = $dir . $name;
182
-			$certificateObject = new Certificate($certificate, $name);
183
-			$this->view->file_put_contents($file, $certificate);
184
-			$this->createCertificateBundle();
185
-			return $certificateObject;
186
-		} catch (\Exception $e) {
187
-			throw $e;
188
-		}
189
-
190
-	}
191
-
192
-	/**
193
-	 * Remove the certificate and re-generate the certificate bundle
194
-	 *
195
-	 * @param string $name
196
-	 * @return bool
197
-	 */
198
-	public function removeCertificate($name) {
199
-		if (!Filesystem::isValidPath($name)) {
200
-			return false;
201
-		}
202
-		$path = $this->getPathToCertificates() . 'uploads/';
203
-		if ($this->view->file_exists($path . $name)) {
204
-			$this->view->unlink($path . $name);
205
-			$this->createCertificateBundle();
206
-		}
207
-		return true;
208
-	}
209
-
210
-	/**
211
-	 * Get the path to the certificate bundle for this user
212
-	 *
213
-	 * @param string|null $uid (optional) user to get the certificate bundle for, use `null` to get the system bundle
214
-	 * @return string
215
-	 */
216
-	public function getCertificateBundle($uid = '') {
217
-		if ($uid === '') {
218
-			$uid = $this->uid;
219
-		}
220
-		return $this->getPathToCertificates($uid) . 'rootcerts.crt';
221
-	}
222
-
223
-	/**
224
-	 * Get the full local path to the certificate bundle for this user
225
-	 *
226
-	 * @param string $uid (optional) user to get the certificate bundle for, use `null` to get the system bundle
227
-	 * @return string
228
-	 */
229
-	public function getAbsoluteBundlePath($uid = '') {
230
-		if ($uid === '') {
231
-			$uid = $this->uid;
232
-		}
233
-		if ($this->needsRebundling($uid)) {
234
-			if (is_null($uid)) {
235
-				$manager = new CertificateManager(null, $this->view, $this->config, $this->logger, $this->random);
236
-				$manager->createCertificateBundle();
237
-			} else {
238
-				$this->createCertificateBundle();
239
-			}
240
-		}
241
-		return $this->view->getLocalFile($this->getCertificateBundle($uid));
242
-	}
243
-
244
-	/**
245
-	 * @param string|null $uid (optional) user to get the certificate path for, use `null` to get the system path
246
-	 * @return string
247
-	 */
248
-	private function getPathToCertificates($uid = '') {
249
-		if ($uid === '') {
250
-			$uid = $this->uid;
251
-		}
252
-		return is_null($uid) ? '/files_external/' : '/' . $uid . '/files_external/';
253
-	}
254
-
255
-	/**
256
-	 * Check if we need to re-bundle the certificates because one of the sources has updated
257
-	 *
258
-	 * @param string $uid (optional) user to get the certificate path for, use `null` to get the system path
259
-	 * @return bool
260
-	 */
261
-	private function needsRebundling($uid = '') {
262
-		if ($uid === '') {
263
-			$uid = $this->uid;
264
-		}
265
-		$sourceMTimes = [$this->getFilemtimeOfCaBundle()];
266
-		$targetBundle = $this->getCertificateBundle($uid);
267
-		if (!$this->view->file_exists($targetBundle)) {
268
-			return true;
269
-		}
270
-
271
-		if (!is_null($uid)) { // also depend on the system bundle
272
-			$sourceMTimes[] = $this->view->filemtime($this->getCertificateBundle(null));
273
-		}
274
-
275
-		$sourceMTime = array_reduce($sourceMTimes, function ($max, $mtime) {
276
-			return max($max, $mtime);
277
-		}, 0);
278
-		return $sourceMTime > $this->view->filemtime($targetBundle);
279
-	}
280
-
281
-	/**
282
-	 * get mtime of ca-bundle shipped by Nextcloud
283
-	 *
284
-	 * @return int
285
-	 */
286
-	protected function getFilemtimeOfCaBundle() {
287
-		return filemtime(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
288
-	}
41
+    /**
42
+     * @var string
43
+     */
44
+    protected $uid;
45
+
46
+    /**
47
+     * @var \OC\Files\View
48
+     */
49
+    protected $view;
50
+
51
+    /**
52
+     * @var IConfig
53
+     */
54
+    protected $config;
55
+
56
+    /**
57
+     * @var ILogger
58
+     */
59
+    protected $logger;
60
+
61
+    /** @var ISecureRandom */
62
+    protected $random;
63
+
64
+    /**
65
+     * @param string $uid
66
+     * @param \OC\Files\View $view relative to data/
67
+     * @param IConfig $config
68
+     * @param ILogger $logger
69
+     * @param ISecureRandom $random
70
+     */
71
+    public function __construct($uid,
72
+                                \OC\Files\View $view,
73
+                                IConfig $config,
74
+                                ILogger $logger,
75
+                                ISecureRandom $random) {
76
+        $this->uid = $uid;
77
+        $this->view = $view;
78
+        $this->config = $config;
79
+        $this->logger = $logger;
80
+        $this->random = $random;
81
+    }
82
+
83
+    /**
84
+     * Returns all certificates trusted by the user
85
+     *
86
+     * @return \OCP\ICertificate[]
87
+     */
88
+    public function listCertificates() {
89
+
90
+        if (!$this->config->getSystemValue('installed', false)) {
91
+            return array();
92
+        }
93
+
94
+        $path = $this->getPathToCertificates() . 'uploads/';
95
+        if (!$this->view->is_dir($path)) {
96
+            return array();
97
+        }
98
+        $result = array();
99
+        $handle = $this->view->opendir($path);
100
+        if (!is_resource($handle)) {
101
+            return array();
102
+        }
103
+        while (false !== ($file = readdir($handle))) {
104
+            if ($file != '.' && $file != '..') {
105
+                try {
106
+                    $result[] = new Certificate($this->view->file_get_contents($path . $file), $file);
107
+                } catch (\Exception $e) {
108
+                }
109
+            }
110
+        }
111
+        closedir($handle);
112
+        return $result;
113
+    }
114
+
115
+    /**
116
+     * create the certificate bundle of all trusted certificated
117
+     */
118
+    public function createCertificateBundle() {
119
+        $path = $this->getPathToCertificates();
120
+        $certs = $this->listCertificates();
121
+
122
+        if (!$this->view->file_exists($path)) {
123
+            $this->view->mkdir($path);
124
+        }
125
+
126
+        $defaultCertificates = file_get_contents(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
127
+        if (strlen($defaultCertificates) < 1024) { // sanity check to verify that we have some content for our bundle
128
+            // log as exception so we have a stacktrace
129
+            $this->logger->logException(new \Exception('Shipped ca-bundle is empty, refusing to create certificate bundle'));
130
+            return;
131
+        }
132
+
133
+        $certPath = $path . 'rootcerts.crt';
134
+        $tmpPath = $certPath . '.tmp' . $this->random->generate(10, ISecureRandom::CHAR_DIGITS);
135
+        $fhCerts = $this->view->fopen($tmpPath, 'w');
136
+
137
+        // Write user certificates
138
+        foreach ($certs as $cert) {
139
+            $file = $path . '/uploads/' . $cert->getName();
140
+            $data = $this->view->file_get_contents($file);
141
+            if (strpos($data, 'BEGIN CERTIFICATE')) {
142
+                fwrite($fhCerts, $data);
143
+                fwrite($fhCerts, "\r\n");
144
+            }
145
+        }
146
+
147
+        // Append the default certificates
148
+        fwrite($fhCerts, $defaultCertificates);
149
+
150
+        // Append the system certificate bundle
151
+        $systemBundle = $this->getCertificateBundle(null);
152
+        if ($systemBundle !== $certPath && $this->view->file_exists($systemBundle)) {
153
+            $systemCertificates = $this->view->file_get_contents($systemBundle);
154
+            fwrite($fhCerts, $systemCertificates);
155
+        }
156
+
157
+        fclose($fhCerts);
158
+
159
+        $this->view->rename($tmpPath, $certPath);
160
+    }
161
+
162
+    /**
163
+     * Save the certificate and re-generate the certificate bundle
164
+     *
165
+     * @param string $certificate the certificate data
166
+     * @param string $name the filename for the certificate
167
+     * @return \OCP\ICertificate
168
+     * @throws \Exception If the certificate could not get added
169
+     */
170
+    public function addCertificate($certificate, $name) {
171
+        if (!Filesystem::isValidPath($name) or Filesystem::isFileBlacklisted($name)) {
172
+            throw new \Exception('Filename is not valid');
173
+        }
174
+
175
+        $dir = $this->getPathToCertificates() . 'uploads/';
176
+        if (!$this->view->file_exists($dir)) {
177
+            $this->view->mkdir($dir);
178
+        }
179
+
180
+        try {
181
+            $file = $dir . $name;
182
+            $certificateObject = new Certificate($certificate, $name);
183
+            $this->view->file_put_contents($file, $certificate);
184
+            $this->createCertificateBundle();
185
+            return $certificateObject;
186
+        } catch (\Exception $e) {
187
+            throw $e;
188
+        }
189
+
190
+    }
191
+
192
+    /**
193
+     * Remove the certificate and re-generate the certificate bundle
194
+     *
195
+     * @param string $name
196
+     * @return bool
197
+     */
198
+    public function removeCertificate($name) {
199
+        if (!Filesystem::isValidPath($name)) {
200
+            return false;
201
+        }
202
+        $path = $this->getPathToCertificates() . 'uploads/';
203
+        if ($this->view->file_exists($path . $name)) {
204
+            $this->view->unlink($path . $name);
205
+            $this->createCertificateBundle();
206
+        }
207
+        return true;
208
+    }
209
+
210
+    /**
211
+     * Get the path to the certificate bundle for this user
212
+     *
213
+     * @param string|null $uid (optional) user to get the certificate bundle for, use `null` to get the system bundle
214
+     * @return string
215
+     */
216
+    public function getCertificateBundle($uid = '') {
217
+        if ($uid === '') {
218
+            $uid = $this->uid;
219
+        }
220
+        return $this->getPathToCertificates($uid) . 'rootcerts.crt';
221
+    }
222
+
223
+    /**
224
+     * Get the full local path to the certificate bundle for this user
225
+     *
226
+     * @param string $uid (optional) user to get the certificate bundle for, use `null` to get the system bundle
227
+     * @return string
228
+     */
229
+    public function getAbsoluteBundlePath($uid = '') {
230
+        if ($uid === '') {
231
+            $uid = $this->uid;
232
+        }
233
+        if ($this->needsRebundling($uid)) {
234
+            if (is_null($uid)) {
235
+                $manager = new CertificateManager(null, $this->view, $this->config, $this->logger, $this->random);
236
+                $manager->createCertificateBundle();
237
+            } else {
238
+                $this->createCertificateBundle();
239
+            }
240
+        }
241
+        return $this->view->getLocalFile($this->getCertificateBundle($uid));
242
+    }
243
+
244
+    /**
245
+     * @param string|null $uid (optional) user to get the certificate path for, use `null` to get the system path
246
+     * @return string
247
+     */
248
+    private function getPathToCertificates($uid = '') {
249
+        if ($uid === '') {
250
+            $uid = $this->uid;
251
+        }
252
+        return is_null($uid) ? '/files_external/' : '/' . $uid . '/files_external/';
253
+    }
254
+
255
+    /**
256
+     * Check if we need to re-bundle the certificates because one of the sources has updated
257
+     *
258
+     * @param string $uid (optional) user to get the certificate path for, use `null` to get the system path
259
+     * @return bool
260
+     */
261
+    private function needsRebundling($uid = '') {
262
+        if ($uid === '') {
263
+            $uid = $this->uid;
264
+        }
265
+        $sourceMTimes = [$this->getFilemtimeOfCaBundle()];
266
+        $targetBundle = $this->getCertificateBundle($uid);
267
+        if (!$this->view->file_exists($targetBundle)) {
268
+            return true;
269
+        }
270
+
271
+        if (!is_null($uid)) { // also depend on the system bundle
272
+            $sourceMTimes[] = $this->view->filemtime($this->getCertificateBundle(null));
273
+        }
274
+
275
+        $sourceMTime = array_reduce($sourceMTimes, function ($max, $mtime) {
276
+            return max($max, $mtime);
277
+        }, 0);
278
+        return $sourceMTime > $this->view->filemtime($targetBundle);
279
+    }
280
+
281
+    /**
282
+     * get mtime of ca-bundle shipped by Nextcloud
283
+     *
284
+     * @return int
285
+     */
286
+    protected function getFilemtimeOfCaBundle() {
287
+        return filemtime(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
288
+    }
289 289
 
290 290
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -91,7 +91,7 @@  discard block
 block discarded – undo
91 91
 			return array();
92 92
 		}
93 93
 
94
-		$path = $this->getPathToCertificates() . 'uploads/';
94
+		$path = $this->getPathToCertificates().'uploads/';
95 95
 		if (!$this->view->is_dir($path)) {
96 96
 			return array();
97 97
 		}
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
 		while (false !== ($file = readdir($handle))) {
104 104
 			if ($file != '.' && $file != '..') {
105 105
 				try {
106
-					$result[] = new Certificate($this->view->file_get_contents($path . $file), $file);
106
+					$result[] = new Certificate($this->view->file_get_contents($path.$file), $file);
107 107
 				} catch (\Exception $e) {
108 108
 				}
109 109
 			}
@@ -123,20 +123,20 @@  discard block
 block discarded – undo
123 123
 			$this->view->mkdir($path);
124 124
 		}
125 125
 
126
-		$defaultCertificates = file_get_contents(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
126
+		$defaultCertificates = file_get_contents(\OC::$SERVERROOT.'/resources/config/ca-bundle.crt');
127 127
 		if (strlen($defaultCertificates) < 1024) { // sanity check to verify that we have some content for our bundle
128 128
 			// log as exception so we have a stacktrace
129 129
 			$this->logger->logException(new \Exception('Shipped ca-bundle is empty, refusing to create certificate bundle'));
130 130
 			return;
131 131
 		}
132 132
 
133
-		$certPath = $path . 'rootcerts.crt';
134
-		$tmpPath = $certPath . '.tmp' . $this->random->generate(10, ISecureRandom::CHAR_DIGITS);
133
+		$certPath = $path.'rootcerts.crt';
134
+		$tmpPath = $certPath.'.tmp'.$this->random->generate(10, ISecureRandom::CHAR_DIGITS);
135 135
 		$fhCerts = $this->view->fopen($tmpPath, 'w');
136 136
 
137 137
 		// Write user certificates
138 138
 		foreach ($certs as $cert) {
139
-			$file = $path . '/uploads/' . $cert->getName();
139
+			$file = $path.'/uploads/'.$cert->getName();
140 140
 			$data = $this->view->file_get_contents($file);
141 141
 			if (strpos($data, 'BEGIN CERTIFICATE')) {
142 142
 				fwrite($fhCerts, $data);
@@ -172,13 +172,13 @@  discard block
 block discarded – undo
172 172
 			throw new \Exception('Filename is not valid');
173 173
 		}
174 174
 
175
-		$dir = $this->getPathToCertificates() . 'uploads/';
175
+		$dir = $this->getPathToCertificates().'uploads/';
176 176
 		if (!$this->view->file_exists($dir)) {
177 177
 			$this->view->mkdir($dir);
178 178
 		}
179 179
 
180 180
 		try {
181
-			$file = $dir . $name;
181
+			$file = $dir.$name;
182 182
 			$certificateObject = new Certificate($certificate, $name);
183 183
 			$this->view->file_put_contents($file, $certificate);
184 184
 			$this->createCertificateBundle();
@@ -199,9 +199,9 @@  discard block
 block discarded – undo
199 199
 		if (!Filesystem::isValidPath($name)) {
200 200
 			return false;
201 201
 		}
202
-		$path = $this->getPathToCertificates() . 'uploads/';
203
-		if ($this->view->file_exists($path . $name)) {
204
-			$this->view->unlink($path . $name);
202
+		$path = $this->getPathToCertificates().'uploads/';
203
+		if ($this->view->file_exists($path.$name)) {
204
+			$this->view->unlink($path.$name);
205 205
 			$this->createCertificateBundle();
206 206
 		}
207 207
 		return true;
@@ -217,7 +217,7 @@  discard block
 block discarded – undo
217 217
 		if ($uid === '') {
218 218
 			$uid = $this->uid;
219 219
 		}
220
-		return $this->getPathToCertificates($uid) . 'rootcerts.crt';
220
+		return $this->getPathToCertificates($uid).'rootcerts.crt';
221 221
 	}
222 222
 
223 223
 	/**
@@ -249,7 +249,7 @@  discard block
 block discarded – undo
249 249
 		if ($uid === '') {
250 250
 			$uid = $this->uid;
251 251
 		}
252
-		return is_null($uid) ? '/files_external/' : '/' . $uid . '/files_external/';
252
+		return is_null($uid) ? '/files_external/' : '/'.$uid.'/files_external/';
253 253
 	}
254 254
 
255 255
 	/**
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
 			$sourceMTimes[] = $this->view->filemtime($this->getCertificateBundle(null));
273 273
 		}
274 274
 
275
-		$sourceMTime = array_reduce($sourceMTimes, function ($max, $mtime) {
275
+		$sourceMTime = array_reduce($sourceMTimes, function($max, $mtime) {
276 276
 			return max($max, $mtime);
277 277
 		}, 0);
278 278
 		return $sourceMTime > $this->view->filemtime($targetBundle);
@@ -284,7 +284,7 @@  discard block
 block discarded – undo
284 284
 	 * @return int
285 285
 	 */
286 286
 	protected function getFilemtimeOfCaBundle() {
287
-		return filemtime(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
287
+		return filemtime(\OC::$SERVERROOT.'/resources/config/ca-bundle.crt');
288 288
 	}
289 289
 
290 290
 }
Please login to merge, or discard this patch.
lib/private/legacy/db.php 2 patches
Indentation   +193 added lines, -193 removed lines patch added patch discarded remove patch
@@ -34,209 +34,209 @@
 block discarded – undo
34 34
  */
35 35
 class OC_DB {
36 36
 
37
-	/**
38
-	 * get MDB2 schema manager
39
-	 *
40
-	 * @return \OC\DB\MDB2SchemaManager
41
-	 */
42
-	private static function getMDB2SchemaManager() {
43
-		return new \OC\DB\MDB2SchemaManager(\OC::$server->getDatabaseConnection());
44
-	}
37
+    /**
38
+     * get MDB2 schema manager
39
+     *
40
+     * @return \OC\DB\MDB2SchemaManager
41
+     */
42
+    private static function getMDB2SchemaManager() {
43
+        return new \OC\DB\MDB2SchemaManager(\OC::$server->getDatabaseConnection());
44
+    }
45 45
 
46
-	/**
47
-	 * Prepare a SQL query
48
-	 * @param string $query Query string
49
-	 * @param int|null $limit
50
-	 * @param int|null $offset
51
-	 * @param bool|null $isManipulation
52
-	 * @throws \OC\DatabaseException
53
-	 * @return OC_DB_StatementWrapper prepared SQL query
54
-	 *
55
-	 * SQL query via Doctrine prepare(), needs to be execute()'d!
56
-	 */
57
-	static public function prepare( $query , $limit = null, $offset = null, $isManipulation = null) {
58
-		$connection = \OC::$server->getDatabaseConnection();
46
+    /**
47
+     * Prepare a SQL query
48
+     * @param string $query Query string
49
+     * @param int|null $limit
50
+     * @param int|null $offset
51
+     * @param bool|null $isManipulation
52
+     * @throws \OC\DatabaseException
53
+     * @return OC_DB_StatementWrapper prepared SQL query
54
+     *
55
+     * SQL query via Doctrine prepare(), needs to be execute()'d!
56
+     */
57
+    static public function prepare( $query , $limit = null, $offset = null, $isManipulation = null) {
58
+        $connection = \OC::$server->getDatabaseConnection();
59 59
 
60
-		if ($isManipulation === null) {
61
-			//try to guess, so we return the number of rows on manipulations
62
-			$isManipulation = self::isManipulation($query);
63
-		}
60
+        if ($isManipulation === null) {
61
+            //try to guess, so we return the number of rows on manipulations
62
+            $isManipulation = self::isManipulation($query);
63
+        }
64 64
 
65
-		// return the result
66
-		try {
67
-			$result =$connection->prepare($query, $limit, $offset);
68
-		} catch (\Doctrine\DBAL\DBALException $e) {
69
-			throw new \OC\DatabaseException($e->getMessage());
70
-		}
71
-		// differentiate between query and manipulation
72
-		$result = new OC_DB_StatementWrapper($result, $isManipulation);
73
-		return $result;
74
-	}
65
+        // return the result
66
+        try {
67
+            $result =$connection->prepare($query, $limit, $offset);
68
+        } catch (\Doctrine\DBAL\DBALException $e) {
69
+            throw new \OC\DatabaseException($e->getMessage());
70
+        }
71
+        // differentiate between query and manipulation
72
+        $result = new OC_DB_StatementWrapper($result, $isManipulation);
73
+        return $result;
74
+    }
75 75
 
76
-	/**
77
-	 * tries to guess the type of statement based on the first 10 characters
78
-	 * the current check allows some whitespace but does not work with IF EXISTS or other more complex statements
79
-	 *
80
-	 * @param string $sql
81
-	 * @return bool
82
-	 */
83
-	static public function isManipulation( $sql ) {
84
-		$selectOccurrence = stripos($sql, 'SELECT');
85
-		if ($selectOccurrence !== false && $selectOccurrence < 10) {
86
-			return false;
87
-		}
88
-		$insertOccurrence = stripos($sql, 'INSERT');
89
-		if ($insertOccurrence !== false && $insertOccurrence < 10) {
90
-			return true;
91
-		}
92
-		$updateOccurrence = stripos($sql, 'UPDATE');
93
-		if ($updateOccurrence !== false && $updateOccurrence < 10) {
94
-			return true;
95
-		}
96
-		$deleteOccurrence = stripos($sql, 'DELETE');
97
-		if ($deleteOccurrence !== false && $deleteOccurrence < 10) {
98
-			return true;
99
-		}
100
-		return false;
101
-	}
76
+    /**
77
+     * tries to guess the type of statement based on the first 10 characters
78
+     * the current check allows some whitespace but does not work with IF EXISTS or other more complex statements
79
+     *
80
+     * @param string $sql
81
+     * @return bool
82
+     */
83
+    static public function isManipulation( $sql ) {
84
+        $selectOccurrence = stripos($sql, 'SELECT');
85
+        if ($selectOccurrence !== false && $selectOccurrence < 10) {
86
+            return false;
87
+        }
88
+        $insertOccurrence = stripos($sql, 'INSERT');
89
+        if ($insertOccurrence !== false && $insertOccurrence < 10) {
90
+            return true;
91
+        }
92
+        $updateOccurrence = stripos($sql, 'UPDATE');
93
+        if ($updateOccurrence !== false && $updateOccurrence < 10) {
94
+            return true;
95
+        }
96
+        $deleteOccurrence = stripos($sql, 'DELETE');
97
+        if ($deleteOccurrence !== false && $deleteOccurrence < 10) {
98
+            return true;
99
+        }
100
+        return false;
101
+    }
102 102
 
103
-	/**
104
-	 * execute a prepared statement, on error write log and throw exception
105
-	 * @param mixed $stmt OC_DB_StatementWrapper,
106
-	 *					  an array with 'sql' and optionally 'limit' and 'offset' keys
107
-	 *					.. or a simple sql query string
108
-	 * @param array $parameters
109
-	 * @return OC_DB_StatementWrapper
110
-	 * @throws \OC\DatabaseException
111
-	 */
112
-	static public function executeAudited( $stmt, array $parameters = []) {
113
-		if (is_string($stmt)) {
114
-			// convert to an array with 'sql'
115
-			if (stripos($stmt, 'LIMIT') !== false) { //OFFSET requires LIMIT, so we only need to check for LIMIT
116
-				// TODO try to convert LIMIT OFFSET notation to parameters
117
-				$message = 'LIMIT and OFFSET are forbidden for portability reasons,'
118
-						 . ' pass an array with \'limit\' and \'offset\' instead';
119
-				throw new \OC\DatabaseException($message);
120
-			}
121
-			$stmt = array('sql' => $stmt, 'limit' => null, 'offset' => null);
122
-		}
123
-		if (is_array($stmt)) {
124
-			// convert to prepared statement
125
-			if ( ! array_key_exists('sql', $stmt) ) {
126
-				$message = 'statement array must at least contain key \'sql\'';
127
-				throw new \OC\DatabaseException($message);
128
-			}
129
-			if ( ! array_key_exists('limit', $stmt) ) {
130
-				$stmt['limit'] = null;
131
-			}
132
-			if ( ! array_key_exists('limit', $stmt) ) {
133
-				$stmt['offset'] = null;
134
-			}
135
-			$stmt = self::prepare($stmt['sql'], $stmt['limit'], $stmt['offset']);
136
-		}
137
-		self::raiseExceptionOnError($stmt, 'Could not prepare statement');
138
-		if ($stmt instanceof OC_DB_StatementWrapper) {
139
-			$result = $stmt->execute($parameters);
140
-			self::raiseExceptionOnError($result, 'Could not execute statement');
141
-		} else {
142
-			if (is_object($stmt)) {
143
-				$message = 'Expected a prepared statement or array got ' . get_class($stmt);
144
-			} else {
145
-				$message = 'Expected a prepared statement or array got ' . gettype($stmt);
146
-			}
147
-			throw new \OC\DatabaseException($message);
148
-		}
149
-		return $result;
150
-	}
103
+    /**
104
+     * execute a prepared statement, on error write log and throw exception
105
+     * @param mixed $stmt OC_DB_StatementWrapper,
106
+     *					  an array with 'sql' and optionally 'limit' and 'offset' keys
107
+     *					.. or a simple sql query string
108
+     * @param array $parameters
109
+     * @return OC_DB_StatementWrapper
110
+     * @throws \OC\DatabaseException
111
+     */
112
+    static public function executeAudited( $stmt, array $parameters = []) {
113
+        if (is_string($stmt)) {
114
+            // convert to an array with 'sql'
115
+            if (stripos($stmt, 'LIMIT') !== false) { //OFFSET requires LIMIT, so we only need to check for LIMIT
116
+                // TODO try to convert LIMIT OFFSET notation to parameters
117
+                $message = 'LIMIT and OFFSET are forbidden for portability reasons,'
118
+                            . ' pass an array with \'limit\' and \'offset\' instead';
119
+                throw new \OC\DatabaseException($message);
120
+            }
121
+            $stmt = array('sql' => $stmt, 'limit' => null, 'offset' => null);
122
+        }
123
+        if (is_array($stmt)) {
124
+            // convert to prepared statement
125
+            if ( ! array_key_exists('sql', $stmt) ) {
126
+                $message = 'statement array must at least contain key \'sql\'';
127
+                throw new \OC\DatabaseException($message);
128
+            }
129
+            if ( ! array_key_exists('limit', $stmt) ) {
130
+                $stmt['limit'] = null;
131
+            }
132
+            if ( ! array_key_exists('limit', $stmt) ) {
133
+                $stmt['offset'] = null;
134
+            }
135
+            $stmt = self::prepare($stmt['sql'], $stmt['limit'], $stmt['offset']);
136
+        }
137
+        self::raiseExceptionOnError($stmt, 'Could not prepare statement');
138
+        if ($stmt instanceof OC_DB_StatementWrapper) {
139
+            $result = $stmt->execute($parameters);
140
+            self::raiseExceptionOnError($result, 'Could not execute statement');
141
+        } else {
142
+            if (is_object($stmt)) {
143
+                $message = 'Expected a prepared statement or array got ' . get_class($stmt);
144
+            } else {
145
+                $message = 'Expected a prepared statement or array got ' . gettype($stmt);
146
+            }
147
+            throw new \OC\DatabaseException($message);
148
+        }
149
+        return $result;
150
+    }
151 151
 
152
-	/**
153
-	 * saves database schema to xml file
154
-	 * @param string $file name of file
155
-	 * @return bool
156
-	 *
157
-	 * TODO: write more documentation
158
-	 */
159
-	public static function getDbStructure($file) {
160
-		$schemaManager = self::getMDB2SchemaManager();
161
-		return $schemaManager->getDbStructure($file);
162
-	}
152
+    /**
153
+     * saves database schema to xml file
154
+     * @param string $file name of file
155
+     * @return bool
156
+     *
157
+     * TODO: write more documentation
158
+     */
159
+    public static function getDbStructure($file) {
160
+        $schemaManager = self::getMDB2SchemaManager();
161
+        return $schemaManager->getDbStructure($file);
162
+    }
163 163
 
164
-	/**
165
-	 * Creates tables from XML file
166
-	 * @param string $file file to read structure from
167
-	 * @return bool
168
-	 *
169
-	 * TODO: write more documentation
170
-	 */
171
-	public static function createDbFromStructure( $file ) {
172
-		$schemaManager = self::getMDB2SchemaManager();
173
-		return $schemaManager->createDbFromStructure($file);
174
-	}
164
+    /**
165
+     * Creates tables from XML file
166
+     * @param string $file file to read structure from
167
+     * @return bool
168
+     *
169
+     * TODO: write more documentation
170
+     */
171
+    public static function createDbFromStructure( $file ) {
172
+        $schemaManager = self::getMDB2SchemaManager();
173
+        return $schemaManager->createDbFromStructure($file);
174
+    }
175 175
 
176
-	/**
177
-	 * update the database schema
178
-	 * @param string $file file to read structure from
179
-	 * @throws Exception
180
-	 * @return string|boolean
181
-	 * @suppress PhanDeprecatedFunction
182
-	 */
183
-	public static function updateDbFromStructure($file) {
184
-		$schemaManager = self::getMDB2SchemaManager();
185
-		try {
186
-			$result = $schemaManager->updateDbFromStructure($file);
187
-		} catch (Exception $e) {
188
-			\OCP\Util::writeLog('core', 'Failed to update database structure ('.$e.')', \OCP\Util::FATAL);
189
-			throw $e;
190
-		}
191
-		return $result;
192
-	}
176
+    /**
177
+     * update the database schema
178
+     * @param string $file file to read structure from
179
+     * @throws Exception
180
+     * @return string|boolean
181
+     * @suppress PhanDeprecatedFunction
182
+     */
183
+    public static function updateDbFromStructure($file) {
184
+        $schemaManager = self::getMDB2SchemaManager();
185
+        try {
186
+            $result = $schemaManager->updateDbFromStructure($file);
187
+        } catch (Exception $e) {
188
+            \OCP\Util::writeLog('core', 'Failed to update database structure ('.$e.')', \OCP\Util::FATAL);
189
+            throw $e;
190
+        }
191
+        return $result;
192
+    }
193 193
 
194
-	/**
195
-	 * remove all tables defined in a database structure xml file
196
-	 * @param string $file the xml file describing the tables
197
-	 */
198
-	public static function removeDBStructure($file) {
199
-		$schemaManager = self::getMDB2SchemaManager();
200
-		$schemaManager->removeDBStructure($file);
201
-	}
194
+    /**
195
+     * remove all tables defined in a database structure xml file
196
+     * @param string $file the xml file describing the tables
197
+     */
198
+    public static function removeDBStructure($file) {
199
+        $schemaManager = self::getMDB2SchemaManager();
200
+        $schemaManager->removeDBStructure($file);
201
+    }
202 202
 
203
-	/**
204
-	 * check if a result is an error and throws an exception, works with \Doctrine\DBAL\DBALException
205
-	 * @param mixed $result
206
-	 * @param string $message
207
-	 * @return void
208
-	 * @throws \OC\DatabaseException
209
-	 */
210
-	public static function raiseExceptionOnError($result, $message = null) {
211
-		if($result === false) {
212
-			if ($message === null) {
213
-				$message = self::getErrorMessage();
214
-			} else {
215
-				$message .= ', Root cause:' . self::getErrorMessage();
216
-			}
217
-			throw new \OC\DatabaseException($message);
218
-		}
219
-	}
203
+    /**
204
+     * check if a result is an error and throws an exception, works with \Doctrine\DBAL\DBALException
205
+     * @param mixed $result
206
+     * @param string $message
207
+     * @return void
208
+     * @throws \OC\DatabaseException
209
+     */
210
+    public static function raiseExceptionOnError($result, $message = null) {
211
+        if($result === false) {
212
+            if ($message === null) {
213
+                $message = self::getErrorMessage();
214
+            } else {
215
+                $message .= ', Root cause:' . self::getErrorMessage();
216
+            }
217
+            throw new \OC\DatabaseException($message);
218
+        }
219
+    }
220 220
 
221
-	/**
222
-	 * returns the error code and message as a string for logging
223
-	 * works with DoctrineException
224
-	 * @return string
225
-	 */
226
-	public static function getErrorMessage() {
227
-		$connection = \OC::$server->getDatabaseConnection();
228
-		return $connection->getError();
229
-	}
221
+    /**
222
+     * returns the error code and message as a string for logging
223
+     * works with DoctrineException
224
+     * @return string
225
+     */
226
+    public static function getErrorMessage() {
227
+        $connection = \OC::$server->getDatabaseConnection();
228
+        return $connection->getError();
229
+    }
230 230
 
231
-	/**
232
-	 * Checks if a table exists in the database - the database prefix will be prepended
233
-	 *
234
-	 * @param string $table
235
-	 * @return bool
236
-	 * @throws \OC\DatabaseException
237
-	 */
238
-	public static function tableExists($table) {
239
-		$connection = \OC::$server->getDatabaseConnection();
240
-		return $connection->tableExists($table);
241
-	}
231
+    /**
232
+     * Checks if a table exists in the database - the database prefix will be prepended
233
+     *
234
+     * @param string $table
235
+     * @return bool
236
+     * @throws \OC\DatabaseException
237
+     */
238
+    public static function tableExists($table) {
239
+        $connection = \OC::$server->getDatabaseConnection();
240
+        return $connection->tableExists($table);
241
+    }
242 242
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -54,7 +54,7 @@  discard block
 block discarded – undo
54 54
 	 *
55 55
 	 * SQL query via Doctrine prepare(), needs to be execute()'d!
56 56
 	 */
57
-	static public function prepare( $query , $limit = null, $offset = null, $isManipulation = null) {
57
+	static public function prepare($query, $limit = null, $offset = null, $isManipulation = null) {
58 58
 		$connection = \OC::$server->getDatabaseConnection();
59 59
 
60 60
 		if ($isManipulation === null) {
@@ -64,7 +64,7 @@  discard block
 block discarded – undo
64 64
 
65 65
 		// return the result
66 66
 		try {
67
-			$result =$connection->prepare($query, $limit, $offset);
67
+			$result = $connection->prepare($query, $limit, $offset);
68 68
 		} catch (\Doctrine\DBAL\DBALException $e) {
69 69
 			throw new \OC\DatabaseException($e->getMessage());
70 70
 		}
@@ -80,7 +80,7 @@  discard block
 block discarded – undo
80 80
 	 * @param string $sql
81 81
 	 * @return bool
82 82
 	 */
83
-	static public function isManipulation( $sql ) {
83
+	static public function isManipulation($sql) {
84 84
 		$selectOccurrence = stripos($sql, 'SELECT');
85 85
 		if ($selectOccurrence !== false && $selectOccurrence < 10) {
86 86
 			return false;
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
 	 * @return OC_DB_StatementWrapper
110 110
 	 * @throws \OC\DatabaseException
111 111
 	 */
112
-	static public function executeAudited( $stmt, array $parameters = []) {
112
+	static public function executeAudited($stmt, array $parameters = []) {
113 113
 		if (is_string($stmt)) {
114 114
 			// convert to an array with 'sql'
115 115
 			if (stripos($stmt, 'LIMIT') !== false) { //OFFSET requires LIMIT, so we only need to check for LIMIT
@@ -122,14 +122,14 @@  discard block
 block discarded – undo
122 122
 		}
123 123
 		if (is_array($stmt)) {
124 124
 			// convert to prepared statement
125
-			if ( ! array_key_exists('sql', $stmt) ) {
125
+			if (!array_key_exists('sql', $stmt)) {
126 126
 				$message = 'statement array must at least contain key \'sql\'';
127 127
 				throw new \OC\DatabaseException($message);
128 128
 			}
129
-			if ( ! array_key_exists('limit', $stmt) ) {
129
+			if (!array_key_exists('limit', $stmt)) {
130 130
 				$stmt['limit'] = null;
131 131
 			}
132
-			if ( ! array_key_exists('limit', $stmt) ) {
132
+			if (!array_key_exists('limit', $stmt)) {
133 133
 				$stmt['offset'] = null;
134 134
 			}
135 135
 			$stmt = self::prepare($stmt['sql'], $stmt['limit'], $stmt['offset']);
@@ -140,9 +140,9 @@  discard block
 block discarded – undo
140 140
 			self::raiseExceptionOnError($result, 'Could not execute statement');
141 141
 		} else {
142 142
 			if (is_object($stmt)) {
143
-				$message = 'Expected a prepared statement or array got ' . get_class($stmt);
143
+				$message = 'Expected a prepared statement or array got '.get_class($stmt);
144 144
 			} else {
145
-				$message = 'Expected a prepared statement or array got ' . gettype($stmt);
145
+				$message = 'Expected a prepared statement or array got '.gettype($stmt);
146 146
 			}
147 147
 			throw new \OC\DatabaseException($message);
148 148
 		}
@@ -168,7 +168,7 @@  discard block
 block discarded – undo
168 168
 	 *
169 169
 	 * TODO: write more documentation
170 170
 	 */
171
-	public static function createDbFromStructure( $file ) {
171
+	public static function createDbFromStructure($file) {
172 172
 		$schemaManager = self::getMDB2SchemaManager();
173 173
 		return $schemaManager->createDbFromStructure($file);
174 174
 	}
@@ -208,11 +208,11 @@  discard block
 block discarded – undo
208 208
 	 * @throws \OC\DatabaseException
209 209
 	 */
210 210
 	public static function raiseExceptionOnError($result, $message = null) {
211
-		if($result === false) {
211
+		if ($result === false) {
212 212
 			if ($message === null) {
213 213
 				$message = self::getErrorMessage();
214 214
 			} else {
215
-				$message .= ', Root cause:' . self::getErrorMessage();
215
+				$message .= ', Root cause:'.self::getErrorMessage();
216 216
 			}
217 217
 			throw new \OC\DatabaseException($message);
218 218
 		}
Please login to merge, or discard this patch.
lib/private/legacy/db/statementwrapper.php 1 patch
Indentation   +72 added lines, -72 removed lines patch added patch discarded remove patch
@@ -37,83 +37,83 @@
 block discarded – undo
37 37
  * @method array fetchAll(integer $fetchMode = null);
38 38
  */
39 39
 class OC_DB_StatementWrapper {
40
-	/**
41
-	 * @var \Doctrine\DBAL\Driver\Statement
42
-	 */
43
-	private $statement = null;
44
-	private $isManipulation = false;
45
-	private $lastArguments = array();
40
+    /**
41
+     * @var \Doctrine\DBAL\Driver\Statement
42
+     */
43
+    private $statement = null;
44
+    private $isManipulation = false;
45
+    private $lastArguments = array();
46 46
 
47
-	/**
48
-	 * @param boolean $isManipulation
49
-	 */
50
-	public function __construct($statement, $isManipulation) {
51
-		$this->statement = $statement;
52
-		$this->isManipulation = $isManipulation;
53
-	}
47
+    /**
48
+     * @param boolean $isManipulation
49
+     */
50
+    public function __construct($statement, $isManipulation) {
51
+        $this->statement = $statement;
52
+        $this->isManipulation = $isManipulation;
53
+    }
54 54
 
55
-	/**
56
-	 * pass all other function directly to the \Doctrine\DBAL\Driver\Statement
57
-	 */
58
-	public function __call($name,$arguments) {
59
-		return call_user_func_array(array($this->statement,$name), $arguments);
60
-	}
55
+    /**
56
+     * pass all other function directly to the \Doctrine\DBAL\Driver\Statement
57
+     */
58
+    public function __call($name,$arguments) {
59
+        return call_user_func_array(array($this->statement,$name), $arguments);
60
+    }
61 61
 
62
-	/**
63
-	 * make execute return the result instead of a bool
64
-	 *
65
-	 * @param array $input
66
-	 * @return \OC_DB_StatementWrapper|int|bool
67
-	 */
68
-	public function execute($input= []) {
69
-		$this->lastArguments = $input;
70
-		if (count($input) > 0) {
71
-			$result = $this->statement->execute($input);
72
-		} else {
73
-			$result = $this->statement->execute();
74
-		}
62
+    /**
63
+     * make execute return the result instead of a bool
64
+     *
65
+     * @param array $input
66
+     * @return \OC_DB_StatementWrapper|int|bool
67
+     */
68
+    public function execute($input= []) {
69
+        $this->lastArguments = $input;
70
+        if (count($input) > 0) {
71
+            $result = $this->statement->execute($input);
72
+        } else {
73
+            $result = $this->statement->execute();
74
+        }
75 75
 
76
-		if ($result === false) {
77
-			return false;
78
-		}
79
-		if ($this->isManipulation) {
80
-			return $this->statement->rowCount();
81
-		} else {
82
-			return $this;
83
-		}
84
-	}
76
+        if ($result === false) {
77
+            return false;
78
+        }
79
+        if ($this->isManipulation) {
80
+            return $this->statement->rowCount();
81
+        } else {
82
+            return $this;
83
+        }
84
+    }
85 85
 
86
-	/**
87
-	 * provide an alias for fetch
88
-	 *
89
-	 * @return mixed
90
-	 */
91
-	public function fetchRow() {
92
-		return $this->statement->fetch();
93
-	}
86
+    /**
87
+     * provide an alias for fetch
88
+     *
89
+     * @return mixed
90
+     */
91
+    public function fetchRow() {
92
+        return $this->statement->fetch();
93
+    }
94 94
 
95
-	/**
96
-	 * Provide a simple fetchOne.
97
-	 *
98
-	 * fetch single column from the next row
99
-	 * @param int $column the column number to fetch
100
-	 * @return string
101
-	 */
102
-	public function fetchOne($column = 0) {
103
-		return $this->statement->fetchColumn($column);
104
-	}
95
+    /**
96
+     * Provide a simple fetchOne.
97
+     *
98
+     * fetch single column from the next row
99
+     * @param int $column the column number to fetch
100
+     * @return string
101
+     */
102
+    public function fetchOne($column = 0) {
103
+        return $this->statement->fetchColumn($column);
104
+    }
105 105
 
106
-	/**
107
-	 * Binds a PHP variable to a corresponding named or question mark placeholder in the
108
-	 * SQL statement that was use to prepare the statement.
109
-	 *
110
-	 * @param mixed $column Either the placeholder name or the 1-indexed placeholder index
111
-	 * @param mixed $variable The variable to bind
112
-	 * @param integer|null $type one of the  PDO::PARAM_* constants
113
-	 * @param integer|null $length max length when using an OUT bind
114
-	 * @return boolean
115
-	 */
116
-	public function bindParam($column, &$variable, $type = null, $length = null){
117
-		return $this->statement->bindParam($column, $variable, $type, $length);
118
-	}
106
+    /**
107
+     * Binds a PHP variable to a corresponding named or question mark placeholder in the
108
+     * SQL statement that was use to prepare the statement.
109
+     *
110
+     * @param mixed $column Either the placeholder name or the 1-indexed placeholder index
111
+     * @param mixed $variable The variable to bind
112
+     * @param integer|null $type one of the  PDO::PARAM_* constants
113
+     * @param integer|null $length max length when using an OUT bind
114
+     * @return boolean
115
+     */
116
+    public function bindParam($column, &$variable, $type = null, $length = null){
117
+        return $this->statement->bindParam($column, $variable, $type, $length);
118
+    }
119 119
 }
Please login to merge, or discard this patch.
lib/private/Server.php 2 patches
Indentation   +1825 added lines, -1825 removed lines patch added patch discarded remove patch
@@ -146,1834 +146,1834 @@
 block discarded – undo
146 146
  * TODO: hookup all manager classes
147 147
  */
148 148
 class Server extends ServerContainer implements IServerContainer {
149
-	/** @var string */
150
-	private $webRoot;
151
-
152
-	/**
153
-	 * @param string $webRoot
154
-	 * @param \OC\Config $config
155
-	 */
156
-	public function __construct($webRoot, \OC\Config $config) {
157
-		parent::__construct();
158
-		$this->webRoot = $webRoot;
159
-
160
-		$this->registerService(\OCP\IServerContainer::class, function (IServerContainer $c) {
161
-			return $c;
162
-		});
163
-
164
-		$this->registerAlias(\OCP\Calendar\IManager::class, \OC\Calendar\Manager::class);
165
-		$this->registerAlias('CalendarManager', \OC\Calendar\Manager::class);
166
-
167
-		$this->registerAlias(\OCP\Contacts\IManager::class, \OC\ContactsManager::class);
168
-		$this->registerAlias('ContactsManager', \OCP\Contacts\IManager::class);
169
-
170
-		$this->registerAlias(IActionFactory::class, ActionFactory::class);
171
-
172
-
173
-		$this->registerService(\OCP\IPreview::class, function (Server $c) {
174
-			return new PreviewManager(
175
-				$c->getConfig(),
176
-				$c->getRootFolder(),
177
-				$c->getAppDataDir('preview'),
178
-				$c->getEventDispatcher(),
179
-				$c->getSession()->get('user_id')
180
-			);
181
-		});
182
-		$this->registerAlias('PreviewManager', \OCP\IPreview::class);
183
-
184
-		$this->registerService(\OC\Preview\Watcher::class, function (Server $c) {
185
-			return new \OC\Preview\Watcher(
186
-				$c->getAppDataDir('preview')
187
-			);
188
-		});
189
-
190
-		$this->registerService('EncryptionManager', function (Server $c) {
191
-			$view = new View();
192
-			$util = new Encryption\Util(
193
-				$view,
194
-				$c->getUserManager(),
195
-				$c->getGroupManager(),
196
-				$c->getConfig()
197
-			);
198
-			return new Encryption\Manager(
199
-				$c->getConfig(),
200
-				$c->getLogger(),
201
-				$c->getL10N('core'),
202
-				new View(),
203
-				$util,
204
-				new ArrayCache()
205
-			);
206
-		});
207
-
208
-		$this->registerService('EncryptionFileHelper', function (Server $c) {
209
-			$util = new Encryption\Util(
210
-				new View(),
211
-				$c->getUserManager(),
212
-				$c->getGroupManager(),
213
-				$c->getConfig()
214
-			);
215
-			return new Encryption\File(
216
-				$util,
217
-				$c->getRootFolder(),
218
-				$c->getShareManager()
219
-			);
220
-		});
221
-
222
-		$this->registerService('EncryptionKeyStorage', function (Server $c) {
223
-			$view = new View();
224
-			$util = new Encryption\Util(
225
-				$view,
226
-				$c->getUserManager(),
227
-				$c->getGroupManager(),
228
-				$c->getConfig()
229
-			);
230
-
231
-			return new Encryption\Keys\Storage($view, $util);
232
-		});
233
-		$this->registerService('TagMapper', function (Server $c) {
234
-			return new TagMapper($c->getDatabaseConnection());
235
-		});
236
-
237
-		$this->registerService(\OCP\ITagManager::class, function (Server $c) {
238
-			$tagMapper = $c->query('TagMapper');
239
-			return new TagManager($tagMapper, $c->getUserSession());
240
-		});
241
-		$this->registerAlias('TagManager', \OCP\ITagManager::class);
242
-
243
-		$this->registerService('SystemTagManagerFactory', function (Server $c) {
244
-			$config = $c->getConfig();
245
-			$factoryClass = $config->getSystemValue('systemtags.managerFactory', '\OC\SystemTag\ManagerFactory');
246
-			return new $factoryClass($this);
247
-		});
248
-		$this->registerService(\OCP\SystemTag\ISystemTagManager::class, function (Server $c) {
249
-			return $c->query('SystemTagManagerFactory')->getManager();
250
-		});
251
-		$this->registerAlias('SystemTagManager', \OCP\SystemTag\ISystemTagManager::class);
252
-
253
-		$this->registerService(\OCP\SystemTag\ISystemTagObjectMapper::class, function (Server $c) {
254
-			return $c->query('SystemTagManagerFactory')->getObjectMapper();
255
-		});
256
-		$this->registerService('RootFolder', function (Server $c) {
257
-			$manager = \OC\Files\Filesystem::getMountManager(null);
258
-			$view = new View();
259
-			$root = new Root(
260
-				$manager,
261
-				$view,
262
-				null,
263
-				$c->getUserMountCache(),
264
-				$this->getLogger(),
265
-				$this->getUserManager()
266
-			);
267
-			$connector = new HookConnector($root, $view);
268
-			$connector->viewToNode();
269
-
270
-			$previewConnector = new \OC\Preview\WatcherConnector($root, $c->getSystemConfig());
271
-			$previewConnector->connectWatcher();
272
-
273
-			return $root;
274
-		});
275
-		$this->registerAlias('SystemTagObjectMapper', \OCP\SystemTag\ISystemTagObjectMapper::class);
276
-
277
-		$this->registerService(\OCP\Files\IRootFolder::class, function (Server $c) {
278
-			return new LazyRoot(function () use ($c) {
279
-				return $c->query('RootFolder');
280
-			});
281
-		});
282
-		$this->registerAlias('LazyRootFolder', \OCP\Files\IRootFolder::class);
283
-
284
-		$this->registerService(\OC\User\Manager::class, function (Server $c) {
285
-			$config = $c->getConfig();
286
-			return new \OC\User\Manager($config);
287
-		});
288
-		$this->registerAlias('UserManager', \OC\User\Manager::class);
289
-		$this->registerAlias(\OCP\IUserManager::class, \OC\User\Manager::class);
290
-
291
-		$this->registerService(\OCP\IGroupManager::class, function (Server $c) {
292
-			$groupManager = new \OC\Group\Manager($this->getUserManager(), $this->getLogger());
293
-			$groupManager->listen('\OC\Group', 'preCreate', function ($gid) {
294
-				\OC_Hook::emit('OC_Group', 'pre_createGroup', array('run' => true, 'gid' => $gid));
295
-			});
296
-			$groupManager->listen('\OC\Group', 'postCreate', function (\OC\Group\Group $gid) {
297
-				\OC_Hook::emit('OC_User', 'post_createGroup', array('gid' => $gid->getGID()));
298
-			});
299
-			$groupManager->listen('\OC\Group', 'preDelete', function (\OC\Group\Group $group) {
300
-				\OC_Hook::emit('OC_Group', 'pre_deleteGroup', array('run' => true, 'gid' => $group->getGID()));
301
-			});
302
-			$groupManager->listen('\OC\Group', 'postDelete', function (\OC\Group\Group $group) {
303
-				\OC_Hook::emit('OC_User', 'post_deleteGroup', array('gid' => $group->getGID()));
304
-			});
305
-			$groupManager->listen('\OC\Group', 'preAddUser', function (\OC\Group\Group $group, \OC\User\User $user) {
306
-				\OC_Hook::emit('OC_Group', 'pre_addToGroup', array('run' => true, 'uid' => $user->getUID(), 'gid' => $group->getGID()));
307
-			});
308
-			$groupManager->listen('\OC\Group', 'postAddUser', function (\OC\Group\Group $group, \OC\User\User $user) {
309
-				\OC_Hook::emit('OC_Group', 'post_addToGroup', array('uid' => $user->getUID(), 'gid' => $group->getGID()));
310
-				//Minimal fix to keep it backward compatible TODO: clean up all the GroupManager hooks
311
-				\OC_Hook::emit('OC_User', 'post_addToGroup', array('uid' => $user->getUID(), 'gid' => $group->getGID()));
312
-			});
313
-			return $groupManager;
314
-		});
315
-		$this->registerAlias('GroupManager', \OCP\IGroupManager::class);
316
-
317
-		$this->registerService(Store::class, function (Server $c) {
318
-			$session = $c->getSession();
319
-			if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
320
-				$tokenProvider = $c->query('OC\Authentication\Token\IProvider');
321
-			} else {
322
-				$tokenProvider = null;
323
-			}
324
-			$logger = $c->getLogger();
325
-			return new Store($session, $logger, $tokenProvider);
326
-		});
327
-		$this->registerAlias(IStore::class, Store::class);
328
-		$this->registerService('OC\Authentication\Token\DefaultTokenMapper', function (Server $c) {
329
-			$dbConnection = $c->getDatabaseConnection();
330
-			return new Authentication\Token\DefaultTokenMapper($dbConnection);
331
-		});
332
-		$this->registerService('OC\Authentication\Token\DefaultTokenProvider', function (Server $c) {
333
-			$mapper = $c->query('OC\Authentication\Token\DefaultTokenMapper');
334
-			$crypto = $c->getCrypto();
335
-			$config = $c->getConfig();
336
-			$logger = $c->getLogger();
337
-			$timeFactory = new TimeFactory();
338
-			return new \OC\Authentication\Token\DefaultTokenProvider($mapper, $crypto, $config, $logger, $timeFactory);
339
-		});
340
-		$this->registerAlias('OC\Authentication\Token\IProvider', 'OC\Authentication\Token\DefaultTokenProvider');
341
-
342
-		$this->registerService(\OCP\IUserSession::class, function (Server $c) {
343
-			$manager = $c->getUserManager();
344
-			$session = new \OC\Session\Memory('');
345
-			$timeFactory = new TimeFactory();
346
-			// Token providers might require a working database. This code
347
-			// might however be called when ownCloud is not yet setup.
348
-			if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
349
-				$defaultTokenProvider = $c->query('OC\Authentication\Token\IProvider');
350
-			} else {
351
-				$defaultTokenProvider = null;
352
-			}
353
-
354
-			$dispatcher = $c->getEventDispatcher();
355
-
356
-			$userSession = new \OC\User\Session(
357
-				$manager,
358
-				$session,
359
-				$timeFactory,
360
-				$defaultTokenProvider,
361
-				$c->getConfig(),
362
-				$c->getSecureRandom(),
363
-				$c->getLockdownManager(),
364
-				$c->getLogger()
365
-			);
366
-			$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
367
-				\OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password));
368
-			});
369
-			$userSession->listen('\OC\User', 'postCreateUser', function ($user, $password) {
370
-				/** @var $user \OC\User\User */
371
-				\OC_Hook::emit('OC_User', 'post_createUser', array('uid' => $user->getUID(), 'password' => $password));
372
-			});
373
-			$userSession->listen('\OC\User', 'preDelete', function ($user) use ($dispatcher) {
374
-				/** @var $user \OC\User\User */
375
-				\OC_Hook::emit('OC_User', 'pre_deleteUser', array('run' => true, 'uid' => $user->getUID()));
376
-				$dispatcher->dispatch('OCP\IUser::preDelete', new GenericEvent($user));
377
-			});
378
-			$userSession->listen('\OC\User', 'postDelete', function ($user) {
379
-				/** @var $user \OC\User\User */
380
-				\OC_Hook::emit('OC_User', 'post_deleteUser', array('uid' => $user->getUID()));
381
-			});
382
-			$userSession->listen('\OC\User', 'preSetPassword', function ($user, $password, $recoveryPassword) {
383
-				/** @var $user \OC\User\User */
384
-				\OC_Hook::emit('OC_User', 'pre_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
385
-			});
386
-			$userSession->listen('\OC\User', 'postSetPassword', function ($user, $password, $recoveryPassword) {
387
-				/** @var $user \OC\User\User */
388
-				\OC_Hook::emit('OC_User', 'post_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
389
-			});
390
-			$userSession->listen('\OC\User', 'preLogin', function ($uid, $password) {
391
-				\OC_Hook::emit('OC_User', 'pre_login', array('run' => true, 'uid' => $uid, 'password' => $password));
392
-			});
393
-			$userSession->listen('\OC\User', 'postLogin', function ($user, $password) {
394
-				/** @var $user \OC\User\User */
395
-				\OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password));
396
-			});
397
-			$userSession->listen('\OC\User', 'postRememberedLogin', function ($user, $password) {
398
-				/** @var $user \OC\User\User */
399
-				\OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password));
400
-			});
401
-			$userSession->listen('\OC\User', 'logout', function () {
402
-				\OC_Hook::emit('OC_User', 'logout', array());
403
-			});
404
-			$userSession->listen('\OC\User', 'changeUser', function ($user, $feature, $value, $oldValue) use ($dispatcher) {
405
-				/** @var $user \OC\User\User */
406
-				\OC_Hook::emit('OC_User', 'changeUser', array('run' => true, 'user' => $user, 'feature' => $feature, 'value' => $value, 'old_value' => $oldValue));
407
-				$dispatcher->dispatch('OCP\IUser::changeUser', new GenericEvent($user, ['feature' => $feature, 'oldValue' => $oldValue, 'value' => $value]));
408
-			});
409
-			return $userSession;
410
-		});
411
-		$this->registerAlias('UserSession', \OCP\IUserSession::class);
412
-
413
-		$this->registerService(\OC\Authentication\TwoFactorAuth\Manager::class, function (Server $c) {
414
-			return new \OC\Authentication\TwoFactorAuth\Manager(
415
-				$c->getAppManager(),
416
-				$c->getSession(),
417
-				$c->getConfig(),
418
-				$c->getActivityManager(),
419
-				$c->getLogger(),
420
-				$c->query(\OC\Authentication\Token\IProvider::class),
421
-				$c->query(ITimeFactory::class),
422
-				$c->query(EventDispatcherInterface::class)
423
-			);
424
-		});
425
-
426
-		$this->registerAlias(\OCP\INavigationManager::class, \OC\NavigationManager::class);
427
-		$this->registerAlias('NavigationManager', \OCP\INavigationManager::class);
428
-
429
-		$this->registerService(\OC\AllConfig::class, function (Server $c) {
430
-			return new \OC\AllConfig(
431
-				$c->getSystemConfig()
432
-			);
433
-		});
434
-		$this->registerAlias('AllConfig', \OC\AllConfig::class);
435
-		$this->registerAlias(\OCP\IConfig::class, \OC\AllConfig::class);
436
-
437
-		$this->registerService('SystemConfig', function ($c) use ($config) {
438
-			return new \OC\SystemConfig($config);
439
-		});
440
-
441
-		$this->registerService(\OC\AppConfig::class, function (Server $c) {
442
-			return new \OC\AppConfig($c->getDatabaseConnection());
443
-		});
444
-		$this->registerAlias('AppConfig', \OC\AppConfig::class);
445
-		$this->registerAlias(\OCP\IAppConfig::class, \OC\AppConfig::class);
446
-
447
-		$this->registerService(\OCP\L10N\IFactory::class, function (Server $c) {
448
-			return new \OC\L10N\Factory(
449
-				$c->getConfig(),
450
-				$c->getRequest(),
451
-				$c->getUserSession(),
452
-				\OC::$SERVERROOT
453
-			);
454
-		});
455
-		$this->registerAlias('L10NFactory', \OCP\L10N\IFactory::class);
456
-
457
-		$this->registerService(\OCP\IURLGenerator::class, function (Server $c) {
458
-			$config = $c->getConfig();
459
-			$cacheFactory = $c->getMemCacheFactory();
460
-			$request = $c->getRequest();
461
-			return new \OC\URLGenerator(
462
-				$config,
463
-				$cacheFactory,
464
-				$request
465
-			);
466
-		});
467
-		$this->registerAlias('URLGenerator', \OCP\IURLGenerator::class);
468
-
469
-		$this->registerService('AppHelper', function ($c) {
470
-			return new \OC\AppHelper();
471
-		});
472
-		$this->registerAlias('AppFetcher', AppFetcher::class);
473
-		$this->registerAlias('CategoryFetcher', CategoryFetcher::class);
474
-
475
-		$this->registerService(\OCP\ICache::class, function ($c) {
476
-			return new Cache\File();
477
-		});
478
-		$this->registerAlias('UserCache', \OCP\ICache::class);
479
-
480
-		$this->registerService(Factory::class, function (Server $c) {
481
-
482
-			$arrayCacheFactory = new \OC\Memcache\Factory('', $c->getLogger(),
483
-				'\\OC\\Memcache\\ArrayCache',
484
-				'\\OC\\Memcache\\ArrayCache',
485
-				'\\OC\\Memcache\\ArrayCache'
486
-			);
487
-			$config = $c->getConfig();
488
-			$request = $c->getRequest();
489
-			$urlGenerator = new URLGenerator($config, $arrayCacheFactory, $request);
490
-
491
-			if ($config->getSystemValue('installed', false) && !(defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
492
-				$v = \OC_App::getAppVersions();
493
-				$v['core'] = implode(',', \OC_Util::getVersion());
494
-				$version = implode(',', $v);
495
-				$instanceId = \OC_Util::getInstanceId();
496
-				$path = \OC::$SERVERROOT;
497
-				$prefix = md5($instanceId . '-' . $version . '-' . $path . '-' . $urlGenerator->getBaseUrl());
498
-				return new \OC\Memcache\Factory($prefix, $c->getLogger(),
499
-					$config->getSystemValue('memcache.local', null),
500
-					$config->getSystemValue('memcache.distributed', null),
501
-					$config->getSystemValue('memcache.locking', null)
502
-				);
503
-			}
504
-			return $arrayCacheFactory;
505
-
506
-		});
507
-		$this->registerAlias('MemCacheFactory', Factory::class);
508
-		$this->registerAlias(ICacheFactory::class, Factory::class);
509
-
510
-		$this->registerService('RedisFactory', function (Server $c) {
511
-			$systemConfig = $c->getSystemConfig();
512
-			return new RedisFactory($systemConfig);
513
-		});
514
-
515
-		$this->registerService(\OCP\Activity\IManager::class, function (Server $c) {
516
-			return new \OC\Activity\Manager(
517
-				$c->getRequest(),
518
-				$c->getUserSession(),
519
-				$c->getConfig(),
520
-				$c->query(IValidator::class)
521
-			);
522
-		});
523
-		$this->registerAlias('ActivityManager', \OCP\Activity\IManager::class);
524
-
525
-		$this->registerService(\OCP\Activity\IEventMerger::class, function (Server $c) {
526
-			return new \OC\Activity\EventMerger(
527
-				$c->getL10N('lib')
528
-			);
529
-		});
530
-		$this->registerAlias(IValidator::class, Validator::class);
531
-
532
-		$this->registerService(\OCP\IAvatarManager::class, function (Server $c) {
533
-			return new AvatarManager(
534
-				$c->query(\OC\User\Manager::class),
535
-				$c->getAppDataDir('avatar'),
536
-				$c->getL10N('lib'),
537
-				$c->getLogger(),
538
-				$c->getConfig()
539
-			);
540
-		});
541
-		$this->registerAlias('AvatarManager', \OCP\IAvatarManager::class);
542
-
543
-		$this->registerAlias(\OCP\Support\CrashReport\IRegistry::class, \OC\Support\CrashReport\Registry::class);
544
-
545
-		$this->registerService(\OCP\ILogger::class, function (Server $c) {
546
-			$logType = $c->query('AllConfig')->getSystemValue('log_type', 'file');
547
-			$logger = Log::getLogClass($logType);
548
-			call_user_func(array($logger, 'init'));
549
-			$config = $this->getSystemConfig();
550
-			$registry = $c->query(\OCP\Support\CrashReport\IRegistry::class);
551
-
552
-			return new Log($logger, $config, null, $registry);
553
-		});
554
-		$this->registerAlias('Logger', \OCP\ILogger::class);
555
-
556
-		$this->registerService(\OCP\BackgroundJob\IJobList::class, function (Server $c) {
557
-			$config = $c->getConfig();
558
-			return new \OC\BackgroundJob\JobList(
559
-				$c->getDatabaseConnection(),
560
-				$config,
561
-				new TimeFactory()
562
-			);
563
-		});
564
-		$this->registerAlias('JobList', \OCP\BackgroundJob\IJobList::class);
565
-
566
-		$this->registerService(\OCP\Route\IRouter::class, function (Server $c) {
567
-			$cacheFactory = $c->getMemCacheFactory();
568
-			$logger = $c->getLogger();
569
-			if ($cacheFactory->isAvailableLowLatency()) {
570
-				$router = new \OC\Route\CachingRouter($cacheFactory->createLocal('route'), $logger);
571
-			} else {
572
-				$router = new \OC\Route\Router($logger);
573
-			}
574
-			return $router;
575
-		});
576
-		$this->registerAlias('Router', \OCP\Route\IRouter::class);
577
-
578
-		$this->registerService(\OCP\ISearch::class, function ($c) {
579
-			return new Search();
580
-		});
581
-		$this->registerAlias('Search', \OCP\ISearch::class);
582
-
583
-		$this->registerService(\OC\Security\RateLimiting\Limiter::class, function ($c) {
584
-			return new \OC\Security\RateLimiting\Limiter(
585
-				$this->getUserSession(),
586
-				$this->getRequest(),
587
-				new \OC\AppFramework\Utility\TimeFactory(),
588
-				$c->query(\OC\Security\RateLimiting\Backend\IBackend::class)
589
-			);
590
-		});
591
-		$this->registerService(\OC\Security\RateLimiting\Backend\IBackend::class, function ($c) {
592
-			return new \OC\Security\RateLimiting\Backend\MemoryCache(
593
-				$this->getMemCacheFactory(),
594
-				new \OC\AppFramework\Utility\TimeFactory()
595
-			);
596
-		});
597
-
598
-		$this->registerService(\OCP\Security\ISecureRandom::class, function ($c) {
599
-			return new SecureRandom();
600
-		});
601
-		$this->registerAlias('SecureRandom', \OCP\Security\ISecureRandom::class);
602
-
603
-		$this->registerService(\OCP\Security\ICrypto::class, function (Server $c) {
604
-			return new Crypto($c->getConfig(), $c->getSecureRandom());
605
-		});
606
-		$this->registerAlias('Crypto', \OCP\Security\ICrypto::class);
607
-
608
-		$this->registerService(\OCP\Security\IHasher::class, function (Server $c) {
609
-			return new Hasher($c->getConfig());
610
-		});
611
-		$this->registerAlias('Hasher', \OCP\Security\IHasher::class);
612
-
613
-		$this->registerService(\OCP\Security\ICredentialsManager::class, function (Server $c) {
614
-			return new CredentialsManager($c->getCrypto(), $c->getDatabaseConnection());
615
-		});
616
-		$this->registerAlias('CredentialsManager', \OCP\Security\ICredentialsManager::class);
617
-
618
-		$this->registerService(IDBConnection::class, function (Server $c) {
619
-			$systemConfig = $c->getSystemConfig();
620
-			$factory = new \OC\DB\ConnectionFactory($systemConfig);
621
-			$type = $systemConfig->getValue('dbtype', 'sqlite');
622
-			if (!$factory->isValidType($type)) {
623
-				throw new \OC\DatabaseException('Invalid database type');
624
-			}
625
-			$connectionParams = $factory->createConnectionParams();
626
-			$connection = $factory->getConnection($type, $connectionParams);
627
-			$connection->getConfiguration()->setSQLLogger($c->getQueryLogger());
628
-			return $connection;
629
-		});
630
-		$this->registerAlias('DatabaseConnection', IDBConnection::class);
631
-
632
-		$this->registerService('HTTPHelper', function (Server $c) {
633
-			$config = $c->getConfig();
634
-			return new HTTPHelper(
635
-				$config,
636
-				$c->getHTTPClientService()
637
-			);
638
-		});
639
-
640
-		$this->registerService(\OCP\Http\Client\IClientService::class, function (Server $c) {
641
-			$user = \OC_User::getUser();
642
-			$uid = $user ? $user : null;
643
-			return new ClientService(
644
-				$c->getConfig(),
645
-				new \OC\Security\CertificateManager(
646
-					$uid,
647
-					new View(),
648
-					$c->getConfig(),
649
-					$c->getLogger(),
650
-					$c->getSecureRandom()
651
-				)
652
-			);
653
-		});
654
-		$this->registerAlias('HttpClientService', \OCP\Http\Client\IClientService::class);
655
-		$this->registerService(\OCP\Diagnostics\IEventLogger::class, function (Server $c) {
656
-			$eventLogger = new EventLogger();
657
-			if ($c->getSystemConfig()->getValue('debug', false)) {
658
-				// In debug mode, module is being activated by default
659
-				$eventLogger->activate();
660
-			}
661
-			return $eventLogger;
662
-		});
663
-		$this->registerAlias('EventLogger', \OCP\Diagnostics\IEventLogger::class);
664
-
665
-		$this->registerService(\OCP\Diagnostics\IQueryLogger::class, function (Server $c) {
666
-			$queryLogger = new QueryLogger();
667
-			if ($c->getSystemConfig()->getValue('debug', false)) {
668
-				// In debug mode, module is being activated by default
669
-				$queryLogger->activate();
670
-			}
671
-			return $queryLogger;
672
-		});
673
-		$this->registerAlias('QueryLogger', \OCP\Diagnostics\IQueryLogger::class);
674
-
675
-		$this->registerService(TempManager::class, function (Server $c) {
676
-			return new TempManager(
677
-				$c->getLogger(),
678
-				$c->getConfig()
679
-			);
680
-		});
681
-		$this->registerAlias('TempManager', TempManager::class);
682
-		$this->registerAlias(ITempManager::class, TempManager::class);
683
-
684
-		$this->registerService(AppManager::class, function (Server $c) {
685
-			return new \OC\App\AppManager(
686
-				$c->getUserSession(),
687
-				$c->query(\OC\AppConfig::class),
688
-				$c->getGroupManager(),
689
-				$c->getMemCacheFactory(),
690
-				$c->getEventDispatcher()
691
-			);
692
-		});
693
-		$this->registerAlias('AppManager', AppManager::class);
694
-		$this->registerAlias(IAppManager::class, AppManager::class);
695
-
696
-		$this->registerService(\OCP\IDateTimeZone::class, function (Server $c) {
697
-			return new DateTimeZone(
698
-				$c->getConfig(),
699
-				$c->getSession()
700
-			);
701
-		});
702
-		$this->registerAlias('DateTimeZone', \OCP\IDateTimeZone::class);
703
-
704
-		$this->registerService(\OCP\IDateTimeFormatter::class, function (Server $c) {
705
-			$language = $c->getConfig()->getUserValue($c->getSession()->get('user_id'), 'core', 'lang', null);
706
-
707
-			return new DateTimeFormatter(
708
-				$c->getDateTimeZone()->getTimeZone(),
709
-				$c->getL10N('lib', $language)
710
-			);
711
-		});
712
-		$this->registerAlias('DateTimeFormatter', \OCP\IDateTimeFormatter::class);
713
-
714
-		$this->registerService(\OCP\Files\Config\IUserMountCache::class, function (Server $c) {
715
-			$mountCache = new UserMountCache($c->getDatabaseConnection(), $c->getUserManager(), $c->getLogger());
716
-			$listener = new UserMountCacheListener($mountCache);
717
-			$listener->listen($c->getUserManager());
718
-			return $mountCache;
719
-		});
720
-		$this->registerAlias('UserMountCache', \OCP\Files\Config\IUserMountCache::class);
721
-
722
-		$this->registerService(\OCP\Files\Config\IMountProviderCollection::class, function (Server $c) {
723
-			$loader = \OC\Files\Filesystem::getLoader();
724
-			$mountCache = $c->query('UserMountCache');
725
-			$manager = new \OC\Files\Config\MountProviderCollection($loader, $mountCache);
726
-
727
-			// builtin providers
728
-
729
-			$config = $c->getConfig();
730
-			$manager->registerProvider(new CacheMountProvider($config));
731
-			$manager->registerHomeProvider(new LocalHomeMountProvider());
732
-			$manager->registerHomeProvider(new ObjectHomeMountProvider($config));
733
-
734
-			return $manager;
735
-		});
736
-		$this->registerAlias('MountConfigManager', \OCP\Files\Config\IMountProviderCollection::class);
737
-
738
-		$this->registerService('IniWrapper', function ($c) {
739
-			return new IniGetWrapper();
740
-		});
741
-		$this->registerService('AsyncCommandBus', function (Server $c) {
742
-			$busClass = $c->getConfig()->getSystemValue('commandbus');
743
-			if ($busClass) {
744
-				list($app, $class) = explode('::', $busClass, 2);
745
-				if ($c->getAppManager()->isInstalled($app)) {
746
-					\OC_App::loadApp($app);
747
-					return $c->query($class);
748
-				} else {
749
-					throw new ServiceUnavailableException("The app providing the command bus ($app) is not enabled");
750
-				}
751
-			} else {
752
-				$jobList = $c->getJobList();
753
-				return new CronBus($jobList);
754
-			}
755
-		});
756
-		$this->registerService('TrustedDomainHelper', function ($c) {
757
-			return new TrustedDomainHelper($this->getConfig());
758
-		});
759
-		$this->registerService('Throttler', function (Server $c) {
760
-			return new Throttler(
761
-				$c->getDatabaseConnection(),
762
-				new TimeFactory(),
763
-				$c->getLogger(),
764
-				$c->getConfig()
765
-			);
766
-		});
767
-		$this->registerService('IntegrityCodeChecker', function (Server $c) {
768
-			// IConfig and IAppManager requires a working database. This code
769
-			// might however be called when ownCloud is not yet setup.
770
-			if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
771
-				$config = $c->getConfig();
772
-				$appManager = $c->getAppManager();
773
-			} else {
774
-				$config = null;
775
-				$appManager = null;
776
-			}
777
-
778
-			return new Checker(
779
-				new EnvironmentHelper(),
780
-				new FileAccessHelper(),
781
-				new AppLocator(),
782
-				$config,
783
-				$c->getMemCacheFactory(),
784
-				$appManager,
785
-				$c->getTempManager()
786
-			);
787
-		});
788
-		$this->registerService(\OCP\IRequest::class, function ($c) {
789
-			if (isset($this['urlParams'])) {
790
-				$urlParams = $this['urlParams'];
791
-			} else {
792
-				$urlParams = [];
793
-			}
794
-
795
-			if (defined('PHPUNIT_RUN') && PHPUNIT_RUN
796
-				&& in_array('fakeinput', stream_get_wrappers())
797
-			) {
798
-				$stream = 'fakeinput://data';
799
-			} else {
800
-				$stream = 'php://input';
801
-			}
802
-
803
-			return new Request(
804
-				[
805
-					'get' => $_GET,
806
-					'post' => $_POST,
807
-					'files' => $_FILES,
808
-					'server' => $_SERVER,
809
-					'env' => $_ENV,
810
-					'cookies' => $_COOKIE,
811
-					'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD']))
812
-						? $_SERVER['REQUEST_METHOD']
813
-						: null,
814
-					'urlParams' => $urlParams,
815
-				],
816
-				$this->getSecureRandom(),
817
-				$this->getConfig(),
818
-				$this->getCsrfTokenManager(),
819
-				$stream
820
-			);
821
-		});
822
-		$this->registerAlias('Request', \OCP\IRequest::class);
823
-
824
-		$this->registerService(\OCP\Mail\IMailer::class, function (Server $c) {
825
-			return new Mailer(
826
-				$c->getConfig(),
827
-				$c->getLogger(),
828
-				$c->query(Defaults::class),
829
-				$c->getURLGenerator(),
830
-				$c->getL10N('lib')
831
-			);
832
-		});
833
-		$this->registerAlias('Mailer', \OCP\Mail\IMailer::class);
834
-
835
-		$this->registerService('LDAPProvider', function (Server $c) {
836
-			$config = $c->getConfig();
837
-			$factoryClass = $config->getSystemValue('ldapProviderFactory', null);
838
-			if (is_null($factoryClass)) {
839
-				throw new \Exception('ldapProviderFactory not set');
840
-			}
841
-			/** @var \OCP\LDAP\ILDAPProviderFactory $factory */
842
-			$factory = new $factoryClass($this);
843
-			return $factory->getLDAPProvider();
844
-		});
845
-		$this->registerService(ILockingProvider::class, function (Server $c) {
846
-			$ini = $c->getIniWrapper();
847
-			$config = $c->getConfig();
848
-			$ttl = $config->getSystemValue('filelocking.ttl', max(3600, $ini->getNumeric('max_execution_time')));
849
-			if ($config->getSystemValue('filelocking.enabled', true) or (defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
850
-				/** @var \OC\Memcache\Factory $memcacheFactory */
851
-				$memcacheFactory = $c->getMemCacheFactory();
852
-				$memcache = $memcacheFactory->createLocking('lock');
853
-				if (!($memcache instanceof \OC\Memcache\NullCache)) {
854
-					return new MemcacheLockingProvider($memcache, $ttl);
855
-				}
856
-				return new DBLockingProvider($c->getDatabaseConnection(), $c->getLogger(), new TimeFactory(), $ttl);
857
-			}
858
-			return new NoopLockingProvider();
859
-		});
860
-		$this->registerAlias('LockingProvider', ILockingProvider::class);
861
-
862
-		$this->registerService(\OCP\Files\Mount\IMountManager::class, function () {
863
-			return new \OC\Files\Mount\Manager();
864
-		});
865
-		$this->registerAlias('MountManager', \OCP\Files\Mount\IMountManager::class);
866
-
867
-		$this->registerService(\OCP\Files\IMimeTypeDetector::class, function (Server $c) {
868
-			return new \OC\Files\Type\Detection(
869
-				$c->getURLGenerator(),
870
-				\OC::$configDir,
871
-				\OC::$SERVERROOT . '/resources/config/'
872
-			);
873
-		});
874
-		$this->registerAlias('MimeTypeDetector', \OCP\Files\IMimeTypeDetector::class);
875
-
876
-		$this->registerService(\OCP\Files\IMimeTypeLoader::class, function (Server $c) {
877
-			return new \OC\Files\Type\Loader(
878
-				$c->getDatabaseConnection()
879
-			);
880
-		});
881
-		$this->registerAlias('MimeTypeLoader', \OCP\Files\IMimeTypeLoader::class);
882
-		$this->registerService(BundleFetcher::class, function () {
883
-			return new BundleFetcher($this->getL10N('lib'));
884
-		});
885
-		$this->registerService(\OCP\Notification\IManager::class, function (Server $c) {
886
-			return new Manager(
887
-				$c->query(IValidator::class)
888
-			);
889
-		});
890
-		$this->registerAlias('NotificationManager', \OCP\Notification\IManager::class);
891
-
892
-		$this->registerService(\OC\CapabilitiesManager::class, function (Server $c) {
893
-			$manager = new \OC\CapabilitiesManager($c->getLogger());
894
-			$manager->registerCapability(function () use ($c) {
895
-				return new \OC\OCS\CoreCapabilities($c->getConfig());
896
-			});
897
-			$manager->registerCapability(function () use ($c) {
898
-				return $c->query(\OC\Security\Bruteforce\Capabilities::class);
899
-			});
900
-			return $manager;
901
-		});
902
-		$this->registerAlias('CapabilitiesManager', \OC\CapabilitiesManager::class);
903
-
904
-		$this->registerService(\OCP\Comments\ICommentsManager::class, function (Server $c) {
905
-			$config = $c->getConfig();
906
-			$factoryClass = $config->getSystemValue('comments.managerFactory', '\OC\Comments\ManagerFactory');
907
-			/** @var \OCP\Comments\ICommentsManagerFactory $factory */
908
-			$factory = new $factoryClass($this);
909
-			$manager = $factory->getManager();
910
-
911
-			$manager->registerDisplayNameResolver('user', function($id) use ($c) {
912
-				$manager = $c->getUserManager();
913
-				$user = $manager->get($id);
914
-				if(is_null($user)) {
915
-					$l = $c->getL10N('core');
916
-					$displayName = $l->t('Unknown user');
917
-				} else {
918
-					$displayName = $user->getDisplayName();
919
-				}
920
-				return $displayName;
921
-			});
922
-
923
-			return $manager;
924
-		});
925
-		$this->registerAlias('CommentsManager', \OCP\Comments\ICommentsManager::class);
926
-
927
-		$this->registerService('ThemingDefaults', function (Server $c) {
928
-			/*
149
+    /** @var string */
150
+    private $webRoot;
151
+
152
+    /**
153
+     * @param string $webRoot
154
+     * @param \OC\Config $config
155
+     */
156
+    public function __construct($webRoot, \OC\Config $config) {
157
+        parent::__construct();
158
+        $this->webRoot = $webRoot;
159
+
160
+        $this->registerService(\OCP\IServerContainer::class, function (IServerContainer $c) {
161
+            return $c;
162
+        });
163
+
164
+        $this->registerAlias(\OCP\Calendar\IManager::class, \OC\Calendar\Manager::class);
165
+        $this->registerAlias('CalendarManager', \OC\Calendar\Manager::class);
166
+
167
+        $this->registerAlias(\OCP\Contacts\IManager::class, \OC\ContactsManager::class);
168
+        $this->registerAlias('ContactsManager', \OCP\Contacts\IManager::class);
169
+
170
+        $this->registerAlias(IActionFactory::class, ActionFactory::class);
171
+
172
+
173
+        $this->registerService(\OCP\IPreview::class, function (Server $c) {
174
+            return new PreviewManager(
175
+                $c->getConfig(),
176
+                $c->getRootFolder(),
177
+                $c->getAppDataDir('preview'),
178
+                $c->getEventDispatcher(),
179
+                $c->getSession()->get('user_id')
180
+            );
181
+        });
182
+        $this->registerAlias('PreviewManager', \OCP\IPreview::class);
183
+
184
+        $this->registerService(\OC\Preview\Watcher::class, function (Server $c) {
185
+            return new \OC\Preview\Watcher(
186
+                $c->getAppDataDir('preview')
187
+            );
188
+        });
189
+
190
+        $this->registerService('EncryptionManager', function (Server $c) {
191
+            $view = new View();
192
+            $util = new Encryption\Util(
193
+                $view,
194
+                $c->getUserManager(),
195
+                $c->getGroupManager(),
196
+                $c->getConfig()
197
+            );
198
+            return new Encryption\Manager(
199
+                $c->getConfig(),
200
+                $c->getLogger(),
201
+                $c->getL10N('core'),
202
+                new View(),
203
+                $util,
204
+                new ArrayCache()
205
+            );
206
+        });
207
+
208
+        $this->registerService('EncryptionFileHelper', function (Server $c) {
209
+            $util = new Encryption\Util(
210
+                new View(),
211
+                $c->getUserManager(),
212
+                $c->getGroupManager(),
213
+                $c->getConfig()
214
+            );
215
+            return new Encryption\File(
216
+                $util,
217
+                $c->getRootFolder(),
218
+                $c->getShareManager()
219
+            );
220
+        });
221
+
222
+        $this->registerService('EncryptionKeyStorage', function (Server $c) {
223
+            $view = new View();
224
+            $util = new Encryption\Util(
225
+                $view,
226
+                $c->getUserManager(),
227
+                $c->getGroupManager(),
228
+                $c->getConfig()
229
+            );
230
+
231
+            return new Encryption\Keys\Storage($view, $util);
232
+        });
233
+        $this->registerService('TagMapper', function (Server $c) {
234
+            return new TagMapper($c->getDatabaseConnection());
235
+        });
236
+
237
+        $this->registerService(\OCP\ITagManager::class, function (Server $c) {
238
+            $tagMapper = $c->query('TagMapper');
239
+            return new TagManager($tagMapper, $c->getUserSession());
240
+        });
241
+        $this->registerAlias('TagManager', \OCP\ITagManager::class);
242
+
243
+        $this->registerService('SystemTagManagerFactory', function (Server $c) {
244
+            $config = $c->getConfig();
245
+            $factoryClass = $config->getSystemValue('systemtags.managerFactory', '\OC\SystemTag\ManagerFactory');
246
+            return new $factoryClass($this);
247
+        });
248
+        $this->registerService(\OCP\SystemTag\ISystemTagManager::class, function (Server $c) {
249
+            return $c->query('SystemTagManagerFactory')->getManager();
250
+        });
251
+        $this->registerAlias('SystemTagManager', \OCP\SystemTag\ISystemTagManager::class);
252
+
253
+        $this->registerService(\OCP\SystemTag\ISystemTagObjectMapper::class, function (Server $c) {
254
+            return $c->query('SystemTagManagerFactory')->getObjectMapper();
255
+        });
256
+        $this->registerService('RootFolder', function (Server $c) {
257
+            $manager = \OC\Files\Filesystem::getMountManager(null);
258
+            $view = new View();
259
+            $root = new Root(
260
+                $manager,
261
+                $view,
262
+                null,
263
+                $c->getUserMountCache(),
264
+                $this->getLogger(),
265
+                $this->getUserManager()
266
+            );
267
+            $connector = new HookConnector($root, $view);
268
+            $connector->viewToNode();
269
+
270
+            $previewConnector = new \OC\Preview\WatcherConnector($root, $c->getSystemConfig());
271
+            $previewConnector->connectWatcher();
272
+
273
+            return $root;
274
+        });
275
+        $this->registerAlias('SystemTagObjectMapper', \OCP\SystemTag\ISystemTagObjectMapper::class);
276
+
277
+        $this->registerService(\OCP\Files\IRootFolder::class, function (Server $c) {
278
+            return new LazyRoot(function () use ($c) {
279
+                return $c->query('RootFolder');
280
+            });
281
+        });
282
+        $this->registerAlias('LazyRootFolder', \OCP\Files\IRootFolder::class);
283
+
284
+        $this->registerService(\OC\User\Manager::class, function (Server $c) {
285
+            $config = $c->getConfig();
286
+            return new \OC\User\Manager($config);
287
+        });
288
+        $this->registerAlias('UserManager', \OC\User\Manager::class);
289
+        $this->registerAlias(\OCP\IUserManager::class, \OC\User\Manager::class);
290
+
291
+        $this->registerService(\OCP\IGroupManager::class, function (Server $c) {
292
+            $groupManager = new \OC\Group\Manager($this->getUserManager(), $this->getLogger());
293
+            $groupManager->listen('\OC\Group', 'preCreate', function ($gid) {
294
+                \OC_Hook::emit('OC_Group', 'pre_createGroup', array('run' => true, 'gid' => $gid));
295
+            });
296
+            $groupManager->listen('\OC\Group', 'postCreate', function (\OC\Group\Group $gid) {
297
+                \OC_Hook::emit('OC_User', 'post_createGroup', array('gid' => $gid->getGID()));
298
+            });
299
+            $groupManager->listen('\OC\Group', 'preDelete', function (\OC\Group\Group $group) {
300
+                \OC_Hook::emit('OC_Group', 'pre_deleteGroup', array('run' => true, 'gid' => $group->getGID()));
301
+            });
302
+            $groupManager->listen('\OC\Group', 'postDelete', function (\OC\Group\Group $group) {
303
+                \OC_Hook::emit('OC_User', 'post_deleteGroup', array('gid' => $group->getGID()));
304
+            });
305
+            $groupManager->listen('\OC\Group', 'preAddUser', function (\OC\Group\Group $group, \OC\User\User $user) {
306
+                \OC_Hook::emit('OC_Group', 'pre_addToGroup', array('run' => true, 'uid' => $user->getUID(), 'gid' => $group->getGID()));
307
+            });
308
+            $groupManager->listen('\OC\Group', 'postAddUser', function (\OC\Group\Group $group, \OC\User\User $user) {
309
+                \OC_Hook::emit('OC_Group', 'post_addToGroup', array('uid' => $user->getUID(), 'gid' => $group->getGID()));
310
+                //Minimal fix to keep it backward compatible TODO: clean up all the GroupManager hooks
311
+                \OC_Hook::emit('OC_User', 'post_addToGroup', array('uid' => $user->getUID(), 'gid' => $group->getGID()));
312
+            });
313
+            return $groupManager;
314
+        });
315
+        $this->registerAlias('GroupManager', \OCP\IGroupManager::class);
316
+
317
+        $this->registerService(Store::class, function (Server $c) {
318
+            $session = $c->getSession();
319
+            if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
320
+                $tokenProvider = $c->query('OC\Authentication\Token\IProvider');
321
+            } else {
322
+                $tokenProvider = null;
323
+            }
324
+            $logger = $c->getLogger();
325
+            return new Store($session, $logger, $tokenProvider);
326
+        });
327
+        $this->registerAlias(IStore::class, Store::class);
328
+        $this->registerService('OC\Authentication\Token\DefaultTokenMapper', function (Server $c) {
329
+            $dbConnection = $c->getDatabaseConnection();
330
+            return new Authentication\Token\DefaultTokenMapper($dbConnection);
331
+        });
332
+        $this->registerService('OC\Authentication\Token\DefaultTokenProvider', function (Server $c) {
333
+            $mapper = $c->query('OC\Authentication\Token\DefaultTokenMapper');
334
+            $crypto = $c->getCrypto();
335
+            $config = $c->getConfig();
336
+            $logger = $c->getLogger();
337
+            $timeFactory = new TimeFactory();
338
+            return new \OC\Authentication\Token\DefaultTokenProvider($mapper, $crypto, $config, $logger, $timeFactory);
339
+        });
340
+        $this->registerAlias('OC\Authentication\Token\IProvider', 'OC\Authentication\Token\DefaultTokenProvider');
341
+
342
+        $this->registerService(\OCP\IUserSession::class, function (Server $c) {
343
+            $manager = $c->getUserManager();
344
+            $session = new \OC\Session\Memory('');
345
+            $timeFactory = new TimeFactory();
346
+            // Token providers might require a working database. This code
347
+            // might however be called when ownCloud is not yet setup.
348
+            if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
349
+                $defaultTokenProvider = $c->query('OC\Authentication\Token\IProvider');
350
+            } else {
351
+                $defaultTokenProvider = null;
352
+            }
353
+
354
+            $dispatcher = $c->getEventDispatcher();
355
+
356
+            $userSession = new \OC\User\Session(
357
+                $manager,
358
+                $session,
359
+                $timeFactory,
360
+                $defaultTokenProvider,
361
+                $c->getConfig(),
362
+                $c->getSecureRandom(),
363
+                $c->getLockdownManager(),
364
+                $c->getLogger()
365
+            );
366
+            $userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
367
+                \OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password));
368
+            });
369
+            $userSession->listen('\OC\User', 'postCreateUser', function ($user, $password) {
370
+                /** @var $user \OC\User\User */
371
+                \OC_Hook::emit('OC_User', 'post_createUser', array('uid' => $user->getUID(), 'password' => $password));
372
+            });
373
+            $userSession->listen('\OC\User', 'preDelete', function ($user) use ($dispatcher) {
374
+                /** @var $user \OC\User\User */
375
+                \OC_Hook::emit('OC_User', 'pre_deleteUser', array('run' => true, 'uid' => $user->getUID()));
376
+                $dispatcher->dispatch('OCP\IUser::preDelete', new GenericEvent($user));
377
+            });
378
+            $userSession->listen('\OC\User', 'postDelete', function ($user) {
379
+                /** @var $user \OC\User\User */
380
+                \OC_Hook::emit('OC_User', 'post_deleteUser', array('uid' => $user->getUID()));
381
+            });
382
+            $userSession->listen('\OC\User', 'preSetPassword', function ($user, $password, $recoveryPassword) {
383
+                /** @var $user \OC\User\User */
384
+                \OC_Hook::emit('OC_User', 'pre_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
385
+            });
386
+            $userSession->listen('\OC\User', 'postSetPassword', function ($user, $password, $recoveryPassword) {
387
+                /** @var $user \OC\User\User */
388
+                \OC_Hook::emit('OC_User', 'post_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
389
+            });
390
+            $userSession->listen('\OC\User', 'preLogin', function ($uid, $password) {
391
+                \OC_Hook::emit('OC_User', 'pre_login', array('run' => true, 'uid' => $uid, 'password' => $password));
392
+            });
393
+            $userSession->listen('\OC\User', 'postLogin', function ($user, $password) {
394
+                /** @var $user \OC\User\User */
395
+                \OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password));
396
+            });
397
+            $userSession->listen('\OC\User', 'postRememberedLogin', function ($user, $password) {
398
+                /** @var $user \OC\User\User */
399
+                \OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password));
400
+            });
401
+            $userSession->listen('\OC\User', 'logout', function () {
402
+                \OC_Hook::emit('OC_User', 'logout', array());
403
+            });
404
+            $userSession->listen('\OC\User', 'changeUser', function ($user, $feature, $value, $oldValue) use ($dispatcher) {
405
+                /** @var $user \OC\User\User */
406
+                \OC_Hook::emit('OC_User', 'changeUser', array('run' => true, 'user' => $user, 'feature' => $feature, 'value' => $value, 'old_value' => $oldValue));
407
+                $dispatcher->dispatch('OCP\IUser::changeUser', new GenericEvent($user, ['feature' => $feature, 'oldValue' => $oldValue, 'value' => $value]));
408
+            });
409
+            return $userSession;
410
+        });
411
+        $this->registerAlias('UserSession', \OCP\IUserSession::class);
412
+
413
+        $this->registerService(\OC\Authentication\TwoFactorAuth\Manager::class, function (Server $c) {
414
+            return new \OC\Authentication\TwoFactorAuth\Manager(
415
+                $c->getAppManager(),
416
+                $c->getSession(),
417
+                $c->getConfig(),
418
+                $c->getActivityManager(),
419
+                $c->getLogger(),
420
+                $c->query(\OC\Authentication\Token\IProvider::class),
421
+                $c->query(ITimeFactory::class),
422
+                $c->query(EventDispatcherInterface::class)
423
+            );
424
+        });
425
+
426
+        $this->registerAlias(\OCP\INavigationManager::class, \OC\NavigationManager::class);
427
+        $this->registerAlias('NavigationManager', \OCP\INavigationManager::class);
428
+
429
+        $this->registerService(\OC\AllConfig::class, function (Server $c) {
430
+            return new \OC\AllConfig(
431
+                $c->getSystemConfig()
432
+            );
433
+        });
434
+        $this->registerAlias('AllConfig', \OC\AllConfig::class);
435
+        $this->registerAlias(\OCP\IConfig::class, \OC\AllConfig::class);
436
+
437
+        $this->registerService('SystemConfig', function ($c) use ($config) {
438
+            return new \OC\SystemConfig($config);
439
+        });
440
+
441
+        $this->registerService(\OC\AppConfig::class, function (Server $c) {
442
+            return new \OC\AppConfig($c->getDatabaseConnection());
443
+        });
444
+        $this->registerAlias('AppConfig', \OC\AppConfig::class);
445
+        $this->registerAlias(\OCP\IAppConfig::class, \OC\AppConfig::class);
446
+
447
+        $this->registerService(\OCP\L10N\IFactory::class, function (Server $c) {
448
+            return new \OC\L10N\Factory(
449
+                $c->getConfig(),
450
+                $c->getRequest(),
451
+                $c->getUserSession(),
452
+                \OC::$SERVERROOT
453
+            );
454
+        });
455
+        $this->registerAlias('L10NFactory', \OCP\L10N\IFactory::class);
456
+
457
+        $this->registerService(\OCP\IURLGenerator::class, function (Server $c) {
458
+            $config = $c->getConfig();
459
+            $cacheFactory = $c->getMemCacheFactory();
460
+            $request = $c->getRequest();
461
+            return new \OC\URLGenerator(
462
+                $config,
463
+                $cacheFactory,
464
+                $request
465
+            );
466
+        });
467
+        $this->registerAlias('URLGenerator', \OCP\IURLGenerator::class);
468
+
469
+        $this->registerService('AppHelper', function ($c) {
470
+            return new \OC\AppHelper();
471
+        });
472
+        $this->registerAlias('AppFetcher', AppFetcher::class);
473
+        $this->registerAlias('CategoryFetcher', CategoryFetcher::class);
474
+
475
+        $this->registerService(\OCP\ICache::class, function ($c) {
476
+            return new Cache\File();
477
+        });
478
+        $this->registerAlias('UserCache', \OCP\ICache::class);
479
+
480
+        $this->registerService(Factory::class, function (Server $c) {
481
+
482
+            $arrayCacheFactory = new \OC\Memcache\Factory('', $c->getLogger(),
483
+                '\\OC\\Memcache\\ArrayCache',
484
+                '\\OC\\Memcache\\ArrayCache',
485
+                '\\OC\\Memcache\\ArrayCache'
486
+            );
487
+            $config = $c->getConfig();
488
+            $request = $c->getRequest();
489
+            $urlGenerator = new URLGenerator($config, $arrayCacheFactory, $request);
490
+
491
+            if ($config->getSystemValue('installed', false) && !(defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
492
+                $v = \OC_App::getAppVersions();
493
+                $v['core'] = implode(',', \OC_Util::getVersion());
494
+                $version = implode(',', $v);
495
+                $instanceId = \OC_Util::getInstanceId();
496
+                $path = \OC::$SERVERROOT;
497
+                $prefix = md5($instanceId . '-' . $version . '-' . $path . '-' . $urlGenerator->getBaseUrl());
498
+                return new \OC\Memcache\Factory($prefix, $c->getLogger(),
499
+                    $config->getSystemValue('memcache.local', null),
500
+                    $config->getSystemValue('memcache.distributed', null),
501
+                    $config->getSystemValue('memcache.locking', null)
502
+                );
503
+            }
504
+            return $arrayCacheFactory;
505
+
506
+        });
507
+        $this->registerAlias('MemCacheFactory', Factory::class);
508
+        $this->registerAlias(ICacheFactory::class, Factory::class);
509
+
510
+        $this->registerService('RedisFactory', function (Server $c) {
511
+            $systemConfig = $c->getSystemConfig();
512
+            return new RedisFactory($systemConfig);
513
+        });
514
+
515
+        $this->registerService(\OCP\Activity\IManager::class, function (Server $c) {
516
+            return new \OC\Activity\Manager(
517
+                $c->getRequest(),
518
+                $c->getUserSession(),
519
+                $c->getConfig(),
520
+                $c->query(IValidator::class)
521
+            );
522
+        });
523
+        $this->registerAlias('ActivityManager', \OCP\Activity\IManager::class);
524
+
525
+        $this->registerService(\OCP\Activity\IEventMerger::class, function (Server $c) {
526
+            return new \OC\Activity\EventMerger(
527
+                $c->getL10N('lib')
528
+            );
529
+        });
530
+        $this->registerAlias(IValidator::class, Validator::class);
531
+
532
+        $this->registerService(\OCP\IAvatarManager::class, function (Server $c) {
533
+            return new AvatarManager(
534
+                $c->query(\OC\User\Manager::class),
535
+                $c->getAppDataDir('avatar'),
536
+                $c->getL10N('lib'),
537
+                $c->getLogger(),
538
+                $c->getConfig()
539
+            );
540
+        });
541
+        $this->registerAlias('AvatarManager', \OCP\IAvatarManager::class);
542
+
543
+        $this->registerAlias(\OCP\Support\CrashReport\IRegistry::class, \OC\Support\CrashReport\Registry::class);
544
+
545
+        $this->registerService(\OCP\ILogger::class, function (Server $c) {
546
+            $logType = $c->query('AllConfig')->getSystemValue('log_type', 'file');
547
+            $logger = Log::getLogClass($logType);
548
+            call_user_func(array($logger, 'init'));
549
+            $config = $this->getSystemConfig();
550
+            $registry = $c->query(\OCP\Support\CrashReport\IRegistry::class);
551
+
552
+            return new Log($logger, $config, null, $registry);
553
+        });
554
+        $this->registerAlias('Logger', \OCP\ILogger::class);
555
+
556
+        $this->registerService(\OCP\BackgroundJob\IJobList::class, function (Server $c) {
557
+            $config = $c->getConfig();
558
+            return new \OC\BackgroundJob\JobList(
559
+                $c->getDatabaseConnection(),
560
+                $config,
561
+                new TimeFactory()
562
+            );
563
+        });
564
+        $this->registerAlias('JobList', \OCP\BackgroundJob\IJobList::class);
565
+
566
+        $this->registerService(\OCP\Route\IRouter::class, function (Server $c) {
567
+            $cacheFactory = $c->getMemCacheFactory();
568
+            $logger = $c->getLogger();
569
+            if ($cacheFactory->isAvailableLowLatency()) {
570
+                $router = new \OC\Route\CachingRouter($cacheFactory->createLocal('route'), $logger);
571
+            } else {
572
+                $router = new \OC\Route\Router($logger);
573
+            }
574
+            return $router;
575
+        });
576
+        $this->registerAlias('Router', \OCP\Route\IRouter::class);
577
+
578
+        $this->registerService(\OCP\ISearch::class, function ($c) {
579
+            return new Search();
580
+        });
581
+        $this->registerAlias('Search', \OCP\ISearch::class);
582
+
583
+        $this->registerService(\OC\Security\RateLimiting\Limiter::class, function ($c) {
584
+            return new \OC\Security\RateLimiting\Limiter(
585
+                $this->getUserSession(),
586
+                $this->getRequest(),
587
+                new \OC\AppFramework\Utility\TimeFactory(),
588
+                $c->query(\OC\Security\RateLimiting\Backend\IBackend::class)
589
+            );
590
+        });
591
+        $this->registerService(\OC\Security\RateLimiting\Backend\IBackend::class, function ($c) {
592
+            return new \OC\Security\RateLimiting\Backend\MemoryCache(
593
+                $this->getMemCacheFactory(),
594
+                new \OC\AppFramework\Utility\TimeFactory()
595
+            );
596
+        });
597
+
598
+        $this->registerService(\OCP\Security\ISecureRandom::class, function ($c) {
599
+            return new SecureRandom();
600
+        });
601
+        $this->registerAlias('SecureRandom', \OCP\Security\ISecureRandom::class);
602
+
603
+        $this->registerService(\OCP\Security\ICrypto::class, function (Server $c) {
604
+            return new Crypto($c->getConfig(), $c->getSecureRandom());
605
+        });
606
+        $this->registerAlias('Crypto', \OCP\Security\ICrypto::class);
607
+
608
+        $this->registerService(\OCP\Security\IHasher::class, function (Server $c) {
609
+            return new Hasher($c->getConfig());
610
+        });
611
+        $this->registerAlias('Hasher', \OCP\Security\IHasher::class);
612
+
613
+        $this->registerService(\OCP\Security\ICredentialsManager::class, function (Server $c) {
614
+            return new CredentialsManager($c->getCrypto(), $c->getDatabaseConnection());
615
+        });
616
+        $this->registerAlias('CredentialsManager', \OCP\Security\ICredentialsManager::class);
617
+
618
+        $this->registerService(IDBConnection::class, function (Server $c) {
619
+            $systemConfig = $c->getSystemConfig();
620
+            $factory = new \OC\DB\ConnectionFactory($systemConfig);
621
+            $type = $systemConfig->getValue('dbtype', 'sqlite');
622
+            if (!$factory->isValidType($type)) {
623
+                throw new \OC\DatabaseException('Invalid database type');
624
+            }
625
+            $connectionParams = $factory->createConnectionParams();
626
+            $connection = $factory->getConnection($type, $connectionParams);
627
+            $connection->getConfiguration()->setSQLLogger($c->getQueryLogger());
628
+            return $connection;
629
+        });
630
+        $this->registerAlias('DatabaseConnection', IDBConnection::class);
631
+
632
+        $this->registerService('HTTPHelper', function (Server $c) {
633
+            $config = $c->getConfig();
634
+            return new HTTPHelper(
635
+                $config,
636
+                $c->getHTTPClientService()
637
+            );
638
+        });
639
+
640
+        $this->registerService(\OCP\Http\Client\IClientService::class, function (Server $c) {
641
+            $user = \OC_User::getUser();
642
+            $uid = $user ? $user : null;
643
+            return new ClientService(
644
+                $c->getConfig(),
645
+                new \OC\Security\CertificateManager(
646
+                    $uid,
647
+                    new View(),
648
+                    $c->getConfig(),
649
+                    $c->getLogger(),
650
+                    $c->getSecureRandom()
651
+                )
652
+            );
653
+        });
654
+        $this->registerAlias('HttpClientService', \OCP\Http\Client\IClientService::class);
655
+        $this->registerService(\OCP\Diagnostics\IEventLogger::class, function (Server $c) {
656
+            $eventLogger = new EventLogger();
657
+            if ($c->getSystemConfig()->getValue('debug', false)) {
658
+                // In debug mode, module is being activated by default
659
+                $eventLogger->activate();
660
+            }
661
+            return $eventLogger;
662
+        });
663
+        $this->registerAlias('EventLogger', \OCP\Diagnostics\IEventLogger::class);
664
+
665
+        $this->registerService(\OCP\Diagnostics\IQueryLogger::class, function (Server $c) {
666
+            $queryLogger = new QueryLogger();
667
+            if ($c->getSystemConfig()->getValue('debug', false)) {
668
+                // In debug mode, module is being activated by default
669
+                $queryLogger->activate();
670
+            }
671
+            return $queryLogger;
672
+        });
673
+        $this->registerAlias('QueryLogger', \OCP\Diagnostics\IQueryLogger::class);
674
+
675
+        $this->registerService(TempManager::class, function (Server $c) {
676
+            return new TempManager(
677
+                $c->getLogger(),
678
+                $c->getConfig()
679
+            );
680
+        });
681
+        $this->registerAlias('TempManager', TempManager::class);
682
+        $this->registerAlias(ITempManager::class, TempManager::class);
683
+
684
+        $this->registerService(AppManager::class, function (Server $c) {
685
+            return new \OC\App\AppManager(
686
+                $c->getUserSession(),
687
+                $c->query(\OC\AppConfig::class),
688
+                $c->getGroupManager(),
689
+                $c->getMemCacheFactory(),
690
+                $c->getEventDispatcher()
691
+            );
692
+        });
693
+        $this->registerAlias('AppManager', AppManager::class);
694
+        $this->registerAlias(IAppManager::class, AppManager::class);
695
+
696
+        $this->registerService(\OCP\IDateTimeZone::class, function (Server $c) {
697
+            return new DateTimeZone(
698
+                $c->getConfig(),
699
+                $c->getSession()
700
+            );
701
+        });
702
+        $this->registerAlias('DateTimeZone', \OCP\IDateTimeZone::class);
703
+
704
+        $this->registerService(\OCP\IDateTimeFormatter::class, function (Server $c) {
705
+            $language = $c->getConfig()->getUserValue($c->getSession()->get('user_id'), 'core', 'lang', null);
706
+
707
+            return new DateTimeFormatter(
708
+                $c->getDateTimeZone()->getTimeZone(),
709
+                $c->getL10N('lib', $language)
710
+            );
711
+        });
712
+        $this->registerAlias('DateTimeFormatter', \OCP\IDateTimeFormatter::class);
713
+
714
+        $this->registerService(\OCP\Files\Config\IUserMountCache::class, function (Server $c) {
715
+            $mountCache = new UserMountCache($c->getDatabaseConnection(), $c->getUserManager(), $c->getLogger());
716
+            $listener = new UserMountCacheListener($mountCache);
717
+            $listener->listen($c->getUserManager());
718
+            return $mountCache;
719
+        });
720
+        $this->registerAlias('UserMountCache', \OCP\Files\Config\IUserMountCache::class);
721
+
722
+        $this->registerService(\OCP\Files\Config\IMountProviderCollection::class, function (Server $c) {
723
+            $loader = \OC\Files\Filesystem::getLoader();
724
+            $mountCache = $c->query('UserMountCache');
725
+            $manager = new \OC\Files\Config\MountProviderCollection($loader, $mountCache);
726
+
727
+            // builtin providers
728
+
729
+            $config = $c->getConfig();
730
+            $manager->registerProvider(new CacheMountProvider($config));
731
+            $manager->registerHomeProvider(new LocalHomeMountProvider());
732
+            $manager->registerHomeProvider(new ObjectHomeMountProvider($config));
733
+
734
+            return $manager;
735
+        });
736
+        $this->registerAlias('MountConfigManager', \OCP\Files\Config\IMountProviderCollection::class);
737
+
738
+        $this->registerService('IniWrapper', function ($c) {
739
+            return new IniGetWrapper();
740
+        });
741
+        $this->registerService('AsyncCommandBus', function (Server $c) {
742
+            $busClass = $c->getConfig()->getSystemValue('commandbus');
743
+            if ($busClass) {
744
+                list($app, $class) = explode('::', $busClass, 2);
745
+                if ($c->getAppManager()->isInstalled($app)) {
746
+                    \OC_App::loadApp($app);
747
+                    return $c->query($class);
748
+                } else {
749
+                    throw new ServiceUnavailableException("The app providing the command bus ($app) is not enabled");
750
+                }
751
+            } else {
752
+                $jobList = $c->getJobList();
753
+                return new CronBus($jobList);
754
+            }
755
+        });
756
+        $this->registerService('TrustedDomainHelper', function ($c) {
757
+            return new TrustedDomainHelper($this->getConfig());
758
+        });
759
+        $this->registerService('Throttler', function (Server $c) {
760
+            return new Throttler(
761
+                $c->getDatabaseConnection(),
762
+                new TimeFactory(),
763
+                $c->getLogger(),
764
+                $c->getConfig()
765
+            );
766
+        });
767
+        $this->registerService('IntegrityCodeChecker', function (Server $c) {
768
+            // IConfig and IAppManager requires a working database. This code
769
+            // might however be called when ownCloud is not yet setup.
770
+            if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
771
+                $config = $c->getConfig();
772
+                $appManager = $c->getAppManager();
773
+            } else {
774
+                $config = null;
775
+                $appManager = null;
776
+            }
777
+
778
+            return new Checker(
779
+                new EnvironmentHelper(),
780
+                new FileAccessHelper(),
781
+                new AppLocator(),
782
+                $config,
783
+                $c->getMemCacheFactory(),
784
+                $appManager,
785
+                $c->getTempManager()
786
+            );
787
+        });
788
+        $this->registerService(\OCP\IRequest::class, function ($c) {
789
+            if (isset($this['urlParams'])) {
790
+                $urlParams = $this['urlParams'];
791
+            } else {
792
+                $urlParams = [];
793
+            }
794
+
795
+            if (defined('PHPUNIT_RUN') && PHPUNIT_RUN
796
+                && in_array('fakeinput', stream_get_wrappers())
797
+            ) {
798
+                $stream = 'fakeinput://data';
799
+            } else {
800
+                $stream = 'php://input';
801
+            }
802
+
803
+            return new Request(
804
+                [
805
+                    'get' => $_GET,
806
+                    'post' => $_POST,
807
+                    'files' => $_FILES,
808
+                    'server' => $_SERVER,
809
+                    'env' => $_ENV,
810
+                    'cookies' => $_COOKIE,
811
+                    'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD']))
812
+                        ? $_SERVER['REQUEST_METHOD']
813
+                        : null,
814
+                    'urlParams' => $urlParams,
815
+                ],
816
+                $this->getSecureRandom(),
817
+                $this->getConfig(),
818
+                $this->getCsrfTokenManager(),
819
+                $stream
820
+            );
821
+        });
822
+        $this->registerAlias('Request', \OCP\IRequest::class);
823
+
824
+        $this->registerService(\OCP\Mail\IMailer::class, function (Server $c) {
825
+            return new Mailer(
826
+                $c->getConfig(),
827
+                $c->getLogger(),
828
+                $c->query(Defaults::class),
829
+                $c->getURLGenerator(),
830
+                $c->getL10N('lib')
831
+            );
832
+        });
833
+        $this->registerAlias('Mailer', \OCP\Mail\IMailer::class);
834
+
835
+        $this->registerService('LDAPProvider', function (Server $c) {
836
+            $config = $c->getConfig();
837
+            $factoryClass = $config->getSystemValue('ldapProviderFactory', null);
838
+            if (is_null($factoryClass)) {
839
+                throw new \Exception('ldapProviderFactory not set');
840
+            }
841
+            /** @var \OCP\LDAP\ILDAPProviderFactory $factory */
842
+            $factory = new $factoryClass($this);
843
+            return $factory->getLDAPProvider();
844
+        });
845
+        $this->registerService(ILockingProvider::class, function (Server $c) {
846
+            $ini = $c->getIniWrapper();
847
+            $config = $c->getConfig();
848
+            $ttl = $config->getSystemValue('filelocking.ttl', max(3600, $ini->getNumeric('max_execution_time')));
849
+            if ($config->getSystemValue('filelocking.enabled', true) or (defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
850
+                /** @var \OC\Memcache\Factory $memcacheFactory */
851
+                $memcacheFactory = $c->getMemCacheFactory();
852
+                $memcache = $memcacheFactory->createLocking('lock');
853
+                if (!($memcache instanceof \OC\Memcache\NullCache)) {
854
+                    return new MemcacheLockingProvider($memcache, $ttl);
855
+                }
856
+                return new DBLockingProvider($c->getDatabaseConnection(), $c->getLogger(), new TimeFactory(), $ttl);
857
+            }
858
+            return new NoopLockingProvider();
859
+        });
860
+        $this->registerAlias('LockingProvider', ILockingProvider::class);
861
+
862
+        $this->registerService(\OCP\Files\Mount\IMountManager::class, function () {
863
+            return new \OC\Files\Mount\Manager();
864
+        });
865
+        $this->registerAlias('MountManager', \OCP\Files\Mount\IMountManager::class);
866
+
867
+        $this->registerService(\OCP\Files\IMimeTypeDetector::class, function (Server $c) {
868
+            return new \OC\Files\Type\Detection(
869
+                $c->getURLGenerator(),
870
+                \OC::$configDir,
871
+                \OC::$SERVERROOT . '/resources/config/'
872
+            );
873
+        });
874
+        $this->registerAlias('MimeTypeDetector', \OCP\Files\IMimeTypeDetector::class);
875
+
876
+        $this->registerService(\OCP\Files\IMimeTypeLoader::class, function (Server $c) {
877
+            return new \OC\Files\Type\Loader(
878
+                $c->getDatabaseConnection()
879
+            );
880
+        });
881
+        $this->registerAlias('MimeTypeLoader', \OCP\Files\IMimeTypeLoader::class);
882
+        $this->registerService(BundleFetcher::class, function () {
883
+            return new BundleFetcher($this->getL10N('lib'));
884
+        });
885
+        $this->registerService(\OCP\Notification\IManager::class, function (Server $c) {
886
+            return new Manager(
887
+                $c->query(IValidator::class)
888
+            );
889
+        });
890
+        $this->registerAlias('NotificationManager', \OCP\Notification\IManager::class);
891
+
892
+        $this->registerService(\OC\CapabilitiesManager::class, function (Server $c) {
893
+            $manager = new \OC\CapabilitiesManager($c->getLogger());
894
+            $manager->registerCapability(function () use ($c) {
895
+                return new \OC\OCS\CoreCapabilities($c->getConfig());
896
+            });
897
+            $manager->registerCapability(function () use ($c) {
898
+                return $c->query(\OC\Security\Bruteforce\Capabilities::class);
899
+            });
900
+            return $manager;
901
+        });
902
+        $this->registerAlias('CapabilitiesManager', \OC\CapabilitiesManager::class);
903
+
904
+        $this->registerService(\OCP\Comments\ICommentsManager::class, function (Server $c) {
905
+            $config = $c->getConfig();
906
+            $factoryClass = $config->getSystemValue('comments.managerFactory', '\OC\Comments\ManagerFactory');
907
+            /** @var \OCP\Comments\ICommentsManagerFactory $factory */
908
+            $factory = new $factoryClass($this);
909
+            $manager = $factory->getManager();
910
+
911
+            $manager->registerDisplayNameResolver('user', function($id) use ($c) {
912
+                $manager = $c->getUserManager();
913
+                $user = $manager->get($id);
914
+                if(is_null($user)) {
915
+                    $l = $c->getL10N('core');
916
+                    $displayName = $l->t('Unknown user');
917
+                } else {
918
+                    $displayName = $user->getDisplayName();
919
+                }
920
+                return $displayName;
921
+            });
922
+
923
+            return $manager;
924
+        });
925
+        $this->registerAlias('CommentsManager', \OCP\Comments\ICommentsManager::class);
926
+
927
+        $this->registerService('ThemingDefaults', function (Server $c) {
928
+            /*
929 929
 			 * Dark magic for autoloader.
930 930
 			 * If we do a class_exists it will try to load the class which will
931 931
 			 * make composer cache the result. Resulting in errors when enabling
932 932
 			 * the theming app.
933 933
 			 */
934
-			$prefixes = \OC::$composerAutoloader->getPrefixesPsr4();
935
-			if (isset($prefixes['OCA\\Theming\\'])) {
936
-				$classExists = true;
937
-			} else {
938
-				$classExists = false;
939
-			}
940
-
941
-			if ($classExists && $c->getConfig()->getSystemValue('installed', false) && $c->getAppManager()->isInstalled('theming') && $c->getTrustedDomainHelper()->isTrustedDomain($c->getRequest()->getInsecureServerHost())) {
942
-				return new ThemingDefaults(
943
-					$c->getConfig(),
944
-					$c->getL10N('theming'),
945
-					$c->getURLGenerator(),
946
-					$c->getAppDataDir('theming'),
947
-					$c->getMemCacheFactory(),
948
-					new Util($c->getConfig(), $this->getAppManager(), $this->getAppDataDir('theming')),
949
-					$this->getAppManager()
950
-				);
951
-			}
952
-			return new \OC_Defaults();
953
-		});
954
-		$this->registerService(SCSSCacher::class, function (Server $c) {
955
-			/** @var Factory $cacheFactory */
956
-			$cacheFactory = $c->query(Factory::class);
957
-			return new SCSSCacher(
958
-				$c->getLogger(),
959
-				$c->query(\OC\Files\AppData\Factory::class),
960
-				$c->getURLGenerator(),
961
-				$c->getConfig(),
962
-				$c->getThemingDefaults(),
963
-				\OC::$SERVERROOT,
964
-				$cacheFactory->createDistributed('SCSS')
965
-			);
966
-		});
967
-		$this->registerService(EventDispatcher::class, function () {
968
-			return new EventDispatcher();
969
-		});
970
-		$this->registerAlias('EventDispatcher', EventDispatcher::class);
971
-		$this->registerAlias(EventDispatcherInterface::class, EventDispatcher::class);
972
-
973
-		$this->registerService('CryptoWrapper', function (Server $c) {
974
-			// FIXME: Instantiiated here due to cyclic dependency
975
-			$request = new Request(
976
-				[
977
-					'get' => $_GET,
978
-					'post' => $_POST,
979
-					'files' => $_FILES,
980
-					'server' => $_SERVER,
981
-					'env' => $_ENV,
982
-					'cookies' => $_COOKIE,
983
-					'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD']))
984
-						? $_SERVER['REQUEST_METHOD']
985
-						: null,
986
-				],
987
-				$c->getSecureRandom(),
988
-				$c->getConfig()
989
-			);
990
-
991
-			return new CryptoWrapper(
992
-				$c->getConfig(),
993
-				$c->getCrypto(),
994
-				$c->getSecureRandom(),
995
-				$request
996
-			);
997
-		});
998
-		$this->registerService('CsrfTokenManager', function (Server $c) {
999
-			$tokenGenerator = new CsrfTokenGenerator($c->getSecureRandom());
1000
-
1001
-			return new CsrfTokenManager(
1002
-				$tokenGenerator,
1003
-				$c->query(SessionStorage::class)
1004
-			);
1005
-		});
1006
-		$this->registerService(SessionStorage::class, function (Server $c) {
1007
-			return new SessionStorage($c->getSession());
1008
-		});
1009
-		$this->registerService(\OCP\Security\IContentSecurityPolicyManager::class, function (Server $c) {
1010
-			return new ContentSecurityPolicyManager();
1011
-		});
1012
-		$this->registerAlias('ContentSecurityPolicyManager', \OCP\Security\IContentSecurityPolicyManager::class);
1013
-
1014
-		$this->registerService('ContentSecurityPolicyNonceManager', function (Server $c) {
1015
-			return new ContentSecurityPolicyNonceManager(
1016
-				$c->getCsrfTokenManager(),
1017
-				$c->getRequest()
1018
-			);
1019
-		});
1020
-
1021
-		$this->registerService(\OCP\Share\IManager::class, function (Server $c) {
1022
-			$config = $c->getConfig();
1023
-			$factoryClass = $config->getSystemValue('sharing.managerFactory', '\OC\Share20\ProviderFactory');
1024
-			/** @var \OCP\Share\IProviderFactory $factory */
1025
-			$factory = new $factoryClass($this);
1026
-
1027
-			$manager = new \OC\Share20\Manager(
1028
-				$c->getLogger(),
1029
-				$c->getConfig(),
1030
-				$c->getSecureRandom(),
1031
-				$c->getHasher(),
1032
-				$c->getMountManager(),
1033
-				$c->getGroupManager(),
1034
-				$c->getL10N('lib'),
1035
-				$c->getL10NFactory(),
1036
-				$factory,
1037
-				$c->getUserManager(),
1038
-				$c->getLazyRootFolder(),
1039
-				$c->getEventDispatcher(),
1040
-				$c->getMailer(),
1041
-				$c->getURLGenerator(),
1042
-				$c->getThemingDefaults()
1043
-			);
1044
-
1045
-			return $manager;
1046
-		});
1047
-		$this->registerAlias('ShareManager', \OCP\Share\IManager::class);
1048
-
1049
-		$this->registerService(\OCP\Collaboration\Collaborators\ISearch::class, function(Server $c) {
1050
-			$instance = new Collaboration\Collaborators\Search($c);
1051
-
1052
-			// register default plugins
1053
-			$instance->registerPlugin(['shareType' => 'SHARE_TYPE_USER', 'class' => UserPlugin::class]);
1054
-			$instance->registerPlugin(['shareType' => 'SHARE_TYPE_GROUP', 'class' => GroupPlugin::class]);
1055
-			$instance->registerPlugin(['shareType' => 'SHARE_TYPE_EMAIL', 'class' => MailPlugin::class]);
1056
-			$instance->registerPlugin(['shareType' => 'SHARE_TYPE_REMOTE', 'class' => RemotePlugin::class]);
1057
-
1058
-			return $instance;
1059
-		});
1060
-		$this->registerAlias('CollaboratorSearch', \OCP\Collaboration\Collaborators\ISearch::class);
1061
-
1062
-		$this->registerAlias(\OCP\Collaboration\AutoComplete\IManager::class, \OC\Collaboration\AutoComplete\Manager::class);
1063
-
1064
-		$this->registerService('SettingsManager', function (Server $c) {
1065
-			$manager = new \OC\Settings\Manager(
1066
-				$c->getLogger(),
1067
-				$c->getDatabaseConnection(),
1068
-				$c->getL10N('lib'),
1069
-				$c->getConfig(),
1070
-				$c->getEncryptionManager(),
1071
-				$c->getUserManager(),
1072
-				$c->getLockingProvider(),
1073
-				$c->getRequest(),
1074
-				new \OC\Settings\Mapper($c->getDatabaseConnection()),
1075
-				$c->getURLGenerator(),
1076
-				$c->query(AccountManager::class),
1077
-				$c->getGroupManager(),
1078
-				$c->getL10NFactory(),
1079
-				$c->getThemingDefaults(),
1080
-				$c->getAppManager()
1081
-			);
1082
-			return $manager;
1083
-		});
1084
-		$this->registerService(\OC\Files\AppData\Factory::class, function (Server $c) {
1085
-			return new \OC\Files\AppData\Factory(
1086
-				$c->getRootFolder(),
1087
-				$c->getSystemConfig()
1088
-			);
1089
-		});
1090
-
1091
-		$this->registerService('LockdownManager', function (Server $c) {
1092
-			return new LockdownManager(function () use ($c) {
1093
-				return $c->getSession();
1094
-			});
1095
-		});
1096
-
1097
-		$this->registerService(\OCP\OCS\IDiscoveryService::class, function (Server $c) {
1098
-			return new DiscoveryService($c->getMemCacheFactory(), $c->getHTTPClientService());
1099
-		});
1100
-
1101
-		$this->registerService(ICloudIdManager::class, function (Server $c) {
1102
-			return new CloudIdManager();
1103
-		});
1104
-
1105
-		$this->registerAlias(\OCP\AppFramework\Utility\IControllerMethodReflector::class, \OC\AppFramework\Utility\ControllerMethodReflector::class);
1106
-		$this->registerAlias('ControllerMethodReflector', \OCP\AppFramework\Utility\IControllerMethodReflector::class);
1107
-
1108
-		$this->registerAlias(\OCP\AppFramework\Utility\ITimeFactory::class, \OC\AppFramework\Utility\TimeFactory::class);
1109
-		$this->registerAlias('TimeFactory', \OCP\AppFramework\Utility\ITimeFactory::class);
1110
-
1111
-		$this->registerService(Defaults::class, function (Server $c) {
1112
-			return new Defaults(
1113
-				$c->getThemingDefaults()
1114
-			);
1115
-		});
1116
-		$this->registerAlias('Defaults', \OCP\Defaults::class);
1117
-
1118
-		$this->registerService(\OCP\ISession::class, function (SimpleContainer $c) {
1119
-			return $c->query(\OCP\IUserSession::class)->getSession();
1120
-		});
1121
-
1122
-		$this->registerService(IShareHelper::class, function (Server $c) {
1123
-			return new ShareHelper(
1124
-				$c->query(\OCP\Share\IManager::class)
1125
-			);
1126
-		});
1127
-
1128
-		$this->registerService(Installer::class, function(Server $c) {
1129
-			return new Installer(
1130
-				$c->getAppFetcher(),
1131
-				$c->getHTTPClientService(),
1132
-				$c->getTempManager(),
1133
-				$c->getLogger(),
1134
-				$c->getConfig()
1135
-			);
1136
-		});
1137
-
1138
-		$this->registerService(IApiFactory::class, function(Server $c) {
1139
-			return new ApiFactory($c->getHTTPClientService());
1140
-		});
1141
-
1142
-		$this->registerService(IInstanceFactory::class, function(Server $c) {
1143
-			$memcacheFactory = $c->getMemCacheFactory();
1144
-			return new InstanceFactory($memcacheFactory->createLocal('remoteinstance.'), $c->getHTTPClientService());
1145
-		});
1146
-
1147
-		$this->registerService(IContactsStore::class, function(Server $c) {
1148
-			return new ContactsStore(
1149
-				$c->getContactsManager(),
1150
-				$c->getConfig(),
1151
-				$c->getUserManager(),
1152
-				$c->getGroupManager()
1153
-			);
1154
-		});
1155
-		$this->registerAlias(IContactsStore::class, ContactsStore::class);
1156
-
1157
-		$this->connectDispatcher();
1158
-	}
1159
-
1160
-	/**
1161
-	 * @return \OCP\Calendar\IManager
1162
-	 */
1163
-	public function getCalendarManager() {
1164
-		return $this->query('CalendarManager');
1165
-	}
1166
-
1167
-	private function connectDispatcher() {
1168
-		$dispatcher = $this->getEventDispatcher();
1169
-
1170
-		// Delete avatar on user deletion
1171
-		$dispatcher->addListener('OCP\IUser::preDelete', function(GenericEvent $e) {
1172
-			$logger = $this->getLogger();
1173
-			$manager = $this->getAvatarManager();
1174
-			/** @var IUser $user */
1175
-			$user = $e->getSubject();
1176
-
1177
-			try {
1178
-				$avatar = $manager->getAvatar($user->getUID());
1179
-				$avatar->remove();
1180
-			} catch (NotFoundException $e) {
1181
-				// no avatar to remove
1182
-			} catch (\Exception $e) {
1183
-				// Ignore exceptions
1184
-				$logger->info('Could not cleanup avatar of ' . $user->getUID());
1185
-			}
1186
-		});
1187
-
1188
-		$dispatcher->addListener('OCP\IUser::changeUser', function (GenericEvent $e) {
1189
-			$manager = $this->getAvatarManager();
1190
-			/** @var IUser $user */
1191
-			$user = $e->getSubject();
1192
-			$feature = $e->getArgument('feature');
1193
-			$oldValue = $e->getArgument('oldValue');
1194
-			$value = $e->getArgument('value');
1195
-
1196
-			try {
1197
-				$avatar = $manager->getAvatar($user->getUID());
1198
-				$avatar->userChanged($feature, $oldValue, $value);
1199
-			} catch (NotFoundException $e) {
1200
-				// no avatar to remove
1201
-			}
1202
-		});
1203
-	}
1204
-
1205
-	/**
1206
-	 * @return \OCP\Contacts\IManager
1207
-	 */
1208
-	public function getContactsManager() {
1209
-		return $this->query('ContactsManager');
1210
-	}
1211
-
1212
-	/**
1213
-	 * @return \OC\Encryption\Manager
1214
-	 */
1215
-	public function getEncryptionManager() {
1216
-		return $this->query('EncryptionManager');
1217
-	}
1218
-
1219
-	/**
1220
-	 * @return \OC\Encryption\File
1221
-	 */
1222
-	public function getEncryptionFilesHelper() {
1223
-		return $this->query('EncryptionFileHelper');
1224
-	}
1225
-
1226
-	/**
1227
-	 * @return \OCP\Encryption\Keys\IStorage
1228
-	 */
1229
-	public function getEncryptionKeyStorage() {
1230
-		return $this->query('EncryptionKeyStorage');
1231
-	}
1232
-
1233
-	/**
1234
-	 * The current request object holding all information about the request
1235
-	 * currently being processed is returned from this method.
1236
-	 * In case the current execution was not initiated by a web request null is returned
1237
-	 *
1238
-	 * @return \OCP\IRequest
1239
-	 */
1240
-	public function getRequest() {
1241
-		return $this->query('Request');
1242
-	}
1243
-
1244
-	/**
1245
-	 * Returns the preview manager which can create preview images for a given file
1246
-	 *
1247
-	 * @return \OCP\IPreview
1248
-	 */
1249
-	public function getPreviewManager() {
1250
-		return $this->query('PreviewManager');
1251
-	}
1252
-
1253
-	/**
1254
-	 * Returns the tag manager which can get and set tags for different object types
1255
-	 *
1256
-	 * @see \OCP\ITagManager::load()
1257
-	 * @return \OCP\ITagManager
1258
-	 */
1259
-	public function getTagManager() {
1260
-		return $this->query('TagManager');
1261
-	}
1262
-
1263
-	/**
1264
-	 * Returns the system-tag manager
1265
-	 *
1266
-	 * @return \OCP\SystemTag\ISystemTagManager
1267
-	 *
1268
-	 * @since 9.0.0
1269
-	 */
1270
-	public function getSystemTagManager() {
1271
-		return $this->query('SystemTagManager');
1272
-	}
1273
-
1274
-	/**
1275
-	 * Returns the system-tag object mapper
1276
-	 *
1277
-	 * @return \OCP\SystemTag\ISystemTagObjectMapper
1278
-	 *
1279
-	 * @since 9.0.0
1280
-	 */
1281
-	public function getSystemTagObjectMapper() {
1282
-		return $this->query('SystemTagObjectMapper');
1283
-	}
1284
-
1285
-	/**
1286
-	 * Returns the avatar manager, used for avatar functionality
1287
-	 *
1288
-	 * @return \OCP\IAvatarManager
1289
-	 */
1290
-	public function getAvatarManager() {
1291
-		return $this->query('AvatarManager');
1292
-	}
1293
-
1294
-	/**
1295
-	 * Returns the root folder of ownCloud's data directory
1296
-	 *
1297
-	 * @return \OCP\Files\IRootFolder
1298
-	 */
1299
-	public function getRootFolder() {
1300
-		return $this->query('LazyRootFolder');
1301
-	}
1302
-
1303
-	/**
1304
-	 * Returns the root folder of ownCloud's data directory
1305
-	 * This is the lazy variant so this gets only initialized once it
1306
-	 * is actually used.
1307
-	 *
1308
-	 * @return \OCP\Files\IRootFolder
1309
-	 */
1310
-	public function getLazyRootFolder() {
1311
-		return $this->query('LazyRootFolder');
1312
-	}
1313
-
1314
-	/**
1315
-	 * Returns a view to ownCloud's files folder
1316
-	 *
1317
-	 * @param string $userId user ID
1318
-	 * @return \OCP\Files\Folder|null
1319
-	 */
1320
-	public function getUserFolder($userId = null) {
1321
-		if ($userId === null) {
1322
-			$user = $this->getUserSession()->getUser();
1323
-			if (!$user) {
1324
-				return null;
1325
-			}
1326
-			$userId = $user->getUID();
1327
-		}
1328
-		$root = $this->getRootFolder();
1329
-		return $root->getUserFolder($userId);
1330
-	}
1331
-
1332
-	/**
1333
-	 * Returns an app-specific view in ownClouds data directory
1334
-	 *
1335
-	 * @return \OCP\Files\Folder
1336
-	 * @deprecated since 9.2.0 use IAppData
1337
-	 */
1338
-	public function getAppFolder() {
1339
-		$dir = '/' . \OC_App::getCurrentApp();
1340
-		$root = $this->getRootFolder();
1341
-		if (!$root->nodeExists($dir)) {
1342
-			$folder = $root->newFolder($dir);
1343
-		} else {
1344
-			$folder = $root->get($dir);
1345
-		}
1346
-		return $folder;
1347
-	}
1348
-
1349
-	/**
1350
-	 * @return \OC\User\Manager
1351
-	 */
1352
-	public function getUserManager() {
1353
-		return $this->query('UserManager');
1354
-	}
1355
-
1356
-	/**
1357
-	 * @return \OC\Group\Manager
1358
-	 */
1359
-	public function getGroupManager() {
1360
-		return $this->query('GroupManager');
1361
-	}
1362
-
1363
-	/**
1364
-	 * @return \OC\User\Session
1365
-	 */
1366
-	public function getUserSession() {
1367
-		return $this->query('UserSession');
1368
-	}
1369
-
1370
-	/**
1371
-	 * @return \OCP\ISession
1372
-	 */
1373
-	public function getSession() {
1374
-		return $this->query('UserSession')->getSession();
1375
-	}
1376
-
1377
-	/**
1378
-	 * @param \OCP\ISession $session
1379
-	 */
1380
-	public function setSession(\OCP\ISession $session) {
1381
-		$this->query(SessionStorage::class)->setSession($session);
1382
-		$this->query('UserSession')->setSession($session);
1383
-		$this->query(Store::class)->setSession($session);
1384
-	}
1385
-
1386
-	/**
1387
-	 * @return \OC\Authentication\TwoFactorAuth\Manager
1388
-	 */
1389
-	public function getTwoFactorAuthManager() {
1390
-		return $this->query('\OC\Authentication\TwoFactorAuth\Manager');
1391
-	}
1392
-
1393
-	/**
1394
-	 * @return \OC\NavigationManager
1395
-	 */
1396
-	public function getNavigationManager() {
1397
-		return $this->query('NavigationManager');
1398
-	}
1399
-
1400
-	/**
1401
-	 * @return \OCP\IConfig
1402
-	 */
1403
-	public function getConfig() {
1404
-		return $this->query('AllConfig');
1405
-	}
1406
-
1407
-	/**
1408
-	 * @return \OC\SystemConfig
1409
-	 */
1410
-	public function getSystemConfig() {
1411
-		return $this->query('SystemConfig');
1412
-	}
1413
-
1414
-	/**
1415
-	 * Returns the app config manager
1416
-	 *
1417
-	 * @return \OCP\IAppConfig
1418
-	 */
1419
-	public function getAppConfig() {
1420
-		return $this->query('AppConfig');
1421
-	}
1422
-
1423
-	/**
1424
-	 * @return \OCP\L10N\IFactory
1425
-	 */
1426
-	public function getL10NFactory() {
1427
-		return $this->query('L10NFactory');
1428
-	}
1429
-
1430
-	/**
1431
-	 * get an L10N instance
1432
-	 *
1433
-	 * @param string $app appid
1434
-	 * @param string $lang
1435
-	 * @return IL10N
1436
-	 */
1437
-	public function getL10N($app, $lang = null) {
1438
-		return $this->getL10NFactory()->get($app, $lang);
1439
-	}
1440
-
1441
-	/**
1442
-	 * @return \OCP\IURLGenerator
1443
-	 */
1444
-	public function getURLGenerator() {
1445
-		return $this->query('URLGenerator');
1446
-	}
1447
-
1448
-	/**
1449
-	 * @return \OCP\IHelper
1450
-	 */
1451
-	public function getHelper() {
1452
-		return $this->query('AppHelper');
1453
-	}
1454
-
1455
-	/**
1456
-	 * @return AppFetcher
1457
-	 */
1458
-	public function getAppFetcher() {
1459
-		return $this->query(AppFetcher::class);
1460
-	}
1461
-
1462
-	/**
1463
-	 * Returns an ICache instance. Since 8.1.0 it returns a fake cache. Use
1464
-	 * getMemCacheFactory() instead.
1465
-	 *
1466
-	 * @return \OCP\ICache
1467
-	 * @deprecated 8.1.0 use getMemCacheFactory to obtain a proper cache
1468
-	 */
1469
-	public function getCache() {
1470
-		return $this->query('UserCache');
1471
-	}
1472
-
1473
-	/**
1474
-	 * Returns an \OCP\CacheFactory instance
1475
-	 *
1476
-	 * @return \OCP\ICacheFactory
1477
-	 */
1478
-	public function getMemCacheFactory() {
1479
-		return $this->query('MemCacheFactory');
1480
-	}
1481
-
1482
-	/**
1483
-	 * Returns an \OC\RedisFactory instance
1484
-	 *
1485
-	 * @return \OC\RedisFactory
1486
-	 */
1487
-	public function getGetRedisFactory() {
1488
-		return $this->query('RedisFactory');
1489
-	}
1490
-
1491
-
1492
-	/**
1493
-	 * Returns the current session
1494
-	 *
1495
-	 * @return \OCP\IDBConnection
1496
-	 */
1497
-	public function getDatabaseConnection() {
1498
-		return $this->query('DatabaseConnection');
1499
-	}
1500
-
1501
-	/**
1502
-	 * Returns the activity manager
1503
-	 *
1504
-	 * @return \OCP\Activity\IManager
1505
-	 */
1506
-	public function getActivityManager() {
1507
-		return $this->query('ActivityManager');
1508
-	}
1509
-
1510
-	/**
1511
-	 * Returns an job list for controlling background jobs
1512
-	 *
1513
-	 * @return \OCP\BackgroundJob\IJobList
1514
-	 */
1515
-	public function getJobList() {
1516
-		return $this->query('JobList');
1517
-	}
1518
-
1519
-	/**
1520
-	 * Returns a logger instance
1521
-	 *
1522
-	 * @return \OCP\ILogger
1523
-	 */
1524
-	public function getLogger() {
1525
-		return $this->query('Logger');
1526
-	}
1527
-
1528
-	/**
1529
-	 * Returns a router for generating and matching urls
1530
-	 *
1531
-	 * @return \OCP\Route\IRouter
1532
-	 */
1533
-	public function getRouter() {
1534
-		return $this->query('Router');
1535
-	}
1536
-
1537
-	/**
1538
-	 * Returns a search instance
1539
-	 *
1540
-	 * @return \OCP\ISearch
1541
-	 */
1542
-	public function getSearch() {
1543
-		return $this->query('Search');
1544
-	}
1545
-
1546
-	/**
1547
-	 * Returns a SecureRandom instance
1548
-	 *
1549
-	 * @return \OCP\Security\ISecureRandom
1550
-	 */
1551
-	public function getSecureRandom() {
1552
-		return $this->query('SecureRandom');
1553
-	}
1554
-
1555
-	/**
1556
-	 * Returns a Crypto instance
1557
-	 *
1558
-	 * @return \OCP\Security\ICrypto
1559
-	 */
1560
-	public function getCrypto() {
1561
-		return $this->query('Crypto');
1562
-	}
1563
-
1564
-	/**
1565
-	 * Returns a Hasher instance
1566
-	 *
1567
-	 * @return \OCP\Security\IHasher
1568
-	 */
1569
-	public function getHasher() {
1570
-		return $this->query('Hasher');
1571
-	}
1572
-
1573
-	/**
1574
-	 * Returns a CredentialsManager instance
1575
-	 *
1576
-	 * @return \OCP\Security\ICredentialsManager
1577
-	 */
1578
-	public function getCredentialsManager() {
1579
-		return $this->query('CredentialsManager');
1580
-	}
1581
-
1582
-	/**
1583
-	 * Returns an instance of the HTTP helper class
1584
-	 *
1585
-	 * @deprecated Use getHTTPClientService()
1586
-	 * @return \OC\HTTPHelper
1587
-	 */
1588
-	public function getHTTPHelper() {
1589
-		return $this->query('HTTPHelper');
1590
-	}
1591
-
1592
-	/**
1593
-	 * Get the certificate manager for the user
1594
-	 *
1595
-	 * @param string $userId (optional) if not specified the current loggedin user is used, use null to get the system certificate manager
1596
-	 * @return \OCP\ICertificateManager | null if $uid is null and no user is logged in
1597
-	 */
1598
-	public function getCertificateManager($userId = '') {
1599
-		if ($userId === '') {
1600
-			$userSession = $this->getUserSession();
1601
-			$user = $userSession->getUser();
1602
-			if (is_null($user)) {
1603
-				return null;
1604
-			}
1605
-			$userId = $user->getUID();
1606
-		}
1607
-		return new CertificateManager(
1608
-			$userId,
1609
-			new View(),
1610
-			$this->getConfig(),
1611
-			$this->getLogger(),
1612
-			$this->getSecureRandom()
1613
-		);
1614
-	}
1615
-
1616
-	/**
1617
-	 * Returns an instance of the HTTP client service
1618
-	 *
1619
-	 * @return \OCP\Http\Client\IClientService
1620
-	 */
1621
-	public function getHTTPClientService() {
1622
-		return $this->query('HttpClientService');
1623
-	}
1624
-
1625
-	/**
1626
-	 * Create a new event source
1627
-	 *
1628
-	 * @return \OCP\IEventSource
1629
-	 */
1630
-	public function createEventSource() {
1631
-		return new \OC_EventSource();
1632
-	}
1633
-
1634
-	/**
1635
-	 * Get the active event logger
1636
-	 *
1637
-	 * The returned logger only logs data when debug mode is enabled
1638
-	 *
1639
-	 * @return \OCP\Diagnostics\IEventLogger
1640
-	 */
1641
-	public function getEventLogger() {
1642
-		return $this->query('EventLogger');
1643
-	}
1644
-
1645
-	/**
1646
-	 * Get the active query logger
1647
-	 *
1648
-	 * The returned logger only logs data when debug mode is enabled
1649
-	 *
1650
-	 * @return \OCP\Diagnostics\IQueryLogger
1651
-	 */
1652
-	public function getQueryLogger() {
1653
-		return $this->query('QueryLogger');
1654
-	}
1655
-
1656
-	/**
1657
-	 * Get the manager for temporary files and folders
1658
-	 *
1659
-	 * @return \OCP\ITempManager
1660
-	 */
1661
-	public function getTempManager() {
1662
-		return $this->query('TempManager');
1663
-	}
1664
-
1665
-	/**
1666
-	 * Get the app manager
1667
-	 *
1668
-	 * @return \OCP\App\IAppManager
1669
-	 */
1670
-	public function getAppManager() {
1671
-		return $this->query('AppManager');
1672
-	}
1673
-
1674
-	/**
1675
-	 * Creates a new mailer
1676
-	 *
1677
-	 * @return \OCP\Mail\IMailer
1678
-	 */
1679
-	public function getMailer() {
1680
-		return $this->query('Mailer');
1681
-	}
1682
-
1683
-	/**
1684
-	 * Get the webroot
1685
-	 *
1686
-	 * @return string
1687
-	 */
1688
-	public function getWebRoot() {
1689
-		return $this->webRoot;
1690
-	}
1691
-
1692
-	/**
1693
-	 * @return \OC\OCSClient
1694
-	 */
1695
-	public function getOcsClient() {
1696
-		return $this->query('OcsClient');
1697
-	}
1698
-
1699
-	/**
1700
-	 * @return \OCP\IDateTimeZone
1701
-	 */
1702
-	public function getDateTimeZone() {
1703
-		return $this->query('DateTimeZone');
1704
-	}
1705
-
1706
-	/**
1707
-	 * @return \OCP\IDateTimeFormatter
1708
-	 */
1709
-	public function getDateTimeFormatter() {
1710
-		return $this->query('DateTimeFormatter');
1711
-	}
1712
-
1713
-	/**
1714
-	 * @return \OCP\Files\Config\IMountProviderCollection
1715
-	 */
1716
-	public function getMountProviderCollection() {
1717
-		return $this->query('MountConfigManager');
1718
-	}
1719
-
1720
-	/**
1721
-	 * Get the IniWrapper
1722
-	 *
1723
-	 * @return IniGetWrapper
1724
-	 */
1725
-	public function getIniWrapper() {
1726
-		return $this->query('IniWrapper');
1727
-	}
1728
-
1729
-	/**
1730
-	 * @return \OCP\Command\IBus
1731
-	 */
1732
-	public function getCommandBus() {
1733
-		return $this->query('AsyncCommandBus');
1734
-	}
1735
-
1736
-	/**
1737
-	 * Get the trusted domain helper
1738
-	 *
1739
-	 * @return TrustedDomainHelper
1740
-	 */
1741
-	public function getTrustedDomainHelper() {
1742
-		return $this->query('TrustedDomainHelper');
1743
-	}
1744
-
1745
-	/**
1746
-	 * Get the locking provider
1747
-	 *
1748
-	 * @return \OCP\Lock\ILockingProvider
1749
-	 * @since 8.1.0
1750
-	 */
1751
-	public function getLockingProvider() {
1752
-		return $this->query('LockingProvider');
1753
-	}
1754
-
1755
-	/**
1756
-	 * @return \OCP\Files\Mount\IMountManager
1757
-	 **/
1758
-	function getMountManager() {
1759
-		return $this->query('MountManager');
1760
-	}
1761
-
1762
-	/** @return \OCP\Files\Config\IUserMountCache */
1763
-	function getUserMountCache() {
1764
-		return $this->query('UserMountCache');
1765
-	}
1766
-
1767
-	/**
1768
-	 * Get the MimeTypeDetector
1769
-	 *
1770
-	 * @return \OCP\Files\IMimeTypeDetector
1771
-	 */
1772
-	public function getMimeTypeDetector() {
1773
-		return $this->query('MimeTypeDetector');
1774
-	}
1775
-
1776
-	/**
1777
-	 * Get the MimeTypeLoader
1778
-	 *
1779
-	 * @return \OCP\Files\IMimeTypeLoader
1780
-	 */
1781
-	public function getMimeTypeLoader() {
1782
-		return $this->query('MimeTypeLoader');
1783
-	}
1784
-
1785
-	/**
1786
-	 * Get the manager of all the capabilities
1787
-	 *
1788
-	 * @return \OC\CapabilitiesManager
1789
-	 */
1790
-	public function getCapabilitiesManager() {
1791
-		return $this->query('CapabilitiesManager');
1792
-	}
1793
-
1794
-	/**
1795
-	 * Get the EventDispatcher
1796
-	 *
1797
-	 * @return EventDispatcherInterface
1798
-	 * @since 8.2.0
1799
-	 */
1800
-	public function getEventDispatcher() {
1801
-		return $this->query('EventDispatcher');
1802
-	}
1803
-
1804
-	/**
1805
-	 * Get the Notification Manager
1806
-	 *
1807
-	 * @return \OCP\Notification\IManager
1808
-	 * @since 8.2.0
1809
-	 */
1810
-	public function getNotificationManager() {
1811
-		return $this->query('NotificationManager');
1812
-	}
1813
-
1814
-	/**
1815
-	 * @return \OCP\Comments\ICommentsManager
1816
-	 */
1817
-	public function getCommentsManager() {
1818
-		return $this->query('CommentsManager');
1819
-	}
1820
-
1821
-	/**
1822
-	 * @return \OCA\Theming\ThemingDefaults
1823
-	 */
1824
-	public function getThemingDefaults() {
1825
-		return $this->query('ThemingDefaults');
1826
-	}
1827
-
1828
-	/**
1829
-	 * @return \OC\IntegrityCheck\Checker
1830
-	 */
1831
-	public function getIntegrityCodeChecker() {
1832
-		return $this->query('IntegrityCodeChecker');
1833
-	}
1834
-
1835
-	/**
1836
-	 * @return \OC\Session\CryptoWrapper
1837
-	 */
1838
-	public function getSessionCryptoWrapper() {
1839
-		return $this->query('CryptoWrapper');
1840
-	}
1841
-
1842
-	/**
1843
-	 * @return CsrfTokenManager
1844
-	 */
1845
-	public function getCsrfTokenManager() {
1846
-		return $this->query('CsrfTokenManager');
1847
-	}
1848
-
1849
-	/**
1850
-	 * @return Throttler
1851
-	 */
1852
-	public function getBruteForceThrottler() {
1853
-		return $this->query('Throttler');
1854
-	}
1855
-
1856
-	/**
1857
-	 * @return IContentSecurityPolicyManager
1858
-	 */
1859
-	public function getContentSecurityPolicyManager() {
1860
-		return $this->query('ContentSecurityPolicyManager');
1861
-	}
1862
-
1863
-	/**
1864
-	 * @return ContentSecurityPolicyNonceManager
1865
-	 */
1866
-	public function getContentSecurityPolicyNonceManager() {
1867
-		return $this->query('ContentSecurityPolicyNonceManager');
1868
-	}
1869
-
1870
-	/**
1871
-	 * Not a public API as of 8.2, wait for 9.0
1872
-	 *
1873
-	 * @return \OCA\Files_External\Service\BackendService
1874
-	 */
1875
-	public function getStoragesBackendService() {
1876
-		return $this->query('OCA\\Files_External\\Service\\BackendService');
1877
-	}
1878
-
1879
-	/**
1880
-	 * Not a public API as of 8.2, wait for 9.0
1881
-	 *
1882
-	 * @return \OCA\Files_External\Service\GlobalStoragesService
1883
-	 */
1884
-	public function getGlobalStoragesService() {
1885
-		return $this->query('OCA\\Files_External\\Service\\GlobalStoragesService');
1886
-	}
1887
-
1888
-	/**
1889
-	 * Not a public API as of 8.2, wait for 9.0
1890
-	 *
1891
-	 * @return \OCA\Files_External\Service\UserGlobalStoragesService
1892
-	 */
1893
-	public function getUserGlobalStoragesService() {
1894
-		return $this->query('OCA\\Files_External\\Service\\UserGlobalStoragesService');
1895
-	}
1896
-
1897
-	/**
1898
-	 * Not a public API as of 8.2, wait for 9.0
1899
-	 *
1900
-	 * @return \OCA\Files_External\Service\UserStoragesService
1901
-	 */
1902
-	public function getUserStoragesService() {
1903
-		return $this->query('OCA\\Files_External\\Service\\UserStoragesService');
1904
-	}
1905
-
1906
-	/**
1907
-	 * @return \OCP\Share\IManager
1908
-	 */
1909
-	public function getShareManager() {
1910
-		return $this->query('ShareManager');
1911
-	}
1912
-
1913
-	/**
1914
-	 * @return \OCP\Collaboration\Collaborators\ISearch
1915
-	 */
1916
-	public function getCollaboratorSearch() {
1917
-		return $this->query('CollaboratorSearch');
1918
-	}
1919
-
1920
-	/**
1921
-	 * @return \OCP\Collaboration\AutoComplete\IManager
1922
-	 */
1923
-	public function getAutoCompleteManager(){
1924
-		return $this->query(IManager::class);
1925
-	}
1926
-
1927
-	/**
1928
-	 * Returns the LDAP Provider
1929
-	 *
1930
-	 * @return \OCP\LDAP\ILDAPProvider
1931
-	 */
1932
-	public function getLDAPProvider() {
1933
-		return $this->query('LDAPProvider');
1934
-	}
1935
-
1936
-	/**
1937
-	 * @return \OCP\Settings\IManager
1938
-	 */
1939
-	public function getSettingsManager() {
1940
-		return $this->query('SettingsManager');
1941
-	}
1942
-
1943
-	/**
1944
-	 * @return \OCP\Files\IAppData
1945
-	 */
1946
-	public function getAppDataDir($app) {
1947
-		/** @var \OC\Files\AppData\Factory $factory */
1948
-		$factory = $this->query(\OC\Files\AppData\Factory::class);
1949
-		return $factory->get($app);
1950
-	}
1951
-
1952
-	/**
1953
-	 * @return \OCP\Lockdown\ILockdownManager
1954
-	 */
1955
-	public function getLockdownManager() {
1956
-		return $this->query('LockdownManager');
1957
-	}
1958
-
1959
-	/**
1960
-	 * @return \OCP\Federation\ICloudIdManager
1961
-	 */
1962
-	public function getCloudIdManager() {
1963
-		return $this->query(ICloudIdManager::class);
1964
-	}
1965
-
1966
-	/**
1967
-	 * @return \OCP\Remote\Api\IApiFactory
1968
-	 */
1969
-	public function getRemoteApiFactory() {
1970
-		return $this->query(IApiFactory::class);
1971
-	}
1972
-
1973
-	/**
1974
-	 * @return \OCP\Remote\IInstanceFactory
1975
-	 */
1976
-	public function getRemoteInstanceFactory() {
1977
-		return $this->query(IInstanceFactory::class);
1978
-	}
934
+            $prefixes = \OC::$composerAutoloader->getPrefixesPsr4();
935
+            if (isset($prefixes['OCA\\Theming\\'])) {
936
+                $classExists = true;
937
+            } else {
938
+                $classExists = false;
939
+            }
940
+
941
+            if ($classExists && $c->getConfig()->getSystemValue('installed', false) && $c->getAppManager()->isInstalled('theming') && $c->getTrustedDomainHelper()->isTrustedDomain($c->getRequest()->getInsecureServerHost())) {
942
+                return new ThemingDefaults(
943
+                    $c->getConfig(),
944
+                    $c->getL10N('theming'),
945
+                    $c->getURLGenerator(),
946
+                    $c->getAppDataDir('theming'),
947
+                    $c->getMemCacheFactory(),
948
+                    new Util($c->getConfig(), $this->getAppManager(), $this->getAppDataDir('theming')),
949
+                    $this->getAppManager()
950
+                );
951
+            }
952
+            return new \OC_Defaults();
953
+        });
954
+        $this->registerService(SCSSCacher::class, function (Server $c) {
955
+            /** @var Factory $cacheFactory */
956
+            $cacheFactory = $c->query(Factory::class);
957
+            return new SCSSCacher(
958
+                $c->getLogger(),
959
+                $c->query(\OC\Files\AppData\Factory::class),
960
+                $c->getURLGenerator(),
961
+                $c->getConfig(),
962
+                $c->getThemingDefaults(),
963
+                \OC::$SERVERROOT,
964
+                $cacheFactory->createDistributed('SCSS')
965
+            );
966
+        });
967
+        $this->registerService(EventDispatcher::class, function () {
968
+            return new EventDispatcher();
969
+        });
970
+        $this->registerAlias('EventDispatcher', EventDispatcher::class);
971
+        $this->registerAlias(EventDispatcherInterface::class, EventDispatcher::class);
972
+
973
+        $this->registerService('CryptoWrapper', function (Server $c) {
974
+            // FIXME: Instantiiated here due to cyclic dependency
975
+            $request = new Request(
976
+                [
977
+                    'get' => $_GET,
978
+                    'post' => $_POST,
979
+                    'files' => $_FILES,
980
+                    'server' => $_SERVER,
981
+                    'env' => $_ENV,
982
+                    'cookies' => $_COOKIE,
983
+                    'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD']))
984
+                        ? $_SERVER['REQUEST_METHOD']
985
+                        : null,
986
+                ],
987
+                $c->getSecureRandom(),
988
+                $c->getConfig()
989
+            );
990
+
991
+            return new CryptoWrapper(
992
+                $c->getConfig(),
993
+                $c->getCrypto(),
994
+                $c->getSecureRandom(),
995
+                $request
996
+            );
997
+        });
998
+        $this->registerService('CsrfTokenManager', function (Server $c) {
999
+            $tokenGenerator = new CsrfTokenGenerator($c->getSecureRandom());
1000
+
1001
+            return new CsrfTokenManager(
1002
+                $tokenGenerator,
1003
+                $c->query(SessionStorage::class)
1004
+            );
1005
+        });
1006
+        $this->registerService(SessionStorage::class, function (Server $c) {
1007
+            return new SessionStorage($c->getSession());
1008
+        });
1009
+        $this->registerService(\OCP\Security\IContentSecurityPolicyManager::class, function (Server $c) {
1010
+            return new ContentSecurityPolicyManager();
1011
+        });
1012
+        $this->registerAlias('ContentSecurityPolicyManager', \OCP\Security\IContentSecurityPolicyManager::class);
1013
+
1014
+        $this->registerService('ContentSecurityPolicyNonceManager', function (Server $c) {
1015
+            return new ContentSecurityPolicyNonceManager(
1016
+                $c->getCsrfTokenManager(),
1017
+                $c->getRequest()
1018
+            );
1019
+        });
1020
+
1021
+        $this->registerService(\OCP\Share\IManager::class, function (Server $c) {
1022
+            $config = $c->getConfig();
1023
+            $factoryClass = $config->getSystemValue('sharing.managerFactory', '\OC\Share20\ProviderFactory');
1024
+            /** @var \OCP\Share\IProviderFactory $factory */
1025
+            $factory = new $factoryClass($this);
1026
+
1027
+            $manager = new \OC\Share20\Manager(
1028
+                $c->getLogger(),
1029
+                $c->getConfig(),
1030
+                $c->getSecureRandom(),
1031
+                $c->getHasher(),
1032
+                $c->getMountManager(),
1033
+                $c->getGroupManager(),
1034
+                $c->getL10N('lib'),
1035
+                $c->getL10NFactory(),
1036
+                $factory,
1037
+                $c->getUserManager(),
1038
+                $c->getLazyRootFolder(),
1039
+                $c->getEventDispatcher(),
1040
+                $c->getMailer(),
1041
+                $c->getURLGenerator(),
1042
+                $c->getThemingDefaults()
1043
+            );
1044
+
1045
+            return $manager;
1046
+        });
1047
+        $this->registerAlias('ShareManager', \OCP\Share\IManager::class);
1048
+
1049
+        $this->registerService(\OCP\Collaboration\Collaborators\ISearch::class, function(Server $c) {
1050
+            $instance = new Collaboration\Collaborators\Search($c);
1051
+
1052
+            // register default plugins
1053
+            $instance->registerPlugin(['shareType' => 'SHARE_TYPE_USER', 'class' => UserPlugin::class]);
1054
+            $instance->registerPlugin(['shareType' => 'SHARE_TYPE_GROUP', 'class' => GroupPlugin::class]);
1055
+            $instance->registerPlugin(['shareType' => 'SHARE_TYPE_EMAIL', 'class' => MailPlugin::class]);
1056
+            $instance->registerPlugin(['shareType' => 'SHARE_TYPE_REMOTE', 'class' => RemotePlugin::class]);
1057
+
1058
+            return $instance;
1059
+        });
1060
+        $this->registerAlias('CollaboratorSearch', \OCP\Collaboration\Collaborators\ISearch::class);
1061
+
1062
+        $this->registerAlias(\OCP\Collaboration\AutoComplete\IManager::class, \OC\Collaboration\AutoComplete\Manager::class);
1063
+
1064
+        $this->registerService('SettingsManager', function (Server $c) {
1065
+            $manager = new \OC\Settings\Manager(
1066
+                $c->getLogger(),
1067
+                $c->getDatabaseConnection(),
1068
+                $c->getL10N('lib'),
1069
+                $c->getConfig(),
1070
+                $c->getEncryptionManager(),
1071
+                $c->getUserManager(),
1072
+                $c->getLockingProvider(),
1073
+                $c->getRequest(),
1074
+                new \OC\Settings\Mapper($c->getDatabaseConnection()),
1075
+                $c->getURLGenerator(),
1076
+                $c->query(AccountManager::class),
1077
+                $c->getGroupManager(),
1078
+                $c->getL10NFactory(),
1079
+                $c->getThemingDefaults(),
1080
+                $c->getAppManager()
1081
+            );
1082
+            return $manager;
1083
+        });
1084
+        $this->registerService(\OC\Files\AppData\Factory::class, function (Server $c) {
1085
+            return new \OC\Files\AppData\Factory(
1086
+                $c->getRootFolder(),
1087
+                $c->getSystemConfig()
1088
+            );
1089
+        });
1090
+
1091
+        $this->registerService('LockdownManager', function (Server $c) {
1092
+            return new LockdownManager(function () use ($c) {
1093
+                return $c->getSession();
1094
+            });
1095
+        });
1096
+
1097
+        $this->registerService(\OCP\OCS\IDiscoveryService::class, function (Server $c) {
1098
+            return new DiscoveryService($c->getMemCacheFactory(), $c->getHTTPClientService());
1099
+        });
1100
+
1101
+        $this->registerService(ICloudIdManager::class, function (Server $c) {
1102
+            return new CloudIdManager();
1103
+        });
1104
+
1105
+        $this->registerAlias(\OCP\AppFramework\Utility\IControllerMethodReflector::class, \OC\AppFramework\Utility\ControllerMethodReflector::class);
1106
+        $this->registerAlias('ControllerMethodReflector', \OCP\AppFramework\Utility\IControllerMethodReflector::class);
1107
+
1108
+        $this->registerAlias(\OCP\AppFramework\Utility\ITimeFactory::class, \OC\AppFramework\Utility\TimeFactory::class);
1109
+        $this->registerAlias('TimeFactory', \OCP\AppFramework\Utility\ITimeFactory::class);
1110
+
1111
+        $this->registerService(Defaults::class, function (Server $c) {
1112
+            return new Defaults(
1113
+                $c->getThemingDefaults()
1114
+            );
1115
+        });
1116
+        $this->registerAlias('Defaults', \OCP\Defaults::class);
1117
+
1118
+        $this->registerService(\OCP\ISession::class, function (SimpleContainer $c) {
1119
+            return $c->query(\OCP\IUserSession::class)->getSession();
1120
+        });
1121
+
1122
+        $this->registerService(IShareHelper::class, function (Server $c) {
1123
+            return new ShareHelper(
1124
+                $c->query(\OCP\Share\IManager::class)
1125
+            );
1126
+        });
1127
+
1128
+        $this->registerService(Installer::class, function(Server $c) {
1129
+            return new Installer(
1130
+                $c->getAppFetcher(),
1131
+                $c->getHTTPClientService(),
1132
+                $c->getTempManager(),
1133
+                $c->getLogger(),
1134
+                $c->getConfig()
1135
+            );
1136
+        });
1137
+
1138
+        $this->registerService(IApiFactory::class, function(Server $c) {
1139
+            return new ApiFactory($c->getHTTPClientService());
1140
+        });
1141
+
1142
+        $this->registerService(IInstanceFactory::class, function(Server $c) {
1143
+            $memcacheFactory = $c->getMemCacheFactory();
1144
+            return new InstanceFactory($memcacheFactory->createLocal('remoteinstance.'), $c->getHTTPClientService());
1145
+        });
1146
+
1147
+        $this->registerService(IContactsStore::class, function(Server $c) {
1148
+            return new ContactsStore(
1149
+                $c->getContactsManager(),
1150
+                $c->getConfig(),
1151
+                $c->getUserManager(),
1152
+                $c->getGroupManager()
1153
+            );
1154
+        });
1155
+        $this->registerAlias(IContactsStore::class, ContactsStore::class);
1156
+
1157
+        $this->connectDispatcher();
1158
+    }
1159
+
1160
+    /**
1161
+     * @return \OCP\Calendar\IManager
1162
+     */
1163
+    public function getCalendarManager() {
1164
+        return $this->query('CalendarManager');
1165
+    }
1166
+
1167
+    private function connectDispatcher() {
1168
+        $dispatcher = $this->getEventDispatcher();
1169
+
1170
+        // Delete avatar on user deletion
1171
+        $dispatcher->addListener('OCP\IUser::preDelete', function(GenericEvent $e) {
1172
+            $logger = $this->getLogger();
1173
+            $manager = $this->getAvatarManager();
1174
+            /** @var IUser $user */
1175
+            $user = $e->getSubject();
1176
+
1177
+            try {
1178
+                $avatar = $manager->getAvatar($user->getUID());
1179
+                $avatar->remove();
1180
+            } catch (NotFoundException $e) {
1181
+                // no avatar to remove
1182
+            } catch (\Exception $e) {
1183
+                // Ignore exceptions
1184
+                $logger->info('Could not cleanup avatar of ' . $user->getUID());
1185
+            }
1186
+        });
1187
+
1188
+        $dispatcher->addListener('OCP\IUser::changeUser', function (GenericEvent $e) {
1189
+            $manager = $this->getAvatarManager();
1190
+            /** @var IUser $user */
1191
+            $user = $e->getSubject();
1192
+            $feature = $e->getArgument('feature');
1193
+            $oldValue = $e->getArgument('oldValue');
1194
+            $value = $e->getArgument('value');
1195
+
1196
+            try {
1197
+                $avatar = $manager->getAvatar($user->getUID());
1198
+                $avatar->userChanged($feature, $oldValue, $value);
1199
+            } catch (NotFoundException $e) {
1200
+                // no avatar to remove
1201
+            }
1202
+        });
1203
+    }
1204
+
1205
+    /**
1206
+     * @return \OCP\Contacts\IManager
1207
+     */
1208
+    public function getContactsManager() {
1209
+        return $this->query('ContactsManager');
1210
+    }
1211
+
1212
+    /**
1213
+     * @return \OC\Encryption\Manager
1214
+     */
1215
+    public function getEncryptionManager() {
1216
+        return $this->query('EncryptionManager');
1217
+    }
1218
+
1219
+    /**
1220
+     * @return \OC\Encryption\File
1221
+     */
1222
+    public function getEncryptionFilesHelper() {
1223
+        return $this->query('EncryptionFileHelper');
1224
+    }
1225
+
1226
+    /**
1227
+     * @return \OCP\Encryption\Keys\IStorage
1228
+     */
1229
+    public function getEncryptionKeyStorage() {
1230
+        return $this->query('EncryptionKeyStorage');
1231
+    }
1232
+
1233
+    /**
1234
+     * The current request object holding all information about the request
1235
+     * currently being processed is returned from this method.
1236
+     * In case the current execution was not initiated by a web request null is returned
1237
+     *
1238
+     * @return \OCP\IRequest
1239
+     */
1240
+    public function getRequest() {
1241
+        return $this->query('Request');
1242
+    }
1243
+
1244
+    /**
1245
+     * Returns the preview manager which can create preview images for a given file
1246
+     *
1247
+     * @return \OCP\IPreview
1248
+     */
1249
+    public function getPreviewManager() {
1250
+        return $this->query('PreviewManager');
1251
+    }
1252
+
1253
+    /**
1254
+     * Returns the tag manager which can get and set tags for different object types
1255
+     *
1256
+     * @see \OCP\ITagManager::load()
1257
+     * @return \OCP\ITagManager
1258
+     */
1259
+    public function getTagManager() {
1260
+        return $this->query('TagManager');
1261
+    }
1262
+
1263
+    /**
1264
+     * Returns the system-tag manager
1265
+     *
1266
+     * @return \OCP\SystemTag\ISystemTagManager
1267
+     *
1268
+     * @since 9.0.0
1269
+     */
1270
+    public function getSystemTagManager() {
1271
+        return $this->query('SystemTagManager');
1272
+    }
1273
+
1274
+    /**
1275
+     * Returns the system-tag object mapper
1276
+     *
1277
+     * @return \OCP\SystemTag\ISystemTagObjectMapper
1278
+     *
1279
+     * @since 9.0.0
1280
+     */
1281
+    public function getSystemTagObjectMapper() {
1282
+        return $this->query('SystemTagObjectMapper');
1283
+    }
1284
+
1285
+    /**
1286
+     * Returns the avatar manager, used for avatar functionality
1287
+     *
1288
+     * @return \OCP\IAvatarManager
1289
+     */
1290
+    public function getAvatarManager() {
1291
+        return $this->query('AvatarManager');
1292
+    }
1293
+
1294
+    /**
1295
+     * Returns the root folder of ownCloud's data directory
1296
+     *
1297
+     * @return \OCP\Files\IRootFolder
1298
+     */
1299
+    public function getRootFolder() {
1300
+        return $this->query('LazyRootFolder');
1301
+    }
1302
+
1303
+    /**
1304
+     * Returns the root folder of ownCloud's data directory
1305
+     * This is the lazy variant so this gets only initialized once it
1306
+     * is actually used.
1307
+     *
1308
+     * @return \OCP\Files\IRootFolder
1309
+     */
1310
+    public function getLazyRootFolder() {
1311
+        return $this->query('LazyRootFolder');
1312
+    }
1313
+
1314
+    /**
1315
+     * Returns a view to ownCloud's files folder
1316
+     *
1317
+     * @param string $userId user ID
1318
+     * @return \OCP\Files\Folder|null
1319
+     */
1320
+    public function getUserFolder($userId = null) {
1321
+        if ($userId === null) {
1322
+            $user = $this->getUserSession()->getUser();
1323
+            if (!$user) {
1324
+                return null;
1325
+            }
1326
+            $userId = $user->getUID();
1327
+        }
1328
+        $root = $this->getRootFolder();
1329
+        return $root->getUserFolder($userId);
1330
+    }
1331
+
1332
+    /**
1333
+     * Returns an app-specific view in ownClouds data directory
1334
+     *
1335
+     * @return \OCP\Files\Folder
1336
+     * @deprecated since 9.2.0 use IAppData
1337
+     */
1338
+    public function getAppFolder() {
1339
+        $dir = '/' . \OC_App::getCurrentApp();
1340
+        $root = $this->getRootFolder();
1341
+        if (!$root->nodeExists($dir)) {
1342
+            $folder = $root->newFolder($dir);
1343
+        } else {
1344
+            $folder = $root->get($dir);
1345
+        }
1346
+        return $folder;
1347
+    }
1348
+
1349
+    /**
1350
+     * @return \OC\User\Manager
1351
+     */
1352
+    public function getUserManager() {
1353
+        return $this->query('UserManager');
1354
+    }
1355
+
1356
+    /**
1357
+     * @return \OC\Group\Manager
1358
+     */
1359
+    public function getGroupManager() {
1360
+        return $this->query('GroupManager');
1361
+    }
1362
+
1363
+    /**
1364
+     * @return \OC\User\Session
1365
+     */
1366
+    public function getUserSession() {
1367
+        return $this->query('UserSession');
1368
+    }
1369
+
1370
+    /**
1371
+     * @return \OCP\ISession
1372
+     */
1373
+    public function getSession() {
1374
+        return $this->query('UserSession')->getSession();
1375
+    }
1376
+
1377
+    /**
1378
+     * @param \OCP\ISession $session
1379
+     */
1380
+    public function setSession(\OCP\ISession $session) {
1381
+        $this->query(SessionStorage::class)->setSession($session);
1382
+        $this->query('UserSession')->setSession($session);
1383
+        $this->query(Store::class)->setSession($session);
1384
+    }
1385
+
1386
+    /**
1387
+     * @return \OC\Authentication\TwoFactorAuth\Manager
1388
+     */
1389
+    public function getTwoFactorAuthManager() {
1390
+        return $this->query('\OC\Authentication\TwoFactorAuth\Manager');
1391
+    }
1392
+
1393
+    /**
1394
+     * @return \OC\NavigationManager
1395
+     */
1396
+    public function getNavigationManager() {
1397
+        return $this->query('NavigationManager');
1398
+    }
1399
+
1400
+    /**
1401
+     * @return \OCP\IConfig
1402
+     */
1403
+    public function getConfig() {
1404
+        return $this->query('AllConfig');
1405
+    }
1406
+
1407
+    /**
1408
+     * @return \OC\SystemConfig
1409
+     */
1410
+    public function getSystemConfig() {
1411
+        return $this->query('SystemConfig');
1412
+    }
1413
+
1414
+    /**
1415
+     * Returns the app config manager
1416
+     *
1417
+     * @return \OCP\IAppConfig
1418
+     */
1419
+    public function getAppConfig() {
1420
+        return $this->query('AppConfig');
1421
+    }
1422
+
1423
+    /**
1424
+     * @return \OCP\L10N\IFactory
1425
+     */
1426
+    public function getL10NFactory() {
1427
+        return $this->query('L10NFactory');
1428
+    }
1429
+
1430
+    /**
1431
+     * get an L10N instance
1432
+     *
1433
+     * @param string $app appid
1434
+     * @param string $lang
1435
+     * @return IL10N
1436
+     */
1437
+    public function getL10N($app, $lang = null) {
1438
+        return $this->getL10NFactory()->get($app, $lang);
1439
+    }
1440
+
1441
+    /**
1442
+     * @return \OCP\IURLGenerator
1443
+     */
1444
+    public function getURLGenerator() {
1445
+        return $this->query('URLGenerator');
1446
+    }
1447
+
1448
+    /**
1449
+     * @return \OCP\IHelper
1450
+     */
1451
+    public function getHelper() {
1452
+        return $this->query('AppHelper');
1453
+    }
1454
+
1455
+    /**
1456
+     * @return AppFetcher
1457
+     */
1458
+    public function getAppFetcher() {
1459
+        return $this->query(AppFetcher::class);
1460
+    }
1461
+
1462
+    /**
1463
+     * Returns an ICache instance. Since 8.1.0 it returns a fake cache. Use
1464
+     * getMemCacheFactory() instead.
1465
+     *
1466
+     * @return \OCP\ICache
1467
+     * @deprecated 8.1.0 use getMemCacheFactory to obtain a proper cache
1468
+     */
1469
+    public function getCache() {
1470
+        return $this->query('UserCache');
1471
+    }
1472
+
1473
+    /**
1474
+     * Returns an \OCP\CacheFactory instance
1475
+     *
1476
+     * @return \OCP\ICacheFactory
1477
+     */
1478
+    public function getMemCacheFactory() {
1479
+        return $this->query('MemCacheFactory');
1480
+    }
1481
+
1482
+    /**
1483
+     * Returns an \OC\RedisFactory instance
1484
+     *
1485
+     * @return \OC\RedisFactory
1486
+     */
1487
+    public function getGetRedisFactory() {
1488
+        return $this->query('RedisFactory');
1489
+    }
1490
+
1491
+
1492
+    /**
1493
+     * Returns the current session
1494
+     *
1495
+     * @return \OCP\IDBConnection
1496
+     */
1497
+    public function getDatabaseConnection() {
1498
+        return $this->query('DatabaseConnection');
1499
+    }
1500
+
1501
+    /**
1502
+     * Returns the activity manager
1503
+     *
1504
+     * @return \OCP\Activity\IManager
1505
+     */
1506
+    public function getActivityManager() {
1507
+        return $this->query('ActivityManager');
1508
+    }
1509
+
1510
+    /**
1511
+     * Returns an job list for controlling background jobs
1512
+     *
1513
+     * @return \OCP\BackgroundJob\IJobList
1514
+     */
1515
+    public function getJobList() {
1516
+        return $this->query('JobList');
1517
+    }
1518
+
1519
+    /**
1520
+     * Returns a logger instance
1521
+     *
1522
+     * @return \OCP\ILogger
1523
+     */
1524
+    public function getLogger() {
1525
+        return $this->query('Logger');
1526
+    }
1527
+
1528
+    /**
1529
+     * Returns a router for generating and matching urls
1530
+     *
1531
+     * @return \OCP\Route\IRouter
1532
+     */
1533
+    public function getRouter() {
1534
+        return $this->query('Router');
1535
+    }
1536
+
1537
+    /**
1538
+     * Returns a search instance
1539
+     *
1540
+     * @return \OCP\ISearch
1541
+     */
1542
+    public function getSearch() {
1543
+        return $this->query('Search');
1544
+    }
1545
+
1546
+    /**
1547
+     * Returns a SecureRandom instance
1548
+     *
1549
+     * @return \OCP\Security\ISecureRandom
1550
+     */
1551
+    public function getSecureRandom() {
1552
+        return $this->query('SecureRandom');
1553
+    }
1554
+
1555
+    /**
1556
+     * Returns a Crypto instance
1557
+     *
1558
+     * @return \OCP\Security\ICrypto
1559
+     */
1560
+    public function getCrypto() {
1561
+        return $this->query('Crypto');
1562
+    }
1563
+
1564
+    /**
1565
+     * Returns a Hasher instance
1566
+     *
1567
+     * @return \OCP\Security\IHasher
1568
+     */
1569
+    public function getHasher() {
1570
+        return $this->query('Hasher');
1571
+    }
1572
+
1573
+    /**
1574
+     * Returns a CredentialsManager instance
1575
+     *
1576
+     * @return \OCP\Security\ICredentialsManager
1577
+     */
1578
+    public function getCredentialsManager() {
1579
+        return $this->query('CredentialsManager');
1580
+    }
1581
+
1582
+    /**
1583
+     * Returns an instance of the HTTP helper class
1584
+     *
1585
+     * @deprecated Use getHTTPClientService()
1586
+     * @return \OC\HTTPHelper
1587
+     */
1588
+    public function getHTTPHelper() {
1589
+        return $this->query('HTTPHelper');
1590
+    }
1591
+
1592
+    /**
1593
+     * Get the certificate manager for the user
1594
+     *
1595
+     * @param string $userId (optional) if not specified the current loggedin user is used, use null to get the system certificate manager
1596
+     * @return \OCP\ICertificateManager | null if $uid is null and no user is logged in
1597
+     */
1598
+    public function getCertificateManager($userId = '') {
1599
+        if ($userId === '') {
1600
+            $userSession = $this->getUserSession();
1601
+            $user = $userSession->getUser();
1602
+            if (is_null($user)) {
1603
+                return null;
1604
+            }
1605
+            $userId = $user->getUID();
1606
+        }
1607
+        return new CertificateManager(
1608
+            $userId,
1609
+            new View(),
1610
+            $this->getConfig(),
1611
+            $this->getLogger(),
1612
+            $this->getSecureRandom()
1613
+        );
1614
+    }
1615
+
1616
+    /**
1617
+     * Returns an instance of the HTTP client service
1618
+     *
1619
+     * @return \OCP\Http\Client\IClientService
1620
+     */
1621
+    public function getHTTPClientService() {
1622
+        return $this->query('HttpClientService');
1623
+    }
1624
+
1625
+    /**
1626
+     * Create a new event source
1627
+     *
1628
+     * @return \OCP\IEventSource
1629
+     */
1630
+    public function createEventSource() {
1631
+        return new \OC_EventSource();
1632
+    }
1633
+
1634
+    /**
1635
+     * Get the active event logger
1636
+     *
1637
+     * The returned logger only logs data when debug mode is enabled
1638
+     *
1639
+     * @return \OCP\Diagnostics\IEventLogger
1640
+     */
1641
+    public function getEventLogger() {
1642
+        return $this->query('EventLogger');
1643
+    }
1644
+
1645
+    /**
1646
+     * Get the active query logger
1647
+     *
1648
+     * The returned logger only logs data when debug mode is enabled
1649
+     *
1650
+     * @return \OCP\Diagnostics\IQueryLogger
1651
+     */
1652
+    public function getQueryLogger() {
1653
+        return $this->query('QueryLogger');
1654
+    }
1655
+
1656
+    /**
1657
+     * Get the manager for temporary files and folders
1658
+     *
1659
+     * @return \OCP\ITempManager
1660
+     */
1661
+    public function getTempManager() {
1662
+        return $this->query('TempManager');
1663
+    }
1664
+
1665
+    /**
1666
+     * Get the app manager
1667
+     *
1668
+     * @return \OCP\App\IAppManager
1669
+     */
1670
+    public function getAppManager() {
1671
+        return $this->query('AppManager');
1672
+    }
1673
+
1674
+    /**
1675
+     * Creates a new mailer
1676
+     *
1677
+     * @return \OCP\Mail\IMailer
1678
+     */
1679
+    public function getMailer() {
1680
+        return $this->query('Mailer');
1681
+    }
1682
+
1683
+    /**
1684
+     * Get the webroot
1685
+     *
1686
+     * @return string
1687
+     */
1688
+    public function getWebRoot() {
1689
+        return $this->webRoot;
1690
+    }
1691
+
1692
+    /**
1693
+     * @return \OC\OCSClient
1694
+     */
1695
+    public function getOcsClient() {
1696
+        return $this->query('OcsClient');
1697
+    }
1698
+
1699
+    /**
1700
+     * @return \OCP\IDateTimeZone
1701
+     */
1702
+    public function getDateTimeZone() {
1703
+        return $this->query('DateTimeZone');
1704
+    }
1705
+
1706
+    /**
1707
+     * @return \OCP\IDateTimeFormatter
1708
+     */
1709
+    public function getDateTimeFormatter() {
1710
+        return $this->query('DateTimeFormatter');
1711
+    }
1712
+
1713
+    /**
1714
+     * @return \OCP\Files\Config\IMountProviderCollection
1715
+     */
1716
+    public function getMountProviderCollection() {
1717
+        return $this->query('MountConfigManager');
1718
+    }
1719
+
1720
+    /**
1721
+     * Get the IniWrapper
1722
+     *
1723
+     * @return IniGetWrapper
1724
+     */
1725
+    public function getIniWrapper() {
1726
+        return $this->query('IniWrapper');
1727
+    }
1728
+
1729
+    /**
1730
+     * @return \OCP\Command\IBus
1731
+     */
1732
+    public function getCommandBus() {
1733
+        return $this->query('AsyncCommandBus');
1734
+    }
1735
+
1736
+    /**
1737
+     * Get the trusted domain helper
1738
+     *
1739
+     * @return TrustedDomainHelper
1740
+     */
1741
+    public function getTrustedDomainHelper() {
1742
+        return $this->query('TrustedDomainHelper');
1743
+    }
1744
+
1745
+    /**
1746
+     * Get the locking provider
1747
+     *
1748
+     * @return \OCP\Lock\ILockingProvider
1749
+     * @since 8.1.0
1750
+     */
1751
+    public function getLockingProvider() {
1752
+        return $this->query('LockingProvider');
1753
+    }
1754
+
1755
+    /**
1756
+     * @return \OCP\Files\Mount\IMountManager
1757
+     **/
1758
+    function getMountManager() {
1759
+        return $this->query('MountManager');
1760
+    }
1761
+
1762
+    /** @return \OCP\Files\Config\IUserMountCache */
1763
+    function getUserMountCache() {
1764
+        return $this->query('UserMountCache');
1765
+    }
1766
+
1767
+    /**
1768
+     * Get the MimeTypeDetector
1769
+     *
1770
+     * @return \OCP\Files\IMimeTypeDetector
1771
+     */
1772
+    public function getMimeTypeDetector() {
1773
+        return $this->query('MimeTypeDetector');
1774
+    }
1775
+
1776
+    /**
1777
+     * Get the MimeTypeLoader
1778
+     *
1779
+     * @return \OCP\Files\IMimeTypeLoader
1780
+     */
1781
+    public function getMimeTypeLoader() {
1782
+        return $this->query('MimeTypeLoader');
1783
+    }
1784
+
1785
+    /**
1786
+     * Get the manager of all the capabilities
1787
+     *
1788
+     * @return \OC\CapabilitiesManager
1789
+     */
1790
+    public function getCapabilitiesManager() {
1791
+        return $this->query('CapabilitiesManager');
1792
+    }
1793
+
1794
+    /**
1795
+     * Get the EventDispatcher
1796
+     *
1797
+     * @return EventDispatcherInterface
1798
+     * @since 8.2.0
1799
+     */
1800
+    public function getEventDispatcher() {
1801
+        return $this->query('EventDispatcher');
1802
+    }
1803
+
1804
+    /**
1805
+     * Get the Notification Manager
1806
+     *
1807
+     * @return \OCP\Notification\IManager
1808
+     * @since 8.2.0
1809
+     */
1810
+    public function getNotificationManager() {
1811
+        return $this->query('NotificationManager');
1812
+    }
1813
+
1814
+    /**
1815
+     * @return \OCP\Comments\ICommentsManager
1816
+     */
1817
+    public function getCommentsManager() {
1818
+        return $this->query('CommentsManager');
1819
+    }
1820
+
1821
+    /**
1822
+     * @return \OCA\Theming\ThemingDefaults
1823
+     */
1824
+    public function getThemingDefaults() {
1825
+        return $this->query('ThemingDefaults');
1826
+    }
1827
+
1828
+    /**
1829
+     * @return \OC\IntegrityCheck\Checker
1830
+     */
1831
+    public function getIntegrityCodeChecker() {
1832
+        return $this->query('IntegrityCodeChecker');
1833
+    }
1834
+
1835
+    /**
1836
+     * @return \OC\Session\CryptoWrapper
1837
+     */
1838
+    public function getSessionCryptoWrapper() {
1839
+        return $this->query('CryptoWrapper');
1840
+    }
1841
+
1842
+    /**
1843
+     * @return CsrfTokenManager
1844
+     */
1845
+    public function getCsrfTokenManager() {
1846
+        return $this->query('CsrfTokenManager');
1847
+    }
1848
+
1849
+    /**
1850
+     * @return Throttler
1851
+     */
1852
+    public function getBruteForceThrottler() {
1853
+        return $this->query('Throttler');
1854
+    }
1855
+
1856
+    /**
1857
+     * @return IContentSecurityPolicyManager
1858
+     */
1859
+    public function getContentSecurityPolicyManager() {
1860
+        return $this->query('ContentSecurityPolicyManager');
1861
+    }
1862
+
1863
+    /**
1864
+     * @return ContentSecurityPolicyNonceManager
1865
+     */
1866
+    public function getContentSecurityPolicyNonceManager() {
1867
+        return $this->query('ContentSecurityPolicyNonceManager');
1868
+    }
1869
+
1870
+    /**
1871
+     * Not a public API as of 8.2, wait for 9.0
1872
+     *
1873
+     * @return \OCA\Files_External\Service\BackendService
1874
+     */
1875
+    public function getStoragesBackendService() {
1876
+        return $this->query('OCA\\Files_External\\Service\\BackendService');
1877
+    }
1878
+
1879
+    /**
1880
+     * Not a public API as of 8.2, wait for 9.0
1881
+     *
1882
+     * @return \OCA\Files_External\Service\GlobalStoragesService
1883
+     */
1884
+    public function getGlobalStoragesService() {
1885
+        return $this->query('OCA\\Files_External\\Service\\GlobalStoragesService');
1886
+    }
1887
+
1888
+    /**
1889
+     * Not a public API as of 8.2, wait for 9.0
1890
+     *
1891
+     * @return \OCA\Files_External\Service\UserGlobalStoragesService
1892
+     */
1893
+    public function getUserGlobalStoragesService() {
1894
+        return $this->query('OCA\\Files_External\\Service\\UserGlobalStoragesService');
1895
+    }
1896
+
1897
+    /**
1898
+     * Not a public API as of 8.2, wait for 9.0
1899
+     *
1900
+     * @return \OCA\Files_External\Service\UserStoragesService
1901
+     */
1902
+    public function getUserStoragesService() {
1903
+        return $this->query('OCA\\Files_External\\Service\\UserStoragesService');
1904
+    }
1905
+
1906
+    /**
1907
+     * @return \OCP\Share\IManager
1908
+     */
1909
+    public function getShareManager() {
1910
+        return $this->query('ShareManager');
1911
+    }
1912
+
1913
+    /**
1914
+     * @return \OCP\Collaboration\Collaborators\ISearch
1915
+     */
1916
+    public function getCollaboratorSearch() {
1917
+        return $this->query('CollaboratorSearch');
1918
+    }
1919
+
1920
+    /**
1921
+     * @return \OCP\Collaboration\AutoComplete\IManager
1922
+     */
1923
+    public function getAutoCompleteManager(){
1924
+        return $this->query(IManager::class);
1925
+    }
1926
+
1927
+    /**
1928
+     * Returns the LDAP Provider
1929
+     *
1930
+     * @return \OCP\LDAP\ILDAPProvider
1931
+     */
1932
+    public function getLDAPProvider() {
1933
+        return $this->query('LDAPProvider');
1934
+    }
1935
+
1936
+    /**
1937
+     * @return \OCP\Settings\IManager
1938
+     */
1939
+    public function getSettingsManager() {
1940
+        return $this->query('SettingsManager');
1941
+    }
1942
+
1943
+    /**
1944
+     * @return \OCP\Files\IAppData
1945
+     */
1946
+    public function getAppDataDir($app) {
1947
+        /** @var \OC\Files\AppData\Factory $factory */
1948
+        $factory = $this->query(\OC\Files\AppData\Factory::class);
1949
+        return $factory->get($app);
1950
+    }
1951
+
1952
+    /**
1953
+     * @return \OCP\Lockdown\ILockdownManager
1954
+     */
1955
+    public function getLockdownManager() {
1956
+        return $this->query('LockdownManager');
1957
+    }
1958
+
1959
+    /**
1960
+     * @return \OCP\Federation\ICloudIdManager
1961
+     */
1962
+    public function getCloudIdManager() {
1963
+        return $this->query(ICloudIdManager::class);
1964
+    }
1965
+
1966
+    /**
1967
+     * @return \OCP\Remote\Api\IApiFactory
1968
+     */
1969
+    public function getRemoteApiFactory() {
1970
+        return $this->query(IApiFactory::class);
1971
+    }
1972
+
1973
+    /**
1974
+     * @return \OCP\Remote\IInstanceFactory
1975
+     */
1976
+    public function getRemoteInstanceFactory() {
1977
+        return $this->query(IInstanceFactory::class);
1978
+    }
1979 1979
 }
Please login to merge, or discard this patch.
Spacing   +114 added lines, -114 removed lines patch added patch discarded remove patch
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
 		parent::__construct();
158 158
 		$this->webRoot = $webRoot;
159 159
 
160
-		$this->registerService(\OCP\IServerContainer::class, function (IServerContainer $c) {
160
+		$this->registerService(\OCP\IServerContainer::class, function(IServerContainer $c) {
161 161
 			return $c;
162 162
 		});
163 163
 
@@ -170,7 +170,7 @@  discard block
 block discarded – undo
170 170
 		$this->registerAlias(IActionFactory::class, ActionFactory::class);
171 171
 
172 172
 
173
-		$this->registerService(\OCP\IPreview::class, function (Server $c) {
173
+		$this->registerService(\OCP\IPreview::class, function(Server $c) {
174 174
 			return new PreviewManager(
175 175
 				$c->getConfig(),
176 176
 				$c->getRootFolder(),
@@ -181,13 +181,13 @@  discard block
 block discarded – undo
181 181
 		});
182 182
 		$this->registerAlias('PreviewManager', \OCP\IPreview::class);
183 183
 
184
-		$this->registerService(\OC\Preview\Watcher::class, function (Server $c) {
184
+		$this->registerService(\OC\Preview\Watcher::class, function(Server $c) {
185 185
 			return new \OC\Preview\Watcher(
186 186
 				$c->getAppDataDir('preview')
187 187
 			);
188 188
 		});
189 189
 
190
-		$this->registerService('EncryptionManager', function (Server $c) {
190
+		$this->registerService('EncryptionManager', function(Server $c) {
191 191
 			$view = new View();
192 192
 			$util = new Encryption\Util(
193 193
 				$view,
@@ -205,7 +205,7 @@  discard block
 block discarded – undo
205 205
 			);
206 206
 		});
207 207
 
208
-		$this->registerService('EncryptionFileHelper', function (Server $c) {
208
+		$this->registerService('EncryptionFileHelper', function(Server $c) {
209 209
 			$util = new Encryption\Util(
210 210
 				new View(),
211 211
 				$c->getUserManager(),
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
 			);
220 220
 		});
221 221
 
222
-		$this->registerService('EncryptionKeyStorage', function (Server $c) {
222
+		$this->registerService('EncryptionKeyStorage', function(Server $c) {
223 223
 			$view = new View();
224 224
 			$util = new Encryption\Util(
225 225
 				$view,
@@ -230,30 +230,30 @@  discard block
 block discarded – undo
230 230
 
231 231
 			return new Encryption\Keys\Storage($view, $util);
232 232
 		});
233
-		$this->registerService('TagMapper', function (Server $c) {
233
+		$this->registerService('TagMapper', function(Server $c) {
234 234
 			return new TagMapper($c->getDatabaseConnection());
235 235
 		});
236 236
 
237
-		$this->registerService(\OCP\ITagManager::class, function (Server $c) {
237
+		$this->registerService(\OCP\ITagManager::class, function(Server $c) {
238 238
 			$tagMapper = $c->query('TagMapper');
239 239
 			return new TagManager($tagMapper, $c->getUserSession());
240 240
 		});
241 241
 		$this->registerAlias('TagManager', \OCP\ITagManager::class);
242 242
 
243
-		$this->registerService('SystemTagManagerFactory', function (Server $c) {
243
+		$this->registerService('SystemTagManagerFactory', function(Server $c) {
244 244
 			$config = $c->getConfig();
245 245
 			$factoryClass = $config->getSystemValue('systemtags.managerFactory', '\OC\SystemTag\ManagerFactory');
246 246
 			return new $factoryClass($this);
247 247
 		});
248
-		$this->registerService(\OCP\SystemTag\ISystemTagManager::class, function (Server $c) {
248
+		$this->registerService(\OCP\SystemTag\ISystemTagManager::class, function(Server $c) {
249 249
 			return $c->query('SystemTagManagerFactory')->getManager();
250 250
 		});
251 251
 		$this->registerAlias('SystemTagManager', \OCP\SystemTag\ISystemTagManager::class);
252 252
 
253
-		$this->registerService(\OCP\SystemTag\ISystemTagObjectMapper::class, function (Server $c) {
253
+		$this->registerService(\OCP\SystemTag\ISystemTagObjectMapper::class, function(Server $c) {
254 254
 			return $c->query('SystemTagManagerFactory')->getObjectMapper();
255 255
 		});
256
-		$this->registerService('RootFolder', function (Server $c) {
256
+		$this->registerService('RootFolder', function(Server $c) {
257 257
 			$manager = \OC\Files\Filesystem::getMountManager(null);
258 258
 			$view = new View();
259 259
 			$root = new Root(
@@ -274,38 +274,38 @@  discard block
 block discarded – undo
274 274
 		});
275 275
 		$this->registerAlias('SystemTagObjectMapper', \OCP\SystemTag\ISystemTagObjectMapper::class);
276 276
 
277
-		$this->registerService(\OCP\Files\IRootFolder::class, function (Server $c) {
278
-			return new LazyRoot(function () use ($c) {
277
+		$this->registerService(\OCP\Files\IRootFolder::class, function(Server $c) {
278
+			return new LazyRoot(function() use ($c) {
279 279
 				return $c->query('RootFolder');
280 280
 			});
281 281
 		});
282 282
 		$this->registerAlias('LazyRootFolder', \OCP\Files\IRootFolder::class);
283 283
 
284
-		$this->registerService(\OC\User\Manager::class, function (Server $c) {
284
+		$this->registerService(\OC\User\Manager::class, function(Server $c) {
285 285
 			$config = $c->getConfig();
286 286
 			return new \OC\User\Manager($config);
287 287
 		});
288 288
 		$this->registerAlias('UserManager', \OC\User\Manager::class);
289 289
 		$this->registerAlias(\OCP\IUserManager::class, \OC\User\Manager::class);
290 290
 
291
-		$this->registerService(\OCP\IGroupManager::class, function (Server $c) {
291
+		$this->registerService(\OCP\IGroupManager::class, function(Server $c) {
292 292
 			$groupManager = new \OC\Group\Manager($this->getUserManager(), $this->getLogger());
293
-			$groupManager->listen('\OC\Group', 'preCreate', function ($gid) {
293
+			$groupManager->listen('\OC\Group', 'preCreate', function($gid) {
294 294
 				\OC_Hook::emit('OC_Group', 'pre_createGroup', array('run' => true, 'gid' => $gid));
295 295
 			});
296
-			$groupManager->listen('\OC\Group', 'postCreate', function (\OC\Group\Group $gid) {
296
+			$groupManager->listen('\OC\Group', 'postCreate', function(\OC\Group\Group $gid) {
297 297
 				\OC_Hook::emit('OC_User', 'post_createGroup', array('gid' => $gid->getGID()));
298 298
 			});
299
-			$groupManager->listen('\OC\Group', 'preDelete', function (\OC\Group\Group $group) {
299
+			$groupManager->listen('\OC\Group', 'preDelete', function(\OC\Group\Group $group) {
300 300
 				\OC_Hook::emit('OC_Group', 'pre_deleteGroup', array('run' => true, 'gid' => $group->getGID()));
301 301
 			});
302
-			$groupManager->listen('\OC\Group', 'postDelete', function (\OC\Group\Group $group) {
302
+			$groupManager->listen('\OC\Group', 'postDelete', function(\OC\Group\Group $group) {
303 303
 				\OC_Hook::emit('OC_User', 'post_deleteGroup', array('gid' => $group->getGID()));
304 304
 			});
305
-			$groupManager->listen('\OC\Group', 'preAddUser', function (\OC\Group\Group $group, \OC\User\User $user) {
305
+			$groupManager->listen('\OC\Group', 'preAddUser', function(\OC\Group\Group $group, \OC\User\User $user) {
306 306
 				\OC_Hook::emit('OC_Group', 'pre_addToGroup', array('run' => true, 'uid' => $user->getUID(), 'gid' => $group->getGID()));
307 307
 			});
308
-			$groupManager->listen('\OC\Group', 'postAddUser', function (\OC\Group\Group $group, \OC\User\User $user) {
308
+			$groupManager->listen('\OC\Group', 'postAddUser', function(\OC\Group\Group $group, \OC\User\User $user) {
309 309
 				\OC_Hook::emit('OC_Group', 'post_addToGroup', array('uid' => $user->getUID(), 'gid' => $group->getGID()));
310 310
 				//Minimal fix to keep it backward compatible TODO: clean up all the GroupManager hooks
311 311
 				\OC_Hook::emit('OC_User', 'post_addToGroup', array('uid' => $user->getUID(), 'gid' => $group->getGID()));
@@ -314,7 +314,7 @@  discard block
 block discarded – undo
314 314
 		});
315 315
 		$this->registerAlias('GroupManager', \OCP\IGroupManager::class);
316 316
 
317
-		$this->registerService(Store::class, function (Server $c) {
317
+		$this->registerService(Store::class, function(Server $c) {
318 318
 			$session = $c->getSession();
319 319
 			if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
320 320
 				$tokenProvider = $c->query('OC\Authentication\Token\IProvider');
@@ -325,11 +325,11 @@  discard block
 block discarded – undo
325 325
 			return new Store($session, $logger, $tokenProvider);
326 326
 		});
327 327
 		$this->registerAlias(IStore::class, Store::class);
328
-		$this->registerService('OC\Authentication\Token\DefaultTokenMapper', function (Server $c) {
328
+		$this->registerService('OC\Authentication\Token\DefaultTokenMapper', function(Server $c) {
329 329
 			$dbConnection = $c->getDatabaseConnection();
330 330
 			return new Authentication\Token\DefaultTokenMapper($dbConnection);
331 331
 		});
332
-		$this->registerService('OC\Authentication\Token\DefaultTokenProvider', function (Server $c) {
332
+		$this->registerService('OC\Authentication\Token\DefaultTokenProvider', function(Server $c) {
333 333
 			$mapper = $c->query('OC\Authentication\Token\DefaultTokenMapper');
334 334
 			$crypto = $c->getCrypto();
335 335
 			$config = $c->getConfig();
@@ -339,7 +339,7 @@  discard block
 block discarded – undo
339 339
 		});
340 340
 		$this->registerAlias('OC\Authentication\Token\IProvider', 'OC\Authentication\Token\DefaultTokenProvider');
341 341
 
342
-		$this->registerService(\OCP\IUserSession::class, function (Server $c) {
342
+		$this->registerService(\OCP\IUserSession::class, function(Server $c) {
343 343
 			$manager = $c->getUserManager();
344 344
 			$session = new \OC\Session\Memory('');
345 345
 			$timeFactory = new TimeFactory();
@@ -363,45 +363,45 @@  discard block
 block discarded – undo
363 363
 				$c->getLockdownManager(),
364 364
 				$c->getLogger()
365 365
 			);
366
-			$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
366
+			$userSession->listen('\OC\User', 'preCreateUser', function($uid, $password) {
367 367
 				\OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password));
368 368
 			});
369
-			$userSession->listen('\OC\User', 'postCreateUser', function ($user, $password) {
369
+			$userSession->listen('\OC\User', 'postCreateUser', function($user, $password) {
370 370
 				/** @var $user \OC\User\User */
371 371
 				\OC_Hook::emit('OC_User', 'post_createUser', array('uid' => $user->getUID(), 'password' => $password));
372 372
 			});
373
-			$userSession->listen('\OC\User', 'preDelete', function ($user) use ($dispatcher) {
373
+			$userSession->listen('\OC\User', 'preDelete', function($user) use ($dispatcher) {
374 374
 				/** @var $user \OC\User\User */
375 375
 				\OC_Hook::emit('OC_User', 'pre_deleteUser', array('run' => true, 'uid' => $user->getUID()));
376 376
 				$dispatcher->dispatch('OCP\IUser::preDelete', new GenericEvent($user));
377 377
 			});
378
-			$userSession->listen('\OC\User', 'postDelete', function ($user) {
378
+			$userSession->listen('\OC\User', 'postDelete', function($user) {
379 379
 				/** @var $user \OC\User\User */
380 380
 				\OC_Hook::emit('OC_User', 'post_deleteUser', array('uid' => $user->getUID()));
381 381
 			});
382
-			$userSession->listen('\OC\User', 'preSetPassword', function ($user, $password, $recoveryPassword) {
382
+			$userSession->listen('\OC\User', 'preSetPassword', function($user, $password, $recoveryPassword) {
383 383
 				/** @var $user \OC\User\User */
384 384
 				\OC_Hook::emit('OC_User', 'pre_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
385 385
 			});
386
-			$userSession->listen('\OC\User', 'postSetPassword', function ($user, $password, $recoveryPassword) {
386
+			$userSession->listen('\OC\User', 'postSetPassword', function($user, $password, $recoveryPassword) {
387 387
 				/** @var $user \OC\User\User */
388 388
 				\OC_Hook::emit('OC_User', 'post_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
389 389
 			});
390
-			$userSession->listen('\OC\User', 'preLogin', function ($uid, $password) {
390
+			$userSession->listen('\OC\User', 'preLogin', function($uid, $password) {
391 391
 				\OC_Hook::emit('OC_User', 'pre_login', array('run' => true, 'uid' => $uid, 'password' => $password));
392 392
 			});
393
-			$userSession->listen('\OC\User', 'postLogin', function ($user, $password) {
393
+			$userSession->listen('\OC\User', 'postLogin', function($user, $password) {
394 394
 				/** @var $user \OC\User\User */
395 395
 				\OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password));
396 396
 			});
397
-			$userSession->listen('\OC\User', 'postRememberedLogin', function ($user, $password) {
397
+			$userSession->listen('\OC\User', 'postRememberedLogin', function($user, $password) {
398 398
 				/** @var $user \OC\User\User */
399 399
 				\OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password));
400 400
 			});
401
-			$userSession->listen('\OC\User', 'logout', function () {
401
+			$userSession->listen('\OC\User', 'logout', function() {
402 402
 				\OC_Hook::emit('OC_User', 'logout', array());
403 403
 			});
404
-			$userSession->listen('\OC\User', 'changeUser', function ($user, $feature, $value, $oldValue) use ($dispatcher) {
404
+			$userSession->listen('\OC\User', 'changeUser', function($user, $feature, $value, $oldValue) use ($dispatcher) {
405 405
 				/** @var $user \OC\User\User */
406 406
 				\OC_Hook::emit('OC_User', 'changeUser', array('run' => true, 'user' => $user, 'feature' => $feature, 'value' => $value, 'old_value' => $oldValue));
407 407
 				$dispatcher->dispatch('OCP\IUser::changeUser', new GenericEvent($user, ['feature' => $feature, 'oldValue' => $oldValue, 'value' => $value]));
@@ -410,7 +410,7 @@  discard block
 block discarded – undo
410 410
 		});
411 411
 		$this->registerAlias('UserSession', \OCP\IUserSession::class);
412 412
 
413
-		$this->registerService(\OC\Authentication\TwoFactorAuth\Manager::class, function (Server $c) {
413
+		$this->registerService(\OC\Authentication\TwoFactorAuth\Manager::class, function(Server $c) {
414 414
 			return new \OC\Authentication\TwoFactorAuth\Manager(
415 415
 				$c->getAppManager(),
416 416
 				$c->getSession(),
@@ -426,7 +426,7 @@  discard block
 block discarded – undo
426 426
 		$this->registerAlias(\OCP\INavigationManager::class, \OC\NavigationManager::class);
427 427
 		$this->registerAlias('NavigationManager', \OCP\INavigationManager::class);
428 428
 
429
-		$this->registerService(\OC\AllConfig::class, function (Server $c) {
429
+		$this->registerService(\OC\AllConfig::class, function(Server $c) {
430 430
 			return new \OC\AllConfig(
431 431
 				$c->getSystemConfig()
432 432
 			);
@@ -434,17 +434,17 @@  discard block
 block discarded – undo
434 434
 		$this->registerAlias('AllConfig', \OC\AllConfig::class);
435 435
 		$this->registerAlias(\OCP\IConfig::class, \OC\AllConfig::class);
436 436
 
437
-		$this->registerService('SystemConfig', function ($c) use ($config) {
437
+		$this->registerService('SystemConfig', function($c) use ($config) {
438 438
 			return new \OC\SystemConfig($config);
439 439
 		});
440 440
 
441
-		$this->registerService(\OC\AppConfig::class, function (Server $c) {
441
+		$this->registerService(\OC\AppConfig::class, function(Server $c) {
442 442
 			return new \OC\AppConfig($c->getDatabaseConnection());
443 443
 		});
444 444
 		$this->registerAlias('AppConfig', \OC\AppConfig::class);
445 445
 		$this->registerAlias(\OCP\IAppConfig::class, \OC\AppConfig::class);
446 446
 
447
-		$this->registerService(\OCP\L10N\IFactory::class, function (Server $c) {
447
+		$this->registerService(\OCP\L10N\IFactory::class, function(Server $c) {
448 448
 			return new \OC\L10N\Factory(
449 449
 				$c->getConfig(),
450 450
 				$c->getRequest(),
@@ -454,7 +454,7 @@  discard block
 block discarded – undo
454 454
 		});
455 455
 		$this->registerAlias('L10NFactory', \OCP\L10N\IFactory::class);
456 456
 
457
-		$this->registerService(\OCP\IURLGenerator::class, function (Server $c) {
457
+		$this->registerService(\OCP\IURLGenerator::class, function(Server $c) {
458 458
 			$config = $c->getConfig();
459 459
 			$cacheFactory = $c->getMemCacheFactory();
460 460
 			$request = $c->getRequest();
@@ -466,18 +466,18 @@  discard block
 block discarded – undo
466 466
 		});
467 467
 		$this->registerAlias('URLGenerator', \OCP\IURLGenerator::class);
468 468
 
469
-		$this->registerService('AppHelper', function ($c) {
469
+		$this->registerService('AppHelper', function($c) {
470 470
 			return new \OC\AppHelper();
471 471
 		});
472 472
 		$this->registerAlias('AppFetcher', AppFetcher::class);
473 473
 		$this->registerAlias('CategoryFetcher', CategoryFetcher::class);
474 474
 
475
-		$this->registerService(\OCP\ICache::class, function ($c) {
475
+		$this->registerService(\OCP\ICache::class, function($c) {
476 476
 			return new Cache\File();
477 477
 		});
478 478
 		$this->registerAlias('UserCache', \OCP\ICache::class);
479 479
 
480
-		$this->registerService(Factory::class, function (Server $c) {
480
+		$this->registerService(Factory::class, function(Server $c) {
481 481
 
482 482
 			$arrayCacheFactory = new \OC\Memcache\Factory('', $c->getLogger(),
483 483
 				'\\OC\\Memcache\\ArrayCache',
@@ -494,7 +494,7 @@  discard block
 block discarded – undo
494 494
 				$version = implode(',', $v);
495 495
 				$instanceId = \OC_Util::getInstanceId();
496 496
 				$path = \OC::$SERVERROOT;
497
-				$prefix = md5($instanceId . '-' . $version . '-' . $path . '-' . $urlGenerator->getBaseUrl());
497
+				$prefix = md5($instanceId.'-'.$version.'-'.$path.'-'.$urlGenerator->getBaseUrl());
498 498
 				return new \OC\Memcache\Factory($prefix, $c->getLogger(),
499 499
 					$config->getSystemValue('memcache.local', null),
500 500
 					$config->getSystemValue('memcache.distributed', null),
@@ -507,12 +507,12 @@  discard block
 block discarded – undo
507 507
 		$this->registerAlias('MemCacheFactory', Factory::class);
508 508
 		$this->registerAlias(ICacheFactory::class, Factory::class);
509 509
 
510
-		$this->registerService('RedisFactory', function (Server $c) {
510
+		$this->registerService('RedisFactory', function(Server $c) {
511 511
 			$systemConfig = $c->getSystemConfig();
512 512
 			return new RedisFactory($systemConfig);
513 513
 		});
514 514
 
515
-		$this->registerService(\OCP\Activity\IManager::class, function (Server $c) {
515
+		$this->registerService(\OCP\Activity\IManager::class, function(Server $c) {
516 516
 			return new \OC\Activity\Manager(
517 517
 				$c->getRequest(),
518 518
 				$c->getUserSession(),
@@ -522,14 +522,14 @@  discard block
 block discarded – undo
522 522
 		});
523 523
 		$this->registerAlias('ActivityManager', \OCP\Activity\IManager::class);
524 524
 
525
-		$this->registerService(\OCP\Activity\IEventMerger::class, function (Server $c) {
525
+		$this->registerService(\OCP\Activity\IEventMerger::class, function(Server $c) {
526 526
 			return new \OC\Activity\EventMerger(
527 527
 				$c->getL10N('lib')
528 528
 			);
529 529
 		});
530 530
 		$this->registerAlias(IValidator::class, Validator::class);
531 531
 
532
-		$this->registerService(\OCP\IAvatarManager::class, function (Server $c) {
532
+		$this->registerService(\OCP\IAvatarManager::class, function(Server $c) {
533 533
 			return new AvatarManager(
534 534
 				$c->query(\OC\User\Manager::class),
535 535
 				$c->getAppDataDir('avatar'),
@@ -542,7 +542,7 @@  discard block
 block discarded – undo
542 542
 
543 543
 		$this->registerAlias(\OCP\Support\CrashReport\IRegistry::class, \OC\Support\CrashReport\Registry::class);
544 544
 
545
-		$this->registerService(\OCP\ILogger::class, function (Server $c) {
545
+		$this->registerService(\OCP\ILogger::class, function(Server $c) {
546 546
 			$logType = $c->query('AllConfig')->getSystemValue('log_type', 'file');
547 547
 			$logger = Log::getLogClass($logType);
548 548
 			call_user_func(array($logger, 'init'));
@@ -553,7 +553,7 @@  discard block
 block discarded – undo
553 553
 		});
554 554
 		$this->registerAlias('Logger', \OCP\ILogger::class);
555 555
 
556
-		$this->registerService(\OCP\BackgroundJob\IJobList::class, function (Server $c) {
556
+		$this->registerService(\OCP\BackgroundJob\IJobList::class, function(Server $c) {
557 557
 			$config = $c->getConfig();
558 558
 			return new \OC\BackgroundJob\JobList(
559 559
 				$c->getDatabaseConnection(),
@@ -563,7 +563,7 @@  discard block
 block discarded – undo
563 563
 		});
564 564
 		$this->registerAlias('JobList', \OCP\BackgroundJob\IJobList::class);
565 565
 
566
-		$this->registerService(\OCP\Route\IRouter::class, function (Server $c) {
566
+		$this->registerService(\OCP\Route\IRouter::class, function(Server $c) {
567 567
 			$cacheFactory = $c->getMemCacheFactory();
568 568
 			$logger = $c->getLogger();
569 569
 			if ($cacheFactory->isAvailableLowLatency()) {
@@ -575,12 +575,12 @@  discard block
 block discarded – undo
575 575
 		});
576 576
 		$this->registerAlias('Router', \OCP\Route\IRouter::class);
577 577
 
578
-		$this->registerService(\OCP\ISearch::class, function ($c) {
578
+		$this->registerService(\OCP\ISearch::class, function($c) {
579 579
 			return new Search();
580 580
 		});
581 581
 		$this->registerAlias('Search', \OCP\ISearch::class);
582 582
 
583
-		$this->registerService(\OC\Security\RateLimiting\Limiter::class, function ($c) {
583
+		$this->registerService(\OC\Security\RateLimiting\Limiter::class, function($c) {
584 584
 			return new \OC\Security\RateLimiting\Limiter(
585 585
 				$this->getUserSession(),
586 586
 				$this->getRequest(),
@@ -588,34 +588,34 @@  discard block
 block discarded – undo
588 588
 				$c->query(\OC\Security\RateLimiting\Backend\IBackend::class)
589 589
 			);
590 590
 		});
591
-		$this->registerService(\OC\Security\RateLimiting\Backend\IBackend::class, function ($c) {
591
+		$this->registerService(\OC\Security\RateLimiting\Backend\IBackend::class, function($c) {
592 592
 			return new \OC\Security\RateLimiting\Backend\MemoryCache(
593 593
 				$this->getMemCacheFactory(),
594 594
 				new \OC\AppFramework\Utility\TimeFactory()
595 595
 			);
596 596
 		});
597 597
 
598
-		$this->registerService(\OCP\Security\ISecureRandom::class, function ($c) {
598
+		$this->registerService(\OCP\Security\ISecureRandom::class, function($c) {
599 599
 			return new SecureRandom();
600 600
 		});
601 601
 		$this->registerAlias('SecureRandom', \OCP\Security\ISecureRandom::class);
602 602
 
603
-		$this->registerService(\OCP\Security\ICrypto::class, function (Server $c) {
603
+		$this->registerService(\OCP\Security\ICrypto::class, function(Server $c) {
604 604
 			return new Crypto($c->getConfig(), $c->getSecureRandom());
605 605
 		});
606 606
 		$this->registerAlias('Crypto', \OCP\Security\ICrypto::class);
607 607
 
608
-		$this->registerService(\OCP\Security\IHasher::class, function (Server $c) {
608
+		$this->registerService(\OCP\Security\IHasher::class, function(Server $c) {
609 609
 			return new Hasher($c->getConfig());
610 610
 		});
611 611
 		$this->registerAlias('Hasher', \OCP\Security\IHasher::class);
612 612
 
613
-		$this->registerService(\OCP\Security\ICredentialsManager::class, function (Server $c) {
613
+		$this->registerService(\OCP\Security\ICredentialsManager::class, function(Server $c) {
614 614
 			return new CredentialsManager($c->getCrypto(), $c->getDatabaseConnection());
615 615
 		});
616 616
 		$this->registerAlias('CredentialsManager', \OCP\Security\ICredentialsManager::class);
617 617
 
618
-		$this->registerService(IDBConnection::class, function (Server $c) {
618
+		$this->registerService(IDBConnection::class, function(Server $c) {
619 619
 			$systemConfig = $c->getSystemConfig();
620 620
 			$factory = new \OC\DB\ConnectionFactory($systemConfig);
621 621
 			$type = $systemConfig->getValue('dbtype', 'sqlite');
@@ -629,7 +629,7 @@  discard block
 block discarded – undo
629 629
 		});
630 630
 		$this->registerAlias('DatabaseConnection', IDBConnection::class);
631 631
 
632
-		$this->registerService('HTTPHelper', function (Server $c) {
632
+		$this->registerService('HTTPHelper', function(Server $c) {
633 633
 			$config = $c->getConfig();
634 634
 			return new HTTPHelper(
635 635
 				$config,
@@ -637,7 +637,7 @@  discard block
 block discarded – undo
637 637
 			);
638 638
 		});
639 639
 
640
-		$this->registerService(\OCP\Http\Client\IClientService::class, function (Server $c) {
640
+		$this->registerService(\OCP\Http\Client\IClientService::class, function(Server $c) {
641 641
 			$user = \OC_User::getUser();
642 642
 			$uid = $user ? $user : null;
643 643
 			return new ClientService(
@@ -652,7 +652,7 @@  discard block
 block discarded – undo
652 652
 			);
653 653
 		});
654 654
 		$this->registerAlias('HttpClientService', \OCP\Http\Client\IClientService::class);
655
-		$this->registerService(\OCP\Diagnostics\IEventLogger::class, function (Server $c) {
655
+		$this->registerService(\OCP\Diagnostics\IEventLogger::class, function(Server $c) {
656 656
 			$eventLogger = new EventLogger();
657 657
 			if ($c->getSystemConfig()->getValue('debug', false)) {
658 658
 				// In debug mode, module is being activated by default
@@ -662,7 +662,7 @@  discard block
 block discarded – undo
662 662
 		});
663 663
 		$this->registerAlias('EventLogger', \OCP\Diagnostics\IEventLogger::class);
664 664
 
665
-		$this->registerService(\OCP\Diagnostics\IQueryLogger::class, function (Server $c) {
665
+		$this->registerService(\OCP\Diagnostics\IQueryLogger::class, function(Server $c) {
666 666
 			$queryLogger = new QueryLogger();
667 667
 			if ($c->getSystemConfig()->getValue('debug', false)) {
668 668
 				// In debug mode, module is being activated by default
@@ -672,7 +672,7 @@  discard block
 block discarded – undo
672 672
 		});
673 673
 		$this->registerAlias('QueryLogger', \OCP\Diagnostics\IQueryLogger::class);
674 674
 
675
-		$this->registerService(TempManager::class, function (Server $c) {
675
+		$this->registerService(TempManager::class, function(Server $c) {
676 676
 			return new TempManager(
677 677
 				$c->getLogger(),
678 678
 				$c->getConfig()
@@ -681,7 +681,7 @@  discard block
 block discarded – undo
681 681
 		$this->registerAlias('TempManager', TempManager::class);
682 682
 		$this->registerAlias(ITempManager::class, TempManager::class);
683 683
 
684
-		$this->registerService(AppManager::class, function (Server $c) {
684
+		$this->registerService(AppManager::class, function(Server $c) {
685 685
 			return new \OC\App\AppManager(
686 686
 				$c->getUserSession(),
687 687
 				$c->query(\OC\AppConfig::class),
@@ -693,7 +693,7 @@  discard block
 block discarded – undo
693 693
 		$this->registerAlias('AppManager', AppManager::class);
694 694
 		$this->registerAlias(IAppManager::class, AppManager::class);
695 695
 
696
-		$this->registerService(\OCP\IDateTimeZone::class, function (Server $c) {
696
+		$this->registerService(\OCP\IDateTimeZone::class, function(Server $c) {
697 697
 			return new DateTimeZone(
698 698
 				$c->getConfig(),
699 699
 				$c->getSession()
@@ -701,7 +701,7 @@  discard block
 block discarded – undo
701 701
 		});
702 702
 		$this->registerAlias('DateTimeZone', \OCP\IDateTimeZone::class);
703 703
 
704
-		$this->registerService(\OCP\IDateTimeFormatter::class, function (Server $c) {
704
+		$this->registerService(\OCP\IDateTimeFormatter::class, function(Server $c) {
705 705
 			$language = $c->getConfig()->getUserValue($c->getSession()->get('user_id'), 'core', 'lang', null);
706 706
 
707 707
 			return new DateTimeFormatter(
@@ -711,7 +711,7 @@  discard block
 block discarded – undo
711 711
 		});
712 712
 		$this->registerAlias('DateTimeFormatter', \OCP\IDateTimeFormatter::class);
713 713
 
714
-		$this->registerService(\OCP\Files\Config\IUserMountCache::class, function (Server $c) {
714
+		$this->registerService(\OCP\Files\Config\IUserMountCache::class, function(Server $c) {
715 715
 			$mountCache = new UserMountCache($c->getDatabaseConnection(), $c->getUserManager(), $c->getLogger());
716 716
 			$listener = new UserMountCacheListener($mountCache);
717 717
 			$listener->listen($c->getUserManager());
@@ -719,7 +719,7 @@  discard block
 block discarded – undo
719 719
 		});
720 720
 		$this->registerAlias('UserMountCache', \OCP\Files\Config\IUserMountCache::class);
721 721
 
722
-		$this->registerService(\OCP\Files\Config\IMountProviderCollection::class, function (Server $c) {
722
+		$this->registerService(\OCP\Files\Config\IMountProviderCollection::class, function(Server $c) {
723 723
 			$loader = \OC\Files\Filesystem::getLoader();
724 724
 			$mountCache = $c->query('UserMountCache');
725 725
 			$manager = new \OC\Files\Config\MountProviderCollection($loader, $mountCache);
@@ -735,10 +735,10 @@  discard block
 block discarded – undo
735 735
 		});
736 736
 		$this->registerAlias('MountConfigManager', \OCP\Files\Config\IMountProviderCollection::class);
737 737
 
738
-		$this->registerService('IniWrapper', function ($c) {
738
+		$this->registerService('IniWrapper', function($c) {
739 739
 			return new IniGetWrapper();
740 740
 		});
741
-		$this->registerService('AsyncCommandBus', function (Server $c) {
741
+		$this->registerService('AsyncCommandBus', function(Server $c) {
742 742
 			$busClass = $c->getConfig()->getSystemValue('commandbus');
743 743
 			if ($busClass) {
744 744
 				list($app, $class) = explode('::', $busClass, 2);
@@ -753,10 +753,10 @@  discard block
 block discarded – undo
753 753
 				return new CronBus($jobList);
754 754
 			}
755 755
 		});
756
-		$this->registerService('TrustedDomainHelper', function ($c) {
756
+		$this->registerService('TrustedDomainHelper', function($c) {
757 757
 			return new TrustedDomainHelper($this->getConfig());
758 758
 		});
759
-		$this->registerService('Throttler', function (Server $c) {
759
+		$this->registerService('Throttler', function(Server $c) {
760 760
 			return new Throttler(
761 761
 				$c->getDatabaseConnection(),
762 762
 				new TimeFactory(),
@@ -764,7 +764,7 @@  discard block
 block discarded – undo
764 764
 				$c->getConfig()
765 765
 			);
766 766
 		});
767
-		$this->registerService('IntegrityCodeChecker', function (Server $c) {
767
+		$this->registerService('IntegrityCodeChecker', function(Server $c) {
768 768
 			// IConfig and IAppManager requires a working database. This code
769 769
 			// might however be called when ownCloud is not yet setup.
770 770
 			if (\OC::$server->getSystemConfig()->getValue('installed', false)) {
@@ -785,7 +785,7 @@  discard block
 block discarded – undo
785 785
 				$c->getTempManager()
786 786
 			);
787 787
 		});
788
-		$this->registerService(\OCP\IRequest::class, function ($c) {
788
+		$this->registerService(\OCP\IRequest::class, function($c) {
789 789
 			if (isset($this['urlParams'])) {
790 790
 				$urlParams = $this['urlParams'];
791 791
 			} else {
@@ -821,7 +821,7 @@  discard block
 block discarded – undo
821 821
 		});
822 822
 		$this->registerAlias('Request', \OCP\IRequest::class);
823 823
 
824
-		$this->registerService(\OCP\Mail\IMailer::class, function (Server $c) {
824
+		$this->registerService(\OCP\Mail\IMailer::class, function(Server $c) {
825 825
 			return new Mailer(
826 826
 				$c->getConfig(),
827 827
 				$c->getLogger(),
@@ -832,7 +832,7 @@  discard block
 block discarded – undo
832 832
 		});
833 833
 		$this->registerAlias('Mailer', \OCP\Mail\IMailer::class);
834 834
 
835
-		$this->registerService('LDAPProvider', function (Server $c) {
835
+		$this->registerService('LDAPProvider', function(Server $c) {
836 836
 			$config = $c->getConfig();
837 837
 			$factoryClass = $config->getSystemValue('ldapProviderFactory', null);
838 838
 			if (is_null($factoryClass)) {
@@ -842,7 +842,7 @@  discard block
 block discarded – undo
842 842
 			$factory = new $factoryClass($this);
843 843
 			return $factory->getLDAPProvider();
844 844
 		});
845
-		$this->registerService(ILockingProvider::class, function (Server $c) {
845
+		$this->registerService(ILockingProvider::class, function(Server $c) {
846 846
 			$ini = $c->getIniWrapper();
847 847
 			$config = $c->getConfig();
848 848
 			$ttl = $config->getSystemValue('filelocking.ttl', max(3600, $ini->getNumeric('max_execution_time')));
@@ -859,49 +859,49 @@  discard block
 block discarded – undo
859 859
 		});
860 860
 		$this->registerAlias('LockingProvider', ILockingProvider::class);
861 861
 
862
-		$this->registerService(\OCP\Files\Mount\IMountManager::class, function () {
862
+		$this->registerService(\OCP\Files\Mount\IMountManager::class, function() {
863 863
 			return new \OC\Files\Mount\Manager();
864 864
 		});
865 865
 		$this->registerAlias('MountManager', \OCP\Files\Mount\IMountManager::class);
866 866
 
867
-		$this->registerService(\OCP\Files\IMimeTypeDetector::class, function (Server $c) {
867
+		$this->registerService(\OCP\Files\IMimeTypeDetector::class, function(Server $c) {
868 868
 			return new \OC\Files\Type\Detection(
869 869
 				$c->getURLGenerator(),
870 870
 				\OC::$configDir,
871
-				\OC::$SERVERROOT . '/resources/config/'
871
+				\OC::$SERVERROOT.'/resources/config/'
872 872
 			);
873 873
 		});
874 874
 		$this->registerAlias('MimeTypeDetector', \OCP\Files\IMimeTypeDetector::class);
875 875
 
876
-		$this->registerService(\OCP\Files\IMimeTypeLoader::class, function (Server $c) {
876
+		$this->registerService(\OCP\Files\IMimeTypeLoader::class, function(Server $c) {
877 877
 			return new \OC\Files\Type\Loader(
878 878
 				$c->getDatabaseConnection()
879 879
 			);
880 880
 		});
881 881
 		$this->registerAlias('MimeTypeLoader', \OCP\Files\IMimeTypeLoader::class);
882
-		$this->registerService(BundleFetcher::class, function () {
882
+		$this->registerService(BundleFetcher::class, function() {
883 883
 			return new BundleFetcher($this->getL10N('lib'));
884 884
 		});
885
-		$this->registerService(\OCP\Notification\IManager::class, function (Server $c) {
885
+		$this->registerService(\OCP\Notification\IManager::class, function(Server $c) {
886 886
 			return new Manager(
887 887
 				$c->query(IValidator::class)
888 888
 			);
889 889
 		});
890 890
 		$this->registerAlias('NotificationManager', \OCP\Notification\IManager::class);
891 891
 
892
-		$this->registerService(\OC\CapabilitiesManager::class, function (Server $c) {
892
+		$this->registerService(\OC\CapabilitiesManager::class, function(Server $c) {
893 893
 			$manager = new \OC\CapabilitiesManager($c->getLogger());
894
-			$manager->registerCapability(function () use ($c) {
894
+			$manager->registerCapability(function() use ($c) {
895 895
 				return new \OC\OCS\CoreCapabilities($c->getConfig());
896 896
 			});
897
-			$manager->registerCapability(function () use ($c) {
897
+			$manager->registerCapability(function() use ($c) {
898 898
 				return $c->query(\OC\Security\Bruteforce\Capabilities::class);
899 899
 			});
900 900
 			return $manager;
901 901
 		});
902 902
 		$this->registerAlias('CapabilitiesManager', \OC\CapabilitiesManager::class);
903 903
 
904
-		$this->registerService(\OCP\Comments\ICommentsManager::class, function (Server $c) {
904
+		$this->registerService(\OCP\Comments\ICommentsManager::class, function(Server $c) {
905 905
 			$config = $c->getConfig();
906 906
 			$factoryClass = $config->getSystemValue('comments.managerFactory', '\OC\Comments\ManagerFactory');
907 907
 			/** @var \OCP\Comments\ICommentsManagerFactory $factory */
@@ -911,7 +911,7 @@  discard block
 block discarded – undo
911 911
 			$manager->registerDisplayNameResolver('user', function($id) use ($c) {
912 912
 				$manager = $c->getUserManager();
913 913
 				$user = $manager->get($id);
914
-				if(is_null($user)) {
914
+				if (is_null($user)) {
915 915
 					$l = $c->getL10N('core');
916 916
 					$displayName = $l->t('Unknown user');
917 917
 				} else {
@@ -924,7 +924,7 @@  discard block
 block discarded – undo
924 924
 		});
925 925
 		$this->registerAlias('CommentsManager', \OCP\Comments\ICommentsManager::class);
926 926
 
927
-		$this->registerService('ThemingDefaults', function (Server $c) {
927
+		$this->registerService('ThemingDefaults', function(Server $c) {
928 928
 			/*
929 929
 			 * Dark magic for autoloader.
930 930
 			 * If we do a class_exists it will try to load the class which will
@@ -951,7 +951,7 @@  discard block
 block discarded – undo
951 951
 			}
952 952
 			return new \OC_Defaults();
953 953
 		});
954
-		$this->registerService(SCSSCacher::class, function (Server $c) {
954
+		$this->registerService(SCSSCacher::class, function(Server $c) {
955 955
 			/** @var Factory $cacheFactory */
956 956
 			$cacheFactory = $c->query(Factory::class);
957 957
 			return new SCSSCacher(
@@ -964,13 +964,13 @@  discard block
 block discarded – undo
964 964
 				$cacheFactory->createDistributed('SCSS')
965 965
 			);
966 966
 		});
967
-		$this->registerService(EventDispatcher::class, function () {
967
+		$this->registerService(EventDispatcher::class, function() {
968 968
 			return new EventDispatcher();
969 969
 		});
970 970
 		$this->registerAlias('EventDispatcher', EventDispatcher::class);
971 971
 		$this->registerAlias(EventDispatcherInterface::class, EventDispatcher::class);
972 972
 
973
-		$this->registerService('CryptoWrapper', function (Server $c) {
973
+		$this->registerService('CryptoWrapper', function(Server $c) {
974 974
 			// FIXME: Instantiiated here due to cyclic dependency
975 975
 			$request = new Request(
976 976
 				[
@@ -995,7 +995,7 @@  discard block
 block discarded – undo
995 995
 				$request
996 996
 			);
997 997
 		});
998
-		$this->registerService('CsrfTokenManager', function (Server $c) {
998
+		$this->registerService('CsrfTokenManager', function(Server $c) {
999 999
 			$tokenGenerator = new CsrfTokenGenerator($c->getSecureRandom());
1000 1000
 
1001 1001
 			return new CsrfTokenManager(
@@ -1003,22 +1003,22 @@  discard block
 block discarded – undo
1003 1003
 				$c->query(SessionStorage::class)
1004 1004
 			);
1005 1005
 		});
1006
-		$this->registerService(SessionStorage::class, function (Server $c) {
1006
+		$this->registerService(SessionStorage::class, function(Server $c) {
1007 1007
 			return new SessionStorage($c->getSession());
1008 1008
 		});
1009
-		$this->registerService(\OCP\Security\IContentSecurityPolicyManager::class, function (Server $c) {
1009
+		$this->registerService(\OCP\Security\IContentSecurityPolicyManager::class, function(Server $c) {
1010 1010
 			return new ContentSecurityPolicyManager();
1011 1011
 		});
1012 1012
 		$this->registerAlias('ContentSecurityPolicyManager', \OCP\Security\IContentSecurityPolicyManager::class);
1013 1013
 
1014
-		$this->registerService('ContentSecurityPolicyNonceManager', function (Server $c) {
1014
+		$this->registerService('ContentSecurityPolicyNonceManager', function(Server $c) {
1015 1015
 			return new ContentSecurityPolicyNonceManager(
1016 1016
 				$c->getCsrfTokenManager(),
1017 1017
 				$c->getRequest()
1018 1018
 			);
1019 1019
 		});
1020 1020
 
1021
-		$this->registerService(\OCP\Share\IManager::class, function (Server $c) {
1021
+		$this->registerService(\OCP\Share\IManager::class, function(Server $c) {
1022 1022
 			$config = $c->getConfig();
1023 1023
 			$factoryClass = $config->getSystemValue('sharing.managerFactory', '\OC\Share20\ProviderFactory');
1024 1024
 			/** @var \OCP\Share\IProviderFactory $factory */
@@ -1061,7 +1061,7 @@  discard block
 block discarded – undo
1061 1061
 
1062 1062
 		$this->registerAlias(\OCP\Collaboration\AutoComplete\IManager::class, \OC\Collaboration\AutoComplete\Manager::class);
1063 1063
 
1064
-		$this->registerService('SettingsManager', function (Server $c) {
1064
+		$this->registerService('SettingsManager', function(Server $c) {
1065 1065
 			$manager = new \OC\Settings\Manager(
1066 1066
 				$c->getLogger(),
1067 1067
 				$c->getDatabaseConnection(),
@@ -1081,24 +1081,24 @@  discard block
 block discarded – undo
1081 1081
 			);
1082 1082
 			return $manager;
1083 1083
 		});
1084
-		$this->registerService(\OC\Files\AppData\Factory::class, function (Server $c) {
1084
+		$this->registerService(\OC\Files\AppData\Factory::class, function(Server $c) {
1085 1085
 			return new \OC\Files\AppData\Factory(
1086 1086
 				$c->getRootFolder(),
1087 1087
 				$c->getSystemConfig()
1088 1088
 			);
1089 1089
 		});
1090 1090
 
1091
-		$this->registerService('LockdownManager', function (Server $c) {
1092
-			return new LockdownManager(function () use ($c) {
1091
+		$this->registerService('LockdownManager', function(Server $c) {
1092
+			return new LockdownManager(function() use ($c) {
1093 1093
 				return $c->getSession();
1094 1094
 			});
1095 1095
 		});
1096 1096
 
1097
-		$this->registerService(\OCP\OCS\IDiscoveryService::class, function (Server $c) {
1097
+		$this->registerService(\OCP\OCS\IDiscoveryService::class, function(Server $c) {
1098 1098
 			return new DiscoveryService($c->getMemCacheFactory(), $c->getHTTPClientService());
1099 1099
 		});
1100 1100
 
1101
-		$this->registerService(ICloudIdManager::class, function (Server $c) {
1101
+		$this->registerService(ICloudIdManager::class, function(Server $c) {
1102 1102
 			return new CloudIdManager();
1103 1103
 		});
1104 1104
 
@@ -1108,18 +1108,18 @@  discard block
 block discarded – undo
1108 1108
 		$this->registerAlias(\OCP\AppFramework\Utility\ITimeFactory::class, \OC\AppFramework\Utility\TimeFactory::class);
1109 1109
 		$this->registerAlias('TimeFactory', \OCP\AppFramework\Utility\ITimeFactory::class);
1110 1110
 
1111
-		$this->registerService(Defaults::class, function (Server $c) {
1111
+		$this->registerService(Defaults::class, function(Server $c) {
1112 1112
 			return new Defaults(
1113 1113
 				$c->getThemingDefaults()
1114 1114
 			);
1115 1115
 		});
1116 1116
 		$this->registerAlias('Defaults', \OCP\Defaults::class);
1117 1117
 
1118
-		$this->registerService(\OCP\ISession::class, function (SimpleContainer $c) {
1118
+		$this->registerService(\OCP\ISession::class, function(SimpleContainer $c) {
1119 1119
 			return $c->query(\OCP\IUserSession::class)->getSession();
1120 1120
 		});
1121 1121
 
1122
-		$this->registerService(IShareHelper::class, function (Server $c) {
1122
+		$this->registerService(IShareHelper::class, function(Server $c) {
1123 1123
 			return new ShareHelper(
1124 1124
 				$c->query(\OCP\Share\IManager::class)
1125 1125
 			);
@@ -1181,11 +1181,11 @@  discard block
 block discarded – undo
1181 1181
 				// no avatar to remove
1182 1182
 			} catch (\Exception $e) {
1183 1183
 				// Ignore exceptions
1184
-				$logger->info('Could not cleanup avatar of ' . $user->getUID());
1184
+				$logger->info('Could not cleanup avatar of '.$user->getUID());
1185 1185
 			}
1186 1186
 		});
1187 1187
 
1188
-		$dispatcher->addListener('OCP\IUser::changeUser', function (GenericEvent $e) {
1188
+		$dispatcher->addListener('OCP\IUser::changeUser', function(GenericEvent $e) {
1189 1189
 			$manager = $this->getAvatarManager();
1190 1190
 			/** @var IUser $user */
1191 1191
 			$user = $e->getSubject();
@@ -1336,7 +1336,7 @@  discard block
 block discarded – undo
1336 1336
 	 * @deprecated since 9.2.0 use IAppData
1337 1337
 	 */
1338 1338
 	public function getAppFolder() {
1339
-		$dir = '/' . \OC_App::getCurrentApp();
1339
+		$dir = '/'.\OC_App::getCurrentApp();
1340 1340
 		$root = $this->getRootFolder();
1341 1341
 		if (!$root->nodeExists($dir)) {
1342 1342
 			$folder = $root->newFolder($dir);
@@ -1920,7 +1920,7 @@  discard block
 block discarded – undo
1920 1920
 	/**
1921 1921
 	 * @return \OCP\Collaboration\AutoComplete\IManager
1922 1922
 	 */
1923
-	public function getAutoCompleteManager(){
1923
+	public function getAutoCompleteManager() {
1924 1924
 		return $this->query(IManager::class);
1925 1925
 	}
1926 1926
 
Please login to merge, or discard this patch.
lib/private/Files/View.php 2 patches
Indentation   +2080 added lines, -2080 removed lines patch added patch discarded remove patch
@@ -80,2084 +80,2084 @@
 block discarded – undo
80 80
  * \OC\Files\Storage\Storage object
81 81
  */
82 82
 class View {
83
-	/** @var string */
84
-	private $fakeRoot = '';
85
-
86
-	/**
87
-	 * @var \OCP\Lock\ILockingProvider
88
-	 */
89
-	protected $lockingProvider;
90
-
91
-	private $lockingEnabled;
92
-
93
-	private $updaterEnabled = true;
94
-
95
-	/** @var \OC\User\Manager */
96
-	private $userManager;
97
-
98
-	/** @var \OCP\ILogger */
99
-	private $logger;
100
-
101
-	/**
102
-	 * @param string $root
103
-	 * @throws \Exception If $root contains an invalid path
104
-	 */
105
-	public function __construct($root = '') {
106
-		if (is_null($root)) {
107
-			throw new \InvalidArgumentException('Root can\'t be null');
108
-		}
109
-		if (!Filesystem::isValidPath($root)) {
110
-			throw new \Exception();
111
-		}
112
-
113
-		$this->fakeRoot = $root;
114
-		$this->lockingProvider = \OC::$server->getLockingProvider();
115
-		$this->lockingEnabled = !($this->lockingProvider instanceof \OC\Lock\NoopLockingProvider);
116
-		$this->userManager = \OC::$server->getUserManager();
117
-		$this->logger = \OC::$server->getLogger();
118
-	}
119
-
120
-	public function getAbsolutePath($path = '/') {
121
-		if ($path === null) {
122
-			return null;
123
-		}
124
-		$this->assertPathLength($path);
125
-		if ($path === '') {
126
-			$path = '/';
127
-		}
128
-		if ($path[0] !== '/') {
129
-			$path = '/' . $path;
130
-		}
131
-		return $this->fakeRoot . $path;
132
-	}
133
-
134
-	/**
135
-	 * change the root to a fake root
136
-	 *
137
-	 * @param string $fakeRoot
138
-	 * @return boolean|null
139
-	 */
140
-	public function chroot($fakeRoot) {
141
-		if (!$fakeRoot == '') {
142
-			if ($fakeRoot[0] !== '/') {
143
-				$fakeRoot = '/' . $fakeRoot;
144
-			}
145
-		}
146
-		$this->fakeRoot = $fakeRoot;
147
-	}
148
-
149
-	/**
150
-	 * get the fake root
151
-	 *
152
-	 * @return string
153
-	 */
154
-	public function getRoot() {
155
-		return $this->fakeRoot;
156
-	}
157
-
158
-	/**
159
-	 * get path relative to the root of the view
160
-	 *
161
-	 * @param string $path
162
-	 * @return string
163
-	 */
164
-	public function getRelativePath($path) {
165
-		$this->assertPathLength($path);
166
-		if ($this->fakeRoot == '') {
167
-			return $path;
168
-		}
169
-
170
-		if (rtrim($path, '/') === rtrim($this->fakeRoot, '/')) {
171
-			return '/';
172
-		}
173
-
174
-		// missing slashes can cause wrong matches!
175
-		$root = rtrim($this->fakeRoot, '/') . '/';
176
-
177
-		if (strpos($path, $root) !== 0) {
178
-			return null;
179
-		} else {
180
-			$path = substr($path, strlen($this->fakeRoot));
181
-			if (strlen($path) === 0) {
182
-				return '/';
183
-			} else {
184
-				return $path;
185
-			}
186
-		}
187
-	}
188
-
189
-	/**
190
-	 * get the mountpoint of the storage object for a path
191
-	 * ( note: because a storage is not always mounted inside the fakeroot, the
192
-	 * returned mountpoint is relative to the absolute root of the filesystem
193
-	 * and does not take the chroot into account )
194
-	 *
195
-	 * @param string $path
196
-	 * @return string
197
-	 */
198
-	public function getMountPoint($path) {
199
-		return Filesystem::getMountPoint($this->getAbsolutePath($path));
200
-	}
201
-
202
-	/**
203
-	 * get the mountpoint of the storage object for a path
204
-	 * ( note: because a storage is not always mounted inside the fakeroot, the
205
-	 * returned mountpoint is relative to the absolute root of the filesystem
206
-	 * and does not take the chroot into account )
207
-	 *
208
-	 * @param string $path
209
-	 * @return \OCP\Files\Mount\IMountPoint
210
-	 */
211
-	public function getMount($path) {
212
-		return Filesystem::getMountManager()->find($this->getAbsolutePath($path));
213
-	}
214
-
215
-	/**
216
-	 * resolve a path to a storage and internal path
217
-	 *
218
-	 * @param string $path
219
-	 * @return array an array consisting of the storage and the internal path
220
-	 */
221
-	public function resolvePath($path) {
222
-		$a = $this->getAbsolutePath($path);
223
-		$p = Filesystem::normalizePath($a);
224
-		return Filesystem::resolvePath($p);
225
-	}
226
-
227
-	/**
228
-	 * return the path to a local version of the file
229
-	 * we need this because we can't know if a file is stored local or not from
230
-	 * outside the filestorage and for some purposes a local file is needed
231
-	 *
232
-	 * @param string $path
233
-	 * @return string
234
-	 */
235
-	public function getLocalFile($path) {
236
-		$parent = substr($path, 0, strrpos($path, '/'));
237
-		$path = $this->getAbsolutePath($path);
238
-		list($storage, $internalPath) = Filesystem::resolvePath($path);
239
-		if (Filesystem::isValidPath($parent) and $storage) {
240
-			return $storage->getLocalFile($internalPath);
241
-		} else {
242
-			return null;
243
-		}
244
-	}
245
-
246
-	/**
247
-	 * @param string $path
248
-	 * @return string
249
-	 */
250
-	public function getLocalFolder($path) {
251
-		$parent = substr($path, 0, strrpos($path, '/'));
252
-		$path = $this->getAbsolutePath($path);
253
-		list($storage, $internalPath) = Filesystem::resolvePath($path);
254
-		if (Filesystem::isValidPath($parent) and $storage) {
255
-			return $storage->getLocalFolder($internalPath);
256
-		} else {
257
-			return null;
258
-		}
259
-	}
260
-
261
-	/**
262
-	 * the following functions operate with arguments and return values identical
263
-	 * to those of their PHP built-in equivalents. Mostly they are merely wrappers
264
-	 * for \OC\Files\Storage\Storage via basicOperation().
265
-	 */
266
-	public function mkdir($path) {
267
-		return $this->basicOperation('mkdir', $path, array('create', 'write'));
268
-	}
269
-
270
-	/**
271
-	 * remove mount point
272
-	 *
273
-	 * @param \OC\Files\Mount\MoveableMount $mount
274
-	 * @param string $path relative to data/
275
-	 * @return boolean
276
-	 */
277
-	protected function removeMount($mount, $path) {
278
-		if ($mount instanceof MoveableMount) {
279
-			// cut of /user/files to get the relative path to data/user/files
280
-			$pathParts = explode('/', $path, 4);
281
-			$relPath = '/' . $pathParts[3];
282
-			$this->lockFile($relPath, ILockingProvider::LOCK_SHARED, true);
283
-			\OC_Hook::emit(
284
-				Filesystem::CLASSNAME, "umount",
285
-				array(Filesystem::signal_param_path => $relPath)
286
-			);
287
-			$this->changeLock($relPath, ILockingProvider::LOCK_EXCLUSIVE, true);
288
-			$result = $mount->removeMount();
289
-			$this->changeLock($relPath, ILockingProvider::LOCK_SHARED, true);
290
-			if ($result) {
291
-				\OC_Hook::emit(
292
-					Filesystem::CLASSNAME, "post_umount",
293
-					array(Filesystem::signal_param_path => $relPath)
294
-				);
295
-			}
296
-			$this->unlockFile($relPath, ILockingProvider::LOCK_SHARED, true);
297
-			return $result;
298
-		} else {
299
-			// do not allow deleting the storage's root / the mount point
300
-			// because for some storages it might delete the whole contents
301
-			// but isn't supposed to work that way
302
-			return false;
303
-		}
304
-	}
305
-
306
-	public function disableCacheUpdate() {
307
-		$this->updaterEnabled = false;
308
-	}
309
-
310
-	public function enableCacheUpdate() {
311
-		$this->updaterEnabled = true;
312
-	}
313
-
314
-	protected function writeUpdate(Storage $storage, $internalPath, $time = null) {
315
-		if ($this->updaterEnabled) {
316
-			if (is_null($time)) {
317
-				$time = time();
318
-			}
319
-			$storage->getUpdater()->update($internalPath, $time);
320
-		}
321
-	}
322
-
323
-	protected function removeUpdate(Storage $storage, $internalPath) {
324
-		if ($this->updaterEnabled) {
325
-			$storage->getUpdater()->remove($internalPath);
326
-		}
327
-	}
328
-
329
-	protected function renameUpdate(Storage $sourceStorage, Storage $targetStorage, $sourceInternalPath, $targetInternalPath) {
330
-		if ($this->updaterEnabled) {
331
-			$targetStorage->getUpdater()->renameFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
332
-		}
333
-	}
334
-
335
-	/**
336
-	 * @param string $path
337
-	 * @return bool|mixed
338
-	 */
339
-	public function rmdir($path) {
340
-		$absolutePath = $this->getAbsolutePath($path);
341
-		$mount = Filesystem::getMountManager()->find($absolutePath);
342
-		if ($mount->getInternalPath($absolutePath) === '') {
343
-			return $this->removeMount($mount, $absolutePath);
344
-		}
345
-		if ($this->is_dir($path)) {
346
-			$result = $this->basicOperation('rmdir', $path, array('delete'));
347
-		} else {
348
-			$result = false;
349
-		}
350
-
351
-		if (!$result && !$this->file_exists($path)) { //clear ghost files from the cache on delete
352
-			$storage = $mount->getStorage();
353
-			$internalPath = $mount->getInternalPath($absolutePath);
354
-			$storage->getUpdater()->remove($internalPath);
355
-		}
356
-		return $result;
357
-	}
358
-
359
-	/**
360
-	 * @param string $path
361
-	 * @return resource
362
-	 */
363
-	public function opendir($path) {
364
-		return $this->basicOperation('opendir', $path, array('read'));
365
-	}
366
-
367
-	/**
368
-	 * @param string $path
369
-	 * @return bool|mixed
370
-	 */
371
-	public function is_dir($path) {
372
-		if ($path == '/') {
373
-			return true;
374
-		}
375
-		return $this->basicOperation('is_dir', $path);
376
-	}
377
-
378
-	/**
379
-	 * @param string $path
380
-	 * @return bool|mixed
381
-	 */
382
-	public function is_file($path) {
383
-		if ($path == '/') {
384
-			return false;
385
-		}
386
-		return $this->basicOperation('is_file', $path);
387
-	}
388
-
389
-	/**
390
-	 * @param string $path
391
-	 * @return mixed
392
-	 */
393
-	public function stat($path) {
394
-		return $this->basicOperation('stat', $path);
395
-	}
396
-
397
-	/**
398
-	 * @param string $path
399
-	 * @return mixed
400
-	 */
401
-	public function filetype($path) {
402
-		return $this->basicOperation('filetype', $path);
403
-	}
404
-
405
-	/**
406
-	 * @param string $path
407
-	 * @return mixed
408
-	 */
409
-	public function filesize($path) {
410
-		return $this->basicOperation('filesize', $path);
411
-	}
412
-
413
-	/**
414
-	 * @param string $path
415
-	 * @return bool|mixed
416
-	 * @throws \OCP\Files\InvalidPathException
417
-	 */
418
-	public function readfile($path) {
419
-		$this->assertPathLength($path);
420
-		@ob_end_clean();
421
-		$handle = $this->fopen($path, 'rb');
422
-		if ($handle) {
423
-			$chunkSize = 8192; // 8 kB chunks
424
-			while (!feof($handle)) {
425
-				echo fread($handle, $chunkSize);
426
-				flush();
427
-			}
428
-			fclose($handle);
429
-			return $this->filesize($path);
430
-		}
431
-		return false;
432
-	}
433
-
434
-	/**
435
-	 * @param string $path
436
-	 * @param int $from
437
-	 * @param int $to
438
-	 * @return bool|mixed
439
-	 * @throws \OCP\Files\InvalidPathException
440
-	 * @throws \OCP\Files\UnseekableException
441
-	 */
442
-	public function readfilePart($path, $from, $to) {
443
-		$this->assertPathLength($path);
444
-		@ob_end_clean();
445
-		$handle = $this->fopen($path, 'rb');
446
-		if ($handle) {
447
-			$chunkSize = 8192; // 8 kB chunks
448
-			$startReading = true;
449
-
450
-			if ($from !== 0 && $from !== '0' && fseek($handle, $from) !== 0) {
451
-				// forward file handle via chunked fread because fseek seem to have failed
452
-
453
-				$end = $from + 1;
454
-				while (!feof($handle) && ftell($handle) < $end) {
455
-					$len = $from - ftell($handle);
456
-					if ($len > $chunkSize) {
457
-						$len = $chunkSize;
458
-					}
459
-					$result = fread($handle, $len);
460
-
461
-					if ($result === false) {
462
-						$startReading = false;
463
-						break;
464
-					}
465
-				}
466
-			}
467
-
468
-			if ($startReading) {
469
-				$end = $to + 1;
470
-				while (!feof($handle) && ftell($handle) < $end) {
471
-					$len = $end - ftell($handle);
472
-					if ($len > $chunkSize) {
473
-						$len = $chunkSize;
474
-					}
475
-					echo fread($handle, $len);
476
-					flush();
477
-				}
478
-				return ftell($handle) - $from;
479
-			}
480
-
481
-			throw new \OCP\Files\UnseekableException('fseek error');
482
-		}
483
-		return false;
484
-	}
485
-
486
-	/**
487
-	 * @param string $path
488
-	 * @return mixed
489
-	 */
490
-	public function isCreatable($path) {
491
-		return $this->basicOperation('isCreatable', $path);
492
-	}
493
-
494
-	/**
495
-	 * @param string $path
496
-	 * @return mixed
497
-	 */
498
-	public function isReadable($path) {
499
-		return $this->basicOperation('isReadable', $path);
500
-	}
501
-
502
-	/**
503
-	 * @param string $path
504
-	 * @return mixed
505
-	 */
506
-	public function isUpdatable($path) {
507
-		return $this->basicOperation('isUpdatable', $path);
508
-	}
509
-
510
-	/**
511
-	 * @param string $path
512
-	 * @return bool|mixed
513
-	 */
514
-	public function isDeletable($path) {
515
-		$absolutePath = $this->getAbsolutePath($path);
516
-		$mount = Filesystem::getMountManager()->find($absolutePath);
517
-		if ($mount->getInternalPath($absolutePath) === '') {
518
-			return $mount instanceof MoveableMount;
519
-		}
520
-		return $this->basicOperation('isDeletable', $path);
521
-	}
522
-
523
-	/**
524
-	 * @param string $path
525
-	 * @return mixed
526
-	 */
527
-	public function isSharable($path) {
528
-		return $this->basicOperation('isSharable', $path);
529
-	}
530
-
531
-	/**
532
-	 * @param string $path
533
-	 * @return bool|mixed
534
-	 */
535
-	public function file_exists($path) {
536
-		if ($path == '/') {
537
-			return true;
538
-		}
539
-		return $this->basicOperation('file_exists', $path);
540
-	}
541
-
542
-	/**
543
-	 * @param string $path
544
-	 * @return mixed
545
-	 */
546
-	public function filemtime($path) {
547
-		return $this->basicOperation('filemtime', $path);
548
-	}
549
-
550
-	/**
551
-	 * @param string $path
552
-	 * @param int|string $mtime
553
-	 * @return bool
554
-	 */
555
-	public function touch($path, $mtime = null) {
556
-		if (!is_null($mtime) and !is_numeric($mtime)) {
557
-			$mtime = strtotime($mtime);
558
-		}
559
-
560
-		$hooks = array('touch');
561
-
562
-		if (!$this->file_exists($path)) {
563
-			$hooks[] = 'create';
564
-			$hooks[] = 'write';
565
-		}
566
-		$result = $this->basicOperation('touch', $path, $hooks, $mtime);
567
-		if (!$result) {
568
-			// If create file fails because of permissions on external storage like SMB folders,
569
-			// check file exists and return false if not.
570
-			if (!$this->file_exists($path)) {
571
-				return false;
572
-			}
573
-			if (is_null($mtime)) {
574
-				$mtime = time();
575
-			}
576
-			//if native touch fails, we emulate it by changing the mtime in the cache
577
-			$this->putFileInfo($path, array('mtime' => floor($mtime)));
578
-		}
579
-		return true;
580
-	}
581
-
582
-	/**
583
-	 * @param string $path
584
-	 * @return mixed
585
-	 */
586
-	public function file_get_contents($path) {
587
-		return $this->basicOperation('file_get_contents', $path, array('read'));
588
-	}
589
-
590
-	/**
591
-	 * @param bool $exists
592
-	 * @param string $path
593
-	 * @param bool $run
594
-	 */
595
-	protected function emit_file_hooks_pre($exists, $path, &$run) {
596
-		if (!$exists) {
597
-			\OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_create, array(
598
-				Filesystem::signal_param_path => $this->getHookPath($path),
599
-				Filesystem::signal_param_run => &$run,
600
-			));
601
-		} else {
602
-			\OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_update, array(
603
-				Filesystem::signal_param_path => $this->getHookPath($path),
604
-				Filesystem::signal_param_run => &$run,
605
-			));
606
-		}
607
-		\OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_write, array(
608
-			Filesystem::signal_param_path => $this->getHookPath($path),
609
-			Filesystem::signal_param_run => &$run,
610
-		));
611
-	}
612
-
613
-	/**
614
-	 * @param bool $exists
615
-	 * @param string $path
616
-	 */
617
-	protected function emit_file_hooks_post($exists, $path) {
618
-		if (!$exists) {
619
-			\OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_create, array(
620
-				Filesystem::signal_param_path => $this->getHookPath($path),
621
-			));
622
-		} else {
623
-			\OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_update, array(
624
-				Filesystem::signal_param_path => $this->getHookPath($path),
625
-			));
626
-		}
627
-		\OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_write, array(
628
-			Filesystem::signal_param_path => $this->getHookPath($path),
629
-		));
630
-	}
631
-
632
-	/**
633
-	 * @param string $path
634
-	 * @param mixed $data
635
-	 * @return bool|mixed
636
-	 * @throws \Exception
637
-	 */
638
-	public function file_put_contents($path, $data) {
639
-		if (is_resource($data)) { //not having to deal with streams in file_put_contents makes life easier
640
-			$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
641
-			if (Filesystem::isValidPath($path)
642
-				and !Filesystem::isFileBlacklisted($path)
643
-			) {
644
-				$path = $this->getRelativePath($absolutePath);
645
-
646
-				$this->lockFile($path, ILockingProvider::LOCK_SHARED);
647
-
648
-				$exists = $this->file_exists($path);
649
-				$run = true;
650
-				if ($this->shouldEmitHooks($path)) {
651
-					$this->emit_file_hooks_pre($exists, $path, $run);
652
-				}
653
-				if (!$run) {
654
-					$this->unlockFile($path, ILockingProvider::LOCK_SHARED);
655
-					return false;
656
-				}
657
-
658
-				$this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
659
-
660
-				/** @var \OC\Files\Storage\Storage $storage */
661
-				list($storage, $internalPath) = $this->resolvePath($path);
662
-				$target = $storage->fopen($internalPath, 'w');
663
-				if ($target) {
664
-					list (, $result) = \OC_Helper::streamCopy($data, $target);
665
-					fclose($target);
666
-					fclose($data);
667
-
668
-					$this->writeUpdate($storage, $internalPath);
669
-
670
-					$this->changeLock($path, ILockingProvider::LOCK_SHARED);
671
-
672
-					if ($this->shouldEmitHooks($path) && $result !== false) {
673
-						$this->emit_file_hooks_post($exists, $path);
674
-					}
675
-					$this->unlockFile($path, ILockingProvider::LOCK_SHARED);
676
-					return $result;
677
-				} else {
678
-					$this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
679
-					return false;
680
-				}
681
-			} else {
682
-				return false;
683
-			}
684
-		} else {
685
-			$hooks = ($this->file_exists($path)) ? array('update', 'write') : array('create', 'write');
686
-			return $this->basicOperation('file_put_contents', $path, $hooks, $data);
687
-		}
688
-	}
689
-
690
-	/**
691
-	 * @param string $path
692
-	 * @return bool|mixed
693
-	 */
694
-	public function unlink($path) {
695
-		if ($path === '' || $path === '/') {
696
-			// do not allow deleting the root
697
-			return false;
698
-		}
699
-		$postFix = (substr($path, -1, 1) === '/') ? '/' : '';
700
-		$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
701
-		$mount = Filesystem::getMountManager()->find($absolutePath . $postFix);
702
-		if ($mount and $mount->getInternalPath($absolutePath) === '') {
703
-			return $this->removeMount($mount, $absolutePath);
704
-		}
705
-		if ($this->is_dir($path)) {
706
-			$result = $this->basicOperation('rmdir', $path, ['delete']);
707
-		} else {
708
-			$result = $this->basicOperation('unlink', $path, ['delete']);
709
-		}
710
-		if (!$result && !$this->file_exists($path)) { //clear ghost files from the cache on delete
711
-			$storage = $mount->getStorage();
712
-			$internalPath = $mount->getInternalPath($absolutePath);
713
-			$storage->getUpdater()->remove($internalPath);
714
-			return true;
715
-		} else {
716
-			return $result;
717
-		}
718
-	}
719
-
720
-	/**
721
-	 * @param string $directory
722
-	 * @return bool|mixed
723
-	 */
724
-	public function deleteAll($directory) {
725
-		return $this->rmdir($directory);
726
-	}
727
-
728
-	/**
729
-	 * Rename/move a file or folder from the source path to target path.
730
-	 *
731
-	 * @param string $path1 source path
732
-	 * @param string $path2 target path
733
-	 *
734
-	 * @return bool|mixed
735
-	 */
736
-	public function rename($path1, $path2) {
737
-		$absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1));
738
-		$absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2));
739
-		$result = false;
740
-		if (
741
-			Filesystem::isValidPath($path2)
742
-			and Filesystem::isValidPath($path1)
743
-			and !Filesystem::isFileBlacklisted($path2)
744
-		) {
745
-			$path1 = $this->getRelativePath($absolutePath1);
746
-			$path2 = $this->getRelativePath($absolutePath2);
747
-			$exists = $this->file_exists($path2);
748
-
749
-			if ($path1 == null or $path2 == null) {
750
-				return false;
751
-			}
752
-
753
-			$this->lockFile($path1, ILockingProvider::LOCK_SHARED, true);
754
-			try {
755
-				$this->lockFile($path2, ILockingProvider::LOCK_SHARED, true);
756
-
757
-				$run = true;
758
-				if ($this->shouldEmitHooks($path1) && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) {
759
-					// if it was a rename from a part file to a regular file it was a write and not a rename operation
760
-					$this->emit_file_hooks_pre($exists, $path2, $run);
761
-				} elseif ($this->shouldEmitHooks($path1)) {
762
-					\OC_Hook::emit(
763
-						Filesystem::CLASSNAME, Filesystem::signal_rename,
764
-						array(
765
-							Filesystem::signal_param_oldpath => $this->getHookPath($path1),
766
-							Filesystem::signal_param_newpath => $this->getHookPath($path2),
767
-							Filesystem::signal_param_run => &$run
768
-						)
769
-					);
770
-				}
771
-				if ($run) {
772
-					$this->verifyPath(dirname($path2), basename($path2));
773
-
774
-					$manager = Filesystem::getMountManager();
775
-					$mount1 = $this->getMount($path1);
776
-					$mount2 = $this->getMount($path2);
777
-					$storage1 = $mount1->getStorage();
778
-					$storage2 = $mount2->getStorage();
779
-					$internalPath1 = $mount1->getInternalPath($absolutePath1);
780
-					$internalPath2 = $mount2->getInternalPath($absolutePath2);
781
-
782
-					$this->changeLock($path1, ILockingProvider::LOCK_EXCLUSIVE, true);
783
-					try {
784
-						$this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE, true);
785
-
786
-						if ($internalPath1 === '') {
787
-							if ($mount1 instanceof MoveableMount) {
788
-								if ($this->isTargetAllowed($absolutePath2)) {
789
-									/**
790
-									 * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1
791
-									 */
792
-									$sourceMountPoint = $mount1->getMountPoint();
793
-									$result = $mount1->moveMount($absolutePath2);
794
-									$manager->moveMount($sourceMountPoint, $mount1->getMountPoint());
795
-								} else {
796
-									$result = false;
797
-								}
798
-							} else {
799
-								$result = false;
800
-							}
801
-							// moving a file/folder within the same mount point
802
-						} elseif ($storage1 === $storage2) {
803
-							if ($storage1) {
804
-								$result = $storage1->rename($internalPath1, $internalPath2);
805
-							} else {
806
-								$result = false;
807
-							}
808
-							// moving a file/folder between storages (from $storage1 to $storage2)
809
-						} else {
810
-							$result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2);
811
-						}
812
-
813
-						if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
814
-							// if it was a rename from a part file to a regular file it was a write and not a rename operation
815
-							$this->writeUpdate($storage2, $internalPath2);
816
-						} else if ($result) {
817
-							if ($internalPath1 !== '') { // don't do a cache update for moved mounts
818
-								$this->renameUpdate($storage1, $storage2, $internalPath1, $internalPath2);
819
-							}
820
-						}
821
-					} catch(\Exception $e) {
822
-						throw $e;
823
-					} finally {
824
-						$this->changeLock($path1, ILockingProvider::LOCK_SHARED, true);
825
-						$this->changeLock($path2, ILockingProvider::LOCK_SHARED, true);
826
-					}
827
-
828
-					if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
829
-						if ($this->shouldEmitHooks()) {
830
-							$this->emit_file_hooks_post($exists, $path2);
831
-						}
832
-					} elseif ($result) {
833
-						if ($this->shouldEmitHooks($path1) and $this->shouldEmitHooks($path2)) {
834
-							\OC_Hook::emit(
835
-								Filesystem::CLASSNAME,
836
-								Filesystem::signal_post_rename,
837
-								array(
838
-									Filesystem::signal_param_oldpath => $this->getHookPath($path1),
839
-									Filesystem::signal_param_newpath => $this->getHookPath($path2)
840
-								)
841
-							);
842
-						}
843
-					}
844
-				}
845
-			} catch(\Exception $e) {
846
-				throw $e;
847
-			} finally {
848
-				$this->unlockFile($path1, ILockingProvider::LOCK_SHARED, true);
849
-				$this->unlockFile($path2, ILockingProvider::LOCK_SHARED, true);
850
-			}
851
-		}
852
-		return $result;
853
-	}
854
-
855
-	/**
856
-	 * Copy a file/folder from the source path to target path
857
-	 *
858
-	 * @param string $path1 source path
859
-	 * @param string $path2 target path
860
-	 * @param bool $preserveMtime whether to preserve mtime on the copy
861
-	 *
862
-	 * @return bool|mixed
863
-	 */
864
-	public function copy($path1, $path2, $preserveMtime = false) {
865
-		$absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1));
866
-		$absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2));
867
-		$result = false;
868
-		if (
869
-			Filesystem::isValidPath($path2)
870
-			and Filesystem::isValidPath($path1)
871
-			and !Filesystem::isFileBlacklisted($path2)
872
-		) {
873
-			$path1 = $this->getRelativePath($absolutePath1);
874
-			$path2 = $this->getRelativePath($absolutePath2);
875
-
876
-			if ($path1 == null or $path2 == null) {
877
-				return false;
878
-			}
879
-			$run = true;
880
-
881
-			$this->lockFile($path2, ILockingProvider::LOCK_SHARED);
882
-			$this->lockFile($path1, ILockingProvider::LOCK_SHARED);
883
-			$lockTypePath1 = ILockingProvider::LOCK_SHARED;
884
-			$lockTypePath2 = ILockingProvider::LOCK_SHARED;
885
-
886
-			try {
887
-
888
-				$exists = $this->file_exists($path2);
889
-				if ($this->shouldEmitHooks()) {
890
-					\OC_Hook::emit(
891
-						Filesystem::CLASSNAME,
892
-						Filesystem::signal_copy,
893
-						array(
894
-							Filesystem::signal_param_oldpath => $this->getHookPath($path1),
895
-							Filesystem::signal_param_newpath => $this->getHookPath($path2),
896
-							Filesystem::signal_param_run => &$run
897
-						)
898
-					);
899
-					$this->emit_file_hooks_pre($exists, $path2, $run);
900
-				}
901
-				if ($run) {
902
-					$mount1 = $this->getMount($path1);
903
-					$mount2 = $this->getMount($path2);
904
-					$storage1 = $mount1->getStorage();
905
-					$internalPath1 = $mount1->getInternalPath($absolutePath1);
906
-					$storage2 = $mount2->getStorage();
907
-					$internalPath2 = $mount2->getInternalPath($absolutePath2);
908
-
909
-					$this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE);
910
-					$lockTypePath2 = ILockingProvider::LOCK_EXCLUSIVE;
911
-
912
-					if ($mount1->getMountPoint() == $mount2->getMountPoint()) {
913
-						if ($storage1) {
914
-							$result = $storage1->copy($internalPath1, $internalPath2);
915
-						} else {
916
-							$result = false;
917
-						}
918
-					} else {
919
-						$result = $storage2->copyFromStorage($storage1, $internalPath1, $internalPath2);
920
-					}
921
-
922
-					$this->writeUpdate($storage2, $internalPath2);
923
-
924
-					$this->changeLock($path2, ILockingProvider::LOCK_SHARED);
925
-					$lockTypePath2 = ILockingProvider::LOCK_SHARED;
926
-
927
-					if ($this->shouldEmitHooks() && $result !== false) {
928
-						\OC_Hook::emit(
929
-							Filesystem::CLASSNAME,
930
-							Filesystem::signal_post_copy,
931
-							array(
932
-								Filesystem::signal_param_oldpath => $this->getHookPath($path1),
933
-								Filesystem::signal_param_newpath => $this->getHookPath($path2)
934
-							)
935
-						);
936
-						$this->emit_file_hooks_post($exists, $path2);
937
-					}
938
-
939
-				}
940
-			} catch (\Exception $e) {
941
-				$this->unlockFile($path2, $lockTypePath2);
942
-				$this->unlockFile($path1, $lockTypePath1);
943
-				throw $e;
944
-			}
945
-
946
-			$this->unlockFile($path2, $lockTypePath2);
947
-			$this->unlockFile($path1, $lockTypePath1);
948
-
949
-		}
950
-		return $result;
951
-	}
952
-
953
-	/**
954
-	 * @param string $path
955
-	 * @param string $mode 'r' or 'w'
956
-	 * @return resource
957
-	 */
958
-	public function fopen($path, $mode) {
959
-		$mode = str_replace('b', '', $mode); // the binary flag is a windows only feature which we do not support
960
-		$hooks = array();
961
-		switch ($mode) {
962
-			case 'r':
963
-				$hooks[] = 'read';
964
-				break;
965
-			case 'r+':
966
-			case 'w+':
967
-			case 'x+':
968
-			case 'a+':
969
-				$hooks[] = 'read';
970
-				$hooks[] = 'write';
971
-				break;
972
-			case 'w':
973
-			case 'x':
974
-			case 'a':
975
-				$hooks[] = 'write';
976
-				break;
977
-			default:
978
-				\OCP\Util::writeLog('core', 'invalid mode (' . $mode . ') for ' . $path, \OCP\Util::ERROR);
979
-		}
980
-
981
-		if ($mode !== 'r' && $mode !== 'w') {
982
-			\OC::$server->getLogger()->info('Trying to open a file with a mode other than "r" or "w" can cause severe performance issues with some backends');
983
-		}
984
-
985
-		return $this->basicOperation('fopen', $path, $hooks, $mode);
986
-	}
987
-
988
-	/**
989
-	 * @param string $path
990
-	 * @return bool|string
991
-	 * @throws \OCP\Files\InvalidPathException
992
-	 */
993
-	public function toTmpFile($path) {
994
-		$this->assertPathLength($path);
995
-		if (Filesystem::isValidPath($path)) {
996
-			$source = $this->fopen($path, 'r');
997
-			if ($source) {
998
-				$extension = pathinfo($path, PATHINFO_EXTENSION);
999
-				$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($extension);
1000
-				file_put_contents($tmpFile, $source);
1001
-				return $tmpFile;
1002
-			} else {
1003
-				return false;
1004
-			}
1005
-		} else {
1006
-			return false;
1007
-		}
1008
-	}
1009
-
1010
-	/**
1011
-	 * @param string $tmpFile
1012
-	 * @param string $path
1013
-	 * @return bool|mixed
1014
-	 * @throws \OCP\Files\InvalidPathException
1015
-	 */
1016
-	public function fromTmpFile($tmpFile, $path) {
1017
-		$this->assertPathLength($path);
1018
-		if (Filesystem::isValidPath($path)) {
1019
-
1020
-			// Get directory that the file is going into
1021
-			$filePath = dirname($path);
1022
-
1023
-			// Create the directories if any
1024
-			if (!$this->file_exists($filePath)) {
1025
-				$result = $this->createParentDirectories($filePath);
1026
-				if ($result === false) {
1027
-					return false;
1028
-				}
1029
-			}
1030
-
1031
-			$source = fopen($tmpFile, 'r');
1032
-			if ($source) {
1033
-				$result = $this->file_put_contents($path, $source);
1034
-				// $this->file_put_contents() might have already closed
1035
-				// the resource, so we check it, before trying to close it
1036
-				// to avoid messages in the error log.
1037
-				if (is_resource($source)) {
1038
-					fclose($source);
1039
-				}
1040
-				unlink($tmpFile);
1041
-				return $result;
1042
-			} else {
1043
-				return false;
1044
-			}
1045
-		} else {
1046
-			return false;
1047
-		}
1048
-	}
1049
-
1050
-
1051
-	/**
1052
-	 * @param string $path
1053
-	 * @return mixed
1054
-	 * @throws \OCP\Files\InvalidPathException
1055
-	 */
1056
-	public function getMimeType($path) {
1057
-		$this->assertPathLength($path);
1058
-		return $this->basicOperation('getMimeType', $path);
1059
-	}
1060
-
1061
-	/**
1062
-	 * @param string $type
1063
-	 * @param string $path
1064
-	 * @param bool $raw
1065
-	 * @return bool|null|string
1066
-	 */
1067
-	public function hash($type, $path, $raw = false) {
1068
-		$postFix = (substr($path, -1, 1) === '/') ? '/' : '';
1069
-		$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
1070
-		if (Filesystem::isValidPath($path)) {
1071
-			$path = $this->getRelativePath($absolutePath);
1072
-			if ($path == null) {
1073
-				return false;
1074
-			}
1075
-			if ($this->shouldEmitHooks($path)) {
1076
-				\OC_Hook::emit(
1077
-					Filesystem::CLASSNAME,
1078
-					Filesystem::signal_read,
1079
-					array(Filesystem::signal_param_path => $this->getHookPath($path))
1080
-				);
1081
-			}
1082
-			list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
1083
-			if ($storage) {
1084
-				return $storage->hash($type, $internalPath, $raw);
1085
-			}
1086
-		}
1087
-		return null;
1088
-	}
1089
-
1090
-	/**
1091
-	 * @param string $path
1092
-	 * @return mixed
1093
-	 * @throws \OCP\Files\InvalidPathException
1094
-	 */
1095
-	public function free_space($path = '/') {
1096
-		$this->assertPathLength($path);
1097
-		$result = $this->basicOperation('free_space', $path);
1098
-		if ($result === null) {
1099
-			throw new InvalidPathException();
1100
-		}
1101
-		return $result;
1102
-	}
1103
-
1104
-	/**
1105
-	 * abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage
1106
-	 *
1107
-	 * @param string $operation
1108
-	 * @param string $path
1109
-	 * @param array $hooks (optional)
1110
-	 * @param mixed $extraParam (optional)
1111
-	 * @return mixed
1112
-	 * @throws \Exception
1113
-	 *
1114
-	 * This method takes requests for basic filesystem functions (e.g. reading & writing
1115
-	 * files), processes hooks and proxies, sanitises paths, and finally passes them on to
1116
-	 * \OC\Files\Storage\Storage for delegation to a storage backend for execution
1117
-	 */
1118
-	private function basicOperation($operation, $path, $hooks = [], $extraParam = null) {
1119
-		$postFix = (substr($path, -1, 1) === '/') ? '/' : '';
1120
-		$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
1121
-		if (Filesystem::isValidPath($path)
1122
-			and !Filesystem::isFileBlacklisted($path)
1123
-		) {
1124
-			$path = $this->getRelativePath($absolutePath);
1125
-			if ($path == null) {
1126
-				return false;
1127
-			}
1128
-
1129
-			if (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks)) {
1130
-				// always a shared lock during pre-hooks so the hook can read the file
1131
-				$this->lockFile($path, ILockingProvider::LOCK_SHARED);
1132
-			}
1133
-
1134
-			$run = $this->runHooks($hooks, $path);
1135
-			/** @var \OC\Files\Storage\Storage $storage */
1136
-			list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
1137
-			if ($run and $storage) {
1138
-				if (in_array('write', $hooks) || in_array('delete', $hooks)) {
1139
-					$this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
1140
-				}
1141
-				try {
1142
-					if (!is_null($extraParam)) {
1143
-						$result = $storage->$operation($internalPath, $extraParam);
1144
-					} else {
1145
-						$result = $storage->$operation($internalPath);
1146
-					}
1147
-				} catch (\Exception $e) {
1148
-					if (in_array('write', $hooks) || in_array('delete', $hooks)) {
1149
-						$this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
1150
-					} else if (in_array('read', $hooks)) {
1151
-						$this->unlockFile($path, ILockingProvider::LOCK_SHARED);
1152
-					}
1153
-					throw $e;
1154
-				}
1155
-
1156
-				if ($result && in_array('delete', $hooks) and $result) {
1157
-					$this->removeUpdate($storage, $internalPath);
1158
-				}
1159
-				if ($result && in_array('write', $hooks) and $operation !== 'fopen') {
1160
-					$this->writeUpdate($storage, $internalPath);
1161
-				}
1162
-				if ($result && in_array('touch', $hooks)) {
1163
-					$this->writeUpdate($storage, $internalPath, $extraParam);
1164
-				}
1165
-
1166
-				if ((in_array('write', $hooks) || in_array('delete', $hooks)) && ($operation !== 'fopen' || $result === false)) {
1167
-					$this->changeLock($path, ILockingProvider::LOCK_SHARED);
1168
-				}
1169
-
1170
-				$unlockLater = false;
1171
-				if ($this->lockingEnabled && $operation === 'fopen' && is_resource($result)) {
1172
-					$unlockLater = true;
1173
-					// make sure our unlocking callback will still be called if connection is aborted
1174
-					ignore_user_abort(true);
1175
-					$result = CallbackWrapper::wrap($result, null, null, function () use ($hooks, $path) {
1176
-						if (in_array('write', $hooks)) {
1177
-							$this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
1178
-						} else if (in_array('read', $hooks)) {
1179
-							$this->unlockFile($path, ILockingProvider::LOCK_SHARED);
1180
-						}
1181
-					});
1182
-				}
1183
-
1184
-				if ($this->shouldEmitHooks($path) && $result !== false) {
1185
-					if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open
1186
-						$this->runHooks($hooks, $path, true);
1187
-					}
1188
-				}
1189
-
1190
-				if (!$unlockLater
1191
-					&& (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks))
1192
-				) {
1193
-					$this->unlockFile($path, ILockingProvider::LOCK_SHARED);
1194
-				}
1195
-				return $result;
1196
-			} else {
1197
-				$this->unlockFile($path, ILockingProvider::LOCK_SHARED);
1198
-			}
1199
-		}
1200
-		return null;
1201
-	}
1202
-
1203
-	/**
1204
-	 * get the path relative to the default root for hook usage
1205
-	 *
1206
-	 * @param string $path
1207
-	 * @return string
1208
-	 */
1209
-	private function getHookPath($path) {
1210
-		if (!Filesystem::getView()) {
1211
-			return $path;
1212
-		}
1213
-		return Filesystem::getView()->getRelativePath($this->getAbsolutePath($path));
1214
-	}
1215
-
1216
-	private function shouldEmitHooks($path = '') {
1217
-		if ($path && Cache\Scanner::isPartialFile($path)) {
1218
-			return false;
1219
-		}
1220
-		if (!Filesystem::$loaded) {
1221
-			return false;
1222
-		}
1223
-		$defaultRoot = Filesystem::getRoot();
1224
-		if ($defaultRoot === null) {
1225
-			return false;
1226
-		}
1227
-		if ($this->fakeRoot === $defaultRoot) {
1228
-			return true;
1229
-		}
1230
-		$fullPath = $this->getAbsolutePath($path);
1231
-
1232
-		if ($fullPath === $defaultRoot) {
1233
-			return true;
1234
-		}
1235
-
1236
-		return (strlen($fullPath) > strlen($defaultRoot)) && (substr($fullPath, 0, strlen($defaultRoot) + 1) === $defaultRoot . '/');
1237
-	}
1238
-
1239
-	/**
1240
-	 * @param string[] $hooks
1241
-	 * @param string $path
1242
-	 * @param bool $post
1243
-	 * @return bool
1244
-	 */
1245
-	private function runHooks($hooks, $path, $post = false) {
1246
-		$relativePath = $path;
1247
-		$path = $this->getHookPath($path);
1248
-		$prefix = ($post) ? 'post_' : '';
1249
-		$run = true;
1250
-		if ($this->shouldEmitHooks($relativePath)) {
1251
-			foreach ($hooks as $hook) {
1252
-				if ($hook != 'read') {
1253
-					\OC_Hook::emit(
1254
-						Filesystem::CLASSNAME,
1255
-						$prefix . $hook,
1256
-						array(
1257
-							Filesystem::signal_param_run => &$run,
1258
-							Filesystem::signal_param_path => $path
1259
-						)
1260
-					);
1261
-				} elseif (!$post) {
1262
-					\OC_Hook::emit(
1263
-						Filesystem::CLASSNAME,
1264
-						$prefix . $hook,
1265
-						array(
1266
-							Filesystem::signal_param_path => $path
1267
-						)
1268
-					);
1269
-				}
1270
-			}
1271
-		}
1272
-		return $run;
1273
-	}
1274
-
1275
-	/**
1276
-	 * check if a file or folder has been updated since $time
1277
-	 *
1278
-	 * @param string $path
1279
-	 * @param int $time
1280
-	 * @return bool
1281
-	 */
1282
-	public function hasUpdated($path, $time) {
1283
-		return $this->basicOperation('hasUpdated', $path, array(), $time);
1284
-	}
1285
-
1286
-	/**
1287
-	 * @param string $ownerId
1288
-	 * @return \OC\User\User
1289
-	 */
1290
-	private function getUserObjectForOwner($ownerId) {
1291
-		$owner = $this->userManager->get($ownerId);
1292
-		if ($owner instanceof IUser) {
1293
-			return $owner;
1294
-		} else {
1295
-			return new User($ownerId, null);
1296
-		}
1297
-	}
1298
-
1299
-	/**
1300
-	 * Get file info from cache
1301
-	 *
1302
-	 * If the file is not in cached it will be scanned
1303
-	 * If the file has changed on storage the cache will be updated
1304
-	 *
1305
-	 * @param \OC\Files\Storage\Storage $storage
1306
-	 * @param string $internalPath
1307
-	 * @param string $relativePath
1308
-	 * @return ICacheEntry|bool
1309
-	 */
1310
-	private function getCacheEntry($storage, $internalPath, $relativePath) {
1311
-		$cache = $storage->getCache($internalPath);
1312
-		$data = $cache->get($internalPath);
1313
-		$watcher = $storage->getWatcher($internalPath);
1314
-
1315
-		try {
1316
-			// if the file is not in the cache or needs to be updated, trigger the scanner and reload the data
1317
-			if (!$data || $data['size'] === -1) {
1318
-				$this->lockFile($relativePath, ILockingProvider::LOCK_SHARED);
1319
-				if (!$storage->file_exists($internalPath)) {
1320
-					$this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED);
1321
-					return false;
1322
-				}
1323
-				$scanner = $storage->getScanner($internalPath);
1324
-				$scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
1325
-				$data = $cache->get($internalPath);
1326
-				$this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED);
1327
-			} else if (!Cache\Scanner::isPartialFile($internalPath) && $watcher->needsUpdate($internalPath, $data)) {
1328
-				$this->lockFile($relativePath, ILockingProvider::LOCK_SHARED);
1329
-				$watcher->update($internalPath, $data);
1330
-				$storage->getPropagator()->propagateChange($internalPath, time());
1331
-				$data = $cache->get($internalPath);
1332
-				$this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED);
1333
-			}
1334
-		} catch (LockedException $e) {
1335
-			// if the file is locked we just use the old cache info
1336
-		}
1337
-
1338
-		return $data;
1339
-	}
1340
-
1341
-	/**
1342
-	 * get the filesystem info
1343
-	 *
1344
-	 * @param string $path
1345
-	 * @param boolean|string $includeMountPoints true to add mountpoint sizes,
1346
-	 * 'ext' to add only ext storage mount point sizes. Defaults to true.
1347
-	 * defaults to true
1348
-	 * @return \OC\Files\FileInfo|false False if file does not exist
1349
-	 */
1350
-	public function getFileInfo($path, $includeMountPoints = true) {
1351
-		$this->assertPathLength($path);
1352
-		if (!Filesystem::isValidPath($path)) {
1353
-			return false;
1354
-		}
1355
-		if (Cache\Scanner::isPartialFile($path)) {
1356
-			return $this->getPartFileInfo($path);
1357
-		}
1358
-		$relativePath = $path;
1359
-		$path = Filesystem::normalizePath($this->fakeRoot . '/' . $path);
1360
-
1361
-		$mount = Filesystem::getMountManager()->find($path);
1362
-		if (!$mount) {
1363
-			return false;
1364
-		}
1365
-		$storage = $mount->getStorage();
1366
-		$internalPath = $mount->getInternalPath($path);
1367
-		if ($storage) {
1368
-			$data = $this->getCacheEntry($storage, $internalPath, $relativePath);
1369
-
1370
-			if (!$data instanceof ICacheEntry) {
1371
-				return false;
1372
-			}
1373
-
1374
-			if ($mount instanceof MoveableMount && $internalPath === '') {
1375
-				$data['permissions'] |= \OCP\Constants::PERMISSION_DELETE;
1376
-			}
1377
-
1378
-			$owner = $this->getUserObjectForOwner($storage->getOwner($internalPath));
1379
-			$info = new FileInfo($path, $storage, $internalPath, $data, $mount, $owner);
1380
-
1381
-			if ($data and isset($data['fileid'])) {
1382
-				if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') {
1383
-					//add the sizes of other mount points to the folder
1384
-					$extOnly = ($includeMountPoints === 'ext');
1385
-					$mounts = Filesystem::getMountManager()->findIn($path);
1386
-					$info->setSubMounts(array_filter($mounts, function (IMountPoint $mount) use ($extOnly) {
1387
-						$subStorage = $mount->getStorage();
1388
-						return !($extOnly && $subStorage instanceof \OCA\Files_Sharing\SharedStorage);
1389
-					}));
1390
-				}
1391
-			}
1392
-
1393
-			return $info;
1394
-		}
1395
-
1396
-		return false;
1397
-	}
1398
-
1399
-	/**
1400
-	 * get the content of a directory
1401
-	 *
1402
-	 * @param string $directory path under datadirectory
1403
-	 * @param string $mimetype_filter limit returned content to this mimetype or mimepart
1404
-	 * @return FileInfo[]
1405
-	 */
1406
-	public function getDirectoryContent($directory, $mimetype_filter = '') {
1407
-		$this->assertPathLength($directory);
1408
-		if (!Filesystem::isValidPath($directory)) {
1409
-			return [];
1410
-		}
1411
-		$path = $this->getAbsolutePath($directory);
1412
-		$path = Filesystem::normalizePath($path);
1413
-		$mount = $this->getMount($directory);
1414
-		if (!$mount) {
1415
-			return [];
1416
-		}
1417
-		$storage = $mount->getStorage();
1418
-		$internalPath = $mount->getInternalPath($path);
1419
-		if ($storage) {
1420
-			$cache = $storage->getCache($internalPath);
1421
-			$user = \OC_User::getUser();
1422
-
1423
-			$data = $this->getCacheEntry($storage, $internalPath, $directory);
1424
-
1425
-			if (!$data instanceof ICacheEntry || !isset($data['fileid']) || !($data->getPermissions() && Constants::PERMISSION_READ)) {
1426
-				return [];
1427
-			}
1428
-
1429
-			$folderId = $data['fileid'];
1430
-			$contents = $cache->getFolderContentsById($folderId); //TODO: mimetype_filter
1431
-
1432
-			$sharingDisabled = \OCP\Util::isSharingDisabledForUser();
1433
-			/**
1434
-			 * @var \OC\Files\FileInfo[] $files
1435
-			 */
1436
-			$files = array_map(function (ICacheEntry $content) use ($path, $storage, $mount, $sharingDisabled) {
1437
-				if ($sharingDisabled) {
1438
-					$content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
1439
-				}
1440
-				$owner = $this->getUserObjectForOwner($storage->getOwner($content['path']));
1441
-				return new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content, $mount, $owner);
1442
-			}, $contents);
1443
-
1444
-			//add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders
1445
-			$mounts = Filesystem::getMountManager()->findIn($path);
1446
-			$dirLength = strlen($path);
1447
-			foreach ($mounts as $mount) {
1448
-				$mountPoint = $mount->getMountPoint();
1449
-				$subStorage = $mount->getStorage();
1450
-				if ($subStorage) {
1451
-					$subCache = $subStorage->getCache('');
1452
-
1453
-					$rootEntry = $subCache->get('');
1454
-					if (!$rootEntry) {
1455
-						$subScanner = $subStorage->getScanner('');
1456
-						try {
1457
-							$subScanner->scanFile('');
1458
-						} catch (\OCP\Files\StorageNotAvailableException $e) {
1459
-							continue;
1460
-						} catch (\OCP\Files\StorageInvalidException $e) {
1461
-							continue;
1462
-						} catch (\Exception $e) {
1463
-							// sometimes when the storage is not available it can be any exception
1464
-							\OC::$server->getLogger()->logException($e, [
1465
-								'message' => 'Exception while scanning storage "' . $subStorage->getId() . '"',
1466
-								'level' => \OCP\Util::ERROR,
1467
-								'app' => 'lib',
1468
-							]);
1469
-							continue;
1470
-						}
1471
-						$rootEntry = $subCache->get('');
1472
-					}
1473
-
1474
-					if ($rootEntry && ($rootEntry->getPermissions() && Constants::PERMISSION_READ)) {
1475
-						$relativePath = trim(substr($mountPoint, $dirLength), '/');
1476
-						if ($pos = strpos($relativePath, '/')) {
1477
-							//mountpoint inside subfolder add size to the correct folder
1478
-							$entryName = substr($relativePath, 0, $pos);
1479
-							foreach ($files as &$entry) {
1480
-								if ($entry->getName() === $entryName) {
1481
-									$entry->addSubEntry($rootEntry, $mountPoint);
1482
-								}
1483
-							}
1484
-						} else { //mountpoint in this folder, add an entry for it
1485
-							$rootEntry['name'] = $relativePath;
1486
-							$rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file';
1487
-							$permissions = $rootEntry['permissions'];
1488
-							// do not allow renaming/deleting the mount point if they are not shared files/folders
1489
-							// for shared files/folders we use the permissions given by the owner
1490
-							if ($mount instanceof MoveableMount) {
1491
-								$rootEntry['permissions'] = $permissions | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
1492
-							} else {
1493
-								$rootEntry['permissions'] = $permissions & (\OCP\Constants::PERMISSION_ALL - (\OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE));
1494
-							}
1495
-
1496
-							//remove any existing entry with the same name
1497
-							foreach ($files as $i => $file) {
1498
-								if ($file['name'] === $rootEntry['name']) {
1499
-									unset($files[$i]);
1500
-									break;
1501
-								}
1502
-							}
1503
-							$rootEntry['path'] = substr(Filesystem::normalizePath($path . '/' . $rootEntry['name']), strlen($user) + 2); // full path without /$user/
1504
-
1505
-							// if sharing was disabled for the user we remove the share permissions
1506
-							if (\OCP\Util::isSharingDisabledForUser()) {
1507
-								$rootEntry['permissions'] = $rootEntry['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
1508
-							}
1509
-
1510
-							$owner = $this->getUserObjectForOwner($subStorage->getOwner(''));
1511
-							$files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry, $mount, $owner);
1512
-						}
1513
-					}
1514
-				}
1515
-			}
1516
-
1517
-			if ($mimetype_filter) {
1518
-				$files = array_filter($files, function (FileInfo $file) use ($mimetype_filter) {
1519
-					if (strpos($mimetype_filter, '/')) {
1520
-						return $file->getMimetype() === $mimetype_filter;
1521
-					} else {
1522
-						return $file->getMimePart() === $mimetype_filter;
1523
-					}
1524
-				});
1525
-			}
1526
-
1527
-			return $files;
1528
-		} else {
1529
-			return [];
1530
-		}
1531
-	}
1532
-
1533
-	/**
1534
-	 * change file metadata
1535
-	 *
1536
-	 * @param string $path
1537
-	 * @param array|\OCP\Files\FileInfo $data
1538
-	 * @return int
1539
-	 *
1540
-	 * returns the fileid of the updated file
1541
-	 */
1542
-	public function putFileInfo($path, $data) {
1543
-		$this->assertPathLength($path);
1544
-		if ($data instanceof FileInfo) {
1545
-			$data = $data->getData();
1546
-		}
1547
-		$path = Filesystem::normalizePath($this->fakeRoot . '/' . $path);
1548
-		/**
1549
-		 * @var \OC\Files\Storage\Storage $storage
1550
-		 * @var string $internalPath
1551
-		 */
1552
-		list($storage, $internalPath) = Filesystem::resolvePath($path);
1553
-		if ($storage) {
1554
-			$cache = $storage->getCache($path);
1555
-
1556
-			if (!$cache->inCache($internalPath)) {
1557
-				$scanner = $storage->getScanner($internalPath);
1558
-				$scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
1559
-			}
1560
-
1561
-			return $cache->put($internalPath, $data);
1562
-		} else {
1563
-			return -1;
1564
-		}
1565
-	}
1566
-
1567
-	/**
1568
-	 * search for files with the name matching $query
1569
-	 *
1570
-	 * @param string $query
1571
-	 * @return FileInfo[]
1572
-	 */
1573
-	public function search($query) {
1574
-		return $this->searchCommon('search', array('%' . $query . '%'));
1575
-	}
1576
-
1577
-	/**
1578
-	 * search for files with the name matching $query
1579
-	 *
1580
-	 * @param string $query
1581
-	 * @return FileInfo[]
1582
-	 */
1583
-	public function searchRaw($query) {
1584
-		return $this->searchCommon('search', array($query));
1585
-	}
1586
-
1587
-	/**
1588
-	 * search for files by mimetype
1589
-	 *
1590
-	 * @param string $mimetype
1591
-	 * @return FileInfo[]
1592
-	 */
1593
-	public function searchByMime($mimetype) {
1594
-		return $this->searchCommon('searchByMime', array($mimetype));
1595
-	}
1596
-
1597
-	/**
1598
-	 * search for files by tag
1599
-	 *
1600
-	 * @param string|int $tag name or tag id
1601
-	 * @param string $userId owner of the tags
1602
-	 * @return FileInfo[]
1603
-	 */
1604
-	public function searchByTag($tag, $userId) {
1605
-		return $this->searchCommon('searchByTag', array($tag, $userId));
1606
-	}
1607
-
1608
-	/**
1609
-	 * @param string $method cache method
1610
-	 * @param array $args
1611
-	 * @return FileInfo[]
1612
-	 */
1613
-	private function searchCommon($method, $args) {
1614
-		$files = array();
1615
-		$rootLength = strlen($this->fakeRoot);
1616
-
1617
-		$mount = $this->getMount('');
1618
-		$mountPoint = $mount->getMountPoint();
1619
-		$storage = $mount->getStorage();
1620
-		if ($storage) {
1621
-			$cache = $storage->getCache('');
1622
-
1623
-			$results = call_user_func_array(array($cache, $method), $args);
1624
-			foreach ($results as $result) {
1625
-				if (substr($mountPoint . $result['path'], 0, $rootLength + 1) === $this->fakeRoot . '/') {
1626
-					$internalPath = $result['path'];
1627
-					$path = $mountPoint . $result['path'];
1628
-					$result['path'] = substr($mountPoint . $result['path'], $rootLength);
1629
-					$owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
1630
-					$files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner);
1631
-				}
1632
-			}
1633
-
1634
-			$mounts = Filesystem::getMountManager()->findIn($this->fakeRoot);
1635
-			foreach ($mounts as $mount) {
1636
-				$mountPoint = $mount->getMountPoint();
1637
-				$storage = $mount->getStorage();
1638
-				if ($storage) {
1639
-					$cache = $storage->getCache('');
1640
-
1641
-					$relativeMountPoint = substr($mountPoint, $rootLength);
1642
-					$results = call_user_func_array(array($cache, $method), $args);
1643
-					if ($results) {
1644
-						foreach ($results as $result) {
1645
-							$internalPath = $result['path'];
1646
-							$result['path'] = rtrim($relativeMountPoint . $result['path'], '/');
1647
-							$path = rtrim($mountPoint . $internalPath, '/');
1648
-							$owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
1649
-							$files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner);
1650
-						}
1651
-					}
1652
-				}
1653
-			}
1654
-		}
1655
-		return $files;
1656
-	}
1657
-
1658
-	/**
1659
-	 * Get the owner for a file or folder
1660
-	 *
1661
-	 * @param string $path
1662
-	 * @return string the user id of the owner
1663
-	 * @throws NotFoundException
1664
-	 */
1665
-	public function getOwner($path) {
1666
-		$info = $this->getFileInfo($path);
1667
-		if (!$info) {
1668
-			throw new NotFoundException($path . ' not found while trying to get owner');
1669
-		}
1670
-		return $info->getOwner()->getUID();
1671
-	}
1672
-
1673
-	/**
1674
-	 * get the ETag for a file or folder
1675
-	 *
1676
-	 * @param string $path
1677
-	 * @return string
1678
-	 */
1679
-	public function getETag($path) {
1680
-		/**
1681
-		 * @var Storage\Storage $storage
1682
-		 * @var string $internalPath
1683
-		 */
1684
-		list($storage, $internalPath) = $this->resolvePath($path);
1685
-		if ($storage) {
1686
-			return $storage->getETag($internalPath);
1687
-		} else {
1688
-			return null;
1689
-		}
1690
-	}
1691
-
1692
-	/**
1693
-	 * Get the path of a file by id, relative to the view
1694
-	 *
1695
-	 * Note that the resulting path is not guarantied to be unique for the id, multiple paths can point to the same file
1696
-	 *
1697
-	 * @param int $id
1698
-	 * @throws NotFoundException
1699
-	 * @return string
1700
-	 */
1701
-	public function getPath($id) {
1702
-		$id = (int)$id;
1703
-		$manager = Filesystem::getMountManager();
1704
-		$mounts = $manager->findIn($this->fakeRoot);
1705
-		$mounts[] = $manager->find($this->fakeRoot);
1706
-		// reverse the array so we start with the storage this view is in
1707
-		// which is the most likely to contain the file we're looking for
1708
-		$mounts = array_reverse($mounts);
1709
-		foreach ($mounts as $mount) {
1710
-			/**
1711
-			 * @var \OC\Files\Mount\MountPoint $mount
1712
-			 */
1713
-			if ($mount->getStorage()) {
1714
-				$cache = $mount->getStorage()->getCache();
1715
-				$internalPath = $cache->getPathById($id);
1716
-				if (is_string($internalPath)) {
1717
-					$fullPath = $mount->getMountPoint() . $internalPath;
1718
-					if (!is_null($path = $this->getRelativePath($fullPath))) {
1719
-						return $path;
1720
-					}
1721
-				}
1722
-			}
1723
-		}
1724
-		throw new NotFoundException(sprintf('File with id "%s" has not been found.', $id));
1725
-	}
1726
-
1727
-	/**
1728
-	 * @param string $path
1729
-	 * @throws InvalidPathException
1730
-	 */
1731
-	private function assertPathLength($path) {
1732
-		$maxLen = min(PHP_MAXPATHLEN, 4000);
1733
-		// Check for the string length - performed using isset() instead of strlen()
1734
-		// because isset() is about 5x-40x faster.
1735
-		if (isset($path[$maxLen])) {
1736
-			$pathLen = strlen($path);
1737
-			throw new \OCP\Files\InvalidPathException("Path length($pathLen) exceeds max path length($maxLen): $path");
1738
-		}
1739
-	}
1740
-
1741
-	/**
1742
-	 * check if it is allowed to move a mount point to a given target.
1743
-	 * It is not allowed to move a mount point into a different mount point or
1744
-	 * into an already shared folder
1745
-	 *
1746
-	 * @param string $target path
1747
-	 * @return boolean
1748
-	 */
1749
-	private function isTargetAllowed($target) {
1750
-
1751
-		list($targetStorage, $targetInternalPath) = \OC\Files\Filesystem::resolvePath($target);
1752
-		if (!$targetStorage->instanceOfStorage('\OCP\Files\IHomeStorage')) {
1753
-			\OCP\Util::writeLog('files',
1754
-				'It is not allowed to move one mount point into another one',
1755
-				\OCP\Util::DEBUG);
1756
-			return false;
1757
-		}
1758
-
1759
-		// note: cannot use the view because the target is already locked
1760
-		$fileId = (int)$targetStorage->getCache()->getId($targetInternalPath);
1761
-		if ($fileId === -1) {
1762
-			// target might not exist, need to check parent instead
1763
-			$fileId = (int)$targetStorage->getCache()->getId(dirname($targetInternalPath));
1764
-		}
1765
-
1766
-		// check if any of the parents were shared by the current owner (include collections)
1767
-		$shares = \OCP\Share::getItemShared(
1768
-			'folder',
1769
-			$fileId,
1770
-			\OCP\Share::FORMAT_NONE,
1771
-			null,
1772
-			true
1773
-		);
1774
-
1775
-		if (count($shares) > 0) {
1776
-			\OCP\Util::writeLog('files',
1777
-				'It is not allowed to move one mount point into a shared folder',
1778
-				\OCP\Util::DEBUG);
1779
-			return false;
1780
-		}
1781
-
1782
-		return true;
1783
-	}
1784
-
1785
-	/**
1786
-	 * Get a fileinfo object for files that are ignored in the cache (part files)
1787
-	 *
1788
-	 * @param string $path
1789
-	 * @return \OCP\Files\FileInfo
1790
-	 */
1791
-	private function getPartFileInfo($path) {
1792
-		$mount = $this->getMount($path);
1793
-		$storage = $mount->getStorage();
1794
-		$internalPath = $mount->getInternalPath($this->getAbsolutePath($path));
1795
-		$owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
1796
-		return new FileInfo(
1797
-			$this->getAbsolutePath($path),
1798
-			$storage,
1799
-			$internalPath,
1800
-			[
1801
-				'fileid' => null,
1802
-				'mimetype' => $storage->getMimeType($internalPath),
1803
-				'name' => basename($path),
1804
-				'etag' => null,
1805
-				'size' => $storage->filesize($internalPath),
1806
-				'mtime' => $storage->filemtime($internalPath),
1807
-				'encrypted' => false,
1808
-				'permissions' => \OCP\Constants::PERMISSION_ALL
1809
-			],
1810
-			$mount,
1811
-			$owner
1812
-		);
1813
-	}
1814
-
1815
-	/**
1816
-	 * @param string $path
1817
-	 * @param string $fileName
1818
-	 * @throws InvalidPathException
1819
-	 */
1820
-	public function verifyPath($path, $fileName) {
1821
-		try {
1822
-			/** @type \OCP\Files\Storage $storage */
1823
-			list($storage, $internalPath) = $this->resolvePath($path);
1824
-			$storage->verifyPath($internalPath, $fileName);
1825
-		} catch (ReservedWordException $ex) {
1826
-			$l = \OC::$server->getL10N('lib');
1827
-			throw new InvalidPathException($l->t('File name is a reserved word'));
1828
-		} catch (InvalidCharacterInPathException $ex) {
1829
-			$l = \OC::$server->getL10N('lib');
1830
-			throw new InvalidPathException($l->t('File name contains at least one invalid character'));
1831
-		} catch (FileNameTooLongException $ex) {
1832
-			$l = \OC::$server->getL10N('lib');
1833
-			throw new InvalidPathException($l->t('File name is too long'));
1834
-		} catch (InvalidDirectoryException $ex) {
1835
-			$l = \OC::$server->getL10N('lib');
1836
-			throw new InvalidPathException($l->t('Dot files are not allowed'));
1837
-		} catch (EmptyFileNameException $ex) {
1838
-			$l = \OC::$server->getL10N('lib');
1839
-			throw new InvalidPathException($l->t('Empty filename is not allowed'));
1840
-		}
1841
-	}
1842
-
1843
-	/**
1844
-	 * get all parent folders of $path
1845
-	 *
1846
-	 * @param string $path
1847
-	 * @return string[]
1848
-	 */
1849
-	private function getParents($path) {
1850
-		$path = trim($path, '/');
1851
-		if (!$path) {
1852
-			return [];
1853
-		}
1854
-
1855
-		$parts = explode('/', $path);
1856
-
1857
-		// remove the single file
1858
-		array_pop($parts);
1859
-		$result = array('/');
1860
-		$resultPath = '';
1861
-		foreach ($parts as $part) {
1862
-			if ($part) {
1863
-				$resultPath .= '/' . $part;
1864
-				$result[] = $resultPath;
1865
-			}
1866
-		}
1867
-		return $result;
1868
-	}
1869
-
1870
-	/**
1871
-	 * Returns the mount point for which to lock
1872
-	 *
1873
-	 * @param string $absolutePath absolute path
1874
-	 * @param bool $useParentMount true to return parent mount instead of whatever
1875
-	 * is mounted directly on the given path, false otherwise
1876
-	 * @return \OC\Files\Mount\MountPoint mount point for which to apply locks
1877
-	 */
1878
-	private function getMountForLock($absolutePath, $useParentMount = false) {
1879
-		$results = [];
1880
-		$mount = Filesystem::getMountManager()->find($absolutePath);
1881
-		if (!$mount) {
1882
-			return $results;
1883
-		}
1884
-
1885
-		if ($useParentMount) {
1886
-			// find out if something is mounted directly on the path
1887
-			$internalPath = $mount->getInternalPath($absolutePath);
1888
-			if ($internalPath === '') {
1889
-				// resolve the parent mount instead
1890
-				$mount = Filesystem::getMountManager()->find(dirname($absolutePath));
1891
-			}
1892
-		}
1893
-
1894
-		return $mount;
1895
-	}
1896
-
1897
-	/**
1898
-	 * Lock the given path
1899
-	 *
1900
-	 * @param string $path the path of the file to lock, relative to the view
1901
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
1902
-	 * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
1903
-	 *
1904
-	 * @return bool False if the path is excluded from locking, true otherwise
1905
-	 * @throws \OCP\Lock\LockedException if the path is already locked
1906
-	 */
1907
-	private function lockPath($path, $type, $lockMountPoint = false) {
1908
-		$absolutePath = $this->getAbsolutePath($path);
1909
-		$absolutePath = Filesystem::normalizePath($absolutePath);
1910
-		if (!$this->shouldLockFile($absolutePath)) {
1911
-			return false;
1912
-		}
1913
-
1914
-		$mount = $this->getMountForLock($absolutePath, $lockMountPoint);
1915
-		if ($mount) {
1916
-			try {
1917
-				$storage = $mount->getStorage();
1918
-				if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
1919
-					$storage->acquireLock(
1920
-						$mount->getInternalPath($absolutePath),
1921
-						$type,
1922
-						$this->lockingProvider
1923
-					);
1924
-				}
1925
-			} catch (\OCP\Lock\LockedException $e) {
1926
-				// rethrow with the a human-readable path
1927
-				throw new \OCP\Lock\LockedException(
1928
-					$this->getPathRelativeToFiles($absolutePath),
1929
-					$e
1930
-				);
1931
-			}
1932
-		}
1933
-
1934
-		return true;
1935
-	}
1936
-
1937
-	/**
1938
-	 * Change the lock type
1939
-	 *
1940
-	 * @param string $path the path of the file to lock, relative to the view
1941
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
1942
-	 * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
1943
-	 *
1944
-	 * @return bool False if the path is excluded from locking, true otherwise
1945
-	 * @throws \OCP\Lock\LockedException if the path is already locked
1946
-	 */
1947
-	public function changeLock($path, $type, $lockMountPoint = false) {
1948
-		$path = Filesystem::normalizePath($path);
1949
-		$absolutePath = $this->getAbsolutePath($path);
1950
-		$absolutePath = Filesystem::normalizePath($absolutePath);
1951
-		if (!$this->shouldLockFile($absolutePath)) {
1952
-			return false;
1953
-		}
1954
-
1955
-		$mount = $this->getMountForLock($absolutePath, $lockMountPoint);
1956
-		if ($mount) {
1957
-			try {
1958
-				$storage = $mount->getStorage();
1959
-				if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
1960
-					$storage->changeLock(
1961
-						$mount->getInternalPath($absolutePath),
1962
-						$type,
1963
-						$this->lockingProvider
1964
-					);
1965
-				}
1966
-			} catch (\OCP\Lock\LockedException $e) {
1967
-				try {
1968
-					// rethrow with the a human-readable path
1969
-					throw new \OCP\Lock\LockedException(
1970
-						$this->getPathRelativeToFiles($absolutePath),
1971
-						$e
1972
-					);
1973
-				} catch (\InvalidArgumentException $e) {
1974
-					throw new \OCP\Lock\LockedException(
1975
-						$absolutePath,
1976
-						$e
1977
-					);
1978
-				}
1979
-			}
1980
-		}
1981
-
1982
-		return true;
1983
-	}
1984
-
1985
-	/**
1986
-	 * Unlock the given path
1987
-	 *
1988
-	 * @param string $path the path of the file to unlock, relative to the view
1989
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
1990
-	 * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
1991
-	 *
1992
-	 * @return bool False if the path is excluded from locking, true otherwise
1993
-	 */
1994
-	private function unlockPath($path, $type, $lockMountPoint = false) {
1995
-		$absolutePath = $this->getAbsolutePath($path);
1996
-		$absolutePath = Filesystem::normalizePath($absolutePath);
1997
-		if (!$this->shouldLockFile($absolutePath)) {
1998
-			return false;
1999
-		}
2000
-
2001
-		$mount = $this->getMountForLock($absolutePath, $lockMountPoint);
2002
-		if ($mount) {
2003
-			$storage = $mount->getStorage();
2004
-			if ($storage && $storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
2005
-				$storage->releaseLock(
2006
-					$mount->getInternalPath($absolutePath),
2007
-					$type,
2008
-					$this->lockingProvider
2009
-				);
2010
-			}
2011
-		}
2012
-
2013
-		return true;
2014
-	}
2015
-
2016
-	/**
2017
-	 * Lock a path and all its parents up to the root of the view
2018
-	 *
2019
-	 * @param string $path the path of the file to lock relative to the view
2020
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
2021
-	 * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
2022
-	 *
2023
-	 * @return bool False if the path is excluded from locking, true otherwise
2024
-	 */
2025
-	public function lockFile($path, $type, $lockMountPoint = false) {
2026
-		$absolutePath = $this->getAbsolutePath($path);
2027
-		$absolutePath = Filesystem::normalizePath($absolutePath);
2028
-		if (!$this->shouldLockFile($absolutePath)) {
2029
-			return false;
2030
-		}
2031
-
2032
-		$this->lockPath($path, $type, $lockMountPoint);
2033
-
2034
-		$parents = $this->getParents($path);
2035
-		foreach ($parents as $parent) {
2036
-			$this->lockPath($parent, ILockingProvider::LOCK_SHARED);
2037
-		}
2038
-
2039
-		return true;
2040
-	}
2041
-
2042
-	/**
2043
-	 * Unlock a path and all its parents up to the root of the view
2044
-	 *
2045
-	 * @param string $path the path of the file to lock relative to the view
2046
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
2047
-	 * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
2048
-	 *
2049
-	 * @return bool False if the path is excluded from locking, true otherwise
2050
-	 */
2051
-	public function unlockFile($path, $type, $lockMountPoint = false) {
2052
-		$absolutePath = $this->getAbsolutePath($path);
2053
-		$absolutePath = Filesystem::normalizePath($absolutePath);
2054
-		if (!$this->shouldLockFile($absolutePath)) {
2055
-			return false;
2056
-		}
2057
-
2058
-		$this->unlockPath($path, $type, $lockMountPoint);
2059
-
2060
-		$parents = $this->getParents($path);
2061
-		foreach ($parents as $parent) {
2062
-			$this->unlockPath($parent, ILockingProvider::LOCK_SHARED);
2063
-		}
2064
-
2065
-		return true;
2066
-	}
2067
-
2068
-	/**
2069
-	 * Only lock files in data/user/files/
2070
-	 *
2071
-	 * @param string $path Absolute path to the file/folder we try to (un)lock
2072
-	 * @return bool
2073
-	 */
2074
-	protected function shouldLockFile($path) {
2075
-		$path = Filesystem::normalizePath($path);
2076
-
2077
-		$pathSegments = explode('/', $path);
2078
-		if (isset($pathSegments[2])) {
2079
-			// E.g.: /username/files/path-to-file
2080
-			return ($pathSegments[2] === 'files') && (count($pathSegments) > 3);
2081
-		}
2082
-
2083
-		return strpos($path, '/appdata_') !== 0;
2084
-	}
2085
-
2086
-	/**
2087
-	 * Shortens the given absolute path to be relative to
2088
-	 * "$user/files".
2089
-	 *
2090
-	 * @param string $absolutePath absolute path which is under "files"
2091
-	 *
2092
-	 * @return string path relative to "files" with trimmed slashes or null
2093
-	 * if the path was NOT relative to files
2094
-	 *
2095
-	 * @throws \InvalidArgumentException if the given path was not under "files"
2096
-	 * @since 8.1.0
2097
-	 */
2098
-	public function getPathRelativeToFiles($absolutePath) {
2099
-		$path = Filesystem::normalizePath($absolutePath);
2100
-		$parts = explode('/', trim($path, '/'), 3);
2101
-		// "$user", "files", "path/to/dir"
2102
-		if (!isset($parts[1]) || $parts[1] !== 'files') {
2103
-			$this->logger->error(
2104
-				'$absolutePath must be relative to "files", value is "%s"',
2105
-				[
2106
-					$absolutePath
2107
-				]
2108
-			);
2109
-			throw new \InvalidArgumentException('$absolutePath must be relative to "files"');
2110
-		}
2111
-		if (isset($parts[2])) {
2112
-			return $parts[2];
2113
-		}
2114
-		return '';
2115
-	}
2116
-
2117
-	/**
2118
-	 * @param string $filename
2119
-	 * @return array
2120
-	 * @throws \OC\User\NoUserException
2121
-	 * @throws NotFoundException
2122
-	 */
2123
-	public function getUidAndFilename($filename) {
2124
-		$info = $this->getFileInfo($filename);
2125
-		if (!$info instanceof \OCP\Files\FileInfo) {
2126
-			throw new NotFoundException($this->getAbsolutePath($filename) . ' not found');
2127
-		}
2128
-		$uid = $info->getOwner()->getUID();
2129
-		if ($uid != \OCP\User::getUser()) {
2130
-			Filesystem::initMountPoints($uid);
2131
-			$ownerView = new View('/' . $uid . '/files');
2132
-			try {
2133
-				$filename = $ownerView->getPath($info['fileid']);
2134
-			} catch (NotFoundException $e) {
2135
-				throw new NotFoundException('File with id ' . $info['fileid'] . ' not found for user ' . $uid);
2136
-			}
2137
-		}
2138
-		return [$uid, $filename];
2139
-	}
2140
-
2141
-	/**
2142
-	 * Creates parent non-existing folders
2143
-	 *
2144
-	 * @param string $filePath
2145
-	 * @return bool
2146
-	 */
2147
-	private function createParentDirectories($filePath) {
2148
-		$directoryParts = explode('/', $filePath);
2149
-		$directoryParts = array_filter($directoryParts);
2150
-		foreach ($directoryParts as $key => $part) {
2151
-			$currentPathElements = array_slice($directoryParts, 0, $key);
2152
-			$currentPath = '/' . implode('/', $currentPathElements);
2153
-			if ($this->is_file($currentPath)) {
2154
-				return false;
2155
-			}
2156
-			if (!$this->file_exists($currentPath)) {
2157
-				$this->mkdir($currentPath);
2158
-			}
2159
-		}
2160
-
2161
-		return true;
2162
-	}
83
+    /** @var string */
84
+    private $fakeRoot = '';
85
+
86
+    /**
87
+     * @var \OCP\Lock\ILockingProvider
88
+     */
89
+    protected $lockingProvider;
90
+
91
+    private $lockingEnabled;
92
+
93
+    private $updaterEnabled = true;
94
+
95
+    /** @var \OC\User\Manager */
96
+    private $userManager;
97
+
98
+    /** @var \OCP\ILogger */
99
+    private $logger;
100
+
101
+    /**
102
+     * @param string $root
103
+     * @throws \Exception If $root contains an invalid path
104
+     */
105
+    public function __construct($root = '') {
106
+        if (is_null($root)) {
107
+            throw new \InvalidArgumentException('Root can\'t be null');
108
+        }
109
+        if (!Filesystem::isValidPath($root)) {
110
+            throw new \Exception();
111
+        }
112
+
113
+        $this->fakeRoot = $root;
114
+        $this->lockingProvider = \OC::$server->getLockingProvider();
115
+        $this->lockingEnabled = !($this->lockingProvider instanceof \OC\Lock\NoopLockingProvider);
116
+        $this->userManager = \OC::$server->getUserManager();
117
+        $this->logger = \OC::$server->getLogger();
118
+    }
119
+
120
+    public function getAbsolutePath($path = '/') {
121
+        if ($path === null) {
122
+            return null;
123
+        }
124
+        $this->assertPathLength($path);
125
+        if ($path === '') {
126
+            $path = '/';
127
+        }
128
+        if ($path[0] !== '/') {
129
+            $path = '/' . $path;
130
+        }
131
+        return $this->fakeRoot . $path;
132
+    }
133
+
134
+    /**
135
+     * change the root to a fake root
136
+     *
137
+     * @param string $fakeRoot
138
+     * @return boolean|null
139
+     */
140
+    public function chroot($fakeRoot) {
141
+        if (!$fakeRoot == '') {
142
+            if ($fakeRoot[0] !== '/') {
143
+                $fakeRoot = '/' . $fakeRoot;
144
+            }
145
+        }
146
+        $this->fakeRoot = $fakeRoot;
147
+    }
148
+
149
+    /**
150
+     * get the fake root
151
+     *
152
+     * @return string
153
+     */
154
+    public function getRoot() {
155
+        return $this->fakeRoot;
156
+    }
157
+
158
+    /**
159
+     * get path relative to the root of the view
160
+     *
161
+     * @param string $path
162
+     * @return string
163
+     */
164
+    public function getRelativePath($path) {
165
+        $this->assertPathLength($path);
166
+        if ($this->fakeRoot == '') {
167
+            return $path;
168
+        }
169
+
170
+        if (rtrim($path, '/') === rtrim($this->fakeRoot, '/')) {
171
+            return '/';
172
+        }
173
+
174
+        // missing slashes can cause wrong matches!
175
+        $root = rtrim($this->fakeRoot, '/') . '/';
176
+
177
+        if (strpos($path, $root) !== 0) {
178
+            return null;
179
+        } else {
180
+            $path = substr($path, strlen($this->fakeRoot));
181
+            if (strlen($path) === 0) {
182
+                return '/';
183
+            } else {
184
+                return $path;
185
+            }
186
+        }
187
+    }
188
+
189
+    /**
190
+     * get the mountpoint of the storage object for a path
191
+     * ( note: because a storage is not always mounted inside the fakeroot, the
192
+     * returned mountpoint is relative to the absolute root of the filesystem
193
+     * and does not take the chroot into account )
194
+     *
195
+     * @param string $path
196
+     * @return string
197
+     */
198
+    public function getMountPoint($path) {
199
+        return Filesystem::getMountPoint($this->getAbsolutePath($path));
200
+    }
201
+
202
+    /**
203
+     * get the mountpoint of the storage object for a path
204
+     * ( note: because a storage is not always mounted inside the fakeroot, the
205
+     * returned mountpoint is relative to the absolute root of the filesystem
206
+     * and does not take the chroot into account )
207
+     *
208
+     * @param string $path
209
+     * @return \OCP\Files\Mount\IMountPoint
210
+     */
211
+    public function getMount($path) {
212
+        return Filesystem::getMountManager()->find($this->getAbsolutePath($path));
213
+    }
214
+
215
+    /**
216
+     * resolve a path to a storage and internal path
217
+     *
218
+     * @param string $path
219
+     * @return array an array consisting of the storage and the internal path
220
+     */
221
+    public function resolvePath($path) {
222
+        $a = $this->getAbsolutePath($path);
223
+        $p = Filesystem::normalizePath($a);
224
+        return Filesystem::resolvePath($p);
225
+    }
226
+
227
+    /**
228
+     * return the path to a local version of the file
229
+     * we need this because we can't know if a file is stored local or not from
230
+     * outside the filestorage and for some purposes a local file is needed
231
+     *
232
+     * @param string $path
233
+     * @return string
234
+     */
235
+    public function getLocalFile($path) {
236
+        $parent = substr($path, 0, strrpos($path, '/'));
237
+        $path = $this->getAbsolutePath($path);
238
+        list($storage, $internalPath) = Filesystem::resolvePath($path);
239
+        if (Filesystem::isValidPath($parent) and $storage) {
240
+            return $storage->getLocalFile($internalPath);
241
+        } else {
242
+            return null;
243
+        }
244
+    }
245
+
246
+    /**
247
+     * @param string $path
248
+     * @return string
249
+     */
250
+    public function getLocalFolder($path) {
251
+        $parent = substr($path, 0, strrpos($path, '/'));
252
+        $path = $this->getAbsolutePath($path);
253
+        list($storage, $internalPath) = Filesystem::resolvePath($path);
254
+        if (Filesystem::isValidPath($parent) and $storage) {
255
+            return $storage->getLocalFolder($internalPath);
256
+        } else {
257
+            return null;
258
+        }
259
+    }
260
+
261
+    /**
262
+     * the following functions operate with arguments and return values identical
263
+     * to those of their PHP built-in equivalents. Mostly they are merely wrappers
264
+     * for \OC\Files\Storage\Storage via basicOperation().
265
+     */
266
+    public function mkdir($path) {
267
+        return $this->basicOperation('mkdir', $path, array('create', 'write'));
268
+    }
269
+
270
+    /**
271
+     * remove mount point
272
+     *
273
+     * @param \OC\Files\Mount\MoveableMount $mount
274
+     * @param string $path relative to data/
275
+     * @return boolean
276
+     */
277
+    protected function removeMount($mount, $path) {
278
+        if ($mount instanceof MoveableMount) {
279
+            // cut of /user/files to get the relative path to data/user/files
280
+            $pathParts = explode('/', $path, 4);
281
+            $relPath = '/' . $pathParts[3];
282
+            $this->lockFile($relPath, ILockingProvider::LOCK_SHARED, true);
283
+            \OC_Hook::emit(
284
+                Filesystem::CLASSNAME, "umount",
285
+                array(Filesystem::signal_param_path => $relPath)
286
+            );
287
+            $this->changeLock($relPath, ILockingProvider::LOCK_EXCLUSIVE, true);
288
+            $result = $mount->removeMount();
289
+            $this->changeLock($relPath, ILockingProvider::LOCK_SHARED, true);
290
+            if ($result) {
291
+                \OC_Hook::emit(
292
+                    Filesystem::CLASSNAME, "post_umount",
293
+                    array(Filesystem::signal_param_path => $relPath)
294
+                );
295
+            }
296
+            $this->unlockFile($relPath, ILockingProvider::LOCK_SHARED, true);
297
+            return $result;
298
+        } else {
299
+            // do not allow deleting the storage's root / the mount point
300
+            // because for some storages it might delete the whole contents
301
+            // but isn't supposed to work that way
302
+            return false;
303
+        }
304
+    }
305
+
306
+    public function disableCacheUpdate() {
307
+        $this->updaterEnabled = false;
308
+    }
309
+
310
+    public function enableCacheUpdate() {
311
+        $this->updaterEnabled = true;
312
+    }
313
+
314
+    protected function writeUpdate(Storage $storage, $internalPath, $time = null) {
315
+        if ($this->updaterEnabled) {
316
+            if (is_null($time)) {
317
+                $time = time();
318
+            }
319
+            $storage->getUpdater()->update($internalPath, $time);
320
+        }
321
+    }
322
+
323
+    protected function removeUpdate(Storage $storage, $internalPath) {
324
+        if ($this->updaterEnabled) {
325
+            $storage->getUpdater()->remove($internalPath);
326
+        }
327
+    }
328
+
329
+    protected function renameUpdate(Storage $sourceStorage, Storage $targetStorage, $sourceInternalPath, $targetInternalPath) {
330
+        if ($this->updaterEnabled) {
331
+            $targetStorage->getUpdater()->renameFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
332
+        }
333
+    }
334
+
335
+    /**
336
+     * @param string $path
337
+     * @return bool|mixed
338
+     */
339
+    public function rmdir($path) {
340
+        $absolutePath = $this->getAbsolutePath($path);
341
+        $mount = Filesystem::getMountManager()->find($absolutePath);
342
+        if ($mount->getInternalPath($absolutePath) === '') {
343
+            return $this->removeMount($mount, $absolutePath);
344
+        }
345
+        if ($this->is_dir($path)) {
346
+            $result = $this->basicOperation('rmdir', $path, array('delete'));
347
+        } else {
348
+            $result = false;
349
+        }
350
+
351
+        if (!$result && !$this->file_exists($path)) { //clear ghost files from the cache on delete
352
+            $storage = $mount->getStorage();
353
+            $internalPath = $mount->getInternalPath($absolutePath);
354
+            $storage->getUpdater()->remove($internalPath);
355
+        }
356
+        return $result;
357
+    }
358
+
359
+    /**
360
+     * @param string $path
361
+     * @return resource
362
+     */
363
+    public function opendir($path) {
364
+        return $this->basicOperation('opendir', $path, array('read'));
365
+    }
366
+
367
+    /**
368
+     * @param string $path
369
+     * @return bool|mixed
370
+     */
371
+    public function is_dir($path) {
372
+        if ($path == '/') {
373
+            return true;
374
+        }
375
+        return $this->basicOperation('is_dir', $path);
376
+    }
377
+
378
+    /**
379
+     * @param string $path
380
+     * @return bool|mixed
381
+     */
382
+    public function is_file($path) {
383
+        if ($path == '/') {
384
+            return false;
385
+        }
386
+        return $this->basicOperation('is_file', $path);
387
+    }
388
+
389
+    /**
390
+     * @param string $path
391
+     * @return mixed
392
+     */
393
+    public function stat($path) {
394
+        return $this->basicOperation('stat', $path);
395
+    }
396
+
397
+    /**
398
+     * @param string $path
399
+     * @return mixed
400
+     */
401
+    public function filetype($path) {
402
+        return $this->basicOperation('filetype', $path);
403
+    }
404
+
405
+    /**
406
+     * @param string $path
407
+     * @return mixed
408
+     */
409
+    public function filesize($path) {
410
+        return $this->basicOperation('filesize', $path);
411
+    }
412
+
413
+    /**
414
+     * @param string $path
415
+     * @return bool|mixed
416
+     * @throws \OCP\Files\InvalidPathException
417
+     */
418
+    public function readfile($path) {
419
+        $this->assertPathLength($path);
420
+        @ob_end_clean();
421
+        $handle = $this->fopen($path, 'rb');
422
+        if ($handle) {
423
+            $chunkSize = 8192; // 8 kB chunks
424
+            while (!feof($handle)) {
425
+                echo fread($handle, $chunkSize);
426
+                flush();
427
+            }
428
+            fclose($handle);
429
+            return $this->filesize($path);
430
+        }
431
+        return false;
432
+    }
433
+
434
+    /**
435
+     * @param string $path
436
+     * @param int $from
437
+     * @param int $to
438
+     * @return bool|mixed
439
+     * @throws \OCP\Files\InvalidPathException
440
+     * @throws \OCP\Files\UnseekableException
441
+     */
442
+    public function readfilePart($path, $from, $to) {
443
+        $this->assertPathLength($path);
444
+        @ob_end_clean();
445
+        $handle = $this->fopen($path, 'rb');
446
+        if ($handle) {
447
+            $chunkSize = 8192; // 8 kB chunks
448
+            $startReading = true;
449
+
450
+            if ($from !== 0 && $from !== '0' && fseek($handle, $from) !== 0) {
451
+                // forward file handle via chunked fread because fseek seem to have failed
452
+
453
+                $end = $from + 1;
454
+                while (!feof($handle) && ftell($handle) < $end) {
455
+                    $len = $from - ftell($handle);
456
+                    if ($len > $chunkSize) {
457
+                        $len = $chunkSize;
458
+                    }
459
+                    $result = fread($handle, $len);
460
+
461
+                    if ($result === false) {
462
+                        $startReading = false;
463
+                        break;
464
+                    }
465
+                }
466
+            }
467
+
468
+            if ($startReading) {
469
+                $end = $to + 1;
470
+                while (!feof($handle) && ftell($handle) < $end) {
471
+                    $len = $end - ftell($handle);
472
+                    if ($len > $chunkSize) {
473
+                        $len = $chunkSize;
474
+                    }
475
+                    echo fread($handle, $len);
476
+                    flush();
477
+                }
478
+                return ftell($handle) - $from;
479
+            }
480
+
481
+            throw new \OCP\Files\UnseekableException('fseek error');
482
+        }
483
+        return false;
484
+    }
485
+
486
+    /**
487
+     * @param string $path
488
+     * @return mixed
489
+     */
490
+    public function isCreatable($path) {
491
+        return $this->basicOperation('isCreatable', $path);
492
+    }
493
+
494
+    /**
495
+     * @param string $path
496
+     * @return mixed
497
+     */
498
+    public function isReadable($path) {
499
+        return $this->basicOperation('isReadable', $path);
500
+    }
501
+
502
+    /**
503
+     * @param string $path
504
+     * @return mixed
505
+     */
506
+    public function isUpdatable($path) {
507
+        return $this->basicOperation('isUpdatable', $path);
508
+    }
509
+
510
+    /**
511
+     * @param string $path
512
+     * @return bool|mixed
513
+     */
514
+    public function isDeletable($path) {
515
+        $absolutePath = $this->getAbsolutePath($path);
516
+        $mount = Filesystem::getMountManager()->find($absolutePath);
517
+        if ($mount->getInternalPath($absolutePath) === '') {
518
+            return $mount instanceof MoveableMount;
519
+        }
520
+        return $this->basicOperation('isDeletable', $path);
521
+    }
522
+
523
+    /**
524
+     * @param string $path
525
+     * @return mixed
526
+     */
527
+    public function isSharable($path) {
528
+        return $this->basicOperation('isSharable', $path);
529
+    }
530
+
531
+    /**
532
+     * @param string $path
533
+     * @return bool|mixed
534
+     */
535
+    public function file_exists($path) {
536
+        if ($path == '/') {
537
+            return true;
538
+        }
539
+        return $this->basicOperation('file_exists', $path);
540
+    }
541
+
542
+    /**
543
+     * @param string $path
544
+     * @return mixed
545
+     */
546
+    public function filemtime($path) {
547
+        return $this->basicOperation('filemtime', $path);
548
+    }
549
+
550
+    /**
551
+     * @param string $path
552
+     * @param int|string $mtime
553
+     * @return bool
554
+     */
555
+    public function touch($path, $mtime = null) {
556
+        if (!is_null($mtime) and !is_numeric($mtime)) {
557
+            $mtime = strtotime($mtime);
558
+        }
559
+
560
+        $hooks = array('touch');
561
+
562
+        if (!$this->file_exists($path)) {
563
+            $hooks[] = 'create';
564
+            $hooks[] = 'write';
565
+        }
566
+        $result = $this->basicOperation('touch', $path, $hooks, $mtime);
567
+        if (!$result) {
568
+            // If create file fails because of permissions on external storage like SMB folders,
569
+            // check file exists and return false if not.
570
+            if (!$this->file_exists($path)) {
571
+                return false;
572
+            }
573
+            if (is_null($mtime)) {
574
+                $mtime = time();
575
+            }
576
+            //if native touch fails, we emulate it by changing the mtime in the cache
577
+            $this->putFileInfo($path, array('mtime' => floor($mtime)));
578
+        }
579
+        return true;
580
+    }
581
+
582
+    /**
583
+     * @param string $path
584
+     * @return mixed
585
+     */
586
+    public function file_get_contents($path) {
587
+        return $this->basicOperation('file_get_contents', $path, array('read'));
588
+    }
589
+
590
+    /**
591
+     * @param bool $exists
592
+     * @param string $path
593
+     * @param bool $run
594
+     */
595
+    protected function emit_file_hooks_pre($exists, $path, &$run) {
596
+        if (!$exists) {
597
+            \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_create, array(
598
+                Filesystem::signal_param_path => $this->getHookPath($path),
599
+                Filesystem::signal_param_run => &$run,
600
+            ));
601
+        } else {
602
+            \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_update, array(
603
+                Filesystem::signal_param_path => $this->getHookPath($path),
604
+                Filesystem::signal_param_run => &$run,
605
+            ));
606
+        }
607
+        \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_write, array(
608
+            Filesystem::signal_param_path => $this->getHookPath($path),
609
+            Filesystem::signal_param_run => &$run,
610
+        ));
611
+    }
612
+
613
+    /**
614
+     * @param bool $exists
615
+     * @param string $path
616
+     */
617
+    protected function emit_file_hooks_post($exists, $path) {
618
+        if (!$exists) {
619
+            \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_create, array(
620
+                Filesystem::signal_param_path => $this->getHookPath($path),
621
+            ));
622
+        } else {
623
+            \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_update, array(
624
+                Filesystem::signal_param_path => $this->getHookPath($path),
625
+            ));
626
+        }
627
+        \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_write, array(
628
+            Filesystem::signal_param_path => $this->getHookPath($path),
629
+        ));
630
+    }
631
+
632
+    /**
633
+     * @param string $path
634
+     * @param mixed $data
635
+     * @return bool|mixed
636
+     * @throws \Exception
637
+     */
638
+    public function file_put_contents($path, $data) {
639
+        if (is_resource($data)) { //not having to deal with streams in file_put_contents makes life easier
640
+            $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
641
+            if (Filesystem::isValidPath($path)
642
+                and !Filesystem::isFileBlacklisted($path)
643
+            ) {
644
+                $path = $this->getRelativePath($absolutePath);
645
+
646
+                $this->lockFile($path, ILockingProvider::LOCK_SHARED);
647
+
648
+                $exists = $this->file_exists($path);
649
+                $run = true;
650
+                if ($this->shouldEmitHooks($path)) {
651
+                    $this->emit_file_hooks_pre($exists, $path, $run);
652
+                }
653
+                if (!$run) {
654
+                    $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
655
+                    return false;
656
+                }
657
+
658
+                $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
659
+
660
+                /** @var \OC\Files\Storage\Storage $storage */
661
+                list($storage, $internalPath) = $this->resolvePath($path);
662
+                $target = $storage->fopen($internalPath, 'w');
663
+                if ($target) {
664
+                    list (, $result) = \OC_Helper::streamCopy($data, $target);
665
+                    fclose($target);
666
+                    fclose($data);
667
+
668
+                    $this->writeUpdate($storage, $internalPath);
669
+
670
+                    $this->changeLock($path, ILockingProvider::LOCK_SHARED);
671
+
672
+                    if ($this->shouldEmitHooks($path) && $result !== false) {
673
+                        $this->emit_file_hooks_post($exists, $path);
674
+                    }
675
+                    $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
676
+                    return $result;
677
+                } else {
678
+                    $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
679
+                    return false;
680
+                }
681
+            } else {
682
+                return false;
683
+            }
684
+        } else {
685
+            $hooks = ($this->file_exists($path)) ? array('update', 'write') : array('create', 'write');
686
+            return $this->basicOperation('file_put_contents', $path, $hooks, $data);
687
+        }
688
+    }
689
+
690
+    /**
691
+     * @param string $path
692
+     * @return bool|mixed
693
+     */
694
+    public function unlink($path) {
695
+        if ($path === '' || $path === '/') {
696
+            // do not allow deleting the root
697
+            return false;
698
+        }
699
+        $postFix = (substr($path, -1, 1) === '/') ? '/' : '';
700
+        $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
701
+        $mount = Filesystem::getMountManager()->find($absolutePath . $postFix);
702
+        if ($mount and $mount->getInternalPath($absolutePath) === '') {
703
+            return $this->removeMount($mount, $absolutePath);
704
+        }
705
+        if ($this->is_dir($path)) {
706
+            $result = $this->basicOperation('rmdir', $path, ['delete']);
707
+        } else {
708
+            $result = $this->basicOperation('unlink', $path, ['delete']);
709
+        }
710
+        if (!$result && !$this->file_exists($path)) { //clear ghost files from the cache on delete
711
+            $storage = $mount->getStorage();
712
+            $internalPath = $mount->getInternalPath($absolutePath);
713
+            $storage->getUpdater()->remove($internalPath);
714
+            return true;
715
+        } else {
716
+            return $result;
717
+        }
718
+    }
719
+
720
+    /**
721
+     * @param string $directory
722
+     * @return bool|mixed
723
+     */
724
+    public function deleteAll($directory) {
725
+        return $this->rmdir($directory);
726
+    }
727
+
728
+    /**
729
+     * Rename/move a file or folder from the source path to target path.
730
+     *
731
+     * @param string $path1 source path
732
+     * @param string $path2 target path
733
+     *
734
+     * @return bool|mixed
735
+     */
736
+    public function rename($path1, $path2) {
737
+        $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1));
738
+        $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2));
739
+        $result = false;
740
+        if (
741
+            Filesystem::isValidPath($path2)
742
+            and Filesystem::isValidPath($path1)
743
+            and !Filesystem::isFileBlacklisted($path2)
744
+        ) {
745
+            $path1 = $this->getRelativePath($absolutePath1);
746
+            $path2 = $this->getRelativePath($absolutePath2);
747
+            $exists = $this->file_exists($path2);
748
+
749
+            if ($path1 == null or $path2 == null) {
750
+                return false;
751
+            }
752
+
753
+            $this->lockFile($path1, ILockingProvider::LOCK_SHARED, true);
754
+            try {
755
+                $this->lockFile($path2, ILockingProvider::LOCK_SHARED, true);
756
+
757
+                $run = true;
758
+                if ($this->shouldEmitHooks($path1) && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) {
759
+                    // if it was a rename from a part file to a regular file it was a write and not a rename operation
760
+                    $this->emit_file_hooks_pre($exists, $path2, $run);
761
+                } elseif ($this->shouldEmitHooks($path1)) {
762
+                    \OC_Hook::emit(
763
+                        Filesystem::CLASSNAME, Filesystem::signal_rename,
764
+                        array(
765
+                            Filesystem::signal_param_oldpath => $this->getHookPath($path1),
766
+                            Filesystem::signal_param_newpath => $this->getHookPath($path2),
767
+                            Filesystem::signal_param_run => &$run
768
+                        )
769
+                    );
770
+                }
771
+                if ($run) {
772
+                    $this->verifyPath(dirname($path2), basename($path2));
773
+
774
+                    $manager = Filesystem::getMountManager();
775
+                    $mount1 = $this->getMount($path1);
776
+                    $mount2 = $this->getMount($path2);
777
+                    $storage1 = $mount1->getStorage();
778
+                    $storage2 = $mount2->getStorage();
779
+                    $internalPath1 = $mount1->getInternalPath($absolutePath1);
780
+                    $internalPath2 = $mount2->getInternalPath($absolutePath2);
781
+
782
+                    $this->changeLock($path1, ILockingProvider::LOCK_EXCLUSIVE, true);
783
+                    try {
784
+                        $this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE, true);
785
+
786
+                        if ($internalPath1 === '') {
787
+                            if ($mount1 instanceof MoveableMount) {
788
+                                if ($this->isTargetAllowed($absolutePath2)) {
789
+                                    /**
790
+                                     * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1
791
+                                     */
792
+                                    $sourceMountPoint = $mount1->getMountPoint();
793
+                                    $result = $mount1->moveMount($absolutePath2);
794
+                                    $manager->moveMount($sourceMountPoint, $mount1->getMountPoint());
795
+                                } else {
796
+                                    $result = false;
797
+                                }
798
+                            } else {
799
+                                $result = false;
800
+                            }
801
+                            // moving a file/folder within the same mount point
802
+                        } elseif ($storage1 === $storage2) {
803
+                            if ($storage1) {
804
+                                $result = $storage1->rename($internalPath1, $internalPath2);
805
+                            } else {
806
+                                $result = false;
807
+                            }
808
+                            // moving a file/folder between storages (from $storage1 to $storage2)
809
+                        } else {
810
+                            $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2);
811
+                        }
812
+
813
+                        if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
814
+                            // if it was a rename from a part file to a regular file it was a write and not a rename operation
815
+                            $this->writeUpdate($storage2, $internalPath2);
816
+                        } else if ($result) {
817
+                            if ($internalPath1 !== '') { // don't do a cache update for moved mounts
818
+                                $this->renameUpdate($storage1, $storage2, $internalPath1, $internalPath2);
819
+                            }
820
+                        }
821
+                    } catch(\Exception $e) {
822
+                        throw $e;
823
+                    } finally {
824
+                        $this->changeLock($path1, ILockingProvider::LOCK_SHARED, true);
825
+                        $this->changeLock($path2, ILockingProvider::LOCK_SHARED, true);
826
+                    }
827
+
828
+                    if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
829
+                        if ($this->shouldEmitHooks()) {
830
+                            $this->emit_file_hooks_post($exists, $path2);
831
+                        }
832
+                    } elseif ($result) {
833
+                        if ($this->shouldEmitHooks($path1) and $this->shouldEmitHooks($path2)) {
834
+                            \OC_Hook::emit(
835
+                                Filesystem::CLASSNAME,
836
+                                Filesystem::signal_post_rename,
837
+                                array(
838
+                                    Filesystem::signal_param_oldpath => $this->getHookPath($path1),
839
+                                    Filesystem::signal_param_newpath => $this->getHookPath($path2)
840
+                                )
841
+                            );
842
+                        }
843
+                    }
844
+                }
845
+            } catch(\Exception $e) {
846
+                throw $e;
847
+            } finally {
848
+                $this->unlockFile($path1, ILockingProvider::LOCK_SHARED, true);
849
+                $this->unlockFile($path2, ILockingProvider::LOCK_SHARED, true);
850
+            }
851
+        }
852
+        return $result;
853
+    }
854
+
855
+    /**
856
+     * Copy a file/folder from the source path to target path
857
+     *
858
+     * @param string $path1 source path
859
+     * @param string $path2 target path
860
+     * @param bool $preserveMtime whether to preserve mtime on the copy
861
+     *
862
+     * @return bool|mixed
863
+     */
864
+    public function copy($path1, $path2, $preserveMtime = false) {
865
+        $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1));
866
+        $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2));
867
+        $result = false;
868
+        if (
869
+            Filesystem::isValidPath($path2)
870
+            and Filesystem::isValidPath($path1)
871
+            and !Filesystem::isFileBlacklisted($path2)
872
+        ) {
873
+            $path1 = $this->getRelativePath($absolutePath1);
874
+            $path2 = $this->getRelativePath($absolutePath2);
875
+
876
+            if ($path1 == null or $path2 == null) {
877
+                return false;
878
+            }
879
+            $run = true;
880
+
881
+            $this->lockFile($path2, ILockingProvider::LOCK_SHARED);
882
+            $this->lockFile($path1, ILockingProvider::LOCK_SHARED);
883
+            $lockTypePath1 = ILockingProvider::LOCK_SHARED;
884
+            $lockTypePath2 = ILockingProvider::LOCK_SHARED;
885
+
886
+            try {
887
+
888
+                $exists = $this->file_exists($path2);
889
+                if ($this->shouldEmitHooks()) {
890
+                    \OC_Hook::emit(
891
+                        Filesystem::CLASSNAME,
892
+                        Filesystem::signal_copy,
893
+                        array(
894
+                            Filesystem::signal_param_oldpath => $this->getHookPath($path1),
895
+                            Filesystem::signal_param_newpath => $this->getHookPath($path2),
896
+                            Filesystem::signal_param_run => &$run
897
+                        )
898
+                    );
899
+                    $this->emit_file_hooks_pre($exists, $path2, $run);
900
+                }
901
+                if ($run) {
902
+                    $mount1 = $this->getMount($path1);
903
+                    $mount2 = $this->getMount($path2);
904
+                    $storage1 = $mount1->getStorage();
905
+                    $internalPath1 = $mount1->getInternalPath($absolutePath1);
906
+                    $storage2 = $mount2->getStorage();
907
+                    $internalPath2 = $mount2->getInternalPath($absolutePath2);
908
+
909
+                    $this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE);
910
+                    $lockTypePath2 = ILockingProvider::LOCK_EXCLUSIVE;
911
+
912
+                    if ($mount1->getMountPoint() == $mount2->getMountPoint()) {
913
+                        if ($storage1) {
914
+                            $result = $storage1->copy($internalPath1, $internalPath2);
915
+                        } else {
916
+                            $result = false;
917
+                        }
918
+                    } else {
919
+                        $result = $storage2->copyFromStorage($storage1, $internalPath1, $internalPath2);
920
+                    }
921
+
922
+                    $this->writeUpdate($storage2, $internalPath2);
923
+
924
+                    $this->changeLock($path2, ILockingProvider::LOCK_SHARED);
925
+                    $lockTypePath2 = ILockingProvider::LOCK_SHARED;
926
+
927
+                    if ($this->shouldEmitHooks() && $result !== false) {
928
+                        \OC_Hook::emit(
929
+                            Filesystem::CLASSNAME,
930
+                            Filesystem::signal_post_copy,
931
+                            array(
932
+                                Filesystem::signal_param_oldpath => $this->getHookPath($path1),
933
+                                Filesystem::signal_param_newpath => $this->getHookPath($path2)
934
+                            )
935
+                        );
936
+                        $this->emit_file_hooks_post($exists, $path2);
937
+                    }
938
+
939
+                }
940
+            } catch (\Exception $e) {
941
+                $this->unlockFile($path2, $lockTypePath2);
942
+                $this->unlockFile($path1, $lockTypePath1);
943
+                throw $e;
944
+            }
945
+
946
+            $this->unlockFile($path2, $lockTypePath2);
947
+            $this->unlockFile($path1, $lockTypePath1);
948
+
949
+        }
950
+        return $result;
951
+    }
952
+
953
+    /**
954
+     * @param string $path
955
+     * @param string $mode 'r' or 'w'
956
+     * @return resource
957
+     */
958
+    public function fopen($path, $mode) {
959
+        $mode = str_replace('b', '', $mode); // the binary flag is a windows only feature which we do not support
960
+        $hooks = array();
961
+        switch ($mode) {
962
+            case 'r':
963
+                $hooks[] = 'read';
964
+                break;
965
+            case 'r+':
966
+            case 'w+':
967
+            case 'x+':
968
+            case 'a+':
969
+                $hooks[] = 'read';
970
+                $hooks[] = 'write';
971
+                break;
972
+            case 'w':
973
+            case 'x':
974
+            case 'a':
975
+                $hooks[] = 'write';
976
+                break;
977
+            default:
978
+                \OCP\Util::writeLog('core', 'invalid mode (' . $mode . ') for ' . $path, \OCP\Util::ERROR);
979
+        }
980
+
981
+        if ($mode !== 'r' && $mode !== 'w') {
982
+            \OC::$server->getLogger()->info('Trying to open a file with a mode other than "r" or "w" can cause severe performance issues with some backends');
983
+        }
984
+
985
+        return $this->basicOperation('fopen', $path, $hooks, $mode);
986
+    }
987
+
988
+    /**
989
+     * @param string $path
990
+     * @return bool|string
991
+     * @throws \OCP\Files\InvalidPathException
992
+     */
993
+    public function toTmpFile($path) {
994
+        $this->assertPathLength($path);
995
+        if (Filesystem::isValidPath($path)) {
996
+            $source = $this->fopen($path, 'r');
997
+            if ($source) {
998
+                $extension = pathinfo($path, PATHINFO_EXTENSION);
999
+                $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($extension);
1000
+                file_put_contents($tmpFile, $source);
1001
+                return $tmpFile;
1002
+            } else {
1003
+                return false;
1004
+            }
1005
+        } else {
1006
+            return false;
1007
+        }
1008
+    }
1009
+
1010
+    /**
1011
+     * @param string $tmpFile
1012
+     * @param string $path
1013
+     * @return bool|mixed
1014
+     * @throws \OCP\Files\InvalidPathException
1015
+     */
1016
+    public function fromTmpFile($tmpFile, $path) {
1017
+        $this->assertPathLength($path);
1018
+        if (Filesystem::isValidPath($path)) {
1019
+
1020
+            // Get directory that the file is going into
1021
+            $filePath = dirname($path);
1022
+
1023
+            // Create the directories if any
1024
+            if (!$this->file_exists($filePath)) {
1025
+                $result = $this->createParentDirectories($filePath);
1026
+                if ($result === false) {
1027
+                    return false;
1028
+                }
1029
+            }
1030
+
1031
+            $source = fopen($tmpFile, 'r');
1032
+            if ($source) {
1033
+                $result = $this->file_put_contents($path, $source);
1034
+                // $this->file_put_contents() might have already closed
1035
+                // the resource, so we check it, before trying to close it
1036
+                // to avoid messages in the error log.
1037
+                if (is_resource($source)) {
1038
+                    fclose($source);
1039
+                }
1040
+                unlink($tmpFile);
1041
+                return $result;
1042
+            } else {
1043
+                return false;
1044
+            }
1045
+        } else {
1046
+            return false;
1047
+        }
1048
+    }
1049
+
1050
+
1051
+    /**
1052
+     * @param string $path
1053
+     * @return mixed
1054
+     * @throws \OCP\Files\InvalidPathException
1055
+     */
1056
+    public function getMimeType($path) {
1057
+        $this->assertPathLength($path);
1058
+        return $this->basicOperation('getMimeType', $path);
1059
+    }
1060
+
1061
+    /**
1062
+     * @param string $type
1063
+     * @param string $path
1064
+     * @param bool $raw
1065
+     * @return bool|null|string
1066
+     */
1067
+    public function hash($type, $path, $raw = false) {
1068
+        $postFix = (substr($path, -1, 1) === '/') ? '/' : '';
1069
+        $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
1070
+        if (Filesystem::isValidPath($path)) {
1071
+            $path = $this->getRelativePath($absolutePath);
1072
+            if ($path == null) {
1073
+                return false;
1074
+            }
1075
+            if ($this->shouldEmitHooks($path)) {
1076
+                \OC_Hook::emit(
1077
+                    Filesystem::CLASSNAME,
1078
+                    Filesystem::signal_read,
1079
+                    array(Filesystem::signal_param_path => $this->getHookPath($path))
1080
+                );
1081
+            }
1082
+            list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
1083
+            if ($storage) {
1084
+                return $storage->hash($type, $internalPath, $raw);
1085
+            }
1086
+        }
1087
+        return null;
1088
+    }
1089
+
1090
+    /**
1091
+     * @param string $path
1092
+     * @return mixed
1093
+     * @throws \OCP\Files\InvalidPathException
1094
+     */
1095
+    public function free_space($path = '/') {
1096
+        $this->assertPathLength($path);
1097
+        $result = $this->basicOperation('free_space', $path);
1098
+        if ($result === null) {
1099
+            throw new InvalidPathException();
1100
+        }
1101
+        return $result;
1102
+    }
1103
+
1104
+    /**
1105
+     * abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage
1106
+     *
1107
+     * @param string $operation
1108
+     * @param string $path
1109
+     * @param array $hooks (optional)
1110
+     * @param mixed $extraParam (optional)
1111
+     * @return mixed
1112
+     * @throws \Exception
1113
+     *
1114
+     * This method takes requests for basic filesystem functions (e.g. reading & writing
1115
+     * files), processes hooks and proxies, sanitises paths, and finally passes them on to
1116
+     * \OC\Files\Storage\Storage for delegation to a storage backend for execution
1117
+     */
1118
+    private function basicOperation($operation, $path, $hooks = [], $extraParam = null) {
1119
+        $postFix = (substr($path, -1, 1) === '/') ? '/' : '';
1120
+        $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
1121
+        if (Filesystem::isValidPath($path)
1122
+            and !Filesystem::isFileBlacklisted($path)
1123
+        ) {
1124
+            $path = $this->getRelativePath($absolutePath);
1125
+            if ($path == null) {
1126
+                return false;
1127
+            }
1128
+
1129
+            if (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks)) {
1130
+                // always a shared lock during pre-hooks so the hook can read the file
1131
+                $this->lockFile($path, ILockingProvider::LOCK_SHARED);
1132
+            }
1133
+
1134
+            $run = $this->runHooks($hooks, $path);
1135
+            /** @var \OC\Files\Storage\Storage $storage */
1136
+            list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
1137
+            if ($run and $storage) {
1138
+                if (in_array('write', $hooks) || in_array('delete', $hooks)) {
1139
+                    $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
1140
+                }
1141
+                try {
1142
+                    if (!is_null($extraParam)) {
1143
+                        $result = $storage->$operation($internalPath, $extraParam);
1144
+                    } else {
1145
+                        $result = $storage->$operation($internalPath);
1146
+                    }
1147
+                } catch (\Exception $e) {
1148
+                    if (in_array('write', $hooks) || in_array('delete', $hooks)) {
1149
+                        $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
1150
+                    } else if (in_array('read', $hooks)) {
1151
+                        $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
1152
+                    }
1153
+                    throw $e;
1154
+                }
1155
+
1156
+                if ($result && in_array('delete', $hooks) and $result) {
1157
+                    $this->removeUpdate($storage, $internalPath);
1158
+                }
1159
+                if ($result && in_array('write', $hooks) and $operation !== 'fopen') {
1160
+                    $this->writeUpdate($storage, $internalPath);
1161
+                }
1162
+                if ($result && in_array('touch', $hooks)) {
1163
+                    $this->writeUpdate($storage, $internalPath, $extraParam);
1164
+                }
1165
+
1166
+                if ((in_array('write', $hooks) || in_array('delete', $hooks)) && ($operation !== 'fopen' || $result === false)) {
1167
+                    $this->changeLock($path, ILockingProvider::LOCK_SHARED);
1168
+                }
1169
+
1170
+                $unlockLater = false;
1171
+                if ($this->lockingEnabled && $operation === 'fopen' && is_resource($result)) {
1172
+                    $unlockLater = true;
1173
+                    // make sure our unlocking callback will still be called if connection is aborted
1174
+                    ignore_user_abort(true);
1175
+                    $result = CallbackWrapper::wrap($result, null, null, function () use ($hooks, $path) {
1176
+                        if (in_array('write', $hooks)) {
1177
+                            $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
1178
+                        } else if (in_array('read', $hooks)) {
1179
+                            $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
1180
+                        }
1181
+                    });
1182
+                }
1183
+
1184
+                if ($this->shouldEmitHooks($path) && $result !== false) {
1185
+                    if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open
1186
+                        $this->runHooks($hooks, $path, true);
1187
+                    }
1188
+                }
1189
+
1190
+                if (!$unlockLater
1191
+                    && (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks))
1192
+                ) {
1193
+                    $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
1194
+                }
1195
+                return $result;
1196
+            } else {
1197
+                $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
1198
+            }
1199
+        }
1200
+        return null;
1201
+    }
1202
+
1203
+    /**
1204
+     * get the path relative to the default root for hook usage
1205
+     *
1206
+     * @param string $path
1207
+     * @return string
1208
+     */
1209
+    private function getHookPath($path) {
1210
+        if (!Filesystem::getView()) {
1211
+            return $path;
1212
+        }
1213
+        return Filesystem::getView()->getRelativePath($this->getAbsolutePath($path));
1214
+    }
1215
+
1216
+    private function shouldEmitHooks($path = '') {
1217
+        if ($path && Cache\Scanner::isPartialFile($path)) {
1218
+            return false;
1219
+        }
1220
+        if (!Filesystem::$loaded) {
1221
+            return false;
1222
+        }
1223
+        $defaultRoot = Filesystem::getRoot();
1224
+        if ($defaultRoot === null) {
1225
+            return false;
1226
+        }
1227
+        if ($this->fakeRoot === $defaultRoot) {
1228
+            return true;
1229
+        }
1230
+        $fullPath = $this->getAbsolutePath($path);
1231
+
1232
+        if ($fullPath === $defaultRoot) {
1233
+            return true;
1234
+        }
1235
+
1236
+        return (strlen($fullPath) > strlen($defaultRoot)) && (substr($fullPath, 0, strlen($defaultRoot) + 1) === $defaultRoot . '/');
1237
+    }
1238
+
1239
+    /**
1240
+     * @param string[] $hooks
1241
+     * @param string $path
1242
+     * @param bool $post
1243
+     * @return bool
1244
+     */
1245
+    private function runHooks($hooks, $path, $post = false) {
1246
+        $relativePath = $path;
1247
+        $path = $this->getHookPath($path);
1248
+        $prefix = ($post) ? 'post_' : '';
1249
+        $run = true;
1250
+        if ($this->shouldEmitHooks($relativePath)) {
1251
+            foreach ($hooks as $hook) {
1252
+                if ($hook != 'read') {
1253
+                    \OC_Hook::emit(
1254
+                        Filesystem::CLASSNAME,
1255
+                        $prefix . $hook,
1256
+                        array(
1257
+                            Filesystem::signal_param_run => &$run,
1258
+                            Filesystem::signal_param_path => $path
1259
+                        )
1260
+                    );
1261
+                } elseif (!$post) {
1262
+                    \OC_Hook::emit(
1263
+                        Filesystem::CLASSNAME,
1264
+                        $prefix . $hook,
1265
+                        array(
1266
+                            Filesystem::signal_param_path => $path
1267
+                        )
1268
+                    );
1269
+                }
1270
+            }
1271
+        }
1272
+        return $run;
1273
+    }
1274
+
1275
+    /**
1276
+     * check if a file or folder has been updated since $time
1277
+     *
1278
+     * @param string $path
1279
+     * @param int $time
1280
+     * @return bool
1281
+     */
1282
+    public function hasUpdated($path, $time) {
1283
+        return $this->basicOperation('hasUpdated', $path, array(), $time);
1284
+    }
1285
+
1286
+    /**
1287
+     * @param string $ownerId
1288
+     * @return \OC\User\User
1289
+     */
1290
+    private function getUserObjectForOwner($ownerId) {
1291
+        $owner = $this->userManager->get($ownerId);
1292
+        if ($owner instanceof IUser) {
1293
+            return $owner;
1294
+        } else {
1295
+            return new User($ownerId, null);
1296
+        }
1297
+    }
1298
+
1299
+    /**
1300
+     * Get file info from cache
1301
+     *
1302
+     * If the file is not in cached it will be scanned
1303
+     * If the file has changed on storage the cache will be updated
1304
+     *
1305
+     * @param \OC\Files\Storage\Storage $storage
1306
+     * @param string $internalPath
1307
+     * @param string $relativePath
1308
+     * @return ICacheEntry|bool
1309
+     */
1310
+    private function getCacheEntry($storage, $internalPath, $relativePath) {
1311
+        $cache = $storage->getCache($internalPath);
1312
+        $data = $cache->get($internalPath);
1313
+        $watcher = $storage->getWatcher($internalPath);
1314
+
1315
+        try {
1316
+            // if the file is not in the cache or needs to be updated, trigger the scanner and reload the data
1317
+            if (!$data || $data['size'] === -1) {
1318
+                $this->lockFile($relativePath, ILockingProvider::LOCK_SHARED);
1319
+                if (!$storage->file_exists($internalPath)) {
1320
+                    $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED);
1321
+                    return false;
1322
+                }
1323
+                $scanner = $storage->getScanner($internalPath);
1324
+                $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
1325
+                $data = $cache->get($internalPath);
1326
+                $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED);
1327
+            } else if (!Cache\Scanner::isPartialFile($internalPath) && $watcher->needsUpdate($internalPath, $data)) {
1328
+                $this->lockFile($relativePath, ILockingProvider::LOCK_SHARED);
1329
+                $watcher->update($internalPath, $data);
1330
+                $storage->getPropagator()->propagateChange($internalPath, time());
1331
+                $data = $cache->get($internalPath);
1332
+                $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED);
1333
+            }
1334
+        } catch (LockedException $e) {
1335
+            // if the file is locked we just use the old cache info
1336
+        }
1337
+
1338
+        return $data;
1339
+    }
1340
+
1341
+    /**
1342
+     * get the filesystem info
1343
+     *
1344
+     * @param string $path
1345
+     * @param boolean|string $includeMountPoints true to add mountpoint sizes,
1346
+     * 'ext' to add only ext storage mount point sizes. Defaults to true.
1347
+     * defaults to true
1348
+     * @return \OC\Files\FileInfo|false False if file does not exist
1349
+     */
1350
+    public function getFileInfo($path, $includeMountPoints = true) {
1351
+        $this->assertPathLength($path);
1352
+        if (!Filesystem::isValidPath($path)) {
1353
+            return false;
1354
+        }
1355
+        if (Cache\Scanner::isPartialFile($path)) {
1356
+            return $this->getPartFileInfo($path);
1357
+        }
1358
+        $relativePath = $path;
1359
+        $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path);
1360
+
1361
+        $mount = Filesystem::getMountManager()->find($path);
1362
+        if (!$mount) {
1363
+            return false;
1364
+        }
1365
+        $storage = $mount->getStorage();
1366
+        $internalPath = $mount->getInternalPath($path);
1367
+        if ($storage) {
1368
+            $data = $this->getCacheEntry($storage, $internalPath, $relativePath);
1369
+
1370
+            if (!$data instanceof ICacheEntry) {
1371
+                return false;
1372
+            }
1373
+
1374
+            if ($mount instanceof MoveableMount && $internalPath === '') {
1375
+                $data['permissions'] |= \OCP\Constants::PERMISSION_DELETE;
1376
+            }
1377
+
1378
+            $owner = $this->getUserObjectForOwner($storage->getOwner($internalPath));
1379
+            $info = new FileInfo($path, $storage, $internalPath, $data, $mount, $owner);
1380
+
1381
+            if ($data and isset($data['fileid'])) {
1382
+                if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') {
1383
+                    //add the sizes of other mount points to the folder
1384
+                    $extOnly = ($includeMountPoints === 'ext');
1385
+                    $mounts = Filesystem::getMountManager()->findIn($path);
1386
+                    $info->setSubMounts(array_filter($mounts, function (IMountPoint $mount) use ($extOnly) {
1387
+                        $subStorage = $mount->getStorage();
1388
+                        return !($extOnly && $subStorage instanceof \OCA\Files_Sharing\SharedStorage);
1389
+                    }));
1390
+                }
1391
+            }
1392
+
1393
+            return $info;
1394
+        }
1395
+
1396
+        return false;
1397
+    }
1398
+
1399
+    /**
1400
+     * get the content of a directory
1401
+     *
1402
+     * @param string $directory path under datadirectory
1403
+     * @param string $mimetype_filter limit returned content to this mimetype or mimepart
1404
+     * @return FileInfo[]
1405
+     */
1406
+    public function getDirectoryContent($directory, $mimetype_filter = '') {
1407
+        $this->assertPathLength($directory);
1408
+        if (!Filesystem::isValidPath($directory)) {
1409
+            return [];
1410
+        }
1411
+        $path = $this->getAbsolutePath($directory);
1412
+        $path = Filesystem::normalizePath($path);
1413
+        $mount = $this->getMount($directory);
1414
+        if (!$mount) {
1415
+            return [];
1416
+        }
1417
+        $storage = $mount->getStorage();
1418
+        $internalPath = $mount->getInternalPath($path);
1419
+        if ($storage) {
1420
+            $cache = $storage->getCache($internalPath);
1421
+            $user = \OC_User::getUser();
1422
+
1423
+            $data = $this->getCacheEntry($storage, $internalPath, $directory);
1424
+
1425
+            if (!$data instanceof ICacheEntry || !isset($data['fileid']) || !($data->getPermissions() && Constants::PERMISSION_READ)) {
1426
+                return [];
1427
+            }
1428
+
1429
+            $folderId = $data['fileid'];
1430
+            $contents = $cache->getFolderContentsById($folderId); //TODO: mimetype_filter
1431
+
1432
+            $sharingDisabled = \OCP\Util::isSharingDisabledForUser();
1433
+            /**
1434
+             * @var \OC\Files\FileInfo[] $files
1435
+             */
1436
+            $files = array_map(function (ICacheEntry $content) use ($path, $storage, $mount, $sharingDisabled) {
1437
+                if ($sharingDisabled) {
1438
+                    $content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
1439
+                }
1440
+                $owner = $this->getUserObjectForOwner($storage->getOwner($content['path']));
1441
+                return new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content, $mount, $owner);
1442
+            }, $contents);
1443
+
1444
+            //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders
1445
+            $mounts = Filesystem::getMountManager()->findIn($path);
1446
+            $dirLength = strlen($path);
1447
+            foreach ($mounts as $mount) {
1448
+                $mountPoint = $mount->getMountPoint();
1449
+                $subStorage = $mount->getStorage();
1450
+                if ($subStorage) {
1451
+                    $subCache = $subStorage->getCache('');
1452
+
1453
+                    $rootEntry = $subCache->get('');
1454
+                    if (!$rootEntry) {
1455
+                        $subScanner = $subStorage->getScanner('');
1456
+                        try {
1457
+                            $subScanner->scanFile('');
1458
+                        } catch (\OCP\Files\StorageNotAvailableException $e) {
1459
+                            continue;
1460
+                        } catch (\OCP\Files\StorageInvalidException $e) {
1461
+                            continue;
1462
+                        } catch (\Exception $e) {
1463
+                            // sometimes when the storage is not available it can be any exception
1464
+                            \OC::$server->getLogger()->logException($e, [
1465
+                                'message' => 'Exception while scanning storage "' . $subStorage->getId() . '"',
1466
+                                'level' => \OCP\Util::ERROR,
1467
+                                'app' => 'lib',
1468
+                            ]);
1469
+                            continue;
1470
+                        }
1471
+                        $rootEntry = $subCache->get('');
1472
+                    }
1473
+
1474
+                    if ($rootEntry && ($rootEntry->getPermissions() && Constants::PERMISSION_READ)) {
1475
+                        $relativePath = trim(substr($mountPoint, $dirLength), '/');
1476
+                        if ($pos = strpos($relativePath, '/')) {
1477
+                            //mountpoint inside subfolder add size to the correct folder
1478
+                            $entryName = substr($relativePath, 0, $pos);
1479
+                            foreach ($files as &$entry) {
1480
+                                if ($entry->getName() === $entryName) {
1481
+                                    $entry->addSubEntry($rootEntry, $mountPoint);
1482
+                                }
1483
+                            }
1484
+                        } else { //mountpoint in this folder, add an entry for it
1485
+                            $rootEntry['name'] = $relativePath;
1486
+                            $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file';
1487
+                            $permissions = $rootEntry['permissions'];
1488
+                            // do not allow renaming/deleting the mount point if they are not shared files/folders
1489
+                            // for shared files/folders we use the permissions given by the owner
1490
+                            if ($mount instanceof MoveableMount) {
1491
+                                $rootEntry['permissions'] = $permissions | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
1492
+                            } else {
1493
+                                $rootEntry['permissions'] = $permissions & (\OCP\Constants::PERMISSION_ALL - (\OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE));
1494
+                            }
1495
+
1496
+                            //remove any existing entry with the same name
1497
+                            foreach ($files as $i => $file) {
1498
+                                if ($file['name'] === $rootEntry['name']) {
1499
+                                    unset($files[$i]);
1500
+                                    break;
1501
+                                }
1502
+                            }
1503
+                            $rootEntry['path'] = substr(Filesystem::normalizePath($path . '/' . $rootEntry['name']), strlen($user) + 2); // full path without /$user/
1504
+
1505
+                            // if sharing was disabled for the user we remove the share permissions
1506
+                            if (\OCP\Util::isSharingDisabledForUser()) {
1507
+                                $rootEntry['permissions'] = $rootEntry['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
1508
+                            }
1509
+
1510
+                            $owner = $this->getUserObjectForOwner($subStorage->getOwner(''));
1511
+                            $files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry, $mount, $owner);
1512
+                        }
1513
+                    }
1514
+                }
1515
+            }
1516
+
1517
+            if ($mimetype_filter) {
1518
+                $files = array_filter($files, function (FileInfo $file) use ($mimetype_filter) {
1519
+                    if (strpos($mimetype_filter, '/')) {
1520
+                        return $file->getMimetype() === $mimetype_filter;
1521
+                    } else {
1522
+                        return $file->getMimePart() === $mimetype_filter;
1523
+                    }
1524
+                });
1525
+            }
1526
+
1527
+            return $files;
1528
+        } else {
1529
+            return [];
1530
+        }
1531
+    }
1532
+
1533
+    /**
1534
+     * change file metadata
1535
+     *
1536
+     * @param string $path
1537
+     * @param array|\OCP\Files\FileInfo $data
1538
+     * @return int
1539
+     *
1540
+     * returns the fileid of the updated file
1541
+     */
1542
+    public function putFileInfo($path, $data) {
1543
+        $this->assertPathLength($path);
1544
+        if ($data instanceof FileInfo) {
1545
+            $data = $data->getData();
1546
+        }
1547
+        $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path);
1548
+        /**
1549
+         * @var \OC\Files\Storage\Storage $storage
1550
+         * @var string $internalPath
1551
+         */
1552
+        list($storage, $internalPath) = Filesystem::resolvePath($path);
1553
+        if ($storage) {
1554
+            $cache = $storage->getCache($path);
1555
+
1556
+            if (!$cache->inCache($internalPath)) {
1557
+                $scanner = $storage->getScanner($internalPath);
1558
+                $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
1559
+            }
1560
+
1561
+            return $cache->put($internalPath, $data);
1562
+        } else {
1563
+            return -1;
1564
+        }
1565
+    }
1566
+
1567
+    /**
1568
+     * search for files with the name matching $query
1569
+     *
1570
+     * @param string $query
1571
+     * @return FileInfo[]
1572
+     */
1573
+    public function search($query) {
1574
+        return $this->searchCommon('search', array('%' . $query . '%'));
1575
+    }
1576
+
1577
+    /**
1578
+     * search for files with the name matching $query
1579
+     *
1580
+     * @param string $query
1581
+     * @return FileInfo[]
1582
+     */
1583
+    public function searchRaw($query) {
1584
+        return $this->searchCommon('search', array($query));
1585
+    }
1586
+
1587
+    /**
1588
+     * search for files by mimetype
1589
+     *
1590
+     * @param string $mimetype
1591
+     * @return FileInfo[]
1592
+     */
1593
+    public function searchByMime($mimetype) {
1594
+        return $this->searchCommon('searchByMime', array($mimetype));
1595
+    }
1596
+
1597
+    /**
1598
+     * search for files by tag
1599
+     *
1600
+     * @param string|int $tag name or tag id
1601
+     * @param string $userId owner of the tags
1602
+     * @return FileInfo[]
1603
+     */
1604
+    public function searchByTag($tag, $userId) {
1605
+        return $this->searchCommon('searchByTag', array($tag, $userId));
1606
+    }
1607
+
1608
+    /**
1609
+     * @param string $method cache method
1610
+     * @param array $args
1611
+     * @return FileInfo[]
1612
+     */
1613
+    private function searchCommon($method, $args) {
1614
+        $files = array();
1615
+        $rootLength = strlen($this->fakeRoot);
1616
+
1617
+        $mount = $this->getMount('');
1618
+        $mountPoint = $mount->getMountPoint();
1619
+        $storage = $mount->getStorage();
1620
+        if ($storage) {
1621
+            $cache = $storage->getCache('');
1622
+
1623
+            $results = call_user_func_array(array($cache, $method), $args);
1624
+            foreach ($results as $result) {
1625
+                if (substr($mountPoint . $result['path'], 0, $rootLength + 1) === $this->fakeRoot . '/') {
1626
+                    $internalPath = $result['path'];
1627
+                    $path = $mountPoint . $result['path'];
1628
+                    $result['path'] = substr($mountPoint . $result['path'], $rootLength);
1629
+                    $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
1630
+                    $files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner);
1631
+                }
1632
+            }
1633
+
1634
+            $mounts = Filesystem::getMountManager()->findIn($this->fakeRoot);
1635
+            foreach ($mounts as $mount) {
1636
+                $mountPoint = $mount->getMountPoint();
1637
+                $storage = $mount->getStorage();
1638
+                if ($storage) {
1639
+                    $cache = $storage->getCache('');
1640
+
1641
+                    $relativeMountPoint = substr($mountPoint, $rootLength);
1642
+                    $results = call_user_func_array(array($cache, $method), $args);
1643
+                    if ($results) {
1644
+                        foreach ($results as $result) {
1645
+                            $internalPath = $result['path'];
1646
+                            $result['path'] = rtrim($relativeMountPoint . $result['path'], '/');
1647
+                            $path = rtrim($mountPoint . $internalPath, '/');
1648
+                            $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
1649
+                            $files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner);
1650
+                        }
1651
+                    }
1652
+                }
1653
+            }
1654
+        }
1655
+        return $files;
1656
+    }
1657
+
1658
+    /**
1659
+     * Get the owner for a file or folder
1660
+     *
1661
+     * @param string $path
1662
+     * @return string the user id of the owner
1663
+     * @throws NotFoundException
1664
+     */
1665
+    public function getOwner($path) {
1666
+        $info = $this->getFileInfo($path);
1667
+        if (!$info) {
1668
+            throw new NotFoundException($path . ' not found while trying to get owner');
1669
+        }
1670
+        return $info->getOwner()->getUID();
1671
+    }
1672
+
1673
+    /**
1674
+     * get the ETag for a file or folder
1675
+     *
1676
+     * @param string $path
1677
+     * @return string
1678
+     */
1679
+    public function getETag($path) {
1680
+        /**
1681
+         * @var Storage\Storage $storage
1682
+         * @var string $internalPath
1683
+         */
1684
+        list($storage, $internalPath) = $this->resolvePath($path);
1685
+        if ($storage) {
1686
+            return $storage->getETag($internalPath);
1687
+        } else {
1688
+            return null;
1689
+        }
1690
+    }
1691
+
1692
+    /**
1693
+     * Get the path of a file by id, relative to the view
1694
+     *
1695
+     * Note that the resulting path is not guarantied to be unique for the id, multiple paths can point to the same file
1696
+     *
1697
+     * @param int $id
1698
+     * @throws NotFoundException
1699
+     * @return string
1700
+     */
1701
+    public function getPath($id) {
1702
+        $id = (int)$id;
1703
+        $manager = Filesystem::getMountManager();
1704
+        $mounts = $manager->findIn($this->fakeRoot);
1705
+        $mounts[] = $manager->find($this->fakeRoot);
1706
+        // reverse the array so we start with the storage this view is in
1707
+        // which is the most likely to contain the file we're looking for
1708
+        $mounts = array_reverse($mounts);
1709
+        foreach ($mounts as $mount) {
1710
+            /**
1711
+             * @var \OC\Files\Mount\MountPoint $mount
1712
+             */
1713
+            if ($mount->getStorage()) {
1714
+                $cache = $mount->getStorage()->getCache();
1715
+                $internalPath = $cache->getPathById($id);
1716
+                if (is_string($internalPath)) {
1717
+                    $fullPath = $mount->getMountPoint() . $internalPath;
1718
+                    if (!is_null($path = $this->getRelativePath($fullPath))) {
1719
+                        return $path;
1720
+                    }
1721
+                }
1722
+            }
1723
+        }
1724
+        throw new NotFoundException(sprintf('File with id "%s" has not been found.', $id));
1725
+    }
1726
+
1727
+    /**
1728
+     * @param string $path
1729
+     * @throws InvalidPathException
1730
+     */
1731
+    private function assertPathLength($path) {
1732
+        $maxLen = min(PHP_MAXPATHLEN, 4000);
1733
+        // Check for the string length - performed using isset() instead of strlen()
1734
+        // because isset() is about 5x-40x faster.
1735
+        if (isset($path[$maxLen])) {
1736
+            $pathLen = strlen($path);
1737
+            throw new \OCP\Files\InvalidPathException("Path length($pathLen) exceeds max path length($maxLen): $path");
1738
+        }
1739
+    }
1740
+
1741
+    /**
1742
+     * check if it is allowed to move a mount point to a given target.
1743
+     * It is not allowed to move a mount point into a different mount point or
1744
+     * into an already shared folder
1745
+     *
1746
+     * @param string $target path
1747
+     * @return boolean
1748
+     */
1749
+    private function isTargetAllowed($target) {
1750
+
1751
+        list($targetStorage, $targetInternalPath) = \OC\Files\Filesystem::resolvePath($target);
1752
+        if (!$targetStorage->instanceOfStorage('\OCP\Files\IHomeStorage')) {
1753
+            \OCP\Util::writeLog('files',
1754
+                'It is not allowed to move one mount point into another one',
1755
+                \OCP\Util::DEBUG);
1756
+            return false;
1757
+        }
1758
+
1759
+        // note: cannot use the view because the target is already locked
1760
+        $fileId = (int)$targetStorage->getCache()->getId($targetInternalPath);
1761
+        if ($fileId === -1) {
1762
+            // target might not exist, need to check parent instead
1763
+            $fileId = (int)$targetStorage->getCache()->getId(dirname($targetInternalPath));
1764
+        }
1765
+
1766
+        // check if any of the parents were shared by the current owner (include collections)
1767
+        $shares = \OCP\Share::getItemShared(
1768
+            'folder',
1769
+            $fileId,
1770
+            \OCP\Share::FORMAT_NONE,
1771
+            null,
1772
+            true
1773
+        );
1774
+
1775
+        if (count($shares) > 0) {
1776
+            \OCP\Util::writeLog('files',
1777
+                'It is not allowed to move one mount point into a shared folder',
1778
+                \OCP\Util::DEBUG);
1779
+            return false;
1780
+        }
1781
+
1782
+        return true;
1783
+    }
1784
+
1785
+    /**
1786
+     * Get a fileinfo object for files that are ignored in the cache (part files)
1787
+     *
1788
+     * @param string $path
1789
+     * @return \OCP\Files\FileInfo
1790
+     */
1791
+    private function getPartFileInfo($path) {
1792
+        $mount = $this->getMount($path);
1793
+        $storage = $mount->getStorage();
1794
+        $internalPath = $mount->getInternalPath($this->getAbsolutePath($path));
1795
+        $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
1796
+        return new FileInfo(
1797
+            $this->getAbsolutePath($path),
1798
+            $storage,
1799
+            $internalPath,
1800
+            [
1801
+                'fileid' => null,
1802
+                'mimetype' => $storage->getMimeType($internalPath),
1803
+                'name' => basename($path),
1804
+                'etag' => null,
1805
+                'size' => $storage->filesize($internalPath),
1806
+                'mtime' => $storage->filemtime($internalPath),
1807
+                'encrypted' => false,
1808
+                'permissions' => \OCP\Constants::PERMISSION_ALL
1809
+            ],
1810
+            $mount,
1811
+            $owner
1812
+        );
1813
+    }
1814
+
1815
+    /**
1816
+     * @param string $path
1817
+     * @param string $fileName
1818
+     * @throws InvalidPathException
1819
+     */
1820
+    public function verifyPath($path, $fileName) {
1821
+        try {
1822
+            /** @type \OCP\Files\Storage $storage */
1823
+            list($storage, $internalPath) = $this->resolvePath($path);
1824
+            $storage->verifyPath($internalPath, $fileName);
1825
+        } catch (ReservedWordException $ex) {
1826
+            $l = \OC::$server->getL10N('lib');
1827
+            throw new InvalidPathException($l->t('File name is a reserved word'));
1828
+        } catch (InvalidCharacterInPathException $ex) {
1829
+            $l = \OC::$server->getL10N('lib');
1830
+            throw new InvalidPathException($l->t('File name contains at least one invalid character'));
1831
+        } catch (FileNameTooLongException $ex) {
1832
+            $l = \OC::$server->getL10N('lib');
1833
+            throw new InvalidPathException($l->t('File name is too long'));
1834
+        } catch (InvalidDirectoryException $ex) {
1835
+            $l = \OC::$server->getL10N('lib');
1836
+            throw new InvalidPathException($l->t('Dot files are not allowed'));
1837
+        } catch (EmptyFileNameException $ex) {
1838
+            $l = \OC::$server->getL10N('lib');
1839
+            throw new InvalidPathException($l->t('Empty filename is not allowed'));
1840
+        }
1841
+    }
1842
+
1843
+    /**
1844
+     * get all parent folders of $path
1845
+     *
1846
+     * @param string $path
1847
+     * @return string[]
1848
+     */
1849
+    private function getParents($path) {
1850
+        $path = trim($path, '/');
1851
+        if (!$path) {
1852
+            return [];
1853
+        }
1854
+
1855
+        $parts = explode('/', $path);
1856
+
1857
+        // remove the single file
1858
+        array_pop($parts);
1859
+        $result = array('/');
1860
+        $resultPath = '';
1861
+        foreach ($parts as $part) {
1862
+            if ($part) {
1863
+                $resultPath .= '/' . $part;
1864
+                $result[] = $resultPath;
1865
+            }
1866
+        }
1867
+        return $result;
1868
+    }
1869
+
1870
+    /**
1871
+     * Returns the mount point for which to lock
1872
+     *
1873
+     * @param string $absolutePath absolute path
1874
+     * @param bool $useParentMount true to return parent mount instead of whatever
1875
+     * is mounted directly on the given path, false otherwise
1876
+     * @return \OC\Files\Mount\MountPoint mount point for which to apply locks
1877
+     */
1878
+    private function getMountForLock($absolutePath, $useParentMount = false) {
1879
+        $results = [];
1880
+        $mount = Filesystem::getMountManager()->find($absolutePath);
1881
+        if (!$mount) {
1882
+            return $results;
1883
+        }
1884
+
1885
+        if ($useParentMount) {
1886
+            // find out if something is mounted directly on the path
1887
+            $internalPath = $mount->getInternalPath($absolutePath);
1888
+            if ($internalPath === '') {
1889
+                // resolve the parent mount instead
1890
+                $mount = Filesystem::getMountManager()->find(dirname($absolutePath));
1891
+            }
1892
+        }
1893
+
1894
+        return $mount;
1895
+    }
1896
+
1897
+    /**
1898
+     * Lock the given path
1899
+     *
1900
+     * @param string $path the path of the file to lock, relative to the view
1901
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
1902
+     * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
1903
+     *
1904
+     * @return bool False if the path is excluded from locking, true otherwise
1905
+     * @throws \OCP\Lock\LockedException if the path is already locked
1906
+     */
1907
+    private function lockPath($path, $type, $lockMountPoint = false) {
1908
+        $absolutePath = $this->getAbsolutePath($path);
1909
+        $absolutePath = Filesystem::normalizePath($absolutePath);
1910
+        if (!$this->shouldLockFile($absolutePath)) {
1911
+            return false;
1912
+        }
1913
+
1914
+        $mount = $this->getMountForLock($absolutePath, $lockMountPoint);
1915
+        if ($mount) {
1916
+            try {
1917
+                $storage = $mount->getStorage();
1918
+                if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
1919
+                    $storage->acquireLock(
1920
+                        $mount->getInternalPath($absolutePath),
1921
+                        $type,
1922
+                        $this->lockingProvider
1923
+                    );
1924
+                }
1925
+            } catch (\OCP\Lock\LockedException $e) {
1926
+                // rethrow with the a human-readable path
1927
+                throw new \OCP\Lock\LockedException(
1928
+                    $this->getPathRelativeToFiles($absolutePath),
1929
+                    $e
1930
+                );
1931
+            }
1932
+        }
1933
+
1934
+        return true;
1935
+    }
1936
+
1937
+    /**
1938
+     * Change the lock type
1939
+     *
1940
+     * @param string $path the path of the file to lock, relative to the view
1941
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
1942
+     * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
1943
+     *
1944
+     * @return bool False if the path is excluded from locking, true otherwise
1945
+     * @throws \OCP\Lock\LockedException if the path is already locked
1946
+     */
1947
+    public function changeLock($path, $type, $lockMountPoint = false) {
1948
+        $path = Filesystem::normalizePath($path);
1949
+        $absolutePath = $this->getAbsolutePath($path);
1950
+        $absolutePath = Filesystem::normalizePath($absolutePath);
1951
+        if (!$this->shouldLockFile($absolutePath)) {
1952
+            return false;
1953
+        }
1954
+
1955
+        $mount = $this->getMountForLock($absolutePath, $lockMountPoint);
1956
+        if ($mount) {
1957
+            try {
1958
+                $storage = $mount->getStorage();
1959
+                if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
1960
+                    $storage->changeLock(
1961
+                        $mount->getInternalPath($absolutePath),
1962
+                        $type,
1963
+                        $this->lockingProvider
1964
+                    );
1965
+                }
1966
+            } catch (\OCP\Lock\LockedException $e) {
1967
+                try {
1968
+                    // rethrow with the a human-readable path
1969
+                    throw new \OCP\Lock\LockedException(
1970
+                        $this->getPathRelativeToFiles($absolutePath),
1971
+                        $e
1972
+                    );
1973
+                } catch (\InvalidArgumentException $e) {
1974
+                    throw new \OCP\Lock\LockedException(
1975
+                        $absolutePath,
1976
+                        $e
1977
+                    );
1978
+                }
1979
+            }
1980
+        }
1981
+
1982
+        return true;
1983
+    }
1984
+
1985
+    /**
1986
+     * Unlock the given path
1987
+     *
1988
+     * @param string $path the path of the file to unlock, relative to the view
1989
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
1990
+     * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
1991
+     *
1992
+     * @return bool False if the path is excluded from locking, true otherwise
1993
+     */
1994
+    private function unlockPath($path, $type, $lockMountPoint = false) {
1995
+        $absolutePath = $this->getAbsolutePath($path);
1996
+        $absolutePath = Filesystem::normalizePath($absolutePath);
1997
+        if (!$this->shouldLockFile($absolutePath)) {
1998
+            return false;
1999
+        }
2000
+
2001
+        $mount = $this->getMountForLock($absolutePath, $lockMountPoint);
2002
+        if ($mount) {
2003
+            $storage = $mount->getStorage();
2004
+            if ($storage && $storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
2005
+                $storage->releaseLock(
2006
+                    $mount->getInternalPath($absolutePath),
2007
+                    $type,
2008
+                    $this->lockingProvider
2009
+                );
2010
+            }
2011
+        }
2012
+
2013
+        return true;
2014
+    }
2015
+
2016
+    /**
2017
+     * Lock a path and all its parents up to the root of the view
2018
+     *
2019
+     * @param string $path the path of the file to lock relative to the view
2020
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
2021
+     * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
2022
+     *
2023
+     * @return bool False if the path is excluded from locking, true otherwise
2024
+     */
2025
+    public function lockFile($path, $type, $lockMountPoint = false) {
2026
+        $absolutePath = $this->getAbsolutePath($path);
2027
+        $absolutePath = Filesystem::normalizePath($absolutePath);
2028
+        if (!$this->shouldLockFile($absolutePath)) {
2029
+            return false;
2030
+        }
2031
+
2032
+        $this->lockPath($path, $type, $lockMountPoint);
2033
+
2034
+        $parents = $this->getParents($path);
2035
+        foreach ($parents as $parent) {
2036
+            $this->lockPath($parent, ILockingProvider::LOCK_SHARED);
2037
+        }
2038
+
2039
+        return true;
2040
+    }
2041
+
2042
+    /**
2043
+     * Unlock a path and all its parents up to the root of the view
2044
+     *
2045
+     * @param string $path the path of the file to lock relative to the view
2046
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
2047
+     * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
2048
+     *
2049
+     * @return bool False if the path is excluded from locking, true otherwise
2050
+     */
2051
+    public function unlockFile($path, $type, $lockMountPoint = false) {
2052
+        $absolutePath = $this->getAbsolutePath($path);
2053
+        $absolutePath = Filesystem::normalizePath($absolutePath);
2054
+        if (!$this->shouldLockFile($absolutePath)) {
2055
+            return false;
2056
+        }
2057
+
2058
+        $this->unlockPath($path, $type, $lockMountPoint);
2059
+
2060
+        $parents = $this->getParents($path);
2061
+        foreach ($parents as $parent) {
2062
+            $this->unlockPath($parent, ILockingProvider::LOCK_SHARED);
2063
+        }
2064
+
2065
+        return true;
2066
+    }
2067
+
2068
+    /**
2069
+     * Only lock files in data/user/files/
2070
+     *
2071
+     * @param string $path Absolute path to the file/folder we try to (un)lock
2072
+     * @return bool
2073
+     */
2074
+    protected function shouldLockFile($path) {
2075
+        $path = Filesystem::normalizePath($path);
2076
+
2077
+        $pathSegments = explode('/', $path);
2078
+        if (isset($pathSegments[2])) {
2079
+            // E.g.: /username/files/path-to-file
2080
+            return ($pathSegments[2] === 'files') && (count($pathSegments) > 3);
2081
+        }
2082
+
2083
+        return strpos($path, '/appdata_') !== 0;
2084
+    }
2085
+
2086
+    /**
2087
+     * Shortens the given absolute path to be relative to
2088
+     * "$user/files".
2089
+     *
2090
+     * @param string $absolutePath absolute path which is under "files"
2091
+     *
2092
+     * @return string path relative to "files" with trimmed slashes or null
2093
+     * if the path was NOT relative to files
2094
+     *
2095
+     * @throws \InvalidArgumentException if the given path was not under "files"
2096
+     * @since 8.1.0
2097
+     */
2098
+    public function getPathRelativeToFiles($absolutePath) {
2099
+        $path = Filesystem::normalizePath($absolutePath);
2100
+        $parts = explode('/', trim($path, '/'), 3);
2101
+        // "$user", "files", "path/to/dir"
2102
+        if (!isset($parts[1]) || $parts[1] !== 'files') {
2103
+            $this->logger->error(
2104
+                '$absolutePath must be relative to "files", value is "%s"',
2105
+                [
2106
+                    $absolutePath
2107
+                ]
2108
+            );
2109
+            throw new \InvalidArgumentException('$absolutePath must be relative to "files"');
2110
+        }
2111
+        if (isset($parts[2])) {
2112
+            return $parts[2];
2113
+        }
2114
+        return '';
2115
+    }
2116
+
2117
+    /**
2118
+     * @param string $filename
2119
+     * @return array
2120
+     * @throws \OC\User\NoUserException
2121
+     * @throws NotFoundException
2122
+     */
2123
+    public function getUidAndFilename($filename) {
2124
+        $info = $this->getFileInfo($filename);
2125
+        if (!$info instanceof \OCP\Files\FileInfo) {
2126
+            throw new NotFoundException($this->getAbsolutePath($filename) . ' not found');
2127
+        }
2128
+        $uid = $info->getOwner()->getUID();
2129
+        if ($uid != \OCP\User::getUser()) {
2130
+            Filesystem::initMountPoints($uid);
2131
+            $ownerView = new View('/' . $uid . '/files');
2132
+            try {
2133
+                $filename = $ownerView->getPath($info['fileid']);
2134
+            } catch (NotFoundException $e) {
2135
+                throw new NotFoundException('File with id ' . $info['fileid'] . ' not found for user ' . $uid);
2136
+            }
2137
+        }
2138
+        return [$uid, $filename];
2139
+    }
2140
+
2141
+    /**
2142
+     * Creates parent non-existing folders
2143
+     *
2144
+     * @param string $filePath
2145
+     * @return bool
2146
+     */
2147
+    private function createParentDirectories($filePath) {
2148
+        $directoryParts = explode('/', $filePath);
2149
+        $directoryParts = array_filter($directoryParts);
2150
+        foreach ($directoryParts as $key => $part) {
2151
+            $currentPathElements = array_slice($directoryParts, 0, $key);
2152
+            $currentPath = '/' . implode('/', $currentPathElements);
2153
+            if ($this->is_file($currentPath)) {
2154
+                return false;
2155
+            }
2156
+            if (!$this->file_exists($currentPath)) {
2157
+                $this->mkdir($currentPath);
2158
+            }
2159
+        }
2160
+
2161
+        return true;
2162
+    }
2163 2163
 }
Please login to merge, or discard this patch.
Spacing   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -126,9 +126,9 @@  discard block
 block discarded – undo
126 126
 			$path = '/';
127 127
 		}
128 128
 		if ($path[0] !== '/') {
129
-			$path = '/' . $path;
129
+			$path = '/'.$path;
130 130
 		}
131
-		return $this->fakeRoot . $path;
131
+		return $this->fakeRoot.$path;
132 132
 	}
133 133
 
134 134
 	/**
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
 	public function chroot($fakeRoot) {
141 141
 		if (!$fakeRoot == '') {
142 142
 			if ($fakeRoot[0] !== '/') {
143
-				$fakeRoot = '/' . $fakeRoot;
143
+				$fakeRoot = '/'.$fakeRoot;
144 144
 			}
145 145
 		}
146 146
 		$this->fakeRoot = $fakeRoot;
@@ -172,7 +172,7 @@  discard block
 block discarded – undo
172 172
 		}
173 173
 
174 174
 		// missing slashes can cause wrong matches!
175
-		$root = rtrim($this->fakeRoot, '/') . '/';
175
+		$root = rtrim($this->fakeRoot, '/').'/';
176 176
 
177 177
 		if (strpos($path, $root) !== 0) {
178 178
 			return null;
@@ -278,7 +278,7 @@  discard block
 block discarded – undo
278 278
 		if ($mount instanceof MoveableMount) {
279 279
 			// cut of /user/files to get the relative path to data/user/files
280 280
 			$pathParts = explode('/', $path, 4);
281
-			$relPath = '/' . $pathParts[3];
281
+			$relPath = '/'.$pathParts[3];
282 282
 			$this->lockFile($relPath, ILockingProvider::LOCK_SHARED, true);
283 283
 			\OC_Hook::emit(
284 284
 				Filesystem::CLASSNAME, "umount",
@@ -698,7 +698,7 @@  discard block
 block discarded – undo
698 698
 		}
699 699
 		$postFix = (substr($path, -1, 1) === '/') ? '/' : '';
700 700
 		$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
701
-		$mount = Filesystem::getMountManager()->find($absolutePath . $postFix);
701
+		$mount = Filesystem::getMountManager()->find($absolutePath.$postFix);
702 702
 		if ($mount and $mount->getInternalPath($absolutePath) === '') {
703 703
 			return $this->removeMount($mount, $absolutePath);
704 704
 		}
@@ -818,7 +818,7 @@  discard block
 block discarded – undo
818 818
 								$this->renameUpdate($storage1, $storage2, $internalPath1, $internalPath2);
819 819
 							}
820 820
 						}
821
-					} catch(\Exception $e) {
821
+					} catch (\Exception $e) {
822 822
 						throw $e;
823 823
 					} finally {
824 824
 						$this->changeLock($path1, ILockingProvider::LOCK_SHARED, true);
@@ -842,7 +842,7 @@  discard block
 block discarded – undo
842 842
 						}
843 843
 					}
844 844
 				}
845
-			} catch(\Exception $e) {
845
+			} catch (\Exception $e) {
846 846
 				throw $e;
847 847
 			} finally {
848 848
 				$this->unlockFile($path1, ILockingProvider::LOCK_SHARED, true);
@@ -975,7 +975,7 @@  discard block
 block discarded – undo
975 975
 				$hooks[] = 'write';
976 976
 				break;
977 977
 			default:
978
-				\OCP\Util::writeLog('core', 'invalid mode (' . $mode . ') for ' . $path, \OCP\Util::ERROR);
978
+				\OCP\Util::writeLog('core', 'invalid mode ('.$mode.') for '.$path, \OCP\Util::ERROR);
979 979
 		}
980 980
 
981 981
 		if ($mode !== 'r' && $mode !== 'w') {
@@ -1079,7 +1079,7 @@  discard block
 block discarded – undo
1079 1079
 					array(Filesystem::signal_param_path => $this->getHookPath($path))
1080 1080
 				);
1081 1081
 			}
1082
-			list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
1082
+			list($storage, $internalPath) = Filesystem::resolvePath($absolutePath.$postFix);
1083 1083
 			if ($storage) {
1084 1084
 				return $storage->hash($type, $internalPath, $raw);
1085 1085
 			}
@@ -1133,7 +1133,7 @@  discard block
 block discarded – undo
1133 1133
 
1134 1134
 			$run = $this->runHooks($hooks, $path);
1135 1135
 			/** @var \OC\Files\Storage\Storage $storage */
1136
-			list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
1136
+			list($storage, $internalPath) = Filesystem::resolvePath($absolutePath.$postFix);
1137 1137
 			if ($run and $storage) {
1138 1138
 				if (in_array('write', $hooks) || in_array('delete', $hooks)) {
1139 1139
 					$this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
@@ -1172,7 +1172,7 @@  discard block
 block discarded – undo
1172 1172
 					$unlockLater = true;
1173 1173
 					// make sure our unlocking callback will still be called if connection is aborted
1174 1174
 					ignore_user_abort(true);
1175
-					$result = CallbackWrapper::wrap($result, null, null, function () use ($hooks, $path) {
1175
+					$result = CallbackWrapper::wrap($result, null, null, function() use ($hooks, $path) {
1176 1176
 						if (in_array('write', $hooks)) {
1177 1177
 							$this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
1178 1178
 						} else if (in_array('read', $hooks)) {
@@ -1233,7 +1233,7 @@  discard block
 block discarded – undo
1233 1233
 			return true;
1234 1234
 		}
1235 1235
 
1236
-		return (strlen($fullPath) > strlen($defaultRoot)) && (substr($fullPath, 0, strlen($defaultRoot) + 1) === $defaultRoot . '/');
1236
+		return (strlen($fullPath) > strlen($defaultRoot)) && (substr($fullPath, 0, strlen($defaultRoot) + 1) === $defaultRoot.'/');
1237 1237
 	}
1238 1238
 
1239 1239
 	/**
@@ -1252,7 +1252,7 @@  discard block
 block discarded – undo
1252 1252
 				if ($hook != 'read') {
1253 1253
 					\OC_Hook::emit(
1254 1254
 						Filesystem::CLASSNAME,
1255
-						$prefix . $hook,
1255
+						$prefix.$hook,
1256 1256
 						array(
1257 1257
 							Filesystem::signal_param_run => &$run,
1258 1258
 							Filesystem::signal_param_path => $path
@@ -1261,7 +1261,7 @@  discard block
 block discarded – undo
1261 1261
 				} elseif (!$post) {
1262 1262
 					\OC_Hook::emit(
1263 1263
 						Filesystem::CLASSNAME,
1264
-						$prefix . $hook,
1264
+						$prefix.$hook,
1265 1265
 						array(
1266 1266
 							Filesystem::signal_param_path => $path
1267 1267
 						)
@@ -1356,7 +1356,7 @@  discard block
 block discarded – undo
1356 1356
 			return $this->getPartFileInfo($path);
1357 1357
 		}
1358 1358
 		$relativePath = $path;
1359
-		$path = Filesystem::normalizePath($this->fakeRoot . '/' . $path);
1359
+		$path = Filesystem::normalizePath($this->fakeRoot.'/'.$path);
1360 1360
 
1361 1361
 		$mount = Filesystem::getMountManager()->find($path);
1362 1362
 		if (!$mount) {
@@ -1383,7 +1383,7 @@  discard block
 block discarded – undo
1383 1383
 					//add the sizes of other mount points to the folder
1384 1384
 					$extOnly = ($includeMountPoints === 'ext');
1385 1385
 					$mounts = Filesystem::getMountManager()->findIn($path);
1386
-					$info->setSubMounts(array_filter($mounts, function (IMountPoint $mount) use ($extOnly) {
1386
+					$info->setSubMounts(array_filter($mounts, function(IMountPoint $mount) use ($extOnly) {
1387 1387
 						$subStorage = $mount->getStorage();
1388 1388
 						return !($extOnly && $subStorage instanceof \OCA\Files_Sharing\SharedStorage);
1389 1389
 					}));
@@ -1433,12 +1433,12 @@  discard block
 block discarded – undo
1433 1433
 			/**
1434 1434
 			 * @var \OC\Files\FileInfo[] $files
1435 1435
 			 */
1436
-			$files = array_map(function (ICacheEntry $content) use ($path, $storage, $mount, $sharingDisabled) {
1436
+			$files = array_map(function(ICacheEntry $content) use ($path, $storage, $mount, $sharingDisabled) {
1437 1437
 				if ($sharingDisabled) {
1438 1438
 					$content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
1439 1439
 				}
1440 1440
 				$owner = $this->getUserObjectForOwner($storage->getOwner($content['path']));
1441
-				return new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content, $mount, $owner);
1441
+				return new FileInfo($path.'/'.$content['name'], $storage, $content['path'], $content, $mount, $owner);
1442 1442
 			}, $contents);
1443 1443
 
1444 1444
 			//add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders
@@ -1462,7 +1462,7 @@  discard block
 block discarded – undo
1462 1462
 						} catch (\Exception $e) {
1463 1463
 							// sometimes when the storage is not available it can be any exception
1464 1464
 							\OC::$server->getLogger()->logException($e, [
1465
-								'message' => 'Exception while scanning storage "' . $subStorage->getId() . '"',
1465
+								'message' => 'Exception while scanning storage "'.$subStorage->getId().'"',
1466 1466
 								'level' => \OCP\Util::ERROR,
1467 1467
 								'app' => 'lib',
1468 1468
 							]);
@@ -1500,7 +1500,7 @@  discard block
 block discarded – undo
1500 1500
 									break;
1501 1501
 								}
1502 1502
 							}
1503
-							$rootEntry['path'] = substr(Filesystem::normalizePath($path . '/' . $rootEntry['name']), strlen($user) + 2); // full path without /$user/
1503
+							$rootEntry['path'] = substr(Filesystem::normalizePath($path.'/'.$rootEntry['name']), strlen($user) + 2); // full path without /$user/
1504 1504
 
1505 1505
 							// if sharing was disabled for the user we remove the share permissions
1506 1506
 							if (\OCP\Util::isSharingDisabledForUser()) {
@@ -1508,14 +1508,14 @@  discard block
 block discarded – undo
1508 1508
 							}
1509 1509
 
1510 1510
 							$owner = $this->getUserObjectForOwner($subStorage->getOwner(''));
1511
-							$files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry, $mount, $owner);
1511
+							$files[] = new FileInfo($path.'/'.$rootEntry['name'], $subStorage, '', $rootEntry, $mount, $owner);
1512 1512
 						}
1513 1513
 					}
1514 1514
 				}
1515 1515
 			}
1516 1516
 
1517 1517
 			if ($mimetype_filter) {
1518
-				$files = array_filter($files, function (FileInfo $file) use ($mimetype_filter) {
1518
+				$files = array_filter($files, function(FileInfo $file) use ($mimetype_filter) {
1519 1519
 					if (strpos($mimetype_filter, '/')) {
1520 1520
 						return $file->getMimetype() === $mimetype_filter;
1521 1521
 					} else {
@@ -1544,7 +1544,7 @@  discard block
 block discarded – undo
1544 1544
 		if ($data instanceof FileInfo) {
1545 1545
 			$data = $data->getData();
1546 1546
 		}
1547
-		$path = Filesystem::normalizePath($this->fakeRoot . '/' . $path);
1547
+		$path = Filesystem::normalizePath($this->fakeRoot.'/'.$path);
1548 1548
 		/**
1549 1549
 		 * @var \OC\Files\Storage\Storage $storage
1550 1550
 		 * @var string $internalPath
@@ -1571,7 +1571,7 @@  discard block
 block discarded – undo
1571 1571
 	 * @return FileInfo[]
1572 1572
 	 */
1573 1573
 	public function search($query) {
1574
-		return $this->searchCommon('search', array('%' . $query . '%'));
1574
+		return $this->searchCommon('search', array('%'.$query.'%'));
1575 1575
 	}
1576 1576
 
1577 1577
 	/**
@@ -1622,10 +1622,10 @@  discard block
 block discarded – undo
1622 1622
 
1623 1623
 			$results = call_user_func_array(array($cache, $method), $args);
1624 1624
 			foreach ($results as $result) {
1625
-				if (substr($mountPoint . $result['path'], 0, $rootLength + 1) === $this->fakeRoot . '/') {
1625
+				if (substr($mountPoint.$result['path'], 0, $rootLength + 1) === $this->fakeRoot.'/') {
1626 1626
 					$internalPath = $result['path'];
1627
-					$path = $mountPoint . $result['path'];
1628
-					$result['path'] = substr($mountPoint . $result['path'], $rootLength);
1627
+					$path = $mountPoint.$result['path'];
1628
+					$result['path'] = substr($mountPoint.$result['path'], $rootLength);
1629 1629
 					$owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
1630 1630
 					$files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner);
1631 1631
 				}
@@ -1643,8 +1643,8 @@  discard block
 block discarded – undo
1643 1643
 					if ($results) {
1644 1644
 						foreach ($results as $result) {
1645 1645
 							$internalPath = $result['path'];
1646
-							$result['path'] = rtrim($relativeMountPoint . $result['path'], '/');
1647
-							$path = rtrim($mountPoint . $internalPath, '/');
1646
+							$result['path'] = rtrim($relativeMountPoint.$result['path'], '/');
1647
+							$path = rtrim($mountPoint.$internalPath, '/');
1648 1648
 							$owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
1649 1649
 							$files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner);
1650 1650
 						}
@@ -1665,7 +1665,7 @@  discard block
 block discarded – undo
1665 1665
 	public function getOwner($path) {
1666 1666
 		$info = $this->getFileInfo($path);
1667 1667
 		if (!$info) {
1668
-			throw new NotFoundException($path . ' not found while trying to get owner');
1668
+			throw new NotFoundException($path.' not found while trying to get owner');
1669 1669
 		}
1670 1670
 		return $info->getOwner()->getUID();
1671 1671
 	}
@@ -1699,7 +1699,7 @@  discard block
 block discarded – undo
1699 1699
 	 * @return string
1700 1700
 	 */
1701 1701
 	public function getPath($id) {
1702
-		$id = (int)$id;
1702
+		$id = (int) $id;
1703 1703
 		$manager = Filesystem::getMountManager();
1704 1704
 		$mounts = $manager->findIn($this->fakeRoot);
1705 1705
 		$mounts[] = $manager->find($this->fakeRoot);
@@ -1714,7 +1714,7 @@  discard block
 block discarded – undo
1714 1714
 				$cache = $mount->getStorage()->getCache();
1715 1715
 				$internalPath = $cache->getPathById($id);
1716 1716
 				if (is_string($internalPath)) {
1717
-					$fullPath = $mount->getMountPoint() . $internalPath;
1717
+					$fullPath = $mount->getMountPoint().$internalPath;
1718 1718
 					if (!is_null($path = $this->getRelativePath($fullPath))) {
1719 1719
 						return $path;
1720 1720
 					}
@@ -1757,10 +1757,10 @@  discard block
 block discarded – undo
1757 1757
 		}
1758 1758
 
1759 1759
 		// note: cannot use the view because the target is already locked
1760
-		$fileId = (int)$targetStorage->getCache()->getId($targetInternalPath);
1760
+		$fileId = (int) $targetStorage->getCache()->getId($targetInternalPath);
1761 1761
 		if ($fileId === -1) {
1762 1762
 			// target might not exist, need to check parent instead
1763
-			$fileId = (int)$targetStorage->getCache()->getId(dirname($targetInternalPath));
1763
+			$fileId = (int) $targetStorage->getCache()->getId(dirname($targetInternalPath));
1764 1764
 		}
1765 1765
 
1766 1766
 		// check if any of the parents were shared by the current owner (include collections)
@@ -1860,7 +1860,7 @@  discard block
 block discarded – undo
1860 1860
 		$resultPath = '';
1861 1861
 		foreach ($parts as $part) {
1862 1862
 			if ($part) {
1863
-				$resultPath .= '/' . $part;
1863
+				$resultPath .= '/'.$part;
1864 1864
 				$result[] = $resultPath;
1865 1865
 			}
1866 1866
 		}
@@ -2123,16 +2123,16 @@  discard block
 block discarded – undo
2123 2123
 	public function getUidAndFilename($filename) {
2124 2124
 		$info = $this->getFileInfo($filename);
2125 2125
 		if (!$info instanceof \OCP\Files\FileInfo) {
2126
-			throw new NotFoundException($this->getAbsolutePath($filename) . ' not found');
2126
+			throw new NotFoundException($this->getAbsolutePath($filename).' not found');
2127 2127
 		}
2128 2128
 		$uid = $info->getOwner()->getUID();
2129 2129
 		if ($uid != \OCP\User::getUser()) {
2130 2130
 			Filesystem::initMountPoints($uid);
2131
-			$ownerView = new View('/' . $uid . '/files');
2131
+			$ownerView = new View('/'.$uid.'/files');
2132 2132
 			try {
2133 2133
 				$filename = $ownerView->getPath($info['fileid']);
2134 2134
 			} catch (NotFoundException $e) {
2135
-				throw new NotFoundException('File with id ' . $info['fileid'] . ' not found for user ' . $uid);
2135
+				throw new NotFoundException('File with id '.$info['fileid'].' not found for user '.$uid);
2136 2136
 			}
2137 2137
 		}
2138 2138
 		return [$uid, $filename];
@@ -2149,7 +2149,7 @@  discard block
 block discarded – undo
2149 2149
 		$directoryParts = array_filter($directoryParts);
2150 2150
 		foreach ($directoryParts as $key => $part) {
2151 2151
 			$currentPathElements = array_slice($directoryParts, 0, $key);
2152
-			$currentPath = '/' . implode('/', $currentPathElements);
2152
+			$currentPath = '/'.implode('/', $currentPathElements);
2153 2153
 			if ($this->is_file($currentPath)) {
2154 2154
 				return false;
2155 2155
 			}
Please login to merge, or discard this patch.
lib/private/App/Platform.php 1 patch
Indentation   +53 added lines, -53 removed lines patch added patch discarded remove patch
@@ -35,65 +35,65 @@
 block discarded – undo
35 35
  */
36 36
 class Platform {
37 37
 
38
-	/**
39
-	 * @param IConfig $config
40
-	 */
41
-	function __construct(IConfig $config) {
42
-		$this->config = $config;
43
-	}
38
+    /**
39
+     * @param IConfig $config
40
+     */
41
+    function __construct(IConfig $config) {
42
+        $this->config = $config;
43
+    }
44 44
 
45
-	/**
46
-	 * @return string
47
-	 */
48
-	public function getPhpVersion() {
49
-		return phpversion();
50
-	}
45
+    /**
46
+     * @return string
47
+     */
48
+    public function getPhpVersion() {
49
+        return phpversion();
50
+    }
51 51
 
52
-	/**
53
-	 * @return int
54
-	 */
55
-	public function getIntSize() {
56
-		return PHP_INT_SIZE;
57
-	}
52
+    /**
53
+     * @return int
54
+     */
55
+    public function getIntSize() {
56
+        return PHP_INT_SIZE;
57
+    }
58 58
 
59
-	/**
60
-	 * @return string
61
-	 */
62
-	public function getOcVersion() {
63
-		$v = \OCP\Util::getVersion();
64
-		return join('.', $v);
65
-	}
59
+    /**
60
+     * @return string
61
+     */
62
+    public function getOcVersion() {
63
+        $v = \OCP\Util::getVersion();
64
+        return join('.', $v);
65
+    }
66 66
 
67
-	/**
68
-	 * @return string
69
-	 */
70
-	public function getDatabase() {
71
-		$dbType = $this->config->getSystemValue('dbtype', 'sqlite');
72
-		if ($dbType === 'sqlite3') {
73
-			$dbType = 'sqlite';
74
-		}
67
+    /**
68
+     * @return string
69
+     */
70
+    public function getDatabase() {
71
+        $dbType = $this->config->getSystemValue('dbtype', 'sqlite');
72
+        if ($dbType === 'sqlite3') {
73
+            $dbType = 'sqlite';
74
+        }
75 75
 
76
-		return $dbType;
77
-	}
76
+        return $dbType;
77
+    }
78 78
 
79
-	/**
80
-	 * @return string
81
-	 */
82
-	public function getOS() {
83
-		return php_uname('s');
84
-	}
79
+    /**
80
+     * @return string
81
+     */
82
+    public function getOS() {
83
+        return php_uname('s');
84
+    }
85 85
 
86
-	/**
87
-	 * @param $command
88
-	 * @return bool
89
-	 */
90
-	public function isCommandKnown($command) {
91
-		$path = \OC_Helper::findBinaryPath($command);
92
-		return ($path !== null);
93
-	}
86
+    /**
87
+     * @param $command
88
+     * @return bool
89
+     */
90
+    public function isCommandKnown($command) {
91
+        $path = \OC_Helper::findBinaryPath($command);
92
+        return ($path !== null);
93
+    }
94 94
 
95
-	public function getLibraryVersion($name) {
96
-		$repo = new PlatformRepository();
97
-		return $repo->findLibrary($name);
98
-	}
95
+    public function getLibraryVersion($name) {
96
+        $repo = new PlatformRepository();
97
+        return $repo->findLibrary($name);
98
+    }
99 99
 }
Please login to merge, or discard this patch.
settings/Controller/UsersController.php 1 patch
Indentation   +981 added lines, -981 removed lines patch added patch discarded remove patch
@@ -69,986 +69,986 @@
 block discarded – undo
69 69
  * @package OC\Settings\Controller
70 70
  */
71 71
 class UsersController extends Controller {
72
-	/** @var IL10N */
73
-	private $l10n;
74
-	/** @var IUserSession */
75
-	private $userSession;
76
-	/** @var bool */
77
-	private $isAdmin;
78
-	/** @var IUserManager */
79
-	private $userManager;
80
-	/** @var IGroupManager */
81
-	private $groupManager;
82
-	/** @var IConfig */
83
-	private $config;
84
-	/** @var ILogger */
85
-	private $log;
86
-	/** @var IMailer */
87
-	private $mailer;
88
-	/** @var bool contains the state of the encryption app */
89
-	private $isEncryptionAppEnabled;
90
-	/** @var bool contains the state of the admin recovery setting */
91
-	private $isRestoreEnabled = false;
92
-	/** @var IAppManager */
93
-	private $appManager;
94
-	/** @var IAvatarManager */
95
-	private $avatarManager;
96
-	/** @var AccountManager */
97
-	private $accountManager;
98
-	/** @var ISecureRandom */
99
-	private $secureRandom;
100
-	/** @var NewUserMailHelper */
101
-	private $newUserMailHelper;
102
-	/** @var ITimeFactory */
103
-	private $timeFactory;
104
-	/** @var ICrypto */
105
-	private $crypto;
106
-	/** @var Manager */
107
-	private $keyManager;
108
-	/** @var IJobList */
109
-	private $jobList;
110
-
111
-	/** @var IUserMountCache */
112
-	private $userMountCache;
113
-
114
-	/** @var IManager */
115
-	private $encryptionManager;
116
-
117
-
118
-	/**
119
-	 * @param string $appName
120
-	 * @param IRequest $request
121
-	 * @param IUserManager $userManager
122
-	 * @param IGroupManager $groupManager
123
-	 * @param IUserSession $userSession
124
-	 * @param IConfig $config
125
-	 * @param bool $isAdmin
126
-	 * @param IL10N $l10n
127
-	 * @param ILogger $log
128
-	 * @param IMailer $mailer
129
-	 * @param IURLGenerator $urlGenerator
130
-	 * @param IAppManager $appManager
131
-	 * @param IAvatarManager $avatarManager
132
-	 * @param AccountManager $accountManager
133
-	 * @param ISecureRandom $secureRandom
134
-	 * @param NewUserMailHelper $newUserMailHelper
135
-	 * @param ITimeFactory $timeFactory
136
-	 * @param ICrypto $crypto
137
-	 * @param Manager $keyManager
138
-	 * @param IJobList $jobList
139
-	 * @param IUserMountCache $userMountCache
140
-	 * @param IManager $encryptionManager
141
-	 */
142
-	public function __construct($appName,
143
-								IRequest $request,
144
-								IUserManager $userManager,
145
-								IGroupManager $groupManager,
146
-								IUserSession $userSession,
147
-								IConfig $config,
148
-								$isAdmin,
149
-								IL10N $l10n,
150
-								ILogger $log,
151
-								IMailer $mailer,
152
-								IURLGenerator $urlGenerator,
153
-								IAppManager $appManager,
154
-								IAvatarManager $avatarManager,
155
-								AccountManager $accountManager,
156
-								ISecureRandom $secureRandom,
157
-								NewUserMailHelper $newUserMailHelper,
158
-								ITimeFactory $timeFactory,
159
-								ICrypto $crypto,
160
-								Manager $keyManager,
161
-								IJobList $jobList,
162
-								IUserMountCache $userMountCache,
163
-								IManager $encryptionManager) {
164
-		parent::__construct($appName, $request);
165
-		$this->userManager = $userManager;
166
-		$this->groupManager = $groupManager;
167
-		$this->userSession = $userSession;
168
-		$this->config = $config;
169
-		$this->isAdmin = $isAdmin;
170
-		$this->l10n = $l10n;
171
-		$this->log = $log;
172
-		$this->mailer = $mailer;
173
-		$this->appManager = $appManager;
174
-		$this->avatarManager = $avatarManager;
175
-		$this->accountManager = $accountManager;
176
-		$this->secureRandom = $secureRandom;
177
-		$this->newUserMailHelper = $newUserMailHelper;
178
-		$this->timeFactory = $timeFactory;
179
-		$this->crypto = $crypto;
180
-		$this->keyManager = $keyManager;
181
-		$this->jobList = $jobList;
182
-		$this->userMountCache = $userMountCache;
183
-		$this->encryptionManager = $encryptionManager;
184
-
185
-		// check for encryption state - TODO see formatUserForIndex
186
-		$this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption');
187
-		if ($this->isEncryptionAppEnabled) {
188
-			// putting this directly in empty is possible in PHP 5.5+
189
-			$result = $config->getAppValue('encryption', 'recoveryAdminEnabled', '0');
190
-			$this->isRestoreEnabled = !empty($result);
191
-		}
192
-	}
193
-
194
-	/**
195
-	 * @param IUser $user
196
-	 * @param array|null $userGroups
197
-	 * @return array
198
-	 */
199
-	private function formatUserForIndex(IUser $user, array $userGroups = null) {
200
-
201
-		// TODO: eliminate this encryption specific code below and somehow
202
-		// hook in additional user info from other apps
203
-
204
-		// recovery isn't possible if admin or user has it disabled and encryption
205
-		// is enabled - so we eliminate the else paths in the conditional tree
206
-		// below
207
-		$restorePossible = false;
208
-
209
-		if ($this->isEncryptionAppEnabled) {
210
-			if ($this->isRestoreEnabled) {
211
-				// check for the users recovery setting
212
-				$recoveryMode = $this->config->getUserValue($user->getUID(), 'encryption', 'recoveryEnabled', '0');
213
-				// method call inside empty is possible with PHP 5.5+
214
-				$recoveryModeEnabled = !empty($recoveryMode);
215
-				if ($recoveryModeEnabled) {
216
-					// user also has recovery mode enabled
217
-					$restorePossible = true;
218
-				}
219
-			} else {
220
-				$modules = $this->encryptionManager->getEncryptionModules();
221
-				$restorePossible = true;
222
-				foreach ($modules as $id => $module) {
223
-					/* @var IEncryptionModule $instance */
224
-					$instance = call_user_func($module['callback']);
225
-					if ($instance->needDetailedAccessList()) {
226
-						$restorePossible = false;
227
-						break;
228
-					}
229
-				}
230
-			}
231
-		} else {
232
-			// recovery is possible if encryption is disabled (plain files are
233
-			// available)
234
-			$restorePossible = true;
235
-		}
236
-
237
-		$subAdminGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
238
-		foreach ($subAdminGroups as $key => $subAdminGroup) {
239
-			$subAdminGroups[$key] = $subAdminGroup->getGID();
240
-		}
241
-
242
-		$displayName = $user->getEMailAddress();
243
-		if (is_null($displayName)) {
244
-			$displayName = '';
245
-		}
246
-
247
-		$avatarAvailable = false;
248
-		try {
249
-			$avatarAvailable = $this->avatarManager->getAvatar($user->getUID())->exists();
250
-		} catch (\Exception $e) {
251
-			//No avatar yet
252
-		}
253
-
254
-		return [
255
-			'name' => $user->getUID(),
256
-			'displayname' => $user->getDisplayName(),
257
-			'groups' => (empty($userGroups)) ? $this->groupManager->getUserGroupIds($user) : $userGroups,
258
-			'subadmin' => $subAdminGroups,
259
-			'quota' => $user->getQuota(),
260
-			'quota_bytes' => Util::computerFileSize($user->getQuota()),
261
-			'storageLocation' => $user->getHome(),
262
-			'lastLogin' => $user->getLastLogin() * 1000,
263
-			'backend' => $user->getBackendClassName(),
264
-			'email' => $displayName,
265
-			'isRestoreDisabled' => !$restorePossible,
266
-			'isAvatarAvailable' => $avatarAvailable,
267
-			'isEnabled' => $user->isEnabled(),
268
-		];
269
-	}
270
-
271
-	/**
272
-	 * @param array $userIDs Array with schema [$uid => $displayName]
273
-	 * @return IUser[]
274
-	 */
275
-	private function getUsersForUID(array $userIDs) {
276
-		$users = [];
277
-		foreach ($userIDs as $uid => $displayName) {
278
-			$users[$uid] = $this->userManager->get($uid);
279
-		}
280
-		return $users;
281
-	}
282
-
283
-	/**
284
-	 * @NoAdminRequired
285
-	 *
286
-	 * @param int $offset
287
-	 * @param int $limit
288
-	 * @param string $gid GID to filter for
289
-	 * @param string $pattern Pattern to search for in the username
290
-	 * @param string $backend Backend to filter for (class-name)
291
-	 * @return DataResponse
292
-	 *
293
-	 * TODO: Tidy up and write unit tests - code is mainly static method calls
294
-	 */
295
-	public function index($offset = 0, $limit = 10, $gid = '', $pattern = '', $backend = '') {
296
-		// Remove backends
297
-		if (!empty($backend)) {
298
-			$activeBackends = $this->userManager->getBackends();
299
-			$this->userManager->clearBackends();
300
-			foreach ($activeBackends as $singleActiveBackend) {
301
-				if ($backend === get_class($singleActiveBackend)) {
302
-					$this->userManager->registerBackend($singleActiveBackend);
303
-					break;
304
-				}
305
-			}
306
-		}
307
-
308
-		$userObjects = [];
309
-		$users = [];
310
-		if ($this->isAdmin) {
311
-			if ($gid !== '' && $gid !== '_disabledUsers' && $gid !== '_everyone') {
312
-				$batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset));
313
-			} else {
314
-				$batch = $this->userManager->search($pattern, $limit, $offset);
315
-			}
316
-
317
-			foreach ($batch as $user) {
318
-				if (($gid !== '_disabledUsers' && $user->isEnabled()) ||
319
-					($gid === '_disabledUsers' && !$user->isEnabled())
320
-				) {
321
-					$userObjects[] = $user;
322
-					$users[] = $this->formatUserForIndex($user);
323
-				}
324
-			}
325
-
326
-		} else {
327
-			$subAdminOfGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser());
328
-			// New class returns IGroup[] so convert back
329
-			$gids = [];
330
-			foreach ($subAdminOfGroups as $group) {
331
-				$gids[] = $group->getGID();
332
-			}
333
-			$subAdminOfGroups = $gids;
334
-
335
-			// Set the $gid parameter to an empty value if the subadmin has no rights to access a specific group
336
-			if ($gid !== '' && $gid !== '_disabledUsers' && !in_array($gid, $subAdminOfGroups)) {
337
-				$gid = '';
338
-			}
339
-
340
-			// Batch all groups the user is subadmin of when a group is specified
341
-			$batch = [];
342
-			if ($gid !== '' && $gid !== '_disabledUsers' && $gid !== '_everyone') {
343
-				$batch = $this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset);
344
-			} else {
345
-				foreach ($subAdminOfGroups as $group) {
346
-					$groupUsers = $this->groupManager->displayNamesInGroup($group, $pattern, $limit, $offset);
347
-
348
-					foreach ($groupUsers as $uid => $displayName) {
349
-						$batch[$uid] = $displayName;
350
-					}
351
-				}
352
-			}
353
-			$batch = $this->getUsersForUID($batch);
354
-
355
-			foreach ($batch as $user) {
356
-				// Only add the groups, this user is a subadmin of
357
-				$userGroups = array_values(array_intersect(
358
-					$this->groupManager->getUserGroupIds($user),
359
-					$subAdminOfGroups
360
-				));
361
-				if (($gid !== '_disabledUsers' && $user->isEnabled()) ||
362
-					($gid === '_disabledUsers' && !$user->isEnabled())
363
-				) {
364
-					$userObjects[] = $user;
365
-					$users[] = $this->formatUserForIndex($user, $userGroups);
366
-				}
367
-			}
368
-		}
369
-
370
-		$usedSpace = $this->userMountCache->getUsedSpaceForUsers($userObjects);
371
-
372
-		foreach ($users as &$userData) {
373
-			$userData['size'] = isset($usedSpace[$userData['name']]) ? $usedSpace[$userData['name']] : 0;
374
-		}
375
-
376
-		return new DataResponse($users);
377
-	}
378
-
379
-	/**
380
-	 * @NoAdminRequired
381
-	 * @PasswordConfirmationRequired
382
-	 *
383
-	 * @param string $username
384
-	 * @param string $password
385
-	 * @param array $groups
386
-	 * @param string $email
387
-	 * @return DataResponse
388
-	 */
389
-	public function create($username, $password, array $groups = [], $email = '') {
390
-		if ($email !== '' && !$this->mailer->validateMailAddress($email)) {
391
-			return new DataResponse(
392
-				[
393
-					'message' => (string)$this->l10n->t('Invalid mail address')
394
-				],
395
-				Http::STATUS_UNPROCESSABLE_ENTITY
396
-			);
397
-		}
398
-
399
-		$currentUser = $this->userSession->getUser();
400
-
401
-		if (!$this->isAdmin) {
402
-			if (!empty($groups)) {
403
-				foreach ($groups as $key => $group) {
404
-					$groupObject = $this->groupManager->get($group);
405
-					if ($groupObject === null) {
406
-						unset($groups[$key]);
407
-						continue;
408
-					}
409
-
410
-					if (!$this->groupManager->getSubAdmin()->isSubAdminofGroup($currentUser, $groupObject)) {
411
-						unset($groups[$key]);
412
-					}
413
-				}
414
-			}
415
-
416
-			if (empty($groups)) {
417
-				return new DataResponse(
418
-					[
419
-						'message' => $this->l10n->t('No valid group selected'),
420
-					],
421
-					Http::STATUS_FORBIDDEN
422
-				);
423
-			}
424
-		}
425
-
426
-		if ($this->userManager->userExists($username)) {
427
-			return new DataResponse(
428
-				[
429
-					'message' => (string)$this->l10n->t('A user with that name already exists.')
430
-				],
431
-				Http::STATUS_CONFLICT
432
-			);
433
-		}
434
-
435
-		$generatePasswordResetToken = false;
436
-		if ($password === '') {
437
-			if ($email === '') {
438
-				return new DataResponse(
439
-					[
440
-						'message' => (string)$this->l10n->t('To send a password link to the user an email address is required.')
441
-					],
442
-					Http::STATUS_UNPROCESSABLE_ENTITY
443
-				);
444
-			}
445
-
446
-			$password = $this->secureRandom->generate(30);
447
-			// Make sure we pass the password_policy
448
-			$password .= $this->secureRandom->generate(2, '$!.,;:-~+*[]{}()');
449
-			$generatePasswordResetToken = true;
450
-		}
451
-
452
-		try {
453
-			$user = $this->userManager->createUser($username, $password);
454
-		} catch (\Exception $exception) {
455
-			$message = $exception->getMessage();
456
-			if ($exception instanceof HintException && $exception->getHint()) {
457
-				$message = $exception->getHint();
458
-			}
459
-			if (!$message) {
460
-				$message = $this->l10n->t('Unable to create user.');
461
-			}
462
-			return new DataResponse(
463
-				[
464
-					'message' => (string)$message,
465
-				],
466
-				Http::STATUS_FORBIDDEN
467
-			);
468
-		}
469
-
470
-		if ($user instanceof IUser) {
471
-			if ($groups !== null) {
472
-				foreach ($groups as $groupName) {
473
-					$group = $this->groupManager->get($groupName);
474
-
475
-					if (empty($group)) {
476
-						$group = $this->groupManager->createGroup($groupName);
477
-					}
478
-					$group->addUser($user);
479
-				}
480
-			}
481
-			/**
482
-			 * Send new user mail only if a mail is set
483
-			 */
484
-			if ($email !== '') {
485
-				$user->setEMailAddress($email);
486
-				try {
487
-					$emailTemplate = $this->newUserMailHelper->generateTemplate($user, $generatePasswordResetToken);
488
-					$this->newUserMailHelper->sendMail($user, $emailTemplate);
489
-				} catch (\Exception $e) {
490
-					$this->log->logException($e, [
491
-						'message' => "Can't send new user mail to $email",
492
-						'level' => \OCP\Util::ERROR,
493
-						'app' => 'settings',
494
-					]);
495
-				}
496
-			}
497
-			// fetch users groups
498
-			$userGroups = $this->groupManager->getUserGroupIds($user);
499
-
500
-			return new DataResponse(
501
-				$this->formatUserForIndex($user, $userGroups),
502
-				Http::STATUS_CREATED
503
-			);
504
-		}
505
-
506
-		return new DataResponse(
507
-			[
508
-				'message' => (string)$this->l10n->t('Unable to create user.')
509
-			],
510
-			Http::STATUS_FORBIDDEN
511
-		);
512
-
513
-	}
514
-
515
-	/**
516
-	 * @NoAdminRequired
517
-	 * @PasswordConfirmationRequired
518
-	 *
519
-	 * @param string $id
520
-	 * @return DataResponse
521
-	 */
522
-	public function destroy($id) {
523
-		$userId = $this->userSession->getUser()->getUID();
524
-		$user = $this->userManager->get($id);
525
-
526
-		if ($userId === $id) {
527
-			return new DataResponse(
528
-				[
529
-					'status' => 'error',
530
-					'data' => [
531
-						'message' => (string)$this->l10n->t('Unable to delete user.')
532
-					]
533
-				],
534
-				Http::STATUS_FORBIDDEN
535
-			);
536
-		}
537
-
538
-		if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
539
-			return new DataResponse(
540
-				[
541
-					'status' => 'error',
542
-					'data' => [
543
-						'message' => (string)$this->l10n->t('Authentication error')
544
-					]
545
-				],
546
-				Http::STATUS_FORBIDDEN
547
-			);
548
-		}
549
-
550
-		if ($user) {
551
-			if ($user->delete()) {
552
-				return new DataResponse(
553
-					[
554
-						'status' => 'success',
555
-						'data' => [
556
-							'username' => $id
557
-						]
558
-					],
559
-					Http::STATUS_NO_CONTENT
560
-				);
561
-			}
562
-		}
563
-
564
-		return new DataResponse(
565
-			[
566
-				'status' => 'error',
567
-				'data' => [
568
-					'message' => (string)$this->l10n->t('Unable to delete user.')
569
-				]
570
-			],
571
-			Http::STATUS_FORBIDDEN
572
-		);
573
-	}
574
-
575
-	/**
576
-	 * @NoAdminRequired
577
-	 *
578
-	 * @param string $id
579
-	 * @param int $enabled
580
-	 * @return DataResponse
581
-	 */
582
-	public function setEnabled($id, $enabled) {
583
-		$enabled = (bool)$enabled;
584
-		if ($enabled) {
585
-			$errorMsgGeneral = (string)$this->l10n->t('Error while enabling user.');
586
-		} else {
587
-			$errorMsgGeneral = (string)$this->l10n->t('Error while disabling user.');
588
-		}
589
-
590
-		$userId = $this->userSession->getUser()->getUID();
591
-		$user = $this->userManager->get($id);
592
-
593
-		if ($userId === $id) {
594
-			return new DataResponse(
595
-				[
596
-					'status' => 'error',
597
-					'data' => [
598
-						'message' => $errorMsgGeneral
599
-					]
600
-				], Http::STATUS_FORBIDDEN
601
-			);
602
-		}
603
-
604
-		if ($user) {
605
-			if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
606
-				return new DataResponse(
607
-					[
608
-						'status' => 'error',
609
-						'data' => [
610
-							'message' => (string)$this->l10n->t('Authentication error')
611
-						]
612
-					],
613
-					Http::STATUS_FORBIDDEN
614
-				);
615
-			}
616
-
617
-			$user->setEnabled($enabled);
618
-			return new DataResponse(
619
-				[
620
-					'status' => 'success',
621
-					'data' => [
622
-						'username' => $id,
623
-						'enabled' => $enabled
624
-					]
625
-				]
626
-			);
627
-		} else {
628
-			return new DataResponse(
629
-				[
630
-					'status' => 'error',
631
-					'data' => [
632
-						'message' => $errorMsgGeneral
633
-					]
634
-				],
635
-				Http::STATUS_FORBIDDEN
636
-			);
637
-		}
638
-
639
-	}
640
-
641
-	/**
642
-	 * Set the mail address of a user
643
-	 *
644
-	 * @NoAdminRequired
645
-	 * @NoSubadminRequired
646
-	 * @PasswordConfirmationRequired
647
-	 *
648
-	 * @param string $account
649
-	 * @param bool $onlyVerificationCode only return verification code without updating the data
650
-	 * @return DataResponse
651
-	 */
652
-	public function getVerificationCode($account, $onlyVerificationCode) {
653
-
654
-		$user = $this->userSession->getUser();
655
-
656
-		if ($user === null) {
657
-			return new DataResponse([], Http::STATUS_BAD_REQUEST);
658
-		}
659
-
660
-		$accountData = $this->accountManager->getUser($user);
661
-		$cloudId = $user->getCloudId();
662
-		$message = "Use my Federated Cloud ID to share with me: " . $cloudId;
663
-		$signature = $this->signMessage($user, $message);
664
-
665
-		$code = $message . ' ' . $signature;
666
-		$codeMd5 = $message . ' ' . md5($signature);
667
-
668
-		switch ($account) {
669
-			case 'verify-twitter':
670
-				$accountData[AccountManager::PROPERTY_TWITTER]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
671
-				$msg = $this->l10n->t('In order to verify your Twitter account, post the following tweet on Twitter (please make sure to post it without any line breaks):');
672
-				$code = $codeMd5;
673
-				$type = AccountManager::PROPERTY_TWITTER;
674
-				$data = $accountData[AccountManager::PROPERTY_TWITTER]['value'];
675
-				$accountData[AccountManager::PROPERTY_TWITTER]['signature'] = $signature;
676
-				break;
677
-			case 'verify-website':
678
-				$accountData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
679
-				$msg = $this->l10n->t('In order to verify your Website, store the following content in your web-root at \'.well-known/CloudIdVerificationCode.txt\' (please make sure that the complete text is in one line):');
680
-				$type = AccountManager::PROPERTY_WEBSITE;
681
-				$data = $accountData[AccountManager::PROPERTY_WEBSITE]['value'];
682
-				$accountData[AccountManager::PROPERTY_WEBSITE]['signature'] = $signature;
683
-				break;
684
-			default:
685
-				return new DataResponse([], Http::STATUS_BAD_REQUEST);
686
-		}
687
-
688
-		if ($onlyVerificationCode === false) {
689
-			$this->accountManager->updateUser($user, $accountData);
690
-
691
-			$this->jobList->add('OC\Settings\BackgroundJobs\VerifyUserData',
692
-				[
693
-					'verificationCode' => $code,
694
-					'data' => $data,
695
-					'type' => $type,
696
-					'uid' => $user->getUID(),
697
-					'try' => 0,
698
-					'lastRun' => $this->getCurrentTime()
699
-				]
700
-			);
701
-		}
702
-
703
-		return new DataResponse(['msg' => $msg, 'code' => $code]);
704
-	}
705
-
706
-	/**
707
-	 * get current timestamp
708
-	 *
709
-	 * @return int
710
-	 */
711
-	protected function getCurrentTime() {
712
-		return time();
713
-	}
714
-
715
-	/**
716
-	 * sign message with users private key
717
-	 *
718
-	 * @param IUser $user
719
-	 * @param string $message
720
-	 *
721
-	 * @return string base64 encoded signature
722
-	 */
723
-	protected function signMessage(IUser $user, $message) {
724
-		$privateKey = $this->keyManager->getKey($user)->getPrivate();
725
-		openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512);
726
-		return base64_encode($signature);
727
-	}
728
-
729
-	/**
730
-	 * @NoAdminRequired
731
-	 * @NoSubadminRequired
732
-	 * @PasswordConfirmationRequired
733
-	 *
734
-	 * @param string $avatarScope
735
-	 * @param string $displayname
736
-	 * @param string $displaynameScope
737
-	 * @param string $phone
738
-	 * @param string $phoneScope
739
-	 * @param string $email
740
-	 * @param string $emailScope
741
-	 * @param string $website
742
-	 * @param string $websiteScope
743
-	 * @param string $address
744
-	 * @param string $addressScope
745
-	 * @param string $twitter
746
-	 * @param string $twitterScope
747
-	 * @return DataResponse
748
-	 */
749
-	public function setUserSettings($avatarScope,
750
-									$displayname,
751
-									$displaynameScope,
752
-									$phone,
753
-									$phoneScope,
754
-									$email,
755
-									$emailScope,
756
-									$website,
757
-									$websiteScope,
758
-									$address,
759
-									$addressScope,
760
-									$twitter,
761
-									$twitterScope
762
-	) {
763
-
764
-		if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
765
-			return new DataResponse(
766
-				[
767
-					'status' => 'error',
768
-					'data' => [
769
-						'message' => (string)$this->l10n->t('Invalid mail address')
770
-					]
771
-				],
772
-				Http::STATUS_UNPROCESSABLE_ENTITY
773
-			);
774
-		}
775
-
776
-		$user = $this->userSession->getUser();
777
-
778
-		$data = $this->accountManager->getUser($user);
779
-
780
-		$data[AccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope];
781
-		if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
782
-			$data[AccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope];
783
-			$data[AccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope];
784
-		}
785
-
786
-		if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
787
-			$federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
788
-			$shareProvider = $federatedFileSharing->getFederatedShareProvider();
789
-			if ($shareProvider->isLookupServerUploadEnabled()) {
790
-				$data[AccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope];
791
-				$data[AccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope];
792
-				$data[AccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope];
793
-				$data[AccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope];
794
-			}
795
-		}
796
-
797
-		try {
798
-			$this->saveUserSettings($user, $data);
799
-			return new DataResponse(
800
-				[
801
-					'status' => 'success',
802
-					'data' => [
803
-						'userId' => $user->getUID(),
804
-						'avatarScope' => $data[AccountManager::PROPERTY_AVATAR]['scope'],
805
-						'displayname' => $data[AccountManager::PROPERTY_DISPLAYNAME]['value'],
806
-						'displaynameScope' => $data[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
807
-						'email' => $data[AccountManager::PROPERTY_EMAIL]['value'],
808
-						'emailScope' => $data[AccountManager::PROPERTY_EMAIL]['scope'],
809
-						'website' => $data[AccountManager::PROPERTY_WEBSITE]['value'],
810
-						'websiteScope' => $data[AccountManager::PROPERTY_WEBSITE]['scope'],
811
-						'address' => $data[AccountManager::PROPERTY_ADDRESS]['value'],
812
-						'addressScope' => $data[AccountManager::PROPERTY_ADDRESS]['scope'],
813
-						'message' => (string)$this->l10n->t('Settings saved')
814
-					]
815
-				],
816
-				Http::STATUS_OK
817
-			);
818
-		} catch (ForbiddenException $e) {
819
-			return new DataResponse([
820
-				'status' => 'error',
821
-				'data' => [
822
-					'message' => $e->getMessage()
823
-				],
824
-			]);
825
-		}
826
-
827
-	}
828
-
829
-
830
-	/**
831
-	 * update account manager with new user data
832
-	 *
833
-	 * @param IUser $user
834
-	 * @param array $data
835
-	 * @throws ForbiddenException
836
-	 */
837
-	protected function saveUserSettings(IUser $user, $data) {
838
-
839
-		// keep the user back-end up-to-date with the latest display name and email
840
-		// address
841
-		$oldDisplayName = $user->getDisplayName();
842
-		$oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
843
-		if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
844
-			&& $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
845
-		) {
846
-			$result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
847
-			if ($result === false) {
848
-				throw new ForbiddenException($this->l10n->t('Unable to change full name'));
849
-			}
850
-		}
851
-
852
-		$oldEmailAddress = $user->getEMailAddress();
853
-		$oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
854
-		if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
855
-			&& $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
856
-		) {
857
-			// this is the only permission a backend provides and is also used
858
-			// for the permission of setting a email address
859
-			if (!$user->canChangeDisplayName()) {
860
-				throw new ForbiddenException($this->l10n->t('Unable to change email address'));
861
-			}
862
-			$user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
863
-		}
864
-
865
-		$this->accountManager->updateUser($user, $data);
866
-	}
867
-
868
-	/**
869
-	 * Count all unique users visible for the current admin/subadmin.
870
-	 *
871
-	 * @NoAdminRequired
872
-	 *
873
-	 * @return DataResponse
874
-	 */
875
-	public function stats() {
876
-		$userCount = 0;
877
-		if ($this->isAdmin) {
878
-			$countByBackend = $this->userManager->countUsers();
879
-
880
-			if (!empty($countByBackend)) {
881
-				foreach ($countByBackend as $count) {
882
-					$userCount += $count;
883
-				}
884
-			}
885
-		} else {
886
-			$groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser());
887
-
888
-			$uniqueUsers = [];
889
-			foreach ($groups as $group) {
890
-				foreach ($group->getUsers() as $uid => $displayName) {
891
-					$uniqueUsers[$uid] = true;
892
-				}
893
-			}
894
-
895
-			$userCount = count($uniqueUsers);
896
-		}
897
-
898
-		return new DataResponse(
899
-			[
900
-				'totalUsers' => $userCount
901
-			]
902
-		);
903
-	}
904
-
905
-
906
-	/**
907
-	 * Set the displayName of a user
908
-	 *
909
-	 * @NoAdminRequired
910
-	 * @NoSubadminRequired
911
-	 * @PasswordConfirmationRequired
912
-	 * @todo merge into saveUserSettings
913
-	 *
914
-	 * @param string $username
915
-	 * @param string $displayName
916
-	 * @return DataResponse
917
-	 */
918
-	public function setDisplayName($username, $displayName) {
919
-		$currentUser = $this->userSession->getUser();
920
-		$user = $this->userManager->get($username);
921
-
922
-		if ($user === null ||
923
-			!$user->canChangeDisplayName() ||
924
-			(
925
-				!$this->groupManager->isAdmin($currentUser->getUID()) &&
926
-				!$this->groupManager->getSubAdmin()->isUserAccessible($currentUser, $user) &&
927
-				$currentUser->getUID() !== $username
928
-
929
-			)
930
-		) {
931
-			return new DataResponse([
932
-				'status' => 'error',
933
-				'data' => [
934
-					'message' => $this->l10n->t('Authentication error'),
935
-				],
936
-			]);
937
-		}
938
-
939
-		$userData = $this->accountManager->getUser($user);
940
-		$userData[AccountManager::PROPERTY_DISPLAYNAME]['value'] = $displayName;
941
-
942
-
943
-		try {
944
-			$this->saveUserSettings($user, $userData);
945
-			return new DataResponse([
946
-				'status' => 'success',
947
-				'data' => [
948
-					'message' => $this->l10n->t('Your full name has been changed.'),
949
-					'username' => $username,
950
-					'displayName' => $displayName,
951
-				],
952
-			]);
953
-		} catch (ForbiddenException $e) {
954
-			return new DataResponse([
955
-				'status' => 'error',
956
-				'data' => [
957
-					'message' => $e->getMessage(),
958
-					'displayName' => $user->getDisplayName(),
959
-				],
960
-			]);
961
-		}
962
-	}
963
-
964
-	/**
965
-	 * Set the mail address of a user
966
-	 *
967
-	 * @NoAdminRequired
968
-	 * @NoSubadminRequired
969
-	 * @PasswordConfirmationRequired
970
-	 *
971
-	 * @param string $id
972
-	 * @param string $mailAddress
973
-	 * @return DataResponse
974
-	 */
975
-	public function setEMailAddress($id, $mailAddress) {
976
-		$user = $this->userManager->get($id);
977
-		if (!$this->isAdmin
978
-			&& !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)
979
-		) {
980
-			return new DataResponse(
981
-				[
982
-					'status' => 'error',
983
-					'data' => [
984
-						'message' => (string)$this->l10n->t('Forbidden')
985
-					]
986
-				],
987
-				Http::STATUS_FORBIDDEN
988
-			);
989
-		}
990
-
991
-		if ($mailAddress !== '' && !$this->mailer->validateMailAddress($mailAddress)) {
992
-			return new DataResponse(
993
-				[
994
-					'status' => 'error',
995
-					'data' => [
996
-						'message' => (string)$this->l10n->t('Invalid mail address')
997
-					]
998
-				],
999
-				Http::STATUS_UNPROCESSABLE_ENTITY
1000
-			);
1001
-		}
1002
-
1003
-		if (!$user) {
1004
-			return new DataResponse(
1005
-				[
1006
-					'status' => 'error',
1007
-					'data' => [
1008
-						'message' => (string)$this->l10n->t('Invalid user')
1009
-					]
1010
-				],
1011
-				Http::STATUS_UNPROCESSABLE_ENTITY
1012
-			);
1013
-		}
1014
-		// this is the only permission a backend provides and is also used
1015
-		// for the permission of setting a email address
1016
-		if (!$user->canChangeDisplayName()) {
1017
-			return new DataResponse(
1018
-				[
1019
-					'status' => 'error',
1020
-					'data' => [
1021
-						'message' => (string)$this->l10n->t('Unable to change mail address')
1022
-					]
1023
-				],
1024
-				Http::STATUS_FORBIDDEN
1025
-			);
1026
-		}
1027
-
1028
-		$userData = $this->accountManager->getUser($user);
1029
-		$userData[AccountManager::PROPERTY_EMAIL]['value'] = $mailAddress;
1030
-
1031
-		try {
1032
-			$this->saveUserSettings($user, $userData);
1033
-			return new DataResponse(
1034
-				[
1035
-					'status' => 'success',
1036
-					'data' => [
1037
-						'username' => $id,
1038
-						'mailAddress' => $mailAddress,
1039
-						'message' => (string)$this->l10n->t('Email saved')
1040
-					]
1041
-				],
1042
-				Http::STATUS_OK
1043
-			);
1044
-		} catch (ForbiddenException $e) {
1045
-			return new DataResponse([
1046
-				'status' => 'error',
1047
-				'data' => [
1048
-					'message' => $e->getMessage()
1049
-				],
1050
-			]);
1051
-		}
1052
-	}
72
+    /** @var IL10N */
73
+    private $l10n;
74
+    /** @var IUserSession */
75
+    private $userSession;
76
+    /** @var bool */
77
+    private $isAdmin;
78
+    /** @var IUserManager */
79
+    private $userManager;
80
+    /** @var IGroupManager */
81
+    private $groupManager;
82
+    /** @var IConfig */
83
+    private $config;
84
+    /** @var ILogger */
85
+    private $log;
86
+    /** @var IMailer */
87
+    private $mailer;
88
+    /** @var bool contains the state of the encryption app */
89
+    private $isEncryptionAppEnabled;
90
+    /** @var bool contains the state of the admin recovery setting */
91
+    private $isRestoreEnabled = false;
92
+    /** @var IAppManager */
93
+    private $appManager;
94
+    /** @var IAvatarManager */
95
+    private $avatarManager;
96
+    /** @var AccountManager */
97
+    private $accountManager;
98
+    /** @var ISecureRandom */
99
+    private $secureRandom;
100
+    /** @var NewUserMailHelper */
101
+    private $newUserMailHelper;
102
+    /** @var ITimeFactory */
103
+    private $timeFactory;
104
+    /** @var ICrypto */
105
+    private $crypto;
106
+    /** @var Manager */
107
+    private $keyManager;
108
+    /** @var IJobList */
109
+    private $jobList;
110
+
111
+    /** @var IUserMountCache */
112
+    private $userMountCache;
113
+
114
+    /** @var IManager */
115
+    private $encryptionManager;
116
+
117
+
118
+    /**
119
+     * @param string $appName
120
+     * @param IRequest $request
121
+     * @param IUserManager $userManager
122
+     * @param IGroupManager $groupManager
123
+     * @param IUserSession $userSession
124
+     * @param IConfig $config
125
+     * @param bool $isAdmin
126
+     * @param IL10N $l10n
127
+     * @param ILogger $log
128
+     * @param IMailer $mailer
129
+     * @param IURLGenerator $urlGenerator
130
+     * @param IAppManager $appManager
131
+     * @param IAvatarManager $avatarManager
132
+     * @param AccountManager $accountManager
133
+     * @param ISecureRandom $secureRandom
134
+     * @param NewUserMailHelper $newUserMailHelper
135
+     * @param ITimeFactory $timeFactory
136
+     * @param ICrypto $crypto
137
+     * @param Manager $keyManager
138
+     * @param IJobList $jobList
139
+     * @param IUserMountCache $userMountCache
140
+     * @param IManager $encryptionManager
141
+     */
142
+    public function __construct($appName,
143
+                                IRequest $request,
144
+                                IUserManager $userManager,
145
+                                IGroupManager $groupManager,
146
+                                IUserSession $userSession,
147
+                                IConfig $config,
148
+                                $isAdmin,
149
+                                IL10N $l10n,
150
+                                ILogger $log,
151
+                                IMailer $mailer,
152
+                                IURLGenerator $urlGenerator,
153
+                                IAppManager $appManager,
154
+                                IAvatarManager $avatarManager,
155
+                                AccountManager $accountManager,
156
+                                ISecureRandom $secureRandom,
157
+                                NewUserMailHelper $newUserMailHelper,
158
+                                ITimeFactory $timeFactory,
159
+                                ICrypto $crypto,
160
+                                Manager $keyManager,
161
+                                IJobList $jobList,
162
+                                IUserMountCache $userMountCache,
163
+                                IManager $encryptionManager) {
164
+        parent::__construct($appName, $request);
165
+        $this->userManager = $userManager;
166
+        $this->groupManager = $groupManager;
167
+        $this->userSession = $userSession;
168
+        $this->config = $config;
169
+        $this->isAdmin = $isAdmin;
170
+        $this->l10n = $l10n;
171
+        $this->log = $log;
172
+        $this->mailer = $mailer;
173
+        $this->appManager = $appManager;
174
+        $this->avatarManager = $avatarManager;
175
+        $this->accountManager = $accountManager;
176
+        $this->secureRandom = $secureRandom;
177
+        $this->newUserMailHelper = $newUserMailHelper;
178
+        $this->timeFactory = $timeFactory;
179
+        $this->crypto = $crypto;
180
+        $this->keyManager = $keyManager;
181
+        $this->jobList = $jobList;
182
+        $this->userMountCache = $userMountCache;
183
+        $this->encryptionManager = $encryptionManager;
184
+
185
+        // check for encryption state - TODO see formatUserForIndex
186
+        $this->isEncryptionAppEnabled = $appManager->isEnabledForUser('encryption');
187
+        if ($this->isEncryptionAppEnabled) {
188
+            // putting this directly in empty is possible in PHP 5.5+
189
+            $result = $config->getAppValue('encryption', 'recoveryAdminEnabled', '0');
190
+            $this->isRestoreEnabled = !empty($result);
191
+        }
192
+    }
193
+
194
+    /**
195
+     * @param IUser $user
196
+     * @param array|null $userGroups
197
+     * @return array
198
+     */
199
+    private function formatUserForIndex(IUser $user, array $userGroups = null) {
200
+
201
+        // TODO: eliminate this encryption specific code below and somehow
202
+        // hook in additional user info from other apps
203
+
204
+        // recovery isn't possible if admin or user has it disabled and encryption
205
+        // is enabled - so we eliminate the else paths in the conditional tree
206
+        // below
207
+        $restorePossible = false;
208
+
209
+        if ($this->isEncryptionAppEnabled) {
210
+            if ($this->isRestoreEnabled) {
211
+                // check for the users recovery setting
212
+                $recoveryMode = $this->config->getUserValue($user->getUID(), 'encryption', 'recoveryEnabled', '0');
213
+                // method call inside empty is possible with PHP 5.5+
214
+                $recoveryModeEnabled = !empty($recoveryMode);
215
+                if ($recoveryModeEnabled) {
216
+                    // user also has recovery mode enabled
217
+                    $restorePossible = true;
218
+                }
219
+            } else {
220
+                $modules = $this->encryptionManager->getEncryptionModules();
221
+                $restorePossible = true;
222
+                foreach ($modules as $id => $module) {
223
+                    /* @var IEncryptionModule $instance */
224
+                    $instance = call_user_func($module['callback']);
225
+                    if ($instance->needDetailedAccessList()) {
226
+                        $restorePossible = false;
227
+                        break;
228
+                    }
229
+                }
230
+            }
231
+        } else {
232
+            // recovery is possible if encryption is disabled (plain files are
233
+            // available)
234
+            $restorePossible = true;
235
+        }
236
+
237
+        $subAdminGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($user);
238
+        foreach ($subAdminGroups as $key => $subAdminGroup) {
239
+            $subAdminGroups[$key] = $subAdminGroup->getGID();
240
+        }
241
+
242
+        $displayName = $user->getEMailAddress();
243
+        if (is_null($displayName)) {
244
+            $displayName = '';
245
+        }
246
+
247
+        $avatarAvailable = false;
248
+        try {
249
+            $avatarAvailable = $this->avatarManager->getAvatar($user->getUID())->exists();
250
+        } catch (\Exception $e) {
251
+            //No avatar yet
252
+        }
253
+
254
+        return [
255
+            'name' => $user->getUID(),
256
+            'displayname' => $user->getDisplayName(),
257
+            'groups' => (empty($userGroups)) ? $this->groupManager->getUserGroupIds($user) : $userGroups,
258
+            'subadmin' => $subAdminGroups,
259
+            'quota' => $user->getQuota(),
260
+            'quota_bytes' => Util::computerFileSize($user->getQuota()),
261
+            'storageLocation' => $user->getHome(),
262
+            'lastLogin' => $user->getLastLogin() * 1000,
263
+            'backend' => $user->getBackendClassName(),
264
+            'email' => $displayName,
265
+            'isRestoreDisabled' => !$restorePossible,
266
+            'isAvatarAvailable' => $avatarAvailable,
267
+            'isEnabled' => $user->isEnabled(),
268
+        ];
269
+    }
270
+
271
+    /**
272
+     * @param array $userIDs Array with schema [$uid => $displayName]
273
+     * @return IUser[]
274
+     */
275
+    private function getUsersForUID(array $userIDs) {
276
+        $users = [];
277
+        foreach ($userIDs as $uid => $displayName) {
278
+            $users[$uid] = $this->userManager->get($uid);
279
+        }
280
+        return $users;
281
+    }
282
+
283
+    /**
284
+     * @NoAdminRequired
285
+     *
286
+     * @param int $offset
287
+     * @param int $limit
288
+     * @param string $gid GID to filter for
289
+     * @param string $pattern Pattern to search for in the username
290
+     * @param string $backend Backend to filter for (class-name)
291
+     * @return DataResponse
292
+     *
293
+     * TODO: Tidy up and write unit tests - code is mainly static method calls
294
+     */
295
+    public function index($offset = 0, $limit = 10, $gid = '', $pattern = '', $backend = '') {
296
+        // Remove backends
297
+        if (!empty($backend)) {
298
+            $activeBackends = $this->userManager->getBackends();
299
+            $this->userManager->clearBackends();
300
+            foreach ($activeBackends as $singleActiveBackend) {
301
+                if ($backend === get_class($singleActiveBackend)) {
302
+                    $this->userManager->registerBackend($singleActiveBackend);
303
+                    break;
304
+                }
305
+            }
306
+        }
307
+
308
+        $userObjects = [];
309
+        $users = [];
310
+        if ($this->isAdmin) {
311
+            if ($gid !== '' && $gid !== '_disabledUsers' && $gid !== '_everyone') {
312
+                $batch = $this->getUsersForUID($this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset));
313
+            } else {
314
+                $batch = $this->userManager->search($pattern, $limit, $offset);
315
+            }
316
+
317
+            foreach ($batch as $user) {
318
+                if (($gid !== '_disabledUsers' && $user->isEnabled()) ||
319
+                    ($gid === '_disabledUsers' && !$user->isEnabled())
320
+                ) {
321
+                    $userObjects[] = $user;
322
+                    $users[] = $this->formatUserForIndex($user);
323
+                }
324
+            }
325
+
326
+        } else {
327
+            $subAdminOfGroups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser());
328
+            // New class returns IGroup[] so convert back
329
+            $gids = [];
330
+            foreach ($subAdminOfGroups as $group) {
331
+                $gids[] = $group->getGID();
332
+            }
333
+            $subAdminOfGroups = $gids;
334
+
335
+            // Set the $gid parameter to an empty value if the subadmin has no rights to access a specific group
336
+            if ($gid !== '' && $gid !== '_disabledUsers' && !in_array($gid, $subAdminOfGroups)) {
337
+                $gid = '';
338
+            }
339
+
340
+            // Batch all groups the user is subadmin of when a group is specified
341
+            $batch = [];
342
+            if ($gid !== '' && $gid !== '_disabledUsers' && $gid !== '_everyone') {
343
+                $batch = $this->groupManager->displayNamesInGroup($gid, $pattern, $limit, $offset);
344
+            } else {
345
+                foreach ($subAdminOfGroups as $group) {
346
+                    $groupUsers = $this->groupManager->displayNamesInGroup($group, $pattern, $limit, $offset);
347
+
348
+                    foreach ($groupUsers as $uid => $displayName) {
349
+                        $batch[$uid] = $displayName;
350
+                    }
351
+                }
352
+            }
353
+            $batch = $this->getUsersForUID($batch);
354
+
355
+            foreach ($batch as $user) {
356
+                // Only add the groups, this user is a subadmin of
357
+                $userGroups = array_values(array_intersect(
358
+                    $this->groupManager->getUserGroupIds($user),
359
+                    $subAdminOfGroups
360
+                ));
361
+                if (($gid !== '_disabledUsers' && $user->isEnabled()) ||
362
+                    ($gid === '_disabledUsers' && !$user->isEnabled())
363
+                ) {
364
+                    $userObjects[] = $user;
365
+                    $users[] = $this->formatUserForIndex($user, $userGroups);
366
+                }
367
+            }
368
+        }
369
+
370
+        $usedSpace = $this->userMountCache->getUsedSpaceForUsers($userObjects);
371
+
372
+        foreach ($users as &$userData) {
373
+            $userData['size'] = isset($usedSpace[$userData['name']]) ? $usedSpace[$userData['name']] : 0;
374
+        }
375
+
376
+        return new DataResponse($users);
377
+    }
378
+
379
+    /**
380
+     * @NoAdminRequired
381
+     * @PasswordConfirmationRequired
382
+     *
383
+     * @param string $username
384
+     * @param string $password
385
+     * @param array $groups
386
+     * @param string $email
387
+     * @return DataResponse
388
+     */
389
+    public function create($username, $password, array $groups = [], $email = '') {
390
+        if ($email !== '' && !$this->mailer->validateMailAddress($email)) {
391
+            return new DataResponse(
392
+                [
393
+                    'message' => (string)$this->l10n->t('Invalid mail address')
394
+                ],
395
+                Http::STATUS_UNPROCESSABLE_ENTITY
396
+            );
397
+        }
398
+
399
+        $currentUser = $this->userSession->getUser();
400
+
401
+        if (!$this->isAdmin) {
402
+            if (!empty($groups)) {
403
+                foreach ($groups as $key => $group) {
404
+                    $groupObject = $this->groupManager->get($group);
405
+                    if ($groupObject === null) {
406
+                        unset($groups[$key]);
407
+                        continue;
408
+                    }
409
+
410
+                    if (!$this->groupManager->getSubAdmin()->isSubAdminofGroup($currentUser, $groupObject)) {
411
+                        unset($groups[$key]);
412
+                    }
413
+                }
414
+            }
415
+
416
+            if (empty($groups)) {
417
+                return new DataResponse(
418
+                    [
419
+                        'message' => $this->l10n->t('No valid group selected'),
420
+                    ],
421
+                    Http::STATUS_FORBIDDEN
422
+                );
423
+            }
424
+        }
425
+
426
+        if ($this->userManager->userExists($username)) {
427
+            return new DataResponse(
428
+                [
429
+                    'message' => (string)$this->l10n->t('A user with that name already exists.')
430
+                ],
431
+                Http::STATUS_CONFLICT
432
+            );
433
+        }
434
+
435
+        $generatePasswordResetToken = false;
436
+        if ($password === '') {
437
+            if ($email === '') {
438
+                return new DataResponse(
439
+                    [
440
+                        'message' => (string)$this->l10n->t('To send a password link to the user an email address is required.')
441
+                    ],
442
+                    Http::STATUS_UNPROCESSABLE_ENTITY
443
+                );
444
+            }
445
+
446
+            $password = $this->secureRandom->generate(30);
447
+            // Make sure we pass the password_policy
448
+            $password .= $this->secureRandom->generate(2, '$!.,;:-~+*[]{}()');
449
+            $generatePasswordResetToken = true;
450
+        }
451
+
452
+        try {
453
+            $user = $this->userManager->createUser($username, $password);
454
+        } catch (\Exception $exception) {
455
+            $message = $exception->getMessage();
456
+            if ($exception instanceof HintException && $exception->getHint()) {
457
+                $message = $exception->getHint();
458
+            }
459
+            if (!$message) {
460
+                $message = $this->l10n->t('Unable to create user.');
461
+            }
462
+            return new DataResponse(
463
+                [
464
+                    'message' => (string)$message,
465
+                ],
466
+                Http::STATUS_FORBIDDEN
467
+            );
468
+        }
469
+
470
+        if ($user instanceof IUser) {
471
+            if ($groups !== null) {
472
+                foreach ($groups as $groupName) {
473
+                    $group = $this->groupManager->get($groupName);
474
+
475
+                    if (empty($group)) {
476
+                        $group = $this->groupManager->createGroup($groupName);
477
+                    }
478
+                    $group->addUser($user);
479
+                }
480
+            }
481
+            /**
482
+             * Send new user mail only if a mail is set
483
+             */
484
+            if ($email !== '') {
485
+                $user->setEMailAddress($email);
486
+                try {
487
+                    $emailTemplate = $this->newUserMailHelper->generateTemplate($user, $generatePasswordResetToken);
488
+                    $this->newUserMailHelper->sendMail($user, $emailTemplate);
489
+                } catch (\Exception $e) {
490
+                    $this->log->logException($e, [
491
+                        'message' => "Can't send new user mail to $email",
492
+                        'level' => \OCP\Util::ERROR,
493
+                        'app' => 'settings',
494
+                    ]);
495
+                }
496
+            }
497
+            // fetch users groups
498
+            $userGroups = $this->groupManager->getUserGroupIds($user);
499
+
500
+            return new DataResponse(
501
+                $this->formatUserForIndex($user, $userGroups),
502
+                Http::STATUS_CREATED
503
+            );
504
+        }
505
+
506
+        return new DataResponse(
507
+            [
508
+                'message' => (string)$this->l10n->t('Unable to create user.')
509
+            ],
510
+            Http::STATUS_FORBIDDEN
511
+        );
512
+
513
+    }
514
+
515
+    /**
516
+     * @NoAdminRequired
517
+     * @PasswordConfirmationRequired
518
+     *
519
+     * @param string $id
520
+     * @return DataResponse
521
+     */
522
+    public function destroy($id) {
523
+        $userId = $this->userSession->getUser()->getUID();
524
+        $user = $this->userManager->get($id);
525
+
526
+        if ($userId === $id) {
527
+            return new DataResponse(
528
+                [
529
+                    'status' => 'error',
530
+                    'data' => [
531
+                        'message' => (string)$this->l10n->t('Unable to delete user.')
532
+                    ]
533
+                ],
534
+                Http::STATUS_FORBIDDEN
535
+            );
536
+        }
537
+
538
+        if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
539
+            return new DataResponse(
540
+                [
541
+                    'status' => 'error',
542
+                    'data' => [
543
+                        'message' => (string)$this->l10n->t('Authentication error')
544
+                    ]
545
+                ],
546
+                Http::STATUS_FORBIDDEN
547
+            );
548
+        }
549
+
550
+        if ($user) {
551
+            if ($user->delete()) {
552
+                return new DataResponse(
553
+                    [
554
+                        'status' => 'success',
555
+                        'data' => [
556
+                            'username' => $id
557
+                        ]
558
+                    ],
559
+                    Http::STATUS_NO_CONTENT
560
+                );
561
+            }
562
+        }
563
+
564
+        return new DataResponse(
565
+            [
566
+                'status' => 'error',
567
+                'data' => [
568
+                    'message' => (string)$this->l10n->t('Unable to delete user.')
569
+                ]
570
+            ],
571
+            Http::STATUS_FORBIDDEN
572
+        );
573
+    }
574
+
575
+    /**
576
+     * @NoAdminRequired
577
+     *
578
+     * @param string $id
579
+     * @param int $enabled
580
+     * @return DataResponse
581
+     */
582
+    public function setEnabled($id, $enabled) {
583
+        $enabled = (bool)$enabled;
584
+        if ($enabled) {
585
+            $errorMsgGeneral = (string)$this->l10n->t('Error while enabling user.');
586
+        } else {
587
+            $errorMsgGeneral = (string)$this->l10n->t('Error while disabling user.');
588
+        }
589
+
590
+        $userId = $this->userSession->getUser()->getUID();
591
+        $user = $this->userManager->get($id);
592
+
593
+        if ($userId === $id) {
594
+            return new DataResponse(
595
+                [
596
+                    'status' => 'error',
597
+                    'data' => [
598
+                        'message' => $errorMsgGeneral
599
+                    ]
600
+                ], Http::STATUS_FORBIDDEN
601
+            );
602
+        }
603
+
604
+        if ($user) {
605
+            if (!$this->isAdmin && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)) {
606
+                return new DataResponse(
607
+                    [
608
+                        'status' => 'error',
609
+                        'data' => [
610
+                            'message' => (string)$this->l10n->t('Authentication error')
611
+                        ]
612
+                    ],
613
+                    Http::STATUS_FORBIDDEN
614
+                );
615
+            }
616
+
617
+            $user->setEnabled($enabled);
618
+            return new DataResponse(
619
+                [
620
+                    'status' => 'success',
621
+                    'data' => [
622
+                        'username' => $id,
623
+                        'enabled' => $enabled
624
+                    ]
625
+                ]
626
+            );
627
+        } else {
628
+            return new DataResponse(
629
+                [
630
+                    'status' => 'error',
631
+                    'data' => [
632
+                        'message' => $errorMsgGeneral
633
+                    ]
634
+                ],
635
+                Http::STATUS_FORBIDDEN
636
+            );
637
+        }
638
+
639
+    }
640
+
641
+    /**
642
+     * Set the mail address of a user
643
+     *
644
+     * @NoAdminRequired
645
+     * @NoSubadminRequired
646
+     * @PasswordConfirmationRequired
647
+     *
648
+     * @param string $account
649
+     * @param bool $onlyVerificationCode only return verification code without updating the data
650
+     * @return DataResponse
651
+     */
652
+    public function getVerificationCode($account, $onlyVerificationCode) {
653
+
654
+        $user = $this->userSession->getUser();
655
+
656
+        if ($user === null) {
657
+            return new DataResponse([], Http::STATUS_BAD_REQUEST);
658
+        }
659
+
660
+        $accountData = $this->accountManager->getUser($user);
661
+        $cloudId = $user->getCloudId();
662
+        $message = "Use my Federated Cloud ID to share with me: " . $cloudId;
663
+        $signature = $this->signMessage($user, $message);
664
+
665
+        $code = $message . ' ' . $signature;
666
+        $codeMd5 = $message . ' ' . md5($signature);
667
+
668
+        switch ($account) {
669
+            case 'verify-twitter':
670
+                $accountData[AccountManager::PROPERTY_TWITTER]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
671
+                $msg = $this->l10n->t('In order to verify your Twitter account, post the following tweet on Twitter (please make sure to post it without any line breaks):');
672
+                $code = $codeMd5;
673
+                $type = AccountManager::PROPERTY_TWITTER;
674
+                $data = $accountData[AccountManager::PROPERTY_TWITTER]['value'];
675
+                $accountData[AccountManager::PROPERTY_TWITTER]['signature'] = $signature;
676
+                break;
677
+            case 'verify-website':
678
+                $accountData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
679
+                $msg = $this->l10n->t('In order to verify your Website, store the following content in your web-root at \'.well-known/CloudIdVerificationCode.txt\' (please make sure that the complete text is in one line):');
680
+                $type = AccountManager::PROPERTY_WEBSITE;
681
+                $data = $accountData[AccountManager::PROPERTY_WEBSITE]['value'];
682
+                $accountData[AccountManager::PROPERTY_WEBSITE]['signature'] = $signature;
683
+                break;
684
+            default:
685
+                return new DataResponse([], Http::STATUS_BAD_REQUEST);
686
+        }
687
+
688
+        if ($onlyVerificationCode === false) {
689
+            $this->accountManager->updateUser($user, $accountData);
690
+
691
+            $this->jobList->add('OC\Settings\BackgroundJobs\VerifyUserData',
692
+                [
693
+                    'verificationCode' => $code,
694
+                    'data' => $data,
695
+                    'type' => $type,
696
+                    'uid' => $user->getUID(),
697
+                    'try' => 0,
698
+                    'lastRun' => $this->getCurrentTime()
699
+                ]
700
+            );
701
+        }
702
+
703
+        return new DataResponse(['msg' => $msg, 'code' => $code]);
704
+    }
705
+
706
+    /**
707
+     * get current timestamp
708
+     *
709
+     * @return int
710
+     */
711
+    protected function getCurrentTime() {
712
+        return time();
713
+    }
714
+
715
+    /**
716
+     * sign message with users private key
717
+     *
718
+     * @param IUser $user
719
+     * @param string $message
720
+     *
721
+     * @return string base64 encoded signature
722
+     */
723
+    protected function signMessage(IUser $user, $message) {
724
+        $privateKey = $this->keyManager->getKey($user)->getPrivate();
725
+        openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512);
726
+        return base64_encode($signature);
727
+    }
728
+
729
+    /**
730
+     * @NoAdminRequired
731
+     * @NoSubadminRequired
732
+     * @PasswordConfirmationRequired
733
+     *
734
+     * @param string $avatarScope
735
+     * @param string $displayname
736
+     * @param string $displaynameScope
737
+     * @param string $phone
738
+     * @param string $phoneScope
739
+     * @param string $email
740
+     * @param string $emailScope
741
+     * @param string $website
742
+     * @param string $websiteScope
743
+     * @param string $address
744
+     * @param string $addressScope
745
+     * @param string $twitter
746
+     * @param string $twitterScope
747
+     * @return DataResponse
748
+     */
749
+    public function setUserSettings($avatarScope,
750
+                                    $displayname,
751
+                                    $displaynameScope,
752
+                                    $phone,
753
+                                    $phoneScope,
754
+                                    $email,
755
+                                    $emailScope,
756
+                                    $website,
757
+                                    $websiteScope,
758
+                                    $address,
759
+                                    $addressScope,
760
+                                    $twitter,
761
+                                    $twitterScope
762
+    ) {
763
+
764
+        if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
765
+            return new DataResponse(
766
+                [
767
+                    'status' => 'error',
768
+                    'data' => [
769
+                        'message' => (string)$this->l10n->t('Invalid mail address')
770
+                    ]
771
+                ],
772
+                Http::STATUS_UNPROCESSABLE_ENTITY
773
+            );
774
+        }
775
+
776
+        $user = $this->userSession->getUser();
777
+
778
+        $data = $this->accountManager->getUser($user);
779
+
780
+        $data[AccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope];
781
+        if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
782
+            $data[AccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope];
783
+            $data[AccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope];
784
+        }
785
+
786
+        if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
787
+            $federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
788
+            $shareProvider = $federatedFileSharing->getFederatedShareProvider();
789
+            if ($shareProvider->isLookupServerUploadEnabled()) {
790
+                $data[AccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope];
791
+                $data[AccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope];
792
+                $data[AccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope];
793
+                $data[AccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope];
794
+            }
795
+        }
796
+
797
+        try {
798
+            $this->saveUserSettings($user, $data);
799
+            return new DataResponse(
800
+                [
801
+                    'status' => 'success',
802
+                    'data' => [
803
+                        'userId' => $user->getUID(),
804
+                        'avatarScope' => $data[AccountManager::PROPERTY_AVATAR]['scope'],
805
+                        'displayname' => $data[AccountManager::PROPERTY_DISPLAYNAME]['value'],
806
+                        'displaynameScope' => $data[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
807
+                        'email' => $data[AccountManager::PROPERTY_EMAIL]['value'],
808
+                        'emailScope' => $data[AccountManager::PROPERTY_EMAIL]['scope'],
809
+                        'website' => $data[AccountManager::PROPERTY_WEBSITE]['value'],
810
+                        'websiteScope' => $data[AccountManager::PROPERTY_WEBSITE]['scope'],
811
+                        'address' => $data[AccountManager::PROPERTY_ADDRESS]['value'],
812
+                        'addressScope' => $data[AccountManager::PROPERTY_ADDRESS]['scope'],
813
+                        'message' => (string)$this->l10n->t('Settings saved')
814
+                    ]
815
+                ],
816
+                Http::STATUS_OK
817
+            );
818
+        } catch (ForbiddenException $e) {
819
+            return new DataResponse([
820
+                'status' => 'error',
821
+                'data' => [
822
+                    'message' => $e->getMessage()
823
+                ],
824
+            ]);
825
+        }
826
+
827
+    }
828
+
829
+
830
+    /**
831
+     * update account manager with new user data
832
+     *
833
+     * @param IUser $user
834
+     * @param array $data
835
+     * @throws ForbiddenException
836
+     */
837
+    protected function saveUserSettings(IUser $user, $data) {
838
+
839
+        // keep the user back-end up-to-date with the latest display name and email
840
+        // address
841
+        $oldDisplayName = $user->getDisplayName();
842
+        $oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
843
+        if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
844
+            && $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
845
+        ) {
846
+            $result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
847
+            if ($result === false) {
848
+                throw new ForbiddenException($this->l10n->t('Unable to change full name'));
849
+            }
850
+        }
851
+
852
+        $oldEmailAddress = $user->getEMailAddress();
853
+        $oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
854
+        if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
855
+            && $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
856
+        ) {
857
+            // this is the only permission a backend provides and is also used
858
+            // for the permission of setting a email address
859
+            if (!$user->canChangeDisplayName()) {
860
+                throw new ForbiddenException($this->l10n->t('Unable to change email address'));
861
+            }
862
+            $user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
863
+        }
864
+
865
+        $this->accountManager->updateUser($user, $data);
866
+    }
867
+
868
+    /**
869
+     * Count all unique users visible for the current admin/subadmin.
870
+     *
871
+     * @NoAdminRequired
872
+     *
873
+     * @return DataResponse
874
+     */
875
+    public function stats() {
876
+        $userCount = 0;
877
+        if ($this->isAdmin) {
878
+            $countByBackend = $this->userManager->countUsers();
879
+
880
+            if (!empty($countByBackend)) {
881
+                foreach ($countByBackend as $count) {
882
+                    $userCount += $count;
883
+                }
884
+            }
885
+        } else {
886
+            $groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($this->userSession->getUser());
887
+
888
+            $uniqueUsers = [];
889
+            foreach ($groups as $group) {
890
+                foreach ($group->getUsers() as $uid => $displayName) {
891
+                    $uniqueUsers[$uid] = true;
892
+                }
893
+            }
894
+
895
+            $userCount = count($uniqueUsers);
896
+        }
897
+
898
+        return new DataResponse(
899
+            [
900
+                'totalUsers' => $userCount
901
+            ]
902
+        );
903
+    }
904
+
905
+
906
+    /**
907
+     * Set the displayName of a user
908
+     *
909
+     * @NoAdminRequired
910
+     * @NoSubadminRequired
911
+     * @PasswordConfirmationRequired
912
+     * @todo merge into saveUserSettings
913
+     *
914
+     * @param string $username
915
+     * @param string $displayName
916
+     * @return DataResponse
917
+     */
918
+    public function setDisplayName($username, $displayName) {
919
+        $currentUser = $this->userSession->getUser();
920
+        $user = $this->userManager->get($username);
921
+
922
+        if ($user === null ||
923
+            !$user->canChangeDisplayName() ||
924
+            (
925
+                !$this->groupManager->isAdmin($currentUser->getUID()) &&
926
+                !$this->groupManager->getSubAdmin()->isUserAccessible($currentUser, $user) &&
927
+                $currentUser->getUID() !== $username
928
+
929
+            )
930
+        ) {
931
+            return new DataResponse([
932
+                'status' => 'error',
933
+                'data' => [
934
+                    'message' => $this->l10n->t('Authentication error'),
935
+                ],
936
+            ]);
937
+        }
938
+
939
+        $userData = $this->accountManager->getUser($user);
940
+        $userData[AccountManager::PROPERTY_DISPLAYNAME]['value'] = $displayName;
941
+
942
+
943
+        try {
944
+            $this->saveUserSettings($user, $userData);
945
+            return new DataResponse([
946
+                'status' => 'success',
947
+                'data' => [
948
+                    'message' => $this->l10n->t('Your full name has been changed.'),
949
+                    'username' => $username,
950
+                    'displayName' => $displayName,
951
+                ],
952
+            ]);
953
+        } catch (ForbiddenException $e) {
954
+            return new DataResponse([
955
+                'status' => 'error',
956
+                'data' => [
957
+                    'message' => $e->getMessage(),
958
+                    'displayName' => $user->getDisplayName(),
959
+                ],
960
+            ]);
961
+        }
962
+    }
963
+
964
+    /**
965
+     * Set the mail address of a user
966
+     *
967
+     * @NoAdminRequired
968
+     * @NoSubadminRequired
969
+     * @PasswordConfirmationRequired
970
+     *
971
+     * @param string $id
972
+     * @param string $mailAddress
973
+     * @return DataResponse
974
+     */
975
+    public function setEMailAddress($id, $mailAddress) {
976
+        $user = $this->userManager->get($id);
977
+        if (!$this->isAdmin
978
+            && !$this->groupManager->getSubAdmin()->isUserAccessible($this->userSession->getUser(), $user)
979
+        ) {
980
+            return new DataResponse(
981
+                [
982
+                    'status' => 'error',
983
+                    'data' => [
984
+                        'message' => (string)$this->l10n->t('Forbidden')
985
+                    ]
986
+                ],
987
+                Http::STATUS_FORBIDDEN
988
+            );
989
+        }
990
+
991
+        if ($mailAddress !== '' && !$this->mailer->validateMailAddress($mailAddress)) {
992
+            return new DataResponse(
993
+                [
994
+                    'status' => 'error',
995
+                    'data' => [
996
+                        'message' => (string)$this->l10n->t('Invalid mail address')
997
+                    ]
998
+                ],
999
+                Http::STATUS_UNPROCESSABLE_ENTITY
1000
+            );
1001
+        }
1002
+
1003
+        if (!$user) {
1004
+            return new DataResponse(
1005
+                [
1006
+                    'status' => 'error',
1007
+                    'data' => [
1008
+                        'message' => (string)$this->l10n->t('Invalid user')
1009
+                    ]
1010
+                ],
1011
+                Http::STATUS_UNPROCESSABLE_ENTITY
1012
+            );
1013
+        }
1014
+        // this is the only permission a backend provides and is also used
1015
+        // for the permission of setting a email address
1016
+        if (!$user->canChangeDisplayName()) {
1017
+            return new DataResponse(
1018
+                [
1019
+                    'status' => 'error',
1020
+                    'data' => [
1021
+                        'message' => (string)$this->l10n->t('Unable to change mail address')
1022
+                    ]
1023
+                ],
1024
+                Http::STATUS_FORBIDDEN
1025
+            );
1026
+        }
1027
+
1028
+        $userData = $this->accountManager->getUser($user);
1029
+        $userData[AccountManager::PROPERTY_EMAIL]['value'] = $mailAddress;
1030
+
1031
+        try {
1032
+            $this->saveUserSettings($user, $userData);
1033
+            return new DataResponse(
1034
+                [
1035
+                    'status' => 'success',
1036
+                    'data' => [
1037
+                        'username' => $id,
1038
+                        'mailAddress' => $mailAddress,
1039
+                        'message' => (string)$this->l10n->t('Email saved')
1040
+                    ]
1041
+                ],
1042
+                Http::STATUS_OK
1043
+            );
1044
+        } catch (ForbiddenException $e) {
1045
+            return new DataResponse([
1046
+                'status' => 'error',
1047
+                'data' => [
1048
+                    'message' => $e->getMessage()
1049
+                ],
1050
+            ]);
1051
+        }
1052
+    }
1053 1053
 
1054 1054
 }
Please login to merge, or discard this patch.
core/Command/Config/Import.php 1 patch
Indentation   +189 added lines, -189 removed lines patch added patch discarded remove patch
@@ -33,193 +33,193 @@
 block discarded – undo
33 33
 use Symfony\Component\Console\Output\OutputInterface;
34 34
 
35 35
 class Import extends Command implements CompletionAwareInterface  {
36
-	protected $validRootKeys = ['system', 'apps'];
37
-
38
-	/** @var IConfig */
39
-	protected $config;
40
-
41
-	/**
42
-	 * @param IConfig $config
43
-	 */
44
-	public function __construct(IConfig $config) {
45
-		parent::__construct();
46
-		$this->config = $config;
47
-	}
48
-
49
-	protected function configure() {
50
-		$this
51
-			->setName('config:import')
52
-			->setDescription('Import a list of configs')
53
-			->addArgument(
54
-				'file',
55
-				InputArgument::OPTIONAL,
56
-				'File with the json array to import'
57
-			)
58
-		;
59
-	}
60
-
61
-	protected function execute(InputInterface $input, OutputInterface $output) {
62
-		$importFile = $input->getArgument('file');
63
-		if ($importFile !== null) {
64
-			$content = $this->getArrayFromFile($importFile);
65
-		} else {
66
-			$content = $this->getArrayFromStdin();
67
-		}
68
-
69
-		try {
70
-			$configs = $this->validateFileContent($content);
71
-		} catch (\UnexpectedValueException $e) {
72
-			$output->writeln('<error>' . $e->getMessage(). '</error>');
73
-			return;
74
-		}
75
-
76
-		if (!empty($configs['system'])) {
77
-			$this->config->setSystemValues($configs['system']);
78
-		}
79
-
80
-		if (!empty($configs['apps'])) {
81
-			foreach ($configs['apps'] as $app => $appConfigs) {
82
-				foreach ($appConfigs as $key => $value) {
83
-					if ($value === null) {
84
-						$this->config->deleteAppValue($app, $key);
85
-					} else {
86
-						$this->config->setAppValue($app, $key, $value);
87
-					}
88
-				}
89
-			}
90
-		}
91
-
92
-		$output->writeln('<info>Config successfully imported from: ' . $importFile . '</info>');
93
-	}
94
-
95
-	/**
96
-	 * Get the content from stdin ("config:import < file.json")
97
-	 *
98
-	 * @return string
99
-	 */
100
-	protected function getArrayFromStdin() {
101
-		// Read from stdin. stream_set_blocking is used to prevent blocking
102
-		// when nothing is passed via stdin.
103
-		stream_set_blocking(STDIN, 0);
104
-		$content = file_get_contents('php://stdin');
105
-		stream_set_blocking(STDIN, 1);
106
-		return $content;
107
-	}
108
-
109
-	/**
110
-	 * Get the content of the specified file ("config:import file.json")
111
-	 *
112
-	 * @param string $importFile
113
-	 * @return string
114
-	 */
115
-	protected function getArrayFromFile($importFile) {
116
-		return file_get_contents($importFile);
117
-	}
118
-
119
-	/**
120
-	 * @param string $content
121
-	 * @return array
122
-	 * @throws \UnexpectedValueException when the array is invalid
123
-	 */
124
-	protected function validateFileContent($content) {
125
-		$decodedContent = json_decode($content, true);
126
-		if (!is_array($decodedContent) || empty($decodedContent)) {
127
-			throw new \UnexpectedValueException('The file must contain a valid json array');
128
-		}
129
-
130
-		$this->validateArray($decodedContent);
131
-
132
-		return $decodedContent;
133
-	}
134
-
135
-	/**
136
-	 * Validates that the array only contains `system` and `apps`
137
-	 *
138
-	 * @param array $array
139
-	 */
140
-	protected function validateArray($array) {
141
-		$arrayKeys = array_keys($array);
142
-		$additionalKeys = array_diff($arrayKeys, $this->validRootKeys);
143
-		$commonKeys = array_intersect($arrayKeys, $this->validRootKeys);
144
-		if (!empty($additionalKeys)) {
145
-			throw new \UnexpectedValueException('Found invalid entries in root: ' . implode(', ', $additionalKeys));
146
-		}
147
-		if (empty($commonKeys)) {
148
-			throw new \UnexpectedValueException('At least one key of the following is expected: ' . implode(', ', $this->validRootKeys));
149
-		}
150
-
151
-		if (isset($array['system'])) {
152
-			if (is_array($array['system'])) {
153
-				foreach ($array['system'] as $name => $value) {
154
-					$this->checkTypeRecursively($value, $name);
155
-				}
156
-			} else {
157
-				throw new \UnexpectedValueException('The system config array is not an array');
158
-			}
159
-		}
160
-
161
-		if (isset($array['apps'])) {
162
-			if (is_array($array['apps'])) {
163
-				$this->validateAppsArray($array['apps']);
164
-			} else {
165
-				throw new \UnexpectedValueException('The apps config array is not an array');
166
-			}
167
-		}
168
-	}
169
-
170
-	/**
171
-	 * @param mixed $configValue
172
-	 * @param string $configName
173
-	 */
174
-	protected function checkTypeRecursively($configValue, $configName) {
175
-		if (!is_array($configValue) && !is_bool($configValue) && !is_int($configValue) && !is_string($configValue) && !is_null($configValue)) {
176
-			throw new \UnexpectedValueException('Invalid system config value for "' . $configName . '". Only arrays, bools, integers, strings and null (delete) are allowed.');
177
-		}
178
-		if (is_array($configValue)) {
179
-			foreach ($configValue as $key => $value) {
180
-				$this->checkTypeRecursively($value, $configName);
181
-			}
182
-		}
183
-	}
184
-
185
-	/**
186
-	 * Validates that app configs are only integers and strings
187
-	 *
188
-	 * @param array $array
189
-	 */
190
-	protected function validateAppsArray($array) {
191
-		foreach ($array as $app => $configs) {
192
-			foreach ($configs as $name => $value) {
193
-				if (!is_int($value) && !is_string($value) && !is_null($value)) {
194
-					throw new \UnexpectedValueException('Invalid app config value for "' . $app . '":"' . $name . '". Only integers, strings and null (delete) are allowed.');
195
-				}
196
-			}
197
-		}
198
-	}
199
-
200
-	/**
201
-	 * @param string $optionName
202
-	 * @param CompletionContext $context
203
-	 * @return string[]
204
-	 */
205
-	public function completeOptionValues($optionName, CompletionContext $context) {
206
-		return [];
207
-	}
208
-
209
-	/**
210
-	 * @param string $argumentName
211
-	 * @param CompletionContext $context
212
-	 * @return string[]
213
-	 */
214
-	public function completeArgumentValues($argumentName, CompletionContext $context) {
215
-		if ($argumentName === 'file') {
216
-			$helper = new ShellPathCompletion(
217
-				$this->getName(),
218
-				'file',
219
-				Completion::TYPE_ARGUMENT
220
-			);
221
-			return $helper->run();
222
-		}
223
-		return [];
224
-	}
36
+    protected $validRootKeys = ['system', 'apps'];
37
+
38
+    /** @var IConfig */
39
+    protected $config;
40
+
41
+    /**
42
+     * @param IConfig $config
43
+     */
44
+    public function __construct(IConfig $config) {
45
+        parent::__construct();
46
+        $this->config = $config;
47
+    }
48
+
49
+    protected function configure() {
50
+        $this
51
+            ->setName('config:import')
52
+            ->setDescription('Import a list of configs')
53
+            ->addArgument(
54
+                'file',
55
+                InputArgument::OPTIONAL,
56
+                'File with the json array to import'
57
+            )
58
+        ;
59
+    }
60
+
61
+    protected function execute(InputInterface $input, OutputInterface $output) {
62
+        $importFile = $input->getArgument('file');
63
+        if ($importFile !== null) {
64
+            $content = $this->getArrayFromFile($importFile);
65
+        } else {
66
+            $content = $this->getArrayFromStdin();
67
+        }
68
+
69
+        try {
70
+            $configs = $this->validateFileContent($content);
71
+        } catch (\UnexpectedValueException $e) {
72
+            $output->writeln('<error>' . $e->getMessage(). '</error>');
73
+            return;
74
+        }
75
+
76
+        if (!empty($configs['system'])) {
77
+            $this->config->setSystemValues($configs['system']);
78
+        }
79
+
80
+        if (!empty($configs['apps'])) {
81
+            foreach ($configs['apps'] as $app => $appConfigs) {
82
+                foreach ($appConfigs as $key => $value) {
83
+                    if ($value === null) {
84
+                        $this->config->deleteAppValue($app, $key);
85
+                    } else {
86
+                        $this->config->setAppValue($app, $key, $value);
87
+                    }
88
+                }
89
+            }
90
+        }
91
+
92
+        $output->writeln('<info>Config successfully imported from: ' . $importFile . '</info>');
93
+    }
94
+
95
+    /**
96
+     * Get the content from stdin ("config:import < file.json")
97
+     *
98
+     * @return string
99
+     */
100
+    protected function getArrayFromStdin() {
101
+        // Read from stdin. stream_set_blocking is used to prevent blocking
102
+        // when nothing is passed via stdin.
103
+        stream_set_blocking(STDIN, 0);
104
+        $content = file_get_contents('php://stdin');
105
+        stream_set_blocking(STDIN, 1);
106
+        return $content;
107
+    }
108
+
109
+    /**
110
+     * Get the content of the specified file ("config:import file.json")
111
+     *
112
+     * @param string $importFile
113
+     * @return string
114
+     */
115
+    protected function getArrayFromFile($importFile) {
116
+        return file_get_contents($importFile);
117
+    }
118
+
119
+    /**
120
+     * @param string $content
121
+     * @return array
122
+     * @throws \UnexpectedValueException when the array is invalid
123
+     */
124
+    protected function validateFileContent($content) {
125
+        $decodedContent = json_decode($content, true);
126
+        if (!is_array($decodedContent) || empty($decodedContent)) {
127
+            throw new \UnexpectedValueException('The file must contain a valid json array');
128
+        }
129
+
130
+        $this->validateArray($decodedContent);
131
+
132
+        return $decodedContent;
133
+    }
134
+
135
+    /**
136
+     * Validates that the array only contains `system` and `apps`
137
+     *
138
+     * @param array $array
139
+     */
140
+    protected function validateArray($array) {
141
+        $arrayKeys = array_keys($array);
142
+        $additionalKeys = array_diff($arrayKeys, $this->validRootKeys);
143
+        $commonKeys = array_intersect($arrayKeys, $this->validRootKeys);
144
+        if (!empty($additionalKeys)) {
145
+            throw new \UnexpectedValueException('Found invalid entries in root: ' . implode(', ', $additionalKeys));
146
+        }
147
+        if (empty($commonKeys)) {
148
+            throw new \UnexpectedValueException('At least one key of the following is expected: ' . implode(', ', $this->validRootKeys));
149
+        }
150
+
151
+        if (isset($array['system'])) {
152
+            if (is_array($array['system'])) {
153
+                foreach ($array['system'] as $name => $value) {
154
+                    $this->checkTypeRecursively($value, $name);
155
+                }
156
+            } else {
157
+                throw new \UnexpectedValueException('The system config array is not an array');
158
+            }
159
+        }
160
+
161
+        if (isset($array['apps'])) {
162
+            if (is_array($array['apps'])) {
163
+                $this->validateAppsArray($array['apps']);
164
+            } else {
165
+                throw new \UnexpectedValueException('The apps config array is not an array');
166
+            }
167
+        }
168
+    }
169
+
170
+    /**
171
+     * @param mixed $configValue
172
+     * @param string $configName
173
+     */
174
+    protected function checkTypeRecursively($configValue, $configName) {
175
+        if (!is_array($configValue) && !is_bool($configValue) && !is_int($configValue) && !is_string($configValue) && !is_null($configValue)) {
176
+            throw new \UnexpectedValueException('Invalid system config value for "' . $configName . '". Only arrays, bools, integers, strings and null (delete) are allowed.');
177
+        }
178
+        if (is_array($configValue)) {
179
+            foreach ($configValue as $key => $value) {
180
+                $this->checkTypeRecursively($value, $configName);
181
+            }
182
+        }
183
+    }
184
+
185
+    /**
186
+     * Validates that app configs are only integers and strings
187
+     *
188
+     * @param array $array
189
+     */
190
+    protected function validateAppsArray($array) {
191
+        foreach ($array as $app => $configs) {
192
+            foreach ($configs as $name => $value) {
193
+                if (!is_int($value) && !is_string($value) && !is_null($value)) {
194
+                    throw new \UnexpectedValueException('Invalid app config value for "' . $app . '":"' . $name . '". Only integers, strings and null (delete) are allowed.');
195
+                }
196
+            }
197
+        }
198
+    }
199
+
200
+    /**
201
+     * @param string $optionName
202
+     * @param CompletionContext $context
203
+     * @return string[]
204
+     */
205
+    public function completeOptionValues($optionName, CompletionContext $context) {
206
+        return [];
207
+    }
208
+
209
+    /**
210
+     * @param string $argumentName
211
+     * @param CompletionContext $context
212
+     * @return string[]
213
+     */
214
+    public function completeArgumentValues($argumentName, CompletionContext $context) {
215
+        if ($argumentName === 'file') {
216
+            $helper = new ShellPathCompletion(
217
+                $this->getName(),
218
+                'file',
219
+                Completion::TYPE_ARGUMENT
220
+            );
221
+            return $helper->run();
222
+        }
223
+        return [];
224
+    }
225 225
 }
Please login to merge, or discard this patch.