Passed
Push — master ( 3cf321...e1a11b )
by Christoph
11:45 queued 13s
created
apps/dav/lib/Connector/Sabre/FilesPlugin.php 1 patch
Indentation   +462 added lines, -462 removed lines patch added patch discarded remove patch
@@ -52,470 +52,470 @@
 block discarded – undo
52 52
 
53 53
 class FilesPlugin extends ServerPlugin {
54 54
 
55
-	// namespace
56
-	const NS_OWNCLOUD = 'http://owncloud.org/ns';
57
-	const NS_NEXTCLOUD = 'http://nextcloud.org/ns';
58
-	const FILEID_PROPERTYNAME = '{http://owncloud.org/ns}id';
59
-	const INTERNAL_FILEID_PROPERTYNAME = '{http://owncloud.org/ns}fileid';
60
-	const PERMISSIONS_PROPERTYNAME = '{http://owncloud.org/ns}permissions';
61
-	const SHARE_PERMISSIONS_PROPERTYNAME = '{http://open-collaboration-services.org/ns}share-permissions';
62
-	const OCM_SHARE_PERMISSIONS_PROPERTYNAME = '{http://open-cloud-mesh.org/ns}share-permissions';
63
-	const DOWNLOADURL_PROPERTYNAME = '{http://owncloud.org/ns}downloadURL';
64
-	const SIZE_PROPERTYNAME = '{http://owncloud.org/ns}size';
65
-	const GETETAG_PROPERTYNAME = '{DAV:}getetag';
66
-	const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified';
67
-	const OWNER_ID_PROPERTYNAME = '{http://owncloud.org/ns}owner-id';
68
-	const OWNER_DISPLAY_NAME_PROPERTYNAME = '{http://owncloud.org/ns}owner-display-name';
69
-	const CHECKSUMS_PROPERTYNAME = '{http://owncloud.org/ns}checksums';
70
-	const DATA_FINGERPRINT_PROPERTYNAME = '{http://owncloud.org/ns}data-fingerprint';
71
-	const HAS_PREVIEW_PROPERTYNAME = '{http://nextcloud.org/ns}has-preview';
72
-	const MOUNT_TYPE_PROPERTYNAME = '{http://nextcloud.org/ns}mount-type';
73
-	const IS_ENCRYPTED_PROPERTYNAME = '{http://nextcloud.org/ns}is-encrypted';
74
-	const METADATA_ETAG_PROPERTYNAME = '{http://nextcloud.org/ns}metadata_etag';
75
-	const UPLOAD_TIME_PROPERTYNAME = '{http://nextcloud.org/ns}upload_time';
76
-	const CREATION_TIME_PROPERTYNAME = '{http://nextcloud.org/ns}creation_time';
77
-	const SHARE_NOTE = '{http://nextcloud.org/ns}note';
78
-
79
-	/**
80
-	 * Reference to main server object
81
-	 *
82
-	 * @var \Sabre\DAV\Server
83
-	 */
84
-	private $server;
85
-
86
-	/**
87
-	 * @var Tree
88
-	 */
89
-	private $tree;
90
-
91
-	/**
92
-	 * Whether this is public webdav.
93
-	 * If true, some returned information will be stripped off.
94
-	 *
95
-	 * @var bool
96
-	 */
97
-	private $isPublic;
98
-
99
-	/**
100
-	 * @var bool
101
-	 */
102
-	private $downloadAttachment;
103
-
104
-	/**
105
-	 * @var IConfig
106
-	 */
107
-	private $config;
108
-
109
-	/**
110
-	 * @var IRequest
111
-	 */
112
-	private $request;
113
-
114
-	/**
115
-	 * @var IPreview
116
-	 */
117
-	private $previewManager;
118
-
119
-	/**
120
-	 * @param Tree $tree
121
-	 * @param IConfig $config
122
-	 * @param IRequest $request
123
-	 * @param IPreview $previewManager
124
-	 * @param bool $isPublic
125
-	 * @param bool $downloadAttachment
126
-	 */
127
-	public function __construct(Tree $tree,
128
-								IConfig $config,
129
-								IRequest $request,
130
-								IPreview $previewManager,
131
-								$isPublic = false,
132
-								$downloadAttachment = true) {
133
-		$this->tree = $tree;
134
-		$this->config = $config;
135
-		$this->request = $request;
136
-		$this->isPublic = $isPublic;
137
-		$this->downloadAttachment = $downloadAttachment;
138
-		$this->previewManager = $previewManager;
139
-	}
140
-
141
-	/**
142
-	 * This initializes the plugin.
143
-	 *
144
-	 * This function is called by \Sabre\DAV\Server, after
145
-	 * addPlugin is called.
146
-	 *
147
-	 * This method should set up the required event subscriptions.
148
-	 *
149
-	 * @param \Sabre\DAV\Server $server
150
-	 * @return void
151
-	 */
152
-	public function initialize(\Sabre\DAV\Server $server) {
153
-		$server->xml->namespaceMap[self::NS_OWNCLOUD] = 'oc';
154
-		$server->xml->namespaceMap[self::NS_NEXTCLOUD] = 'nc';
155
-		$server->protectedProperties[] = self::FILEID_PROPERTYNAME;
156
-		$server->protectedProperties[] = self::INTERNAL_FILEID_PROPERTYNAME;
157
-		$server->protectedProperties[] = self::PERMISSIONS_PROPERTYNAME;
158
-		$server->protectedProperties[] = self::SHARE_PERMISSIONS_PROPERTYNAME;
159
-		$server->protectedProperties[] = self::OCM_SHARE_PERMISSIONS_PROPERTYNAME;
160
-		$server->protectedProperties[] = self::SIZE_PROPERTYNAME;
161
-		$server->protectedProperties[] = self::DOWNLOADURL_PROPERTYNAME;
162
-		$server->protectedProperties[] = self::OWNER_ID_PROPERTYNAME;
163
-		$server->protectedProperties[] = self::OWNER_DISPLAY_NAME_PROPERTYNAME;
164
-		$server->protectedProperties[] = self::CHECKSUMS_PROPERTYNAME;
165
-		$server->protectedProperties[] = self::DATA_FINGERPRINT_PROPERTYNAME;
166
-		$server->protectedProperties[] = self::HAS_PREVIEW_PROPERTYNAME;
167
-		$server->protectedProperties[] = self::MOUNT_TYPE_PROPERTYNAME;
168
-		$server->protectedProperties[] = self::IS_ENCRYPTED_PROPERTYNAME;
169
-		$server->protectedProperties[] = self::SHARE_NOTE;
170
-
171
-		// normally these cannot be changed (RFC4918), but we want them modifiable through PROPPATCH
172
-		$allowedProperties = ['{DAV:}getetag'];
173
-		$server->protectedProperties = array_diff($server->protectedProperties, $allowedProperties);
174
-
175
-		$this->server = $server;
176
-		$this->server->on('propFind', array($this, 'handleGetProperties'));
177
-		$this->server->on('propPatch', array($this, 'handleUpdateProperties'));
178
-		$this->server->on('afterBind', array($this, 'sendFileIdHeader'));
179
-		$this->server->on('afterWriteContent', array($this, 'sendFileIdHeader'));
180
-		$this->server->on('afterMethod:GET', [$this,'httpGet']);
181
-		$this->server->on('afterMethod:GET', array($this, 'handleDownloadToken'));
182
-		$this->server->on('afterResponse', function($request, ResponseInterface $response) {
183
-			$body = $response->getBody();
184
-			if (is_resource($body)) {
185
-				fclose($body);
186
-			}
187
-		});
188
-		$this->server->on('beforeMove', [$this, 'checkMove']);
189
-	}
190
-
191
-	/**
192
-	 * Plugin that checks if a move can actually be performed.
193
-	 *
194
-	 * @param string $source source path
195
-	 * @param string $destination destination path
196
-	 * @throws Forbidden
197
-	 * @throws NotFound
198
-	 */
199
-	function checkMove($source, $destination) {
200
-		$sourceNode = $this->tree->getNodeForPath($source);
201
-		if (!$sourceNode instanceof Node) {
202
-			return;
203
-		}
204
-		list($sourceDir,) = \Sabre\Uri\split($source);
205
-		list($destinationDir,) = \Sabre\Uri\split($destination);
206
-
207
-		if ($sourceDir !== $destinationDir) {
208
-			$sourceNodeFileInfo = $sourceNode->getFileInfo();
209
-			if ($sourceNodeFileInfo === null) {
210
-				throw new NotFound($source . ' does not exist');
211
- 			}
212
-
213
-			if (!$sourceNodeFileInfo->isDeletable()) {
214
-				throw new Forbidden($source . " cannot be deleted");
215
-			}
216
-		}
217
-	}
218
-
219
-	/**
220
-	 * This sets a cookie to be able to recognize the start of the download
221
-	 * the content must not be longer than 32 characters and must only contain
222
-	 * alphanumeric characters
223
-	 *
224
-	 * @param RequestInterface $request
225
-	 * @param ResponseInterface $response
226
-	 */
227
-	function handleDownloadToken(RequestInterface $request, ResponseInterface $response) {
228
-		$queryParams = $request->getQueryParameters();
229
-
230
-		/**
231
-		 * this sets a cookie to be able to recognize the start of the download
232
-		 * the content must not be longer than 32 characters and must only contain
233
-		 * alphanumeric characters
234
-		 */
235
-		if (isset($queryParams['downloadStartSecret'])) {
236
-			$token = $queryParams['downloadStartSecret'];
237
-			if (!isset($token[32])
238
-				&& preg_match('!^[a-zA-Z0-9]+$!', $token) === 1) {
239
-				// FIXME: use $response->setHeader() instead
240
-				setcookie('ocDownloadStarted', $token, time() + 20, '/');
241
-			}
242
-		}
243
-	}
244
-
245
-	/**
246
-	 * Add headers to file download
247
-	 *
248
-	 * @param RequestInterface $request
249
-	 * @param ResponseInterface $response
250
-	 */
251
-	function httpGet(RequestInterface $request, ResponseInterface $response) {
252
-		// Only handle valid files
253
-		$node = $this->tree->getNodeForPath($request->getPath());
254
-		if (!($node instanceof IFile)) return;
255
-
256
-		// adds a 'Content-Disposition: attachment' header in case no disposition
257
-		// header has been set before
258
-		if ($this->downloadAttachment &&
259
-			$response->getHeader('Content-Disposition') === null) {
260
-			$filename = $node->getName();
261
-			if ($this->request->isUserAgent(
262
-				[
263
-					Request::USER_AGENT_IE,
264
-					Request::USER_AGENT_ANDROID_MOBILE_CHROME,
265
-					Request::USER_AGENT_FREEBOX,
266
-				])) {
267
-				$response->addHeader('Content-Disposition', 'attachment; filename="' . rawurlencode($filename) . '"');
268
-			} else {
269
-				$response->addHeader('Content-Disposition', 'attachment; filename*=UTF-8\'\'' . rawurlencode($filename)
270
-													 . '; filename="' . rawurlencode($filename) . '"');
271
-			}
272
-		}
273
-
274
-		if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
275
-			//Add OC-Checksum header
276
-			/** @var $node File */
277
-			$checksum = $node->getChecksum();
278
-			if ($checksum !== null && $checksum !== '') {
279
-				$response->addHeader('OC-Checksum', $checksum);
280
-			}
281
-		}
282
-	}
283
-
284
-	/**
285
-	 * Adds all ownCloud-specific properties
286
-	 *
287
-	 * @param PropFind $propFind
288
-	 * @param \Sabre\DAV\INode $node
289
-	 * @return void
290
-	 */
291
-	public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node) {
292
-
293
-		$httpRequest = $this->server->httpRequest;
294
-
295
-		if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
296
-			/**
297
-			 * This was disabled, because it made dir listing throw an exception,
298
-			 * so users were unable to navigate into folders where one subitem
299
-			 * is blocked by the files_accesscontrol app, see:
300
-			 * https://github.com/nextcloud/files_accesscontrol/issues/65
55
+    // namespace
56
+    const NS_OWNCLOUD = 'http://owncloud.org/ns';
57
+    const NS_NEXTCLOUD = 'http://nextcloud.org/ns';
58
+    const FILEID_PROPERTYNAME = '{http://owncloud.org/ns}id';
59
+    const INTERNAL_FILEID_PROPERTYNAME = '{http://owncloud.org/ns}fileid';
60
+    const PERMISSIONS_PROPERTYNAME = '{http://owncloud.org/ns}permissions';
61
+    const SHARE_PERMISSIONS_PROPERTYNAME = '{http://open-collaboration-services.org/ns}share-permissions';
62
+    const OCM_SHARE_PERMISSIONS_PROPERTYNAME = '{http://open-cloud-mesh.org/ns}share-permissions';
63
+    const DOWNLOADURL_PROPERTYNAME = '{http://owncloud.org/ns}downloadURL';
64
+    const SIZE_PROPERTYNAME = '{http://owncloud.org/ns}size';
65
+    const GETETAG_PROPERTYNAME = '{DAV:}getetag';
66
+    const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified';
67
+    const OWNER_ID_PROPERTYNAME = '{http://owncloud.org/ns}owner-id';
68
+    const OWNER_DISPLAY_NAME_PROPERTYNAME = '{http://owncloud.org/ns}owner-display-name';
69
+    const CHECKSUMS_PROPERTYNAME = '{http://owncloud.org/ns}checksums';
70
+    const DATA_FINGERPRINT_PROPERTYNAME = '{http://owncloud.org/ns}data-fingerprint';
71
+    const HAS_PREVIEW_PROPERTYNAME = '{http://nextcloud.org/ns}has-preview';
72
+    const MOUNT_TYPE_PROPERTYNAME = '{http://nextcloud.org/ns}mount-type';
73
+    const IS_ENCRYPTED_PROPERTYNAME = '{http://nextcloud.org/ns}is-encrypted';
74
+    const METADATA_ETAG_PROPERTYNAME = '{http://nextcloud.org/ns}metadata_etag';
75
+    const UPLOAD_TIME_PROPERTYNAME = '{http://nextcloud.org/ns}upload_time';
76
+    const CREATION_TIME_PROPERTYNAME = '{http://nextcloud.org/ns}creation_time';
77
+    const SHARE_NOTE = '{http://nextcloud.org/ns}note';
78
+
79
+    /**
80
+     * Reference to main server object
81
+     *
82
+     * @var \Sabre\DAV\Server
83
+     */
84
+    private $server;
85
+
86
+    /**
87
+     * @var Tree
88
+     */
89
+    private $tree;
90
+
91
+    /**
92
+     * Whether this is public webdav.
93
+     * If true, some returned information will be stripped off.
94
+     *
95
+     * @var bool
96
+     */
97
+    private $isPublic;
98
+
99
+    /**
100
+     * @var bool
101
+     */
102
+    private $downloadAttachment;
103
+
104
+    /**
105
+     * @var IConfig
106
+     */
107
+    private $config;
108
+
109
+    /**
110
+     * @var IRequest
111
+     */
112
+    private $request;
113
+
114
+    /**
115
+     * @var IPreview
116
+     */
117
+    private $previewManager;
118
+
119
+    /**
120
+     * @param Tree $tree
121
+     * @param IConfig $config
122
+     * @param IRequest $request
123
+     * @param IPreview $previewManager
124
+     * @param bool $isPublic
125
+     * @param bool $downloadAttachment
126
+     */
127
+    public function __construct(Tree $tree,
128
+                                IConfig $config,
129
+                                IRequest $request,
130
+                                IPreview $previewManager,
131
+                                $isPublic = false,
132
+                                $downloadAttachment = true) {
133
+        $this->tree = $tree;
134
+        $this->config = $config;
135
+        $this->request = $request;
136
+        $this->isPublic = $isPublic;
137
+        $this->downloadAttachment = $downloadAttachment;
138
+        $this->previewManager = $previewManager;
139
+    }
140
+
141
+    /**
142
+     * This initializes the plugin.
143
+     *
144
+     * This function is called by \Sabre\DAV\Server, after
145
+     * addPlugin is called.
146
+     *
147
+     * This method should set up the required event subscriptions.
148
+     *
149
+     * @param \Sabre\DAV\Server $server
150
+     * @return void
151
+     */
152
+    public function initialize(\Sabre\DAV\Server $server) {
153
+        $server->xml->namespaceMap[self::NS_OWNCLOUD] = 'oc';
154
+        $server->xml->namespaceMap[self::NS_NEXTCLOUD] = 'nc';
155
+        $server->protectedProperties[] = self::FILEID_PROPERTYNAME;
156
+        $server->protectedProperties[] = self::INTERNAL_FILEID_PROPERTYNAME;
157
+        $server->protectedProperties[] = self::PERMISSIONS_PROPERTYNAME;
158
+        $server->protectedProperties[] = self::SHARE_PERMISSIONS_PROPERTYNAME;
159
+        $server->protectedProperties[] = self::OCM_SHARE_PERMISSIONS_PROPERTYNAME;
160
+        $server->protectedProperties[] = self::SIZE_PROPERTYNAME;
161
+        $server->protectedProperties[] = self::DOWNLOADURL_PROPERTYNAME;
162
+        $server->protectedProperties[] = self::OWNER_ID_PROPERTYNAME;
163
+        $server->protectedProperties[] = self::OWNER_DISPLAY_NAME_PROPERTYNAME;
164
+        $server->protectedProperties[] = self::CHECKSUMS_PROPERTYNAME;
165
+        $server->protectedProperties[] = self::DATA_FINGERPRINT_PROPERTYNAME;
166
+        $server->protectedProperties[] = self::HAS_PREVIEW_PROPERTYNAME;
167
+        $server->protectedProperties[] = self::MOUNT_TYPE_PROPERTYNAME;
168
+        $server->protectedProperties[] = self::IS_ENCRYPTED_PROPERTYNAME;
169
+        $server->protectedProperties[] = self::SHARE_NOTE;
170
+
171
+        // normally these cannot be changed (RFC4918), but we want them modifiable through PROPPATCH
172
+        $allowedProperties = ['{DAV:}getetag'];
173
+        $server->protectedProperties = array_diff($server->protectedProperties, $allowedProperties);
174
+
175
+        $this->server = $server;
176
+        $this->server->on('propFind', array($this, 'handleGetProperties'));
177
+        $this->server->on('propPatch', array($this, 'handleUpdateProperties'));
178
+        $this->server->on('afterBind', array($this, 'sendFileIdHeader'));
179
+        $this->server->on('afterWriteContent', array($this, 'sendFileIdHeader'));
180
+        $this->server->on('afterMethod:GET', [$this,'httpGet']);
181
+        $this->server->on('afterMethod:GET', array($this, 'handleDownloadToken'));
182
+        $this->server->on('afterResponse', function($request, ResponseInterface $response) {
183
+            $body = $response->getBody();
184
+            if (is_resource($body)) {
185
+                fclose($body);
186
+            }
187
+        });
188
+        $this->server->on('beforeMove', [$this, 'checkMove']);
189
+    }
190
+
191
+    /**
192
+     * Plugin that checks if a move can actually be performed.
193
+     *
194
+     * @param string $source source path
195
+     * @param string $destination destination path
196
+     * @throws Forbidden
197
+     * @throws NotFound
198
+     */
199
+    function checkMove($source, $destination) {
200
+        $sourceNode = $this->tree->getNodeForPath($source);
201
+        if (!$sourceNode instanceof Node) {
202
+            return;
203
+        }
204
+        list($sourceDir,) = \Sabre\Uri\split($source);
205
+        list($destinationDir,) = \Sabre\Uri\split($destination);
206
+
207
+        if ($sourceDir !== $destinationDir) {
208
+            $sourceNodeFileInfo = $sourceNode->getFileInfo();
209
+            if ($sourceNodeFileInfo === null) {
210
+                throw new NotFound($source . ' does not exist');
211
+                }
212
+
213
+            if (!$sourceNodeFileInfo->isDeletable()) {
214
+                throw new Forbidden($source . " cannot be deleted");
215
+            }
216
+        }
217
+    }
218
+
219
+    /**
220
+     * This sets a cookie to be able to recognize the start of the download
221
+     * the content must not be longer than 32 characters and must only contain
222
+     * alphanumeric characters
223
+     *
224
+     * @param RequestInterface $request
225
+     * @param ResponseInterface $response
226
+     */
227
+    function handleDownloadToken(RequestInterface $request, ResponseInterface $response) {
228
+        $queryParams = $request->getQueryParameters();
229
+
230
+        /**
231
+         * this sets a cookie to be able to recognize the start of the download
232
+         * the content must not be longer than 32 characters and must only contain
233
+         * alphanumeric characters
234
+         */
235
+        if (isset($queryParams['downloadStartSecret'])) {
236
+            $token = $queryParams['downloadStartSecret'];
237
+            if (!isset($token[32])
238
+                && preg_match('!^[a-zA-Z0-9]+$!', $token) === 1) {
239
+                // FIXME: use $response->setHeader() instead
240
+                setcookie('ocDownloadStarted', $token, time() + 20, '/');
241
+            }
242
+        }
243
+    }
244
+
245
+    /**
246
+     * Add headers to file download
247
+     *
248
+     * @param RequestInterface $request
249
+     * @param ResponseInterface $response
250
+     */
251
+    function httpGet(RequestInterface $request, ResponseInterface $response) {
252
+        // Only handle valid files
253
+        $node = $this->tree->getNodeForPath($request->getPath());
254
+        if (!($node instanceof IFile)) return;
255
+
256
+        // adds a 'Content-Disposition: attachment' header in case no disposition
257
+        // header has been set before
258
+        if ($this->downloadAttachment &&
259
+            $response->getHeader('Content-Disposition') === null) {
260
+            $filename = $node->getName();
261
+            if ($this->request->isUserAgent(
262
+                [
263
+                    Request::USER_AGENT_IE,
264
+                    Request::USER_AGENT_ANDROID_MOBILE_CHROME,
265
+                    Request::USER_AGENT_FREEBOX,
266
+                ])) {
267
+                $response->addHeader('Content-Disposition', 'attachment; filename="' . rawurlencode($filename) . '"');
268
+            } else {
269
+                $response->addHeader('Content-Disposition', 'attachment; filename*=UTF-8\'\'' . rawurlencode($filename)
270
+                                                        . '; filename="' . rawurlencode($filename) . '"');
271
+            }
272
+        }
273
+
274
+        if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
275
+            //Add OC-Checksum header
276
+            /** @var $node File */
277
+            $checksum = $node->getChecksum();
278
+            if ($checksum !== null && $checksum !== '') {
279
+                $response->addHeader('OC-Checksum', $checksum);
280
+            }
281
+        }
282
+    }
283
+
284
+    /**
285
+     * Adds all ownCloud-specific properties
286
+     *
287
+     * @param PropFind $propFind
288
+     * @param \Sabre\DAV\INode $node
289
+     * @return void
290
+     */
291
+    public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node) {
292
+
293
+        $httpRequest = $this->server->httpRequest;
294
+
295
+        if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
296
+            /**
297
+             * This was disabled, because it made dir listing throw an exception,
298
+             * so users were unable to navigate into folders where one subitem
299
+             * is blocked by the files_accesscontrol app, see:
300
+             * https://github.com/nextcloud/files_accesscontrol/issues/65
301 301
 			if (!$node->getFileInfo()->isReadable()) {
302 302
 				// avoid detecting files through this means
303 303
 				throw new NotFound();
304 304
 			}
305
-			 */
306
-
307
-			$propFind->handle(self::FILEID_PROPERTYNAME, function() use ($node) {
308
-				return $node->getFileId();
309
-			});
310
-
311
-			$propFind->handle(self::INTERNAL_FILEID_PROPERTYNAME, function() use ($node) {
312
-				return $node->getInternalFileId();
313
-			});
314
-
315
-			$propFind->handle(self::PERMISSIONS_PROPERTYNAME, function() use ($node) {
316
-				$perms = $node->getDavPermissions();
317
-				if ($this->isPublic) {
318
-					// remove mount information
319
-					$perms = str_replace(['S', 'M'], '', $perms);
320
-				}
321
-				return $perms;
322
-			});
323
-
324
-			$propFind->handle(self::SHARE_PERMISSIONS_PROPERTYNAME, function() use ($node, $httpRequest) {
325
-				return $node->getSharePermissions(
326
-					$httpRequest->getRawServerValue('PHP_AUTH_USER')
327
-				);
328
-			});
329
-
330
-			$propFind->handle(self::OCM_SHARE_PERMISSIONS_PROPERTYNAME, function() use ($node, $httpRequest) {
331
-				$ncPermissions = $node->getSharePermissions(
332
-					$httpRequest->getRawServerValue('PHP_AUTH_USER')
333
-				);
334
-				$ocmPermissions = $this->ncPermissions2ocmPermissions($ncPermissions);
335
-				return json_encode($ocmPermissions);
336
-			});
337
-
338
-			$propFind->handle(self::GETETAG_PROPERTYNAME, function() use ($node) {
339
-				return $node->getETag();
340
-			});
341
-
342
-			$propFind->handle(self::OWNER_ID_PROPERTYNAME, function() use ($node) {
343
-				$owner = $node->getOwner();
344
-				if (!$owner) {
345
-					return null;
346
-				} else {
347
-					return $owner->getUID();
348
-				}
349
-			});
350
-			$propFind->handle(self::OWNER_DISPLAY_NAME_PROPERTYNAME, function() use ($node) {
351
-				$owner = $node->getOwner();
352
-				if (!$owner) {
353
-					return null;
354
-				} else {
355
-					return $owner->getDisplayName();
356
-				}
357
-			});
358
-
359
-			$propFind->handle(self::HAS_PREVIEW_PROPERTYNAME, function () use ($node) {
360
-				return json_encode($this->previewManager->isAvailable($node->getFileInfo()));
361
-			});
362
-			$propFind->handle(self::SIZE_PROPERTYNAME, function() use ($node) {
363
-				return $node->getSize();
364
-			});
365
-			$propFind->handle(self::MOUNT_TYPE_PROPERTYNAME, function () use ($node) {
366
-				return $node->getFileInfo()->getMountPoint()->getMountType();
367
-			});
368
-
369
-			$propFind->handle(self::SHARE_NOTE, function() use ($node, $httpRequest) {
370
-				return $node->getNoteFromShare(
371
-					$httpRequest->getRawServerValue('PHP_AUTH_USER')
372
-				);
373
-			});
374
-		}
375
-
376
-		if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
377
-			$propFind->handle(self::DATA_FINGERPRINT_PROPERTYNAME, function() use ($node) {
378
-				return $this->config->getSystemValue('data-fingerprint', '');
379
-			});
380
-		}
381
-
382
-		if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
383
-			$propFind->handle(self::DOWNLOADURL_PROPERTYNAME, function() use ($node) {
384
-				/** @var $node \OCA\DAV\Connector\Sabre\File */
385
-				try {
386
-					$directDownloadUrl = $node->getDirectDownload();
387
-					if (isset($directDownloadUrl['url'])) {
388
-						return $directDownloadUrl['url'];
389
-					}
390
-				} catch (StorageNotAvailableException $e) {
391
-					return false;
392
-				} catch (ForbiddenException $e) {
393
-					return false;
394
-				}
395
-				return false;
396
-			});
397
-
398
-			$propFind->handle(self::CHECKSUMS_PROPERTYNAME, function() use ($node) {
399
-				$checksum = $node->getChecksum();
400
-				if ($checksum === null || $checksum === '') {
401
-					return null;
402
-				}
403
-
404
-				return new ChecksumList($checksum);
405
-			});
406
-
407
-			$propFind->handle(self::CREATION_TIME_PROPERTYNAME, function() use ($node) {
408
-				return $node->getFileInfo()->getCreationTime();
409
-			});
410
-
411
-			$propFind->handle(self::UPLOAD_TIME_PROPERTYNAME, function() use ($node) {
412
-				return $node->getFileInfo()->getUploadTime();
413
-			});
414
-
415
-		}
416
-
417
-		if ($node instanceof \OCA\DAV\Connector\Sabre\Directory) {
418
-			$propFind->handle(self::SIZE_PROPERTYNAME, function() use ($node) {
419
-				return $node->getSize();
420
-			});
421
-
422
-			$propFind->handle(self::IS_ENCRYPTED_PROPERTYNAME, function() use ($node) {
423
-				return $node->getFileInfo()->isEncrypted() ? '1' : '0';
424
-			});
425
-		}
426
-	}
427
-
428
-	/**
429
-	 * translate Nextcloud permissions to OCM Permissions
430
-	 *
431
-	 * @param $ncPermissions
432
-	 * @return array
433
-	 */
434
-	protected function ncPermissions2ocmPermissions($ncPermissions) {
435
-
436
-		$ocmPermissions = [];
437
-
438
-		if ($ncPermissions & Constants::PERMISSION_SHARE) {
439
-			$ocmPermissions[] = 'share';
440
-		}
441
-
442
-		if ($ncPermissions & Constants::PERMISSION_READ) {
443
-			$ocmPermissions[] = 'read';
444
-		}
445
-
446
-		if (($ncPermissions & Constants::PERMISSION_CREATE) ||
447
-			($ncPermissions & Constants::PERMISSION_UPDATE)) {
448
-			$ocmPermissions[] = 'write';
449
-		}
450
-
451
-		return $ocmPermissions;
452
-
453
-	}
454
-
455
-	/**
456
-	 * Update ownCloud-specific properties
457
-	 *
458
-	 * @param string $path
459
-	 * @param PropPatch $propPatch
460
-	 *
461
-	 * @return void
462
-	 */
463
-	public function handleUpdateProperties($path, PropPatch $propPatch) {
464
-		$node = $this->tree->getNodeForPath($path);
465
-		if (!($node instanceof \OCA\DAV\Connector\Sabre\Node)) {
466
-			return;
467
-		}
468
-
469
-		$propPatch->handle(self::LASTMODIFIED_PROPERTYNAME, function($time) use ($node) {
470
-			if (empty($time)) {
471
-				return false;
472
-			}
473
-			$node->touch($time);
474
-			return true;
475
-		});
476
-		$propPatch->handle(self::GETETAG_PROPERTYNAME, function($etag) use ($node) {
477
-			if (empty($etag)) {
478
-				return false;
479
-			}
480
-			if ($node->setEtag($etag) !== -1) {
481
-				return true;
482
-			}
483
-			return false;
484
-		});
485
-		$propPatch->handle(self::CREATION_TIME_PROPERTYNAME, function($time) use ($node) {
486
-			if (empty($time)) {
487
-				return false;
488
-			}
489
-			$node->setCreationTime((int) $time);
490
-			return true;
491
-		});
492
-	}
493
-
494
-	/**
495
-	 * @param string $filePath
496
-	 * @param \Sabre\DAV\INode $node
497
-	 * @throws \Sabre\DAV\Exception\BadRequest
498
-	 */
499
-	public function sendFileIdHeader($filePath, \Sabre\DAV\INode $node = null) {
500
-		// chunked upload handling
501
-		if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
502
-			list($path, $name) = \Sabre\Uri\split($filePath);
503
-			$info = \OC_FileChunking::decodeName($name);
504
-			if (!empty($info)) {
505
-				$filePath = $path . '/' . $info['name'];
506
-			}
507
-		}
508
-
509
-		// we get the node for the given $filePath here because in case of afterCreateFile $node is the parent folder
510
-		if (!$this->server->tree->nodeExists($filePath)) {
511
-			return;
512
-		}
513
-		$node = $this->server->tree->getNodeForPath($filePath);
514
-		if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
515
-			$fileId = $node->getFileId();
516
-			if (!is_null($fileId)) {
517
-				$this->server->httpResponse->setHeader('OC-FileId', $fileId);
518
-			}
519
-		}
520
-	}
305
+             */
306
+
307
+            $propFind->handle(self::FILEID_PROPERTYNAME, function() use ($node) {
308
+                return $node->getFileId();
309
+            });
310
+
311
+            $propFind->handle(self::INTERNAL_FILEID_PROPERTYNAME, function() use ($node) {
312
+                return $node->getInternalFileId();
313
+            });
314
+
315
+            $propFind->handle(self::PERMISSIONS_PROPERTYNAME, function() use ($node) {
316
+                $perms = $node->getDavPermissions();
317
+                if ($this->isPublic) {
318
+                    // remove mount information
319
+                    $perms = str_replace(['S', 'M'], '', $perms);
320
+                }
321
+                return $perms;
322
+            });
323
+
324
+            $propFind->handle(self::SHARE_PERMISSIONS_PROPERTYNAME, function() use ($node, $httpRequest) {
325
+                return $node->getSharePermissions(
326
+                    $httpRequest->getRawServerValue('PHP_AUTH_USER')
327
+                );
328
+            });
329
+
330
+            $propFind->handle(self::OCM_SHARE_PERMISSIONS_PROPERTYNAME, function() use ($node, $httpRequest) {
331
+                $ncPermissions = $node->getSharePermissions(
332
+                    $httpRequest->getRawServerValue('PHP_AUTH_USER')
333
+                );
334
+                $ocmPermissions = $this->ncPermissions2ocmPermissions($ncPermissions);
335
+                return json_encode($ocmPermissions);
336
+            });
337
+
338
+            $propFind->handle(self::GETETAG_PROPERTYNAME, function() use ($node) {
339
+                return $node->getETag();
340
+            });
341
+
342
+            $propFind->handle(self::OWNER_ID_PROPERTYNAME, function() use ($node) {
343
+                $owner = $node->getOwner();
344
+                if (!$owner) {
345
+                    return null;
346
+                } else {
347
+                    return $owner->getUID();
348
+                }
349
+            });
350
+            $propFind->handle(self::OWNER_DISPLAY_NAME_PROPERTYNAME, function() use ($node) {
351
+                $owner = $node->getOwner();
352
+                if (!$owner) {
353
+                    return null;
354
+                } else {
355
+                    return $owner->getDisplayName();
356
+                }
357
+            });
358
+
359
+            $propFind->handle(self::HAS_PREVIEW_PROPERTYNAME, function () use ($node) {
360
+                return json_encode($this->previewManager->isAvailable($node->getFileInfo()));
361
+            });
362
+            $propFind->handle(self::SIZE_PROPERTYNAME, function() use ($node) {
363
+                return $node->getSize();
364
+            });
365
+            $propFind->handle(self::MOUNT_TYPE_PROPERTYNAME, function () use ($node) {
366
+                return $node->getFileInfo()->getMountPoint()->getMountType();
367
+            });
368
+
369
+            $propFind->handle(self::SHARE_NOTE, function() use ($node, $httpRequest) {
370
+                return $node->getNoteFromShare(
371
+                    $httpRequest->getRawServerValue('PHP_AUTH_USER')
372
+                );
373
+            });
374
+        }
375
+
376
+        if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
377
+            $propFind->handle(self::DATA_FINGERPRINT_PROPERTYNAME, function() use ($node) {
378
+                return $this->config->getSystemValue('data-fingerprint', '');
379
+            });
380
+        }
381
+
382
+        if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
383
+            $propFind->handle(self::DOWNLOADURL_PROPERTYNAME, function() use ($node) {
384
+                /** @var $node \OCA\DAV\Connector\Sabre\File */
385
+                try {
386
+                    $directDownloadUrl = $node->getDirectDownload();
387
+                    if (isset($directDownloadUrl['url'])) {
388
+                        return $directDownloadUrl['url'];
389
+                    }
390
+                } catch (StorageNotAvailableException $e) {
391
+                    return false;
392
+                } catch (ForbiddenException $e) {
393
+                    return false;
394
+                }
395
+                return false;
396
+            });
397
+
398
+            $propFind->handle(self::CHECKSUMS_PROPERTYNAME, function() use ($node) {
399
+                $checksum = $node->getChecksum();
400
+                if ($checksum === null || $checksum === '') {
401
+                    return null;
402
+                }
403
+
404
+                return new ChecksumList($checksum);
405
+            });
406
+
407
+            $propFind->handle(self::CREATION_TIME_PROPERTYNAME, function() use ($node) {
408
+                return $node->getFileInfo()->getCreationTime();
409
+            });
410
+
411
+            $propFind->handle(self::UPLOAD_TIME_PROPERTYNAME, function() use ($node) {
412
+                return $node->getFileInfo()->getUploadTime();
413
+            });
414
+
415
+        }
416
+
417
+        if ($node instanceof \OCA\DAV\Connector\Sabre\Directory) {
418
+            $propFind->handle(self::SIZE_PROPERTYNAME, function() use ($node) {
419
+                return $node->getSize();
420
+            });
421
+
422
+            $propFind->handle(self::IS_ENCRYPTED_PROPERTYNAME, function() use ($node) {
423
+                return $node->getFileInfo()->isEncrypted() ? '1' : '0';
424
+            });
425
+        }
426
+    }
427
+
428
+    /**
429
+     * translate Nextcloud permissions to OCM Permissions
430
+     *
431
+     * @param $ncPermissions
432
+     * @return array
433
+     */
434
+    protected function ncPermissions2ocmPermissions($ncPermissions) {
435
+
436
+        $ocmPermissions = [];
437
+
438
+        if ($ncPermissions & Constants::PERMISSION_SHARE) {
439
+            $ocmPermissions[] = 'share';
440
+        }
441
+
442
+        if ($ncPermissions & Constants::PERMISSION_READ) {
443
+            $ocmPermissions[] = 'read';
444
+        }
445
+
446
+        if (($ncPermissions & Constants::PERMISSION_CREATE) ||
447
+            ($ncPermissions & Constants::PERMISSION_UPDATE)) {
448
+            $ocmPermissions[] = 'write';
449
+        }
450
+
451
+        return $ocmPermissions;
452
+
453
+    }
454
+
455
+    /**
456
+     * Update ownCloud-specific properties
457
+     *
458
+     * @param string $path
459
+     * @param PropPatch $propPatch
460
+     *
461
+     * @return void
462
+     */
463
+    public function handleUpdateProperties($path, PropPatch $propPatch) {
464
+        $node = $this->tree->getNodeForPath($path);
465
+        if (!($node instanceof \OCA\DAV\Connector\Sabre\Node)) {
466
+            return;
467
+        }
468
+
469
+        $propPatch->handle(self::LASTMODIFIED_PROPERTYNAME, function($time) use ($node) {
470
+            if (empty($time)) {
471
+                return false;
472
+            }
473
+            $node->touch($time);
474
+            return true;
475
+        });
476
+        $propPatch->handle(self::GETETAG_PROPERTYNAME, function($etag) use ($node) {
477
+            if (empty($etag)) {
478
+                return false;
479
+            }
480
+            if ($node->setEtag($etag) !== -1) {
481
+                return true;
482
+            }
483
+            return false;
484
+        });
485
+        $propPatch->handle(self::CREATION_TIME_PROPERTYNAME, function($time) use ($node) {
486
+            if (empty($time)) {
487
+                return false;
488
+            }
489
+            $node->setCreationTime((int) $time);
490
+            return true;
491
+        });
492
+    }
493
+
494
+    /**
495
+     * @param string $filePath
496
+     * @param \Sabre\DAV\INode $node
497
+     * @throws \Sabre\DAV\Exception\BadRequest
498
+     */
499
+    public function sendFileIdHeader($filePath, \Sabre\DAV\INode $node = null) {
500
+        // chunked upload handling
501
+        if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
502
+            list($path, $name) = \Sabre\Uri\split($filePath);
503
+            $info = \OC_FileChunking::decodeName($name);
504
+            if (!empty($info)) {
505
+                $filePath = $path . '/' . $info['name'];
506
+            }
507
+        }
508
+
509
+        // we get the node for the given $filePath here because in case of afterCreateFile $node is the parent folder
510
+        if (!$this->server->tree->nodeExists($filePath)) {
511
+            return;
512
+        }
513
+        $node = $this->server->tree->getNodeForPath($filePath);
514
+        if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
515
+            $fileId = $node->getFileId();
516
+            if (!is_null($fileId)) {
517
+                $this->server->httpResponse->setHeader('OC-FileId', $fileId);
518
+            }
519
+        }
520
+    }
521 521
 }
Please login to merge, or discard this patch.
apps/dav/lib/Connector/Sabre/AnonymousOptionsPlugin.php 1 patch
Indentation   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -34,50 +34,50 @@
 block discarded – undo
34 34
 
35 35
 class AnonymousOptionsPlugin extends ServerPlugin {
36 36
 
37
-	/**
38
-	 * @var \Sabre\DAV\Server
39
-	 */
40
-	private $server;
37
+    /**
38
+     * @var \Sabre\DAV\Server
39
+     */
40
+    private $server;
41 41
 
42
-	/**
43
-	 * @param \Sabre\DAV\Server $server
44
-	 * @return void
45
-	 */
46
-	public function initialize(\Sabre\DAV\Server $server) {
47
-		$this->server = $server;
48
-		// before auth
49
-		$this->server->on('beforeMethod', [$this, 'handleAnonymousOptions'], 9);
50
-	}
42
+    /**
43
+     * @param \Sabre\DAV\Server $server
44
+     * @return void
45
+     */
46
+    public function initialize(\Sabre\DAV\Server $server) {
47
+        $this->server = $server;
48
+        // before auth
49
+        $this->server->on('beforeMethod', [$this, 'handleAnonymousOptions'], 9);
50
+    }
51 51
 
52
-	/**
53
-	 * @return bool
54
-	 */
55
-	public function isRequestInRoot($path) {
56
-		return $path === '' || (is_string($path) && strpos($path, '/') === false);
57
-	}
52
+    /**
53
+     * @return bool
54
+     */
55
+    public function isRequestInRoot($path) {
56
+        return $path === '' || (is_string($path) && strpos($path, '/') === false);
57
+    }
58 58
 
59
-	/**
60
-	 * @throws \Sabre\DAV\Exception\Forbidden
61
-	 * @return bool
62
-	 */
63
-	public function handleAnonymousOptions(RequestInterface $request, ResponseInterface $response) {
64
-		$isOffice = preg_match('/Microsoft Office/i', $request->getHeader('User-Agent'));
65
-		$emptyAuth = $request->getHeader('Authorization') === null
66
-			|| $request->getHeader('Authorization') === ''
67
-			|| trim($request->getHeader('Authorization')) === 'Bearer';
68
-		$isAnonymousOption = $request->getMethod() === 'OPTIONS' && $emptyAuth;
69
-		$isOfficeHead = $request->getMethod() === 'HEAD' && $isOffice && $emptyAuth;
70
-		if ($isAnonymousOption || $isOfficeHead) {
71
-			/** @var CorePlugin $corePlugin */
72
-			$corePlugin = $this->server->getPlugin('core');
73
-			// setup a fake tree for anonymous access
74
-			$this->server->tree = new Tree(new Directory(''));
75
-			$corePlugin->httpOptions($request, $response);
76
-			$this->server->emit('afterMethod', [$request, $response]);
77
-			$this->server->emit('afterMethod:OPTIONS', [$request, $response]);
59
+    /**
60
+     * @throws \Sabre\DAV\Exception\Forbidden
61
+     * @return bool
62
+     */
63
+    public function handleAnonymousOptions(RequestInterface $request, ResponseInterface $response) {
64
+        $isOffice = preg_match('/Microsoft Office/i', $request->getHeader('User-Agent'));
65
+        $emptyAuth = $request->getHeader('Authorization') === null
66
+            || $request->getHeader('Authorization') === ''
67
+            || trim($request->getHeader('Authorization')) === 'Bearer';
68
+        $isAnonymousOption = $request->getMethod() === 'OPTIONS' && $emptyAuth;
69
+        $isOfficeHead = $request->getMethod() === 'HEAD' && $isOffice && $emptyAuth;
70
+        if ($isAnonymousOption || $isOfficeHead) {
71
+            /** @var CorePlugin $corePlugin */
72
+            $corePlugin = $this->server->getPlugin('core');
73
+            // setup a fake tree for anonymous access
74
+            $this->server->tree = new Tree(new Directory(''));
75
+            $corePlugin->httpOptions($request, $response);
76
+            $this->server->emit('afterMethod', [$request, $response]);
77
+            $this->server->emit('afterMethod:OPTIONS', [$request, $response]);
78 78
 
79
-			$this->server->sapi->sendResponse($response);
80
-			return false;
81
-		}
82
-	}
79
+            $this->server->sapi->sendResponse($response);
80
+            return false;
81
+        }
82
+    }
83 83
 }
Please login to merge, or discard this patch.
lib/private/legacy/util.php 1 patch
Indentation   +1395 added lines, -1395 removed lines patch added patch discarded remove patch
@@ -69,1405 +69,1405 @@
 block discarded – undo
69 69
 use OCP\IUser;
70 70
 
71 71
 class OC_Util {
72
-	public static $scripts = array();
73
-	public static $styles = array();
74
-	public static $headers = array();
75
-	private static $rootMounted = false;
76
-	private static $fsSetup = false;
77
-
78
-	/** @var array Local cache of version.php */
79
-	private static $versionCache = null;
80
-
81
-	protected static function getAppManager() {
82
-		return \OC::$server->getAppManager();
83
-	}
84
-
85
-	private static function initLocalStorageRootFS() {
86
-		// mount local file backend as root
87
-		$configDataDirectory = \OC::$server->getSystemConfig()->getValue("datadirectory", OC::$SERVERROOT . "/data");
88
-		//first set up the local "root" storage
89
-		\OC\Files\Filesystem::initMountManager();
90
-		if (!self::$rootMounted) {
91
-			\OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $configDataDirectory), '/');
92
-			self::$rootMounted = true;
93
-		}
94
-	}
95
-
96
-	/**
97
-	 * mounting an object storage as the root fs will in essence remove the
98
-	 * necessity of a data folder being present.
99
-	 * TODO make home storage aware of this and use the object storage instead of local disk access
100
-	 *
101
-	 * @param array $config containing 'class' and optional 'arguments'
102
-	 * @suppress PhanDeprecatedFunction
103
-	 */
104
-	private static function initObjectStoreRootFS($config) {
105
-		// check misconfiguration
106
-		if (empty($config['class'])) {
107
-			\OCP\Util::writeLog('files', 'No class given for objectstore', ILogger::ERROR);
108
-		}
109
-		if (!isset($config['arguments'])) {
110
-			$config['arguments'] = array();
111
-		}
112
-
113
-		// instantiate object store implementation
114
-		$name = $config['class'];
115
-		if (strpos($name, 'OCA\\') === 0 && substr_count($name, '\\') >= 2) {
116
-			$segments = explode('\\', $name);
117
-			OC_App::loadApp(strtolower($segments[1]));
118
-		}
119
-		$config['arguments']['objectstore'] = new $config['class']($config['arguments']);
120
-		// mount with plain / root object store implementation
121
-		$config['class'] = '\OC\Files\ObjectStore\ObjectStoreStorage';
122
-
123
-		// mount object storage as root
124
-		\OC\Files\Filesystem::initMountManager();
125
-		if (!self::$rootMounted) {
126
-			\OC\Files\Filesystem::mount($config['class'], $config['arguments'], '/');
127
-			self::$rootMounted = true;
128
-		}
129
-	}
130
-
131
-	/**
132
-	 * mounting an object storage as the root fs will in essence remove the
133
-	 * necessity of a data folder being present.
134
-	 *
135
-	 * @param array $config containing 'class' and optional 'arguments'
136
-	 * @suppress PhanDeprecatedFunction
137
-	 */
138
-	private static function initObjectStoreMultibucketRootFS($config) {
139
-		// check misconfiguration
140
-		if (empty($config['class'])) {
141
-			\OCP\Util::writeLog('files', 'No class given for objectstore', ILogger::ERROR);
142
-		}
143
-		if (!isset($config['arguments'])) {
144
-			$config['arguments'] = array();
145
-		}
146
-
147
-		// instantiate object store implementation
148
-		$name = $config['class'];
149
-		if (strpos($name, 'OCA\\') === 0 && substr_count($name, '\\') >= 2) {
150
-			$segments = explode('\\', $name);
151
-			OC_App::loadApp(strtolower($segments[1]));
152
-		}
153
-
154
-		if (!isset($config['arguments']['bucket'])) {
155
-			$config['arguments']['bucket'] = '';
156
-		}
157
-		// put the root FS always in first bucket for multibucket configuration
158
-		$config['arguments']['bucket'] .= '0';
159
-
160
-		$config['arguments']['objectstore'] = new $config['class']($config['arguments']);
161
-		// mount with plain / root object store implementation
162
-		$config['class'] = '\OC\Files\ObjectStore\ObjectStoreStorage';
163
-
164
-		// mount object storage as root
165
-		\OC\Files\Filesystem::initMountManager();
166
-		if (!self::$rootMounted) {
167
-			\OC\Files\Filesystem::mount($config['class'], $config['arguments'], '/');
168
-			self::$rootMounted = true;
169
-		}
170
-	}
171
-
172
-	/**
173
-	 * Can be set up
174
-	 *
175
-	 * @param string $user
176
-	 * @return boolean
177
-	 * @description configure the initial filesystem based on the configuration
178
-	 * @suppress PhanDeprecatedFunction
179
-	 * @suppress PhanAccessMethodInternal
180
-	 */
181
-	public static function setupFS($user = '') {
182
-		//setting up the filesystem twice can only lead to trouble
183
-		if (self::$fsSetup) {
184
-			return false;
185
-		}
186
-
187
-		\OC::$server->getEventLogger()->start('setup_fs', 'Setup filesystem');
188
-
189
-		// If we are not forced to load a specific user we load the one that is logged in
190
-		if ($user === null) {
191
-			$user = '';
192
-		} else if ($user == "" && \OC::$server->getUserSession()->isLoggedIn()) {
193
-			$user = OC_User::getUser();
194
-		}
195
-
196
-		// load all filesystem apps before, so no setup-hook gets lost
197
-		OC_App::loadApps(array('filesystem'));
198
-
199
-		// the filesystem will finish when $user is not empty,
200
-		// mark fs setup here to avoid doing the setup from loading
201
-		// OC_Filesystem
202
-		if ($user != '') {
203
-			self::$fsSetup = true;
204
-		}
205
-
206
-		\OC\Files\Filesystem::initMountManager();
207
-
208
-		$prevLogging = \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper(false);
209
-		\OC\Files\Filesystem::addStorageWrapper('mount_options', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) {
210
-			if ($storage->instanceOfStorage('\OC\Files\Storage\Common')) {
211
-				/** @var \OC\Files\Storage\Common $storage */
212
-				$storage->setMountOptions($mount->getOptions());
213
-			}
214
-			return $storage;
215
-		});
216
-
217
-		\OC\Files\Filesystem::addStorageWrapper('enable_sharing', function ($mountPoint, \OCP\Files\Storage\IStorage $storage, \OCP\Files\Mount\IMountPoint $mount) {
218
-			if (!$mount->getOption('enable_sharing', true)) {
219
-				return new \OC\Files\Storage\Wrapper\PermissionsMask([
220
-					'storage' => $storage,
221
-					'mask' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_SHARE
222
-				]);
223
-			}
224
-			return $storage;
225
-		});
226
-
227
-		// install storage availability wrapper, before most other wrappers
228
-		\OC\Files\Filesystem::addStorageWrapper('oc_availability', function ($mountPoint, \OCP\Files\Storage\IStorage $storage) {
229
-			if (!$storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage') && !$storage->isLocal()) {
230
-				return new \OC\Files\Storage\Wrapper\Availability(['storage' => $storage]);
231
-			}
232
-			return $storage;
233
-		});
234
-
235
-		\OC\Files\Filesystem::addStorageWrapper('oc_encoding', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) {
236
-			if ($mount->getOption('encoding_compatibility', false) && !$storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage') && !$storage->isLocal()) {
237
-				return new \OC\Files\Storage\Wrapper\Encoding(['storage' => $storage]);
238
-			}
239
-			return $storage;
240
-		});
241
-
242
-		\OC\Files\Filesystem::addStorageWrapper('oc_quota', function ($mountPoint, $storage) {
243
-			// set up quota for home storages, even for other users
244
-			// which can happen when using sharing
245
-
246
-			/**
247
-			 * @var \OC\Files\Storage\Storage $storage
248
-			 */
249
-			if ($storage->instanceOfStorage('\OC\Files\Storage\Home')
250
-				|| $storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage')
251
-			) {
252
-				/** @var \OC\Files\Storage\Home $storage */
253
-				if (is_object($storage->getUser())) {
254
-					$user = $storage->getUser()->getUID();
255
-					$quota = OC_Util::getUserQuota($user);
256
-					if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
257
-						return new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => $quota, 'root' => 'files'));
258
-					}
259
-				}
260
-			}
261
-
262
-			return $storage;
263
-		});
264
-
265
-		\OC\Files\Filesystem::addStorageWrapper('readonly', function ($mountPoint, \OCP\Files\Storage\IStorage $storage, \OCP\Files\Mount\IMountPoint $mount) {
266
-			/*
72
+    public static $scripts = array();
73
+    public static $styles = array();
74
+    public static $headers = array();
75
+    private static $rootMounted = false;
76
+    private static $fsSetup = false;
77
+
78
+    /** @var array Local cache of version.php */
79
+    private static $versionCache = null;
80
+
81
+    protected static function getAppManager() {
82
+        return \OC::$server->getAppManager();
83
+    }
84
+
85
+    private static function initLocalStorageRootFS() {
86
+        // mount local file backend as root
87
+        $configDataDirectory = \OC::$server->getSystemConfig()->getValue("datadirectory", OC::$SERVERROOT . "/data");
88
+        //first set up the local "root" storage
89
+        \OC\Files\Filesystem::initMountManager();
90
+        if (!self::$rootMounted) {
91
+            \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $configDataDirectory), '/');
92
+            self::$rootMounted = true;
93
+        }
94
+    }
95
+
96
+    /**
97
+     * mounting an object storage as the root fs will in essence remove the
98
+     * necessity of a data folder being present.
99
+     * TODO make home storage aware of this and use the object storage instead of local disk access
100
+     *
101
+     * @param array $config containing 'class' and optional 'arguments'
102
+     * @suppress PhanDeprecatedFunction
103
+     */
104
+    private static function initObjectStoreRootFS($config) {
105
+        // check misconfiguration
106
+        if (empty($config['class'])) {
107
+            \OCP\Util::writeLog('files', 'No class given for objectstore', ILogger::ERROR);
108
+        }
109
+        if (!isset($config['arguments'])) {
110
+            $config['arguments'] = array();
111
+        }
112
+
113
+        // instantiate object store implementation
114
+        $name = $config['class'];
115
+        if (strpos($name, 'OCA\\') === 0 && substr_count($name, '\\') >= 2) {
116
+            $segments = explode('\\', $name);
117
+            OC_App::loadApp(strtolower($segments[1]));
118
+        }
119
+        $config['arguments']['objectstore'] = new $config['class']($config['arguments']);
120
+        // mount with plain / root object store implementation
121
+        $config['class'] = '\OC\Files\ObjectStore\ObjectStoreStorage';
122
+
123
+        // mount object storage as root
124
+        \OC\Files\Filesystem::initMountManager();
125
+        if (!self::$rootMounted) {
126
+            \OC\Files\Filesystem::mount($config['class'], $config['arguments'], '/');
127
+            self::$rootMounted = true;
128
+        }
129
+    }
130
+
131
+    /**
132
+     * mounting an object storage as the root fs will in essence remove the
133
+     * necessity of a data folder being present.
134
+     *
135
+     * @param array $config containing 'class' and optional 'arguments'
136
+     * @suppress PhanDeprecatedFunction
137
+     */
138
+    private static function initObjectStoreMultibucketRootFS($config) {
139
+        // check misconfiguration
140
+        if (empty($config['class'])) {
141
+            \OCP\Util::writeLog('files', 'No class given for objectstore', ILogger::ERROR);
142
+        }
143
+        if (!isset($config['arguments'])) {
144
+            $config['arguments'] = array();
145
+        }
146
+
147
+        // instantiate object store implementation
148
+        $name = $config['class'];
149
+        if (strpos($name, 'OCA\\') === 0 && substr_count($name, '\\') >= 2) {
150
+            $segments = explode('\\', $name);
151
+            OC_App::loadApp(strtolower($segments[1]));
152
+        }
153
+
154
+        if (!isset($config['arguments']['bucket'])) {
155
+            $config['arguments']['bucket'] = '';
156
+        }
157
+        // put the root FS always in first bucket for multibucket configuration
158
+        $config['arguments']['bucket'] .= '0';
159
+
160
+        $config['arguments']['objectstore'] = new $config['class']($config['arguments']);
161
+        // mount with plain / root object store implementation
162
+        $config['class'] = '\OC\Files\ObjectStore\ObjectStoreStorage';
163
+
164
+        // mount object storage as root
165
+        \OC\Files\Filesystem::initMountManager();
166
+        if (!self::$rootMounted) {
167
+            \OC\Files\Filesystem::mount($config['class'], $config['arguments'], '/');
168
+            self::$rootMounted = true;
169
+        }
170
+    }
171
+
172
+    /**
173
+     * Can be set up
174
+     *
175
+     * @param string $user
176
+     * @return boolean
177
+     * @description configure the initial filesystem based on the configuration
178
+     * @suppress PhanDeprecatedFunction
179
+     * @suppress PhanAccessMethodInternal
180
+     */
181
+    public static function setupFS($user = '') {
182
+        //setting up the filesystem twice can only lead to trouble
183
+        if (self::$fsSetup) {
184
+            return false;
185
+        }
186
+
187
+        \OC::$server->getEventLogger()->start('setup_fs', 'Setup filesystem');
188
+
189
+        // If we are not forced to load a specific user we load the one that is logged in
190
+        if ($user === null) {
191
+            $user = '';
192
+        } else if ($user == "" && \OC::$server->getUserSession()->isLoggedIn()) {
193
+            $user = OC_User::getUser();
194
+        }
195
+
196
+        // load all filesystem apps before, so no setup-hook gets lost
197
+        OC_App::loadApps(array('filesystem'));
198
+
199
+        // the filesystem will finish when $user is not empty,
200
+        // mark fs setup here to avoid doing the setup from loading
201
+        // OC_Filesystem
202
+        if ($user != '') {
203
+            self::$fsSetup = true;
204
+        }
205
+
206
+        \OC\Files\Filesystem::initMountManager();
207
+
208
+        $prevLogging = \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper(false);
209
+        \OC\Files\Filesystem::addStorageWrapper('mount_options', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) {
210
+            if ($storage->instanceOfStorage('\OC\Files\Storage\Common')) {
211
+                /** @var \OC\Files\Storage\Common $storage */
212
+                $storage->setMountOptions($mount->getOptions());
213
+            }
214
+            return $storage;
215
+        });
216
+
217
+        \OC\Files\Filesystem::addStorageWrapper('enable_sharing', function ($mountPoint, \OCP\Files\Storage\IStorage $storage, \OCP\Files\Mount\IMountPoint $mount) {
218
+            if (!$mount->getOption('enable_sharing', true)) {
219
+                return new \OC\Files\Storage\Wrapper\PermissionsMask([
220
+                    'storage' => $storage,
221
+                    'mask' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_SHARE
222
+                ]);
223
+            }
224
+            return $storage;
225
+        });
226
+
227
+        // install storage availability wrapper, before most other wrappers
228
+        \OC\Files\Filesystem::addStorageWrapper('oc_availability', function ($mountPoint, \OCP\Files\Storage\IStorage $storage) {
229
+            if (!$storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage') && !$storage->isLocal()) {
230
+                return new \OC\Files\Storage\Wrapper\Availability(['storage' => $storage]);
231
+            }
232
+            return $storage;
233
+        });
234
+
235
+        \OC\Files\Filesystem::addStorageWrapper('oc_encoding', function ($mountPoint, \OCP\Files\Storage $storage, \OCP\Files\Mount\IMountPoint $mount) {
236
+            if ($mount->getOption('encoding_compatibility', false) && !$storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage') && !$storage->isLocal()) {
237
+                return new \OC\Files\Storage\Wrapper\Encoding(['storage' => $storage]);
238
+            }
239
+            return $storage;
240
+        });
241
+
242
+        \OC\Files\Filesystem::addStorageWrapper('oc_quota', function ($mountPoint, $storage) {
243
+            // set up quota for home storages, even for other users
244
+            // which can happen when using sharing
245
+
246
+            /**
247
+             * @var \OC\Files\Storage\Storage $storage
248
+             */
249
+            if ($storage->instanceOfStorage('\OC\Files\Storage\Home')
250
+                || $storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage')
251
+            ) {
252
+                /** @var \OC\Files\Storage\Home $storage */
253
+                if (is_object($storage->getUser())) {
254
+                    $user = $storage->getUser()->getUID();
255
+                    $quota = OC_Util::getUserQuota($user);
256
+                    if ($quota !== \OCP\Files\FileInfo::SPACE_UNLIMITED) {
257
+                        return new \OC\Files\Storage\Wrapper\Quota(array('storage' => $storage, 'quota' => $quota, 'root' => 'files'));
258
+                    }
259
+                }
260
+            }
261
+
262
+            return $storage;
263
+        });
264
+
265
+        \OC\Files\Filesystem::addStorageWrapper('readonly', function ($mountPoint, \OCP\Files\Storage\IStorage $storage, \OCP\Files\Mount\IMountPoint $mount) {
266
+            /*
267 267
 			 * Do not allow any operations that modify the storage
268 268
 			 */
269
-			if ($mount->getOption('readonly', false)) {
270
-				return new \OC\Files\Storage\Wrapper\PermissionsMask([
271
-					'storage' => $storage,
272
-					'mask' => \OCP\Constants::PERMISSION_ALL & ~(
273
-						\OCP\Constants::PERMISSION_UPDATE |
274
-						\OCP\Constants::PERMISSION_CREATE |
275
-						\OCP\Constants::PERMISSION_DELETE
276
-					),
277
-				]);
278
-			}
279
-			return $storage;
280
-		});
281
-
282
-		OC_Hook::emit('OC_Filesystem', 'preSetup', array('user' => $user));
283
-
284
-		\OC\Files\Filesystem::logWarningWhenAddingStorageWrapper($prevLogging);
285
-
286
-		//check if we are using an object storage
287
-		$objectStore = \OC::$server->getSystemConfig()->getValue('objectstore', null);
288
-		$objectStoreMultibucket = \OC::$server->getSystemConfig()->getValue('objectstore_multibucket', null);
289
-
290
-		// use the same order as in ObjectHomeMountProvider
291
-		if (isset($objectStoreMultibucket)) {
292
-			self::initObjectStoreMultibucketRootFS($objectStoreMultibucket);
293
-		} elseif (isset($objectStore)) {
294
-			self::initObjectStoreRootFS($objectStore);
295
-		} else {
296
-			self::initLocalStorageRootFS();
297
-		}
298
-
299
-		if ($user != '' && !\OC::$server->getUserManager()->userExists($user)) {
300
-			\OC::$server->getEventLogger()->end('setup_fs');
301
-			return false;
302
-		}
303
-
304
-		//if we aren't logged in, there is no use to set up the filesystem
305
-		if ($user != "") {
306
-
307
-			$userDir = '/' . $user . '/files';
308
-
309
-			//jail the user into his "home" directory
310
-			\OC\Files\Filesystem::init($user, $userDir);
311
-
312
-			OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $userDir));
313
-		}
314
-		\OC::$server->getEventLogger()->end('setup_fs');
315
-		return true;
316
-	}
317
-
318
-	/**
319
-	 * check if a password is required for each public link
320
-	 *
321
-	 * @return boolean
322
-	 * @suppress PhanDeprecatedFunction
323
-	 */
324
-	public static function isPublicLinkPasswordRequired() {
325
-		$enforcePassword = \OC::$server->getConfig()->getAppValue('core', 'shareapi_enforce_links_password', 'no');
326
-		return $enforcePassword === 'yes';
327
-	}
328
-
329
-	/**
330
-	 * check if sharing is disabled for the current user
331
-	 * @param IConfig $config
332
-	 * @param IGroupManager $groupManager
333
-	 * @param IUser|null $user
334
-	 * @return bool
335
-	 */
336
-	public static function isSharingDisabledForUser(IConfig $config, IGroupManager $groupManager, $user) {
337
-		if ($config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
338
-			$groupsList = $config->getAppValue('core', 'shareapi_exclude_groups_list', '');
339
-			$excludedGroups = json_decode($groupsList);
340
-			if (is_null($excludedGroups)) {
341
-				$excludedGroups = explode(',', $groupsList);
342
-				$newValue = json_encode($excludedGroups);
343
-				$config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
344
-			}
345
-			$usersGroups = $groupManager->getUserGroupIds($user);
346
-			if (!empty($usersGroups)) {
347
-				$remainingGroups = array_diff($usersGroups, $excludedGroups);
348
-				// if the user is only in groups which are disabled for sharing then
349
-				// sharing is also disabled for the user
350
-				if (empty($remainingGroups)) {
351
-					return true;
352
-				}
353
-			}
354
-		}
355
-		return false;
356
-	}
357
-
358
-	/**
359
-	 * check if share API enforces a default expire date
360
-	 *
361
-	 * @return boolean
362
-	 * @suppress PhanDeprecatedFunction
363
-	 */
364
-	public static function isDefaultExpireDateEnforced() {
365
-		$isDefaultExpireDateEnabled = \OC::$server->getConfig()->getAppValue('core', 'shareapi_default_expire_date', 'no');
366
-		$enforceDefaultExpireDate = false;
367
-		if ($isDefaultExpireDateEnabled === 'yes') {
368
-			$value = \OC::$server->getConfig()->getAppValue('core', 'shareapi_enforce_expire_date', 'no');
369
-			$enforceDefaultExpireDate = $value === 'yes';
370
-		}
371
-
372
-		return $enforceDefaultExpireDate;
373
-	}
374
-
375
-	/**
376
-	 * Get the quota of a user
377
-	 *
378
-	 * @param string $userId
379
-	 * @return float Quota bytes
380
-	 */
381
-	public static function getUserQuota($userId) {
382
-		$user = \OC::$server->getUserManager()->get($userId);
383
-		if (is_null($user)) {
384
-			return \OCP\Files\FileInfo::SPACE_UNLIMITED;
385
-		}
386
-		$userQuota = $user->getQuota();
387
-		if($userQuota === 'none') {
388
-			return \OCP\Files\FileInfo::SPACE_UNLIMITED;
389
-		}
390
-		return OC_Helper::computerFileSize($userQuota);
391
-	}
392
-
393
-	/**
394
-	 * copies the skeleton to the users /files
395
-	 *
396
-	 * @param string $userId
397
-	 * @param \OCP\Files\Folder $userDirectory
398
-	 * @throws \OCP\Files\NotFoundException
399
-	 * @throws \OCP\Files\NotPermittedException
400
-	 * @suppress PhanDeprecatedFunction
401
-	 */
402
-	public static function copySkeleton($userId, \OCP\Files\Folder $userDirectory) {
403
-
404
-		$plainSkeletonDirectory = \OC::$server->getConfig()->getSystemValue('skeletondirectory', \OC::$SERVERROOT . '/core/skeleton');
405
-		$userLang = \OC::$server->getL10NFactory()->findLanguage();
406
-		$skeletonDirectory = str_replace('{lang}', $userLang, $plainSkeletonDirectory);
407
-
408
-		if (!file_exists($skeletonDirectory)) {
409
-			$dialectStart = strpos($userLang, '_');
410
-			if ($dialectStart !== false) {
411
-				$skeletonDirectory = str_replace('{lang}', substr($userLang, 0, $dialectStart), $plainSkeletonDirectory);
412
-			}
413
-			if ($dialectStart === false || !file_exists($skeletonDirectory)) {
414
-				$skeletonDirectory = str_replace('{lang}', 'default', $plainSkeletonDirectory);
415
-			}
416
-			if (!file_exists($skeletonDirectory)) {
417
-				$skeletonDirectory = '';
418
-			}
419
-		}
420
-
421
-		$instanceId = \OC::$server->getConfig()->getSystemValue('instanceid', '');
422
-
423
-		if ($instanceId === null) {
424
-			throw new \RuntimeException('no instance id!');
425
-		}
426
-		$appdata = 'appdata_' . $instanceId;
427
-		if ($userId === $appdata) {
428
-			throw new \RuntimeException('username is reserved name: ' . $appdata);
429
-		}
430
-
431
-		if (!empty($skeletonDirectory)) {
432
-			\OCP\Util::writeLog(
433
-				'files_skeleton',
434
-				'copying skeleton for '.$userId.' from '.$skeletonDirectory.' to '.$userDirectory->getFullPath('/'),
435
-				ILogger::DEBUG
436
-			);
437
-			self::copyr($skeletonDirectory, $userDirectory);
438
-			// update the file cache
439
-			$userDirectory->getStorage()->getScanner()->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE);
440
-		}
441
-	}
442
-
443
-	/**
444
-	 * copies a directory recursively by using streams
445
-	 *
446
-	 * @param string $source
447
-	 * @param \OCP\Files\Folder $target
448
-	 * @return void
449
-	 */
450
-	public static function copyr($source, \OCP\Files\Folder $target) {
451
-		$logger = \OC::$server->getLogger();
452
-
453
-		// Verify if folder exists
454
-		$dir = opendir($source);
455
-		if($dir === false) {
456
-			$logger->error(sprintf('Could not opendir "%s"', $source), ['app' => 'core']);
457
-			return;
458
-		}
459
-
460
-		// Copy the files
461
-		while (false !== ($file = readdir($dir))) {
462
-			if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
463
-				if (is_dir($source . '/' . $file)) {
464
-					$child = $target->newFolder($file);
465
-					self::copyr($source . '/' . $file, $child);
466
-				} else {
467
-					$child = $target->newFile($file);
468
-					$sourceStream = fopen($source . '/' . $file, 'r');
469
-					if($sourceStream === false) {
470
-						$logger->error(sprintf('Could not fopen "%s"', $source . '/' . $file), ['app' => 'core']);
471
-						closedir($dir);
472
-						return;
473
-					}
474
-					stream_copy_to_stream($sourceStream, $child->fopen('w'));
475
-				}
476
-			}
477
-		}
478
-		closedir($dir);
479
-	}
480
-
481
-	/**
482
-	 * @return void
483
-	 * @suppress PhanUndeclaredMethod
484
-	 */
485
-	public static function tearDownFS() {
486
-		\OC\Files\Filesystem::tearDown();
487
-		\OC::$server->getRootFolder()->clearCache();
488
-		self::$fsSetup = false;
489
-		self::$rootMounted = false;
490
-	}
491
-
492
-	/**
493
-	 * get the current installed version of ownCloud
494
-	 *
495
-	 * @return array
496
-	 */
497
-	public static function getVersion() {
498
-		OC_Util::loadVersion();
499
-		return self::$versionCache['OC_Version'];
500
-	}
501
-
502
-	/**
503
-	 * get the current installed version string of ownCloud
504
-	 *
505
-	 * @return string
506
-	 */
507
-	public static function getVersionString() {
508
-		OC_Util::loadVersion();
509
-		return self::$versionCache['OC_VersionString'];
510
-	}
511
-
512
-	/**
513
-	 * @deprecated the value is of no use anymore
514
-	 * @return string
515
-	 */
516
-	public static function getEditionString() {
517
-		return '';
518
-	}
519
-
520
-	/**
521
-	 * @description get the update channel of the current installed of ownCloud.
522
-	 * @return string
523
-	 */
524
-	public static function getChannel() {
525
-		OC_Util::loadVersion();
526
-		return \OC::$server->getConfig()->getSystemValue('updater.release.channel', self::$versionCache['OC_Channel']);
527
-	}
528
-
529
-	/**
530
-	 * @description get the build number of the current installed of ownCloud.
531
-	 * @return string
532
-	 */
533
-	public static function getBuild() {
534
-		OC_Util::loadVersion();
535
-		return self::$versionCache['OC_Build'];
536
-	}
537
-
538
-	/**
539
-	 * @description load the version.php into the session as cache
540
-	 * @suppress PhanUndeclaredVariable
541
-	 */
542
-	private static function loadVersion() {
543
-		if (self::$versionCache !== null) {
544
-			return;
545
-		}
546
-
547
-		$timestamp = filemtime(OC::$SERVERROOT . '/version.php');
548
-		require OC::$SERVERROOT . '/version.php';
549
-		/** @var $timestamp int */
550
-		self::$versionCache['OC_Version_Timestamp'] = $timestamp;
551
-		/** @var $OC_Version string */
552
-		self::$versionCache['OC_Version'] = $OC_Version;
553
-		/** @var $OC_VersionString string */
554
-		self::$versionCache['OC_VersionString'] = $OC_VersionString;
555
-		/** @var $OC_Build string */
556
-		self::$versionCache['OC_Build'] = $OC_Build;
557
-
558
-		/** @var $OC_Channel string */
559
-		self::$versionCache['OC_Channel'] = $OC_Channel;
560
-	}
561
-
562
-	/**
563
-	 * generates a path for JS/CSS files. If no application is provided it will create the path for core.
564
-	 *
565
-	 * @param string $application application to get the files from
566
-	 * @param string $directory directory within this application (css, js, vendor, etc)
567
-	 * @param string $file the file inside of the above folder
568
-	 * @return string the path
569
-	 */
570
-	private static function generatePath($application, $directory, $file) {
571
-		if (is_null($file)) {
572
-			$file = $application;
573
-			$application = "";
574
-		}
575
-		if (!empty($application)) {
576
-			return "$application/$directory/$file";
577
-		} else {
578
-			return "$directory/$file";
579
-		}
580
-	}
581
-
582
-	/**
583
-	 * add a javascript file
584
-	 *
585
-	 * @param string $application application id
586
-	 * @param string|null $file filename
587
-	 * @param bool $prepend prepend the Script to the beginning of the list
588
-	 * @return void
589
-	 */
590
-	public static function addScript($application, $file = null, $prepend = false) {
591
-		$path = OC_Util::generatePath($application, 'js', $file);
592
-
593
-		// core js files need separate handling
594
-		if ($application !== 'core' && $file !== null) {
595
-			self::addTranslations ( $application );
596
-		}
597
-		self::addExternalResource($application, $prepend, $path, "script");
598
-	}
599
-
600
-	/**
601
-	 * add a javascript file from the vendor sub folder
602
-	 *
603
-	 * @param string $application application id
604
-	 * @param string|null $file filename
605
-	 * @param bool $prepend prepend the Script to the beginning of the list
606
-	 * @return void
607
-	 */
608
-	public static function addVendorScript($application, $file = null, $prepend = false) {
609
-		$path = OC_Util::generatePath($application, 'vendor', $file);
610
-		self::addExternalResource($application, $prepend, $path, "script");
611
-	}
612
-
613
-	/**
614
-	 * add a translation JS file
615
-	 *
616
-	 * @param string $application application id
617
-	 * @param string|null $languageCode language code, defaults to the current language
618
-	 * @param bool|null $prepend prepend the Script to the beginning of the list
619
-	 */
620
-	public static function addTranslations($application, $languageCode = null, $prepend = false) {
621
-		if (is_null($languageCode)) {
622
-			$languageCode = \OC::$server->getL10NFactory()->findLanguage($application);
623
-		}
624
-		if (!empty($application)) {
625
-			$path = "$application/l10n/$languageCode";
626
-		} else {
627
-			$path = "l10n/$languageCode";
628
-		}
629
-		self::addExternalResource($application, $prepend, $path, "script");
630
-	}
631
-
632
-	/**
633
-	 * add a css file
634
-	 *
635
-	 * @param string $application application id
636
-	 * @param string|null $file filename
637
-	 * @param bool $prepend prepend the Style to the beginning of the list
638
-	 * @return void
639
-	 */
640
-	public static function addStyle($application, $file = null, $prepend = false) {
641
-		$path = OC_Util::generatePath($application, 'css', $file);
642
-		self::addExternalResource($application, $prepend, $path, "style");
643
-	}
644
-
645
-	/**
646
-	 * add a css file from the vendor sub folder
647
-	 *
648
-	 * @param string $application application id
649
-	 * @param string|null $file filename
650
-	 * @param bool $prepend prepend the Style to the beginning of the list
651
-	 * @return void
652
-	 */
653
-	public static function addVendorStyle($application, $file = null, $prepend = false) {
654
-		$path = OC_Util::generatePath($application, 'vendor', $file);
655
-		self::addExternalResource($application, $prepend, $path, "style");
656
-	}
657
-
658
-	/**
659
-	 * add an external resource css/js file
660
-	 *
661
-	 * @param string $application application id
662
-	 * @param bool $prepend prepend the file to the beginning of the list
663
-	 * @param string $path
664
-	 * @param string $type (script or style)
665
-	 * @return void
666
-	 */
667
-	private static function addExternalResource($application, $prepend, $path, $type = "script") {
668
-
669
-		if ($type === "style") {
670
-			if (!in_array($path, self::$styles)) {
671
-				if ($prepend === true) {
672
-					array_unshift ( self::$styles, $path );
673
-				} else {
674
-					self::$styles[] = $path;
675
-				}
676
-			}
677
-		} elseif ($type === "script") {
678
-			if (!in_array($path, self::$scripts)) {
679
-				if ($prepend === true) {
680
-					array_unshift ( self::$scripts, $path );
681
-				} else {
682
-					self::$scripts [] = $path;
683
-				}
684
-			}
685
-		}
686
-	}
687
-
688
-	/**
689
-	 * Add a custom element to the header
690
-	 * If $text is null then the element will be written as empty element.
691
-	 * So use "" to get a closing tag.
692
-	 * @param string $tag tag name of the element
693
-	 * @param array $attributes array of attributes for the element
694
-	 * @param string $text the text content for the element
695
-	 * @param bool $prepend prepend the header to the beginning of the list
696
-	 */
697
-	public static function addHeader($tag, $attributes, $text = null, $prepend = false) {
698
-		$header = array(
699
-			'tag' => $tag,
700
-			'attributes' => $attributes,
701
-			'text' => $text
702
-		);
703
-		if ($prepend === true) {
704
-			array_unshift (self::$headers, $header);
705
-
706
-		} else {
707
-			self::$headers[] = $header;
708
-		}
709
-	}
710
-
711
-	/**
712
-	 * check if the current server configuration is suitable for ownCloud
713
-	 *
714
-	 * @param \OC\SystemConfig $config
715
-	 * @return array arrays with error messages and hints
716
-	 */
717
-	public static function checkServer(\OC\SystemConfig $config) {
718
-		$l = \OC::$server->getL10N('lib');
719
-		$errors = array();
720
-		$CONFIG_DATADIRECTORY = $config->getValue('datadirectory', OC::$SERVERROOT . '/data');
721
-
722
-		if (!self::needUpgrade($config) && $config->getValue('installed', false)) {
723
-			// this check needs to be done every time
724
-			$errors = self::checkDataDirectoryValidity($CONFIG_DATADIRECTORY);
725
-		}
726
-
727
-		// Assume that if checkServer() succeeded before in this session, then all is fine.
728
-		if (\OC::$server->getSession()->exists('checkServer_succeeded') && \OC::$server->getSession()->get('checkServer_succeeded')) {
729
-			return $errors;
730
-		}
731
-
732
-		$webServerRestart = false;
733
-		$setup = new \OC\Setup(
734
-			$config,
735
-			\OC::$server->getIniWrapper(),
736
-			\OC::$server->getL10N('lib'),
737
-			\OC::$server->query(\OCP\Defaults::class),
738
-			\OC::$server->getLogger(),
739
-			\OC::$server->getSecureRandom(),
740
-			\OC::$server->query(\OC\Installer::class)
741
-		);
742
-
743
-		$urlGenerator = \OC::$server->getURLGenerator();
744
-
745
-		$availableDatabases = $setup->getSupportedDatabases();
746
-		if (empty($availableDatabases)) {
747
-			$errors[] = array(
748
-				'error' => $l->t('No database drivers (sqlite, mysql, or postgresql) installed.'),
749
-				'hint' => '' //TODO: sane hint
750
-			);
751
-			$webServerRestart = true;
752
-		}
753
-
754
-		// Check if config folder is writable.
755
-		if(!OC_Helper::isReadOnlyConfigEnabled()) {
756
-			if (!is_writable(OC::$configDir) or !is_readable(OC::$configDir)) {
757
-				$errors[] = array(
758
-					'error' => $l->t('Cannot write into "config" directory'),
759
-					'hint' => $l->t('This can usually be fixed by giving the webserver write access to the config directory. See %s',
760
-						[ $urlGenerator->linkToDocs('admin-dir_permissions') ]) . '. '
761
-						. $l->t('Or, if you prefer to keep config.php file read only, set the option "config_is_read_only" to true in it. See %s',
762
-						[ $urlGenerator->linkToDocs('admin-config') ] )
763
-				);
764
-			}
765
-		}
766
-
767
-		// Check if there is a writable install folder.
768
-		if ($config->getValue('appstoreenabled', true)) {
769
-			if (OC_App::getInstallPath() === null
770
-				|| !is_writable(OC_App::getInstallPath())
771
-				|| !is_readable(OC_App::getInstallPath())
772
-			) {
773
-				$errors[] = array(
774
-					'error' => $l->t('Cannot write into "apps" directory'),
775
-					'hint' => $l->t('This can usually be fixed by giving the webserver write access to the apps directory'
776
-						. ' or disabling the appstore in the config file. See %s',
777
-						[$urlGenerator->linkToDocs('admin-dir_permissions')])
778
-				);
779
-			}
780
-		}
781
-		// Create root dir.
782
-		if ($config->getValue('installed', false)) {
783
-			if (!is_dir($CONFIG_DATADIRECTORY)) {
784
-				$success = @mkdir($CONFIG_DATADIRECTORY);
785
-				if ($success) {
786
-					$errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY));
787
-				} else {
788
-					$errors[] = [
789
-						'error' => $l->t('Cannot create "data" directory'),
790
-						'hint' => $l->t('This can usually be fixed by giving the webserver write access to the root directory. See %s',
791
-							[$urlGenerator->linkToDocs('admin-dir_permissions')])
792
-					];
793
-				}
794
-			} else if (!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) {
795
-				// is_writable doesn't work for NFS mounts, so try to write a file and check if it exists.
796
-				$testFile = sprintf('%s/%s.tmp', $CONFIG_DATADIRECTORY, uniqid('data_dir_writability_test_'));
797
-				$handle = fopen($testFile, 'w');
798
-				if (!$handle || fwrite($handle, 'Test write operation') === false) {
799
-					$permissionsHint = $l->t('Permissions can usually be fixed by giving the webserver write access to the root directory. See %s.',
800
-						[$urlGenerator->linkToDocs('admin-dir_permissions')]);
801
-					$errors[] = [
802
-						'error' => 'Your data directory is not writable',
803
-						'hint' => $permissionsHint
804
-					];
805
-				} else {
806
-					fclose($handle);
807
-					unlink($testFile);
808
-				}
809
-			} else {
810
-				$errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY));
811
-			}
812
-		}
813
-
814
-		if (!OC_Util::isSetLocaleWorking()) {
815
-			$errors[] = array(
816
-				'error' => $l->t('Setting locale to %s failed',
817
-					array('en_US.UTF-8/fr_FR.UTF-8/es_ES.UTF-8/de_DE.UTF-8/ru_RU.UTF-8/'
818
-						. 'pt_BR.UTF-8/it_IT.UTF-8/ja_JP.UTF-8/zh_CN.UTF-8')),
819
-				'hint' => $l->t('Please install one of these locales on your system and restart your webserver.')
820
-			);
821
-		}
822
-
823
-		// Contains the dependencies that should be checked against
824
-		// classes = class_exists
825
-		// functions = function_exists
826
-		// defined = defined
827
-		// ini = ini_get
828
-		// If the dependency is not found the missing module name is shown to the EndUser
829
-		// When adding new checks always verify that they pass on Travis as well
830
-		// for ini settings, see https://github.com/owncloud/administration/blob/master/travis-ci/custom.ini
831
-		$dependencies = array(
832
-			'classes' => array(
833
-				'ZipArchive' => 'zip',
834
-				'DOMDocument' => 'dom',
835
-				'XMLWriter' => 'XMLWriter',
836
-				'XMLReader' => 'XMLReader',
837
-			),
838
-			'functions' => [
839
-				'xml_parser_create' => 'libxml',
840
-				'mb_strcut' => 'mbstring',
841
-				'ctype_digit' => 'ctype',
842
-				'json_encode' => 'JSON',
843
-				'gd_info' => 'GD',
844
-				'gzencode' => 'zlib',
845
-				'iconv' => 'iconv',
846
-				'simplexml_load_string' => 'SimpleXML',
847
-				'hash' => 'HASH Message Digest Framework',
848
-				'curl_init' => 'cURL',
849
-				'openssl_verify' => 'OpenSSL',
850
-			],
851
-			'defined' => array(
852
-				'PDO::ATTR_DRIVER_NAME' => 'PDO'
853
-			),
854
-			'ini' => [
855
-				'default_charset' => 'UTF-8',
856
-			],
857
-		);
858
-		$missingDependencies = array();
859
-		$invalidIniSettings = [];
860
-		$moduleHint = $l->t('Please ask your server administrator to install the module.');
861
-
862
-		$iniWrapper = \OC::$server->getIniWrapper();
863
-		foreach ($dependencies['classes'] as $class => $module) {
864
-			if (!class_exists($class)) {
865
-				$missingDependencies[] = $module;
866
-			}
867
-		}
868
-		foreach ($dependencies['functions'] as $function => $module) {
869
-			if (!function_exists($function)) {
870
-				$missingDependencies[] = $module;
871
-			}
872
-		}
873
-		foreach ($dependencies['defined'] as $defined => $module) {
874
-			if (!defined($defined)) {
875
-				$missingDependencies[] = $module;
876
-			}
877
-		}
878
-		foreach ($dependencies['ini'] as $setting => $expected) {
879
-			if (is_bool($expected)) {
880
-				if ($iniWrapper->getBool($setting) !== $expected) {
881
-					$invalidIniSettings[] = [$setting, $expected];
882
-				}
883
-			}
884
-			if (is_int($expected)) {
885
-				if ($iniWrapper->getNumeric($setting) !== $expected) {
886
-					$invalidIniSettings[] = [$setting, $expected];
887
-				}
888
-			}
889
-			if (is_string($expected)) {
890
-				if (strtolower($iniWrapper->getString($setting)) !== strtolower($expected)) {
891
-					$invalidIniSettings[] = [$setting, $expected];
892
-				}
893
-			}
894
-		}
895
-
896
-		foreach($missingDependencies as $missingDependency) {
897
-			$errors[] = array(
898
-				'error' => $l->t('PHP module %s not installed.', array($missingDependency)),
899
-				'hint' => $moduleHint
900
-			);
901
-			$webServerRestart = true;
902
-		}
903
-		foreach($invalidIniSettings as $setting) {
904
-			if(is_bool($setting[1])) {
905
-				$setting[1] = $setting[1] ? 'on' : 'off';
906
-			}
907
-			$errors[] = [
908
-				'error' => $l->t('PHP setting "%s" is not set to "%s".', [$setting[0], var_export($setting[1], true)]),
909
-				'hint' =>  $l->t('Adjusting this setting in php.ini will make Nextcloud run again')
910
-			];
911
-			$webServerRestart = true;
912
-		}
913
-
914
-		/**
915
-		 * The mbstring.func_overload check can only be performed if the mbstring
916
-		 * module is installed as it will return null if the checking setting is
917
-		 * not available and thus a check on the boolean value fails.
918
-		 *
919
-		 * TODO: Should probably be implemented in the above generic dependency
920
-		 *       check somehow in the long-term.
921
-		 */
922
-		if($iniWrapper->getBool('mbstring.func_overload') !== null &&
923
-			$iniWrapper->getBool('mbstring.func_overload') === true) {
924
-			$errors[] = array(
925
-				'error' => $l->t('mbstring.func_overload is set to "%s" instead of the expected value "0"', [$iniWrapper->getString('mbstring.func_overload')]),
926
-				'hint' => $l->t('To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini')
927
-			);
928
-		}
929
-
930
-		if(function_exists('xml_parser_create') &&
931
-			LIBXML_LOADED_VERSION < 20700 ) {
932
-			$version = LIBXML_LOADED_VERSION;
933
-			$major = floor($version/10000);
934
-			$version -= ($major * 10000);
935
-			$minor = floor($version/100);
936
-			$version -= ($minor * 100);
937
-			$patch = $version;
938
-			$errors[] = array(
939
-				'error' => $l->t('libxml2 2.7.0 is at least required. Currently %s is installed.', [$major . '.' . $minor . '.' . $patch]),
940
-				'hint' => $l->t('To fix this issue update your libxml2 version and restart your web server.')
941
-			);
942
-		}
943
-
944
-		if (!self::isAnnotationsWorking()) {
945
-			$errors[] = array(
946
-				'error' => $l->t('PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible.'),
947
-				'hint' => $l->t('This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator.')
948
-			);
949
-		}
950
-
951
-		if (!\OC::$CLI && $webServerRestart) {
952
-			$errors[] = array(
953
-				'error' => $l->t('PHP modules have been installed, but they are still listed as missing?'),
954
-				'hint' => $l->t('Please ask your server administrator to restart the web server.')
955
-			);
956
-		}
957
-
958
-		$errors = array_merge($errors, self::checkDatabaseVersion());
959
-
960
-		// Cache the result of this function
961
-		\OC::$server->getSession()->set('checkServer_succeeded', count($errors) == 0);
962
-
963
-		return $errors;
964
-	}
965
-
966
-	/**
967
-	 * Check the database version
968
-	 *
969
-	 * @return array errors array
970
-	 */
971
-	public static function checkDatabaseVersion() {
972
-		$l = \OC::$server->getL10N('lib');
973
-		$errors = array();
974
-		$dbType = \OC::$server->getSystemConfig()->getValue('dbtype', 'sqlite');
975
-		if ($dbType === 'pgsql') {
976
-			// check PostgreSQL version
977
-			try {
978
-				$result = \OC_DB::executeAudited('SHOW SERVER_VERSION');
979
-				$data = $result->fetchRow();
980
-				if (isset($data['server_version'])) {
981
-					$version = $data['server_version'];
982
-					if (version_compare($version, '9.0.0', '<')) {
983
-						$errors[] = array(
984
-							'error' => $l->t('PostgreSQL >= 9 required'),
985
-							'hint' => $l->t('Please upgrade your database version')
986
-						);
987
-					}
988
-				}
989
-			} catch (\Doctrine\DBAL\DBALException $e) {
990
-				$logger = \OC::$server->getLogger();
991
-				$logger->warning('Error occurred while checking PostgreSQL version, assuming >= 9');
992
-				$logger->logException($e);
993
-			}
994
-		}
995
-		return $errors;
996
-	}
997
-
998
-	/**
999
-	 * Check for correct file permissions of data directory
1000
-	 *
1001
-	 * @param string $dataDirectory
1002
-	 * @return array arrays with error messages and hints
1003
-	 */
1004
-	public static function checkDataDirectoryPermissions($dataDirectory) {
1005
-		if(\OC::$server->getConfig()->getSystemValue('check_data_directory_permissions', true) === false) {
1006
-			return  [];
1007
-		}
1008
-		$l = \OC::$server->getL10N('lib');
1009
-		$errors = [];
1010
-		$permissionsModHint = $l->t('Please change the permissions to 0770 so that the directory'
1011
-			. ' cannot be listed by other users.');
1012
-		$perms = substr(decoct(@fileperms($dataDirectory)), -3);
1013
-		if (substr($perms, -1) !== '0') {
1014
-			chmod($dataDirectory, 0770);
1015
-			clearstatcache();
1016
-			$perms = substr(decoct(@fileperms($dataDirectory)), -3);
1017
-			if ($perms[2] !== '0') {
1018
-				$errors[] = [
1019
-					'error' => $l->t('Your data directory is readable by other users'),
1020
-					'hint' => $permissionsModHint
1021
-				];
1022
-			}
1023
-		}
1024
-		return $errors;
1025
-	}
1026
-
1027
-	/**
1028
-	 * Check that the data directory exists and is valid by
1029
-	 * checking the existence of the ".ocdata" file.
1030
-	 *
1031
-	 * @param string $dataDirectory data directory path
1032
-	 * @return array errors found
1033
-	 */
1034
-	public static function checkDataDirectoryValidity($dataDirectory) {
1035
-		$l = \OC::$server->getL10N('lib');
1036
-		$errors = [];
1037
-		if ($dataDirectory[0] !== '/') {
1038
-			$errors[] = [
1039
-				'error' => $l->t('Your data directory must be an absolute path'),
1040
-				'hint' => $l->t('Check the value of "datadirectory" in your configuration')
1041
-			];
1042
-		}
1043
-		if (!file_exists($dataDirectory . '/.ocdata')) {
1044
-			$errors[] = [
1045
-				'error' => $l->t('Your data directory is invalid'),
1046
-				'hint' => $l->t('Ensure there is a file called ".ocdata"' .
1047
-					' in the root of the data directory.')
1048
-			];
1049
-		}
1050
-		return $errors;
1051
-	}
1052
-
1053
-	/**
1054
-	 * Check if the user is logged in, redirects to home if not. With
1055
-	 * redirect URL parameter to the request URI.
1056
-	 *
1057
-	 * @return void
1058
-	 */
1059
-	public static function checkLoggedIn() {
1060
-		// Check if we are a user
1061
-		if (!\OC::$server->getUserSession()->isLoggedIn()) {
1062
-			header('Location: ' . \OC::$server->getURLGenerator()->linkToRoute(
1063
-						'core.login.showLoginForm',
1064
-						[
1065
-							'redirect_url' => \OC::$server->getRequest()->getRequestUri(),
1066
-						]
1067
-					)
1068
-			);
1069
-			exit();
1070
-		}
1071
-		// Redirect to 2FA challenge selection if 2FA challenge was not solved yet
1072
-		if (\OC::$server->getTwoFactorAuthManager()->needsSecondFactor(\OC::$server->getUserSession()->getUser())) {
1073
-			header('Location: ' . \OC::$server->getURLGenerator()->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
1074
-			exit();
1075
-		}
1076
-	}
1077
-
1078
-	/**
1079
-	 * Check if the user is a admin, redirects to home if not
1080
-	 *
1081
-	 * @return void
1082
-	 */
1083
-	public static function checkAdminUser() {
1084
-		OC_Util::checkLoggedIn();
1085
-		if (!OC_User::isAdminUser(OC_User::getUser())) {
1086
-			header('Location: ' . \OCP\Util::linkToAbsolute('', 'index.php'));
1087
-			exit();
1088
-		}
1089
-	}
1090
-
1091
-	/**
1092
-	 * Returns the URL of the default page
1093
-	 * based on the system configuration and
1094
-	 * the apps visible for the current user
1095
-	 *
1096
-	 * @return string URL
1097
-	 * @suppress PhanDeprecatedFunction
1098
-	 */
1099
-	public static function getDefaultPageUrl() {
1100
-		$urlGenerator = \OC::$server->getURLGenerator();
1101
-		// Deny the redirect if the URL contains a @
1102
-		// This prevents unvalidated redirects like ?redirect_url=:[email protected]
1103
-		if (isset($_REQUEST['redirect_url']) && strpos($_REQUEST['redirect_url'], '@') === false) {
1104
-			$location = $urlGenerator->getAbsoluteURL(urldecode($_REQUEST['redirect_url']));
1105
-		} else {
1106
-			$defaultPage = \OC::$server->getConfig()->getAppValue('core', 'defaultpage');
1107
-			if ($defaultPage) {
1108
-				$location = $urlGenerator->getAbsoluteURL($defaultPage);
1109
-			} else {
1110
-				$appId = 'files';
1111
-				$config = \OC::$server->getConfig();
1112
-				$defaultApps = explode(',', $config->getSystemValue('defaultapp', 'files'));
1113
-				// find the first app that is enabled for the current user
1114
-				foreach ($defaultApps as $defaultApp) {
1115
-					$defaultApp = OC_App::cleanAppId(strip_tags($defaultApp));
1116
-					if (static::getAppManager()->isEnabledForUser($defaultApp)) {
1117
-						$appId = $defaultApp;
1118
-						break;
1119
-					}
1120
-				}
1121
-
1122
-				if($config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true') {
1123
-					$location = $urlGenerator->getAbsoluteURL('/apps/' . $appId . '/');
1124
-				} else {
1125
-					$location = $urlGenerator->getAbsoluteURL('/index.php/apps/' . $appId . '/');
1126
-				}
1127
-			}
1128
-		}
1129
-		return $location;
1130
-	}
1131
-
1132
-	/**
1133
-	 * Redirect to the user default page
1134
-	 *
1135
-	 * @return void
1136
-	 */
1137
-	public static function redirectToDefaultPage() {
1138
-		$location = self::getDefaultPageUrl();
1139
-		header('Location: ' . $location);
1140
-		exit();
1141
-	}
1142
-
1143
-	/**
1144
-	 * get an id unique for this instance
1145
-	 *
1146
-	 * @return string
1147
-	 */
1148
-	public static function getInstanceId() {
1149
-		$id = \OC::$server->getSystemConfig()->getValue('instanceid', null);
1150
-		if (is_null($id)) {
1151
-			// We need to guarantee at least one letter in instanceid so it can be used as the session_name
1152
-			$id = 'oc' . \OC::$server->getSecureRandom()->generate(10, \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_DIGITS);
1153
-			\OC::$server->getSystemConfig()->setValue('instanceid', $id);
1154
-		}
1155
-		return $id;
1156
-	}
1157
-
1158
-	/**
1159
-	 * Public function to sanitize HTML
1160
-	 *
1161
-	 * This function is used to sanitize HTML and should be applied on any
1162
-	 * string or array of strings before displaying it on a web page.
1163
-	 *
1164
-	 * @param string|array $value
1165
-	 * @return string|array an array of sanitized strings or a single sanitized string, depends on the input parameter.
1166
-	 */
1167
-	public static function sanitizeHTML($value) {
1168
-		if (is_array($value)) {
1169
-			$value = array_map(function($value) {
1170
-				return self::sanitizeHTML($value);
1171
-			}, $value);
1172
-		} else {
1173
-			// Specify encoding for PHP<5.4
1174
-			$value = htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
1175
-		}
1176
-		return $value;
1177
-	}
1178
-
1179
-	/**
1180
-	 * Public function to encode url parameters
1181
-	 *
1182
-	 * This function is used to encode path to file before output.
1183
-	 * Encoding is done according to RFC 3986 with one exception:
1184
-	 * Character '/' is preserved as is.
1185
-	 *
1186
-	 * @param string $component part of URI to encode
1187
-	 * @return string
1188
-	 */
1189
-	public static function encodePath($component) {
1190
-		$encoded = rawurlencode($component);
1191
-		$encoded = str_replace('%2F', '/', $encoded);
1192
-		return $encoded;
1193
-	}
1194
-
1195
-
1196
-	public function createHtaccessTestFile(\OCP\IConfig $config) {
1197
-		// php dev server does not support htaccess
1198
-		if (php_sapi_name() === 'cli-server') {
1199
-			return false;
1200
-		}
1201
-
1202
-		// testdata
1203
-		$fileName = '/htaccesstest.txt';
1204
-		$testContent = 'This is used for testing whether htaccess is properly enabled to disallow access from the outside. This file can be safely removed.';
1205
-
1206
-		// creating a test file
1207
-		$testFile = $config->getSystemValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $fileName;
1208
-
1209
-		if (file_exists($testFile)) {// already running this test, possible recursive call
1210
-			return false;
1211
-		}
1212
-
1213
-		$fp = @fopen($testFile, 'w');
1214
-		if (!$fp) {
1215
-			throw new OC\HintException('Can\'t create test file to check for working .htaccess file.',
1216
-				'Make sure it is possible for the webserver to write to ' . $testFile);
1217
-		}
1218
-		fwrite($fp, $testContent);
1219
-		fclose($fp);
1220
-
1221
-		return $testContent;
1222
-	}
1223
-
1224
-	/**
1225
-	 * Check if the .htaccess file is working
1226
-	 * @param \OCP\IConfig $config
1227
-	 * @return bool
1228
-	 * @throws Exception
1229
-	 * @throws \OC\HintException If the test file can't get written.
1230
-	 */
1231
-	public function isHtaccessWorking(\OCP\IConfig $config) {
1232
-
1233
-		if (\OC::$CLI || !$config->getSystemValue('check_for_working_htaccess', true)) {
1234
-			return true;
1235
-		}
1236
-
1237
-		$testContent = $this->createHtaccessTestFile($config);
1238
-		if ($testContent === false) {
1239
-			return false;
1240
-		}
1241
-
1242
-		$fileName = '/htaccesstest.txt';
1243
-		$testFile = $config->getSystemValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $fileName;
1244
-
1245
-		// accessing the file via http
1246
-		$url = \OC::$server->getURLGenerator()->getAbsoluteURL(OC::$WEBROOT . '/data' . $fileName);
1247
-		try {
1248
-			$content = \OC::$server->getHTTPClientService()->newClient()->get($url)->getBody();
1249
-		} catch (\Exception $e) {
1250
-			$content = false;
1251
-		}
1252
-
1253
-		if (strpos($url, 'https:') === 0) {
1254
-			$url = 'http:' . substr($url, 6);
1255
-		} else {
1256
-			$url = 'https:' . substr($url, 5);
1257
-		}
1258
-
1259
-		try {
1260
-			$fallbackContent = \OC::$server->getHTTPClientService()->newClient()->get($url)->getBody();
1261
-		} catch (\Exception $e) {
1262
-			$fallbackContent = false;
1263
-		}
1264
-
1265
-		// cleanup
1266
-		@unlink($testFile);
1267
-
1268
-		/*
269
+            if ($mount->getOption('readonly', false)) {
270
+                return new \OC\Files\Storage\Wrapper\PermissionsMask([
271
+                    'storage' => $storage,
272
+                    'mask' => \OCP\Constants::PERMISSION_ALL & ~(
273
+                        \OCP\Constants::PERMISSION_UPDATE |
274
+                        \OCP\Constants::PERMISSION_CREATE |
275
+                        \OCP\Constants::PERMISSION_DELETE
276
+                    ),
277
+                ]);
278
+            }
279
+            return $storage;
280
+        });
281
+
282
+        OC_Hook::emit('OC_Filesystem', 'preSetup', array('user' => $user));
283
+
284
+        \OC\Files\Filesystem::logWarningWhenAddingStorageWrapper($prevLogging);
285
+
286
+        //check if we are using an object storage
287
+        $objectStore = \OC::$server->getSystemConfig()->getValue('objectstore', null);
288
+        $objectStoreMultibucket = \OC::$server->getSystemConfig()->getValue('objectstore_multibucket', null);
289
+
290
+        // use the same order as in ObjectHomeMountProvider
291
+        if (isset($objectStoreMultibucket)) {
292
+            self::initObjectStoreMultibucketRootFS($objectStoreMultibucket);
293
+        } elseif (isset($objectStore)) {
294
+            self::initObjectStoreRootFS($objectStore);
295
+        } else {
296
+            self::initLocalStorageRootFS();
297
+        }
298
+
299
+        if ($user != '' && !\OC::$server->getUserManager()->userExists($user)) {
300
+            \OC::$server->getEventLogger()->end('setup_fs');
301
+            return false;
302
+        }
303
+
304
+        //if we aren't logged in, there is no use to set up the filesystem
305
+        if ($user != "") {
306
+
307
+            $userDir = '/' . $user . '/files';
308
+
309
+            //jail the user into his "home" directory
310
+            \OC\Files\Filesystem::init($user, $userDir);
311
+
312
+            OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $userDir));
313
+        }
314
+        \OC::$server->getEventLogger()->end('setup_fs');
315
+        return true;
316
+    }
317
+
318
+    /**
319
+     * check if a password is required for each public link
320
+     *
321
+     * @return boolean
322
+     * @suppress PhanDeprecatedFunction
323
+     */
324
+    public static function isPublicLinkPasswordRequired() {
325
+        $enforcePassword = \OC::$server->getConfig()->getAppValue('core', 'shareapi_enforce_links_password', 'no');
326
+        return $enforcePassword === 'yes';
327
+    }
328
+
329
+    /**
330
+     * check if sharing is disabled for the current user
331
+     * @param IConfig $config
332
+     * @param IGroupManager $groupManager
333
+     * @param IUser|null $user
334
+     * @return bool
335
+     */
336
+    public static function isSharingDisabledForUser(IConfig $config, IGroupManager $groupManager, $user) {
337
+        if ($config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
338
+            $groupsList = $config->getAppValue('core', 'shareapi_exclude_groups_list', '');
339
+            $excludedGroups = json_decode($groupsList);
340
+            if (is_null($excludedGroups)) {
341
+                $excludedGroups = explode(',', $groupsList);
342
+                $newValue = json_encode($excludedGroups);
343
+                $config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
344
+            }
345
+            $usersGroups = $groupManager->getUserGroupIds($user);
346
+            if (!empty($usersGroups)) {
347
+                $remainingGroups = array_diff($usersGroups, $excludedGroups);
348
+                // if the user is only in groups which are disabled for sharing then
349
+                // sharing is also disabled for the user
350
+                if (empty($remainingGroups)) {
351
+                    return true;
352
+                }
353
+            }
354
+        }
355
+        return false;
356
+    }
357
+
358
+    /**
359
+     * check if share API enforces a default expire date
360
+     *
361
+     * @return boolean
362
+     * @suppress PhanDeprecatedFunction
363
+     */
364
+    public static function isDefaultExpireDateEnforced() {
365
+        $isDefaultExpireDateEnabled = \OC::$server->getConfig()->getAppValue('core', 'shareapi_default_expire_date', 'no');
366
+        $enforceDefaultExpireDate = false;
367
+        if ($isDefaultExpireDateEnabled === 'yes') {
368
+            $value = \OC::$server->getConfig()->getAppValue('core', 'shareapi_enforce_expire_date', 'no');
369
+            $enforceDefaultExpireDate = $value === 'yes';
370
+        }
371
+
372
+        return $enforceDefaultExpireDate;
373
+    }
374
+
375
+    /**
376
+     * Get the quota of a user
377
+     *
378
+     * @param string $userId
379
+     * @return float Quota bytes
380
+     */
381
+    public static function getUserQuota($userId) {
382
+        $user = \OC::$server->getUserManager()->get($userId);
383
+        if (is_null($user)) {
384
+            return \OCP\Files\FileInfo::SPACE_UNLIMITED;
385
+        }
386
+        $userQuota = $user->getQuota();
387
+        if($userQuota === 'none') {
388
+            return \OCP\Files\FileInfo::SPACE_UNLIMITED;
389
+        }
390
+        return OC_Helper::computerFileSize($userQuota);
391
+    }
392
+
393
+    /**
394
+     * copies the skeleton to the users /files
395
+     *
396
+     * @param string $userId
397
+     * @param \OCP\Files\Folder $userDirectory
398
+     * @throws \OCP\Files\NotFoundException
399
+     * @throws \OCP\Files\NotPermittedException
400
+     * @suppress PhanDeprecatedFunction
401
+     */
402
+    public static function copySkeleton($userId, \OCP\Files\Folder $userDirectory) {
403
+
404
+        $plainSkeletonDirectory = \OC::$server->getConfig()->getSystemValue('skeletondirectory', \OC::$SERVERROOT . '/core/skeleton');
405
+        $userLang = \OC::$server->getL10NFactory()->findLanguage();
406
+        $skeletonDirectory = str_replace('{lang}', $userLang, $plainSkeletonDirectory);
407
+
408
+        if (!file_exists($skeletonDirectory)) {
409
+            $dialectStart = strpos($userLang, '_');
410
+            if ($dialectStart !== false) {
411
+                $skeletonDirectory = str_replace('{lang}', substr($userLang, 0, $dialectStart), $plainSkeletonDirectory);
412
+            }
413
+            if ($dialectStart === false || !file_exists($skeletonDirectory)) {
414
+                $skeletonDirectory = str_replace('{lang}', 'default', $plainSkeletonDirectory);
415
+            }
416
+            if (!file_exists($skeletonDirectory)) {
417
+                $skeletonDirectory = '';
418
+            }
419
+        }
420
+
421
+        $instanceId = \OC::$server->getConfig()->getSystemValue('instanceid', '');
422
+
423
+        if ($instanceId === null) {
424
+            throw new \RuntimeException('no instance id!');
425
+        }
426
+        $appdata = 'appdata_' . $instanceId;
427
+        if ($userId === $appdata) {
428
+            throw new \RuntimeException('username is reserved name: ' . $appdata);
429
+        }
430
+
431
+        if (!empty($skeletonDirectory)) {
432
+            \OCP\Util::writeLog(
433
+                'files_skeleton',
434
+                'copying skeleton for '.$userId.' from '.$skeletonDirectory.' to '.$userDirectory->getFullPath('/'),
435
+                ILogger::DEBUG
436
+            );
437
+            self::copyr($skeletonDirectory, $userDirectory);
438
+            // update the file cache
439
+            $userDirectory->getStorage()->getScanner()->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE);
440
+        }
441
+    }
442
+
443
+    /**
444
+     * copies a directory recursively by using streams
445
+     *
446
+     * @param string $source
447
+     * @param \OCP\Files\Folder $target
448
+     * @return void
449
+     */
450
+    public static function copyr($source, \OCP\Files\Folder $target) {
451
+        $logger = \OC::$server->getLogger();
452
+
453
+        // Verify if folder exists
454
+        $dir = opendir($source);
455
+        if($dir === false) {
456
+            $logger->error(sprintf('Could not opendir "%s"', $source), ['app' => 'core']);
457
+            return;
458
+        }
459
+
460
+        // Copy the files
461
+        while (false !== ($file = readdir($dir))) {
462
+            if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
463
+                if (is_dir($source . '/' . $file)) {
464
+                    $child = $target->newFolder($file);
465
+                    self::copyr($source . '/' . $file, $child);
466
+                } else {
467
+                    $child = $target->newFile($file);
468
+                    $sourceStream = fopen($source . '/' . $file, 'r');
469
+                    if($sourceStream === false) {
470
+                        $logger->error(sprintf('Could not fopen "%s"', $source . '/' . $file), ['app' => 'core']);
471
+                        closedir($dir);
472
+                        return;
473
+                    }
474
+                    stream_copy_to_stream($sourceStream, $child->fopen('w'));
475
+                }
476
+            }
477
+        }
478
+        closedir($dir);
479
+    }
480
+
481
+    /**
482
+     * @return void
483
+     * @suppress PhanUndeclaredMethod
484
+     */
485
+    public static function tearDownFS() {
486
+        \OC\Files\Filesystem::tearDown();
487
+        \OC::$server->getRootFolder()->clearCache();
488
+        self::$fsSetup = false;
489
+        self::$rootMounted = false;
490
+    }
491
+
492
+    /**
493
+     * get the current installed version of ownCloud
494
+     *
495
+     * @return array
496
+     */
497
+    public static function getVersion() {
498
+        OC_Util::loadVersion();
499
+        return self::$versionCache['OC_Version'];
500
+    }
501
+
502
+    /**
503
+     * get the current installed version string of ownCloud
504
+     *
505
+     * @return string
506
+     */
507
+    public static function getVersionString() {
508
+        OC_Util::loadVersion();
509
+        return self::$versionCache['OC_VersionString'];
510
+    }
511
+
512
+    /**
513
+     * @deprecated the value is of no use anymore
514
+     * @return string
515
+     */
516
+    public static function getEditionString() {
517
+        return '';
518
+    }
519
+
520
+    /**
521
+     * @description get the update channel of the current installed of ownCloud.
522
+     * @return string
523
+     */
524
+    public static function getChannel() {
525
+        OC_Util::loadVersion();
526
+        return \OC::$server->getConfig()->getSystemValue('updater.release.channel', self::$versionCache['OC_Channel']);
527
+    }
528
+
529
+    /**
530
+     * @description get the build number of the current installed of ownCloud.
531
+     * @return string
532
+     */
533
+    public static function getBuild() {
534
+        OC_Util::loadVersion();
535
+        return self::$versionCache['OC_Build'];
536
+    }
537
+
538
+    /**
539
+     * @description load the version.php into the session as cache
540
+     * @suppress PhanUndeclaredVariable
541
+     */
542
+    private static function loadVersion() {
543
+        if (self::$versionCache !== null) {
544
+            return;
545
+        }
546
+
547
+        $timestamp = filemtime(OC::$SERVERROOT . '/version.php');
548
+        require OC::$SERVERROOT . '/version.php';
549
+        /** @var $timestamp int */
550
+        self::$versionCache['OC_Version_Timestamp'] = $timestamp;
551
+        /** @var $OC_Version string */
552
+        self::$versionCache['OC_Version'] = $OC_Version;
553
+        /** @var $OC_VersionString string */
554
+        self::$versionCache['OC_VersionString'] = $OC_VersionString;
555
+        /** @var $OC_Build string */
556
+        self::$versionCache['OC_Build'] = $OC_Build;
557
+
558
+        /** @var $OC_Channel string */
559
+        self::$versionCache['OC_Channel'] = $OC_Channel;
560
+    }
561
+
562
+    /**
563
+     * generates a path for JS/CSS files. If no application is provided it will create the path for core.
564
+     *
565
+     * @param string $application application to get the files from
566
+     * @param string $directory directory within this application (css, js, vendor, etc)
567
+     * @param string $file the file inside of the above folder
568
+     * @return string the path
569
+     */
570
+    private static function generatePath($application, $directory, $file) {
571
+        if (is_null($file)) {
572
+            $file = $application;
573
+            $application = "";
574
+        }
575
+        if (!empty($application)) {
576
+            return "$application/$directory/$file";
577
+        } else {
578
+            return "$directory/$file";
579
+        }
580
+    }
581
+
582
+    /**
583
+     * add a javascript file
584
+     *
585
+     * @param string $application application id
586
+     * @param string|null $file filename
587
+     * @param bool $prepend prepend the Script to the beginning of the list
588
+     * @return void
589
+     */
590
+    public static function addScript($application, $file = null, $prepend = false) {
591
+        $path = OC_Util::generatePath($application, 'js', $file);
592
+
593
+        // core js files need separate handling
594
+        if ($application !== 'core' && $file !== null) {
595
+            self::addTranslations ( $application );
596
+        }
597
+        self::addExternalResource($application, $prepend, $path, "script");
598
+    }
599
+
600
+    /**
601
+     * add a javascript file from the vendor sub folder
602
+     *
603
+     * @param string $application application id
604
+     * @param string|null $file filename
605
+     * @param bool $prepend prepend the Script to the beginning of the list
606
+     * @return void
607
+     */
608
+    public static function addVendorScript($application, $file = null, $prepend = false) {
609
+        $path = OC_Util::generatePath($application, 'vendor', $file);
610
+        self::addExternalResource($application, $prepend, $path, "script");
611
+    }
612
+
613
+    /**
614
+     * add a translation JS file
615
+     *
616
+     * @param string $application application id
617
+     * @param string|null $languageCode language code, defaults to the current language
618
+     * @param bool|null $prepend prepend the Script to the beginning of the list
619
+     */
620
+    public static function addTranslations($application, $languageCode = null, $prepend = false) {
621
+        if (is_null($languageCode)) {
622
+            $languageCode = \OC::$server->getL10NFactory()->findLanguage($application);
623
+        }
624
+        if (!empty($application)) {
625
+            $path = "$application/l10n/$languageCode";
626
+        } else {
627
+            $path = "l10n/$languageCode";
628
+        }
629
+        self::addExternalResource($application, $prepend, $path, "script");
630
+    }
631
+
632
+    /**
633
+     * add a css file
634
+     *
635
+     * @param string $application application id
636
+     * @param string|null $file filename
637
+     * @param bool $prepend prepend the Style to the beginning of the list
638
+     * @return void
639
+     */
640
+    public static function addStyle($application, $file = null, $prepend = false) {
641
+        $path = OC_Util::generatePath($application, 'css', $file);
642
+        self::addExternalResource($application, $prepend, $path, "style");
643
+    }
644
+
645
+    /**
646
+     * add a css file from the vendor sub folder
647
+     *
648
+     * @param string $application application id
649
+     * @param string|null $file filename
650
+     * @param bool $prepend prepend the Style to the beginning of the list
651
+     * @return void
652
+     */
653
+    public static function addVendorStyle($application, $file = null, $prepend = false) {
654
+        $path = OC_Util::generatePath($application, 'vendor', $file);
655
+        self::addExternalResource($application, $prepend, $path, "style");
656
+    }
657
+
658
+    /**
659
+     * add an external resource css/js file
660
+     *
661
+     * @param string $application application id
662
+     * @param bool $prepend prepend the file to the beginning of the list
663
+     * @param string $path
664
+     * @param string $type (script or style)
665
+     * @return void
666
+     */
667
+    private static function addExternalResource($application, $prepend, $path, $type = "script") {
668
+
669
+        if ($type === "style") {
670
+            if (!in_array($path, self::$styles)) {
671
+                if ($prepend === true) {
672
+                    array_unshift ( self::$styles, $path );
673
+                } else {
674
+                    self::$styles[] = $path;
675
+                }
676
+            }
677
+        } elseif ($type === "script") {
678
+            if (!in_array($path, self::$scripts)) {
679
+                if ($prepend === true) {
680
+                    array_unshift ( self::$scripts, $path );
681
+                } else {
682
+                    self::$scripts [] = $path;
683
+                }
684
+            }
685
+        }
686
+    }
687
+
688
+    /**
689
+     * Add a custom element to the header
690
+     * If $text is null then the element will be written as empty element.
691
+     * So use "" to get a closing tag.
692
+     * @param string $tag tag name of the element
693
+     * @param array $attributes array of attributes for the element
694
+     * @param string $text the text content for the element
695
+     * @param bool $prepend prepend the header to the beginning of the list
696
+     */
697
+    public static function addHeader($tag, $attributes, $text = null, $prepend = false) {
698
+        $header = array(
699
+            'tag' => $tag,
700
+            'attributes' => $attributes,
701
+            'text' => $text
702
+        );
703
+        if ($prepend === true) {
704
+            array_unshift (self::$headers, $header);
705
+
706
+        } else {
707
+            self::$headers[] = $header;
708
+        }
709
+    }
710
+
711
+    /**
712
+     * check if the current server configuration is suitable for ownCloud
713
+     *
714
+     * @param \OC\SystemConfig $config
715
+     * @return array arrays with error messages and hints
716
+     */
717
+    public static function checkServer(\OC\SystemConfig $config) {
718
+        $l = \OC::$server->getL10N('lib');
719
+        $errors = array();
720
+        $CONFIG_DATADIRECTORY = $config->getValue('datadirectory', OC::$SERVERROOT . '/data');
721
+
722
+        if (!self::needUpgrade($config) && $config->getValue('installed', false)) {
723
+            // this check needs to be done every time
724
+            $errors = self::checkDataDirectoryValidity($CONFIG_DATADIRECTORY);
725
+        }
726
+
727
+        // Assume that if checkServer() succeeded before in this session, then all is fine.
728
+        if (\OC::$server->getSession()->exists('checkServer_succeeded') && \OC::$server->getSession()->get('checkServer_succeeded')) {
729
+            return $errors;
730
+        }
731
+
732
+        $webServerRestart = false;
733
+        $setup = new \OC\Setup(
734
+            $config,
735
+            \OC::$server->getIniWrapper(),
736
+            \OC::$server->getL10N('lib'),
737
+            \OC::$server->query(\OCP\Defaults::class),
738
+            \OC::$server->getLogger(),
739
+            \OC::$server->getSecureRandom(),
740
+            \OC::$server->query(\OC\Installer::class)
741
+        );
742
+
743
+        $urlGenerator = \OC::$server->getURLGenerator();
744
+
745
+        $availableDatabases = $setup->getSupportedDatabases();
746
+        if (empty($availableDatabases)) {
747
+            $errors[] = array(
748
+                'error' => $l->t('No database drivers (sqlite, mysql, or postgresql) installed.'),
749
+                'hint' => '' //TODO: sane hint
750
+            );
751
+            $webServerRestart = true;
752
+        }
753
+
754
+        // Check if config folder is writable.
755
+        if(!OC_Helper::isReadOnlyConfigEnabled()) {
756
+            if (!is_writable(OC::$configDir) or !is_readable(OC::$configDir)) {
757
+                $errors[] = array(
758
+                    'error' => $l->t('Cannot write into "config" directory'),
759
+                    'hint' => $l->t('This can usually be fixed by giving the webserver write access to the config directory. See %s',
760
+                        [ $urlGenerator->linkToDocs('admin-dir_permissions') ]) . '. '
761
+                        . $l->t('Or, if you prefer to keep config.php file read only, set the option "config_is_read_only" to true in it. See %s',
762
+                        [ $urlGenerator->linkToDocs('admin-config') ] )
763
+                );
764
+            }
765
+        }
766
+
767
+        // Check if there is a writable install folder.
768
+        if ($config->getValue('appstoreenabled', true)) {
769
+            if (OC_App::getInstallPath() === null
770
+                || !is_writable(OC_App::getInstallPath())
771
+                || !is_readable(OC_App::getInstallPath())
772
+            ) {
773
+                $errors[] = array(
774
+                    'error' => $l->t('Cannot write into "apps" directory'),
775
+                    'hint' => $l->t('This can usually be fixed by giving the webserver write access to the apps directory'
776
+                        . ' or disabling the appstore in the config file. See %s',
777
+                        [$urlGenerator->linkToDocs('admin-dir_permissions')])
778
+                );
779
+            }
780
+        }
781
+        // Create root dir.
782
+        if ($config->getValue('installed', false)) {
783
+            if (!is_dir($CONFIG_DATADIRECTORY)) {
784
+                $success = @mkdir($CONFIG_DATADIRECTORY);
785
+                if ($success) {
786
+                    $errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY));
787
+                } else {
788
+                    $errors[] = [
789
+                        'error' => $l->t('Cannot create "data" directory'),
790
+                        'hint' => $l->t('This can usually be fixed by giving the webserver write access to the root directory. See %s',
791
+                            [$urlGenerator->linkToDocs('admin-dir_permissions')])
792
+                    ];
793
+                }
794
+            } else if (!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) {
795
+                // is_writable doesn't work for NFS mounts, so try to write a file and check if it exists.
796
+                $testFile = sprintf('%s/%s.tmp', $CONFIG_DATADIRECTORY, uniqid('data_dir_writability_test_'));
797
+                $handle = fopen($testFile, 'w');
798
+                if (!$handle || fwrite($handle, 'Test write operation') === false) {
799
+                    $permissionsHint = $l->t('Permissions can usually be fixed by giving the webserver write access to the root directory. See %s.',
800
+                        [$urlGenerator->linkToDocs('admin-dir_permissions')]);
801
+                    $errors[] = [
802
+                        'error' => 'Your data directory is not writable',
803
+                        'hint' => $permissionsHint
804
+                    ];
805
+                } else {
806
+                    fclose($handle);
807
+                    unlink($testFile);
808
+                }
809
+            } else {
810
+                $errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY));
811
+            }
812
+        }
813
+
814
+        if (!OC_Util::isSetLocaleWorking()) {
815
+            $errors[] = array(
816
+                'error' => $l->t('Setting locale to %s failed',
817
+                    array('en_US.UTF-8/fr_FR.UTF-8/es_ES.UTF-8/de_DE.UTF-8/ru_RU.UTF-8/'
818
+                        . 'pt_BR.UTF-8/it_IT.UTF-8/ja_JP.UTF-8/zh_CN.UTF-8')),
819
+                'hint' => $l->t('Please install one of these locales on your system and restart your webserver.')
820
+            );
821
+        }
822
+
823
+        // Contains the dependencies that should be checked against
824
+        // classes = class_exists
825
+        // functions = function_exists
826
+        // defined = defined
827
+        // ini = ini_get
828
+        // If the dependency is not found the missing module name is shown to the EndUser
829
+        // When adding new checks always verify that they pass on Travis as well
830
+        // for ini settings, see https://github.com/owncloud/administration/blob/master/travis-ci/custom.ini
831
+        $dependencies = array(
832
+            'classes' => array(
833
+                'ZipArchive' => 'zip',
834
+                'DOMDocument' => 'dom',
835
+                'XMLWriter' => 'XMLWriter',
836
+                'XMLReader' => 'XMLReader',
837
+            ),
838
+            'functions' => [
839
+                'xml_parser_create' => 'libxml',
840
+                'mb_strcut' => 'mbstring',
841
+                'ctype_digit' => 'ctype',
842
+                'json_encode' => 'JSON',
843
+                'gd_info' => 'GD',
844
+                'gzencode' => 'zlib',
845
+                'iconv' => 'iconv',
846
+                'simplexml_load_string' => 'SimpleXML',
847
+                'hash' => 'HASH Message Digest Framework',
848
+                'curl_init' => 'cURL',
849
+                'openssl_verify' => 'OpenSSL',
850
+            ],
851
+            'defined' => array(
852
+                'PDO::ATTR_DRIVER_NAME' => 'PDO'
853
+            ),
854
+            'ini' => [
855
+                'default_charset' => 'UTF-8',
856
+            ],
857
+        );
858
+        $missingDependencies = array();
859
+        $invalidIniSettings = [];
860
+        $moduleHint = $l->t('Please ask your server administrator to install the module.');
861
+
862
+        $iniWrapper = \OC::$server->getIniWrapper();
863
+        foreach ($dependencies['classes'] as $class => $module) {
864
+            if (!class_exists($class)) {
865
+                $missingDependencies[] = $module;
866
+            }
867
+        }
868
+        foreach ($dependencies['functions'] as $function => $module) {
869
+            if (!function_exists($function)) {
870
+                $missingDependencies[] = $module;
871
+            }
872
+        }
873
+        foreach ($dependencies['defined'] as $defined => $module) {
874
+            if (!defined($defined)) {
875
+                $missingDependencies[] = $module;
876
+            }
877
+        }
878
+        foreach ($dependencies['ini'] as $setting => $expected) {
879
+            if (is_bool($expected)) {
880
+                if ($iniWrapper->getBool($setting) !== $expected) {
881
+                    $invalidIniSettings[] = [$setting, $expected];
882
+                }
883
+            }
884
+            if (is_int($expected)) {
885
+                if ($iniWrapper->getNumeric($setting) !== $expected) {
886
+                    $invalidIniSettings[] = [$setting, $expected];
887
+                }
888
+            }
889
+            if (is_string($expected)) {
890
+                if (strtolower($iniWrapper->getString($setting)) !== strtolower($expected)) {
891
+                    $invalidIniSettings[] = [$setting, $expected];
892
+                }
893
+            }
894
+        }
895
+
896
+        foreach($missingDependencies as $missingDependency) {
897
+            $errors[] = array(
898
+                'error' => $l->t('PHP module %s not installed.', array($missingDependency)),
899
+                'hint' => $moduleHint
900
+            );
901
+            $webServerRestart = true;
902
+        }
903
+        foreach($invalidIniSettings as $setting) {
904
+            if(is_bool($setting[1])) {
905
+                $setting[1] = $setting[1] ? 'on' : 'off';
906
+            }
907
+            $errors[] = [
908
+                'error' => $l->t('PHP setting "%s" is not set to "%s".', [$setting[0], var_export($setting[1], true)]),
909
+                'hint' =>  $l->t('Adjusting this setting in php.ini will make Nextcloud run again')
910
+            ];
911
+            $webServerRestart = true;
912
+        }
913
+
914
+        /**
915
+         * The mbstring.func_overload check can only be performed if the mbstring
916
+         * module is installed as it will return null if the checking setting is
917
+         * not available and thus a check on the boolean value fails.
918
+         *
919
+         * TODO: Should probably be implemented in the above generic dependency
920
+         *       check somehow in the long-term.
921
+         */
922
+        if($iniWrapper->getBool('mbstring.func_overload') !== null &&
923
+            $iniWrapper->getBool('mbstring.func_overload') === true) {
924
+            $errors[] = array(
925
+                'error' => $l->t('mbstring.func_overload is set to "%s" instead of the expected value "0"', [$iniWrapper->getString('mbstring.func_overload')]),
926
+                'hint' => $l->t('To fix this issue set <code>mbstring.func_overload</code> to <code>0</code> in your php.ini')
927
+            );
928
+        }
929
+
930
+        if(function_exists('xml_parser_create') &&
931
+            LIBXML_LOADED_VERSION < 20700 ) {
932
+            $version = LIBXML_LOADED_VERSION;
933
+            $major = floor($version/10000);
934
+            $version -= ($major * 10000);
935
+            $minor = floor($version/100);
936
+            $version -= ($minor * 100);
937
+            $patch = $version;
938
+            $errors[] = array(
939
+                'error' => $l->t('libxml2 2.7.0 is at least required. Currently %s is installed.', [$major . '.' . $minor . '.' . $patch]),
940
+                'hint' => $l->t('To fix this issue update your libxml2 version and restart your web server.')
941
+            );
942
+        }
943
+
944
+        if (!self::isAnnotationsWorking()) {
945
+            $errors[] = array(
946
+                'error' => $l->t('PHP is apparently set up to strip inline doc blocks. This will make several core apps inaccessible.'),
947
+                'hint' => $l->t('This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator.')
948
+            );
949
+        }
950
+
951
+        if (!\OC::$CLI && $webServerRestart) {
952
+            $errors[] = array(
953
+                'error' => $l->t('PHP modules have been installed, but they are still listed as missing?'),
954
+                'hint' => $l->t('Please ask your server administrator to restart the web server.')
955
+            );
956
+        }
957
+
958
+        $errors = array_merge($errors, self::checkDatabaseVersion());
959
+
960
+        // Cache the result of this function
961
+        \OC::$server->getSession()->set('checkServer_succeeded', count($errors) == 0);
962
+
963
+        return $errors;
964
+    }
965
+
966
+    /**
967
+     * Check the database version
968
+     *
969
+     * @return array errors array
970
+     */
971
+    public static function checkDatabaseVersion() {
972
+        $l = \OC::$server->getL10N('lib');
973
+        $errors = array();
974
+        $dbType = \OC::$server->getSystemConfig()->getValue('dbtype', 'sqlite');
975
+        if ($dbType === 'pgsql') {
976
+            // check PostgreSQL version
977
+            try {
978
+                $result = \OC_DB::executeAudited('SHOW SERVER_VERSION');
979
+                $data = $result->fetchRow();
980
+                if (isset($data['server_version'])) {
981
+                    $version = $data['server_version'];
982
+                    if (version_compare($version, '9.0.0', '<')) {
983
+                        $errors[] = array(
984
+                            'error' => $l->t('PostgreSQL >= 9 required'),
985
+                            'hint' => $l->t('Please upgrade your database version')
986
+                        );
987
+                    }
988
+                }
989
+            } catch (\Doctrine\DBAL\DBALException $e) {
990
+                $logger = \OC::$server->getLogger();
991
+                $logger->warning('Error occurred while checking PostgreSQL version, assuming >= 9');
992
+                $logger->logException($e);
993
+            }
994
+        }
995
+        return $errors;
996
+    }
997
+
998
+    /**
999
+     * Check for correct file permissions of data directory
1000
+     *
1001
+     * @param string $dataDirectory
1002
+     * @return array arrays with error messages and hints
1003
+     */
1004
+    public static function checkDataDirectoryPermissions($dataDirectory) {
1005
+        if(\OC::$server->getConfig()->getSystemValue('check_data_directory_permissions', true) === false) {
1006
+            return  [];
1007
+        }
1008
+        $l = \OC::$server->getL10N('lib');
1009
+        $errors = [];
1010
+        $permissionsModHint = $l->t('Please change the permissions to 0770 so that the directory'
1011
+            . ' cannot be listed by other users.');
1012
+        $perms = substr(decoct(@fileperms($dataDirectory)), -3);
1013
+        if (substr($perms, -1) !== '0') {
1014
+            chmod($dataDirectory, 0770);
1015
+            clearstatcache();
1016
+            $perms = substr(decoct(@fileperms($dataDirectory)), -3);
1017
+            if ($perms[2] !== '0') {
1018
+                $errors[] = [
1019
+                    'error' => $l->t('Your data directory is readable by other users'),
1020
+                    'hint' => $permissionsModHint
1021
+                ];
1022
+            }
1023
+        }
1024
+        return $errors;
1025
+    }
1026
+
1027
+    /**
1028
+     * Check that the data directory exists and is valid by
1029
+     * checking the existence of the ".ocdata" file.
1030
+     *
1031
+     * @param string $dataDirectory data directory path
1032
+     * @return array errors found
1033
+     */
1034
+    public static function checkDataDirectoryValidity($dataDirectory) {
1035
+        $l = \OC::$server->getL10N('lib');
1036
+        $errors = [];
1037
+        if ($dataDirectory[0] !== '/') {
1038
+            $errors[] = [
1039
+                'error' => $l->t('Your data directory must be an absolute path'),
1040
+                'hint' => $l->t('Check the value of "datadirectory" in your configuration')
1041
+            ];
1042
+        }
1043
+        if (!file_exists($dataDirectory . '/.ocdata')) {
1044
+            $errors[] = [
1045
+                'error' => $l->t('Your data directory is invalid'),
1046
+                'hint' => $l->t('Ensure there is a file called ".ocdata"' .
1047
+                    ' in the root of the data directory.')
1048
+            ];
1049
+        }
1050
+        return $errors;
1051
+    }
1052
+
1053
+    /**
1054
+     * Check if the user is logged in, redirects to home if not. With
1055
+     * redirect URL parameter to the request URI.
1056
+     *
1057
+     * @return void
1058
+     */
1059
+    public static function checkLoggedIn() {
1060
+        // Check if we are a user
1061
+        if (!\OC::$server->getUserSession()->isLoggedIn()) {
1062
+            header('Location: ' . \OC::$server->getURLGenerator()->linkToRoute(
1063
+                        'core.login.showLoginForm',
1064
+                        [
1065
+                            'redirect_url' => \OC::$server->getRequest()->getRequestUri(),
1066
+                        ]
1067
+                    )
1068
+            );
1069
+            exit();
1070
+        }
1071
+        // Redirect to 2FA challenge selection if 2FA challenge was not solved yet
1072
+        if (\OC::$server->getTwoFactorAuthManager()->needsSecondFactor(\OC::$server->getUserSession()->getUser())) {
1073
+            header('Location: ' . \OC::$server->getURLGenerator()->linkToRoute('core.TwoFactorChallenge.selectChallenge'));
1074
+            exit();
1075
+        }
1076
+    }
1077
+
1078
+    /**
1079
+     * Check if the user is a admin, redirects to home if not
1080
+     *
1081
+     * @return void
1082
+     */
1083
+    public static function checkAdminUser() {
1084
+        OC_Util::checkLoggedIn();
1085
+        if (!OC_User::isAdminUser(OC_User::getUser())) {
1086
+            header('Location: ' . \OCP\Util::linkToAbsolute('', 'index.php'));
1087
+            exit();
1088
+        }
1089
+    }
1090
+
1091
+    /**
1092
+     * Returns the URL of the default page
1093
+     * based on the system configuration and
1094
+     * the apps visible for the current user
1095
+     *
1096
+     * @return string URL
1097
+     * @suppress PhanDeprecatedFunction
1098
+     */
1099
+    public static function getDefaultPageUrl() {
1100
+        $urlGenerator = \OC::$server->getURLGenerator();
1101
+        // Deny the redirect if the URL contains a @
1102
+        // This prevents unvalidated redirects like ?redirect_url=:[email protected]
1103
+        if (isset($_REQUEST['redirect_url']) && strpos($_REQUEST['redirect_url'], '@') === false) {
1104
+            $location = $urlGenerator->getAbsoluteURL(urldecode($_REQUEST['redirect_url']));
1105
+        } else {
1106
+            $defaultPage = \OC::$server->getConfig()->getAppValue('core', 'defaultpage');
1107
+            if ($defaultPage) {
1108
+                $location = $urlGenerator->getAbsoluteURL($defaultPage);
1109
+            } else {
1110
+                $appId = 'files';
1111
+                $config = \OC::$server->getConfig();
1112
+                $defaultApps = explode(',', $config->getSystemValue('defaultapp', 'files'));
1113
+                // find the first app that is enabled for the current user
1114
+                foreach ($defaultApps as $defaultApp) {
1115
+                    $defaultApp = OC_App::cleanAppId(strip_tags($defaultApp));
1116
+                    if (static::getAppManager()->isEnabledForUser($defaultApp)) {
1117
+                        $appId = $defaultApp;
1118
+                        break;
1119
+                    }
1120
+                }
1121
+
1122
+                if($config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true') {
1123
+                    $location = $urlGenerator->getAbsoluteURL('/apps/' . $appId . '/');
1124
+                } else {
1125
+                    $location = $urlGenerator->getAbsoluteURL('/index.php/apps/' . $appId . '/');
1126
+                }
1127
+            }
1128
+        }
1129
+        return $location;
1130
+    }
1131
+
1132
+    /**
1133
+     * Redirect to the user default page
1134
+     *
1135
+     * @return void
1136
+     */
1137
+    public static function redirectToDefaultPage() {
1138
+        $location = self::getDefaultPageUrl();
1139
+        header('Location: ' . $location);
1140
+        exit();
1141
+    }
1142
+
1143
+    /**
1144
+     * get an id unique for this instance
1145
+     *
1146
+     * @return string
1147
+     */
1148
+    public static function getInstanceId() {
1149
+        $id = \OC::$server->getSystemConfig()->getValue('instanceid', null);
1150
+        if (is_null($id)) {
1151
+            // We need to guarantee at least one letter in instanceid so it can be used as the session_name
1152
+            $id = 'oc' . \OC::$server->getSecureRandom()->generate(10, \OCP\Security\ISecureRandom::CHAR_LOWER.\OCP\Security\ISecureRandom::CHAR_DIGITS);
1153
+            \OC::$server->getSystemConfig()->setValue('instanceid', $id);
1154
+        }
1155
+        return $id;
1156
+    }
1157
+
1158
+    /**
1159
+     * Public function to sanitize HTML
1160
+     *
1161
+     * This function is used to sanitize HTML and should be applied on any
1162
+     * string or array of strings before displaying it on a web page.
1163
+     *
1164
+     * @param string|array $value
1165
+     * @return string|array an array of sanitized strings or a single sanitized string, depends on the input parameter.
1166
+     */
1167
+    public static function sanitizeHTML($value) {
1168
+        if (is_array($value)) {
1169
+            $value = array_map(function($value) {
1170
+                return self::sanitizeHTML($value);
1171
+            }, $value);
1172
+        } else {
1173
+            // Specify encoding for PHP<5.4
1174
+            $value = htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
1175
+        }
1176
+        return $value;
1177
+    }
1178
+
1179
+    /**
1180
+     * Public function to encode url parameters
1181
+     *
1182
+     * This function is used to encode path to file before output.
1183
+     * Encoding is done according to RFC 3986 with one exception:
1184
+     * Character '/' is preserved as is.
1185
+     *
1186
+     * @param string $component part of URI to encode
1187
+     * @return string
1188
+     */
1189
+    public static function encodePath($component) {
1190
+        $encoded = rawurlencode($component);
1191
+        $encoded = str_replace('%2F', '/', $encoded);
1192
+        return $encoded;
1193
+    }
1194
+
1195
+
1196
+    public function createHtaccessTestFile(\OCP\IConfig $config) {
1197
+        // php dev server does not support htaccess
1198
+        if (php_sapi_name() === 'cli-server') {
1199
+            return false;
1200
+        }
1201
+
1202
+        // testdata
1203
+        $fileName = '/htaccesstest.txt';
1204
+        $testContent = 'This is used for testing whether htaccess is properly enabled to disallow access from the outside. This file can be safely removed.';
1205
+
1206
+        // creating a test file
1207
+        $testFile = $config->getSystemValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $fileName;
1208
+
1209
+        if (file_exists($testFile)) {// already running this test, possible recursive call
1210
+            return false;
1211
+        }
1212
+
1213
+        $fp = @fopen($testFile, 'w');
1214
+        if (!$fp) {
1215
+            throw new OC\HintException('Can\'t create test file to check for working .htaccess file.',
1216
+                'Make sure it is possible for the webserver to write to ' . $testFile);
1217
+        }
1218
+        fwrite($fp, $testContent);
1219
+        fclose($fp);
1220
+
1221
+        return $testContent;
1222
+    }
1223
+
1224
+    /**
1225
+     * Check if the .htaccess file is working
1226
+     * @param \OCP\IConfig $config
1227
+     * @return bool
1228
+     * @throws Exception
1229
+     * @throws \OC\HintException If the test file can't get written.
1230
+     */
1231
+    public function isHtaccessWorking(\OCP\IConfig $config) {
1232
+
1233
+        if (\OC::$CLI || !$config->getSystemValue('check_for_working_htaccess', true)) {
1234
+            return true;
1235
+        }
1236
+
1237
+        $testContent = $this->createHtaccessTestFile($config);
1238
+        if ($testContent === false) {
1239
+            return false;
1240
+        }
1241
+
1242
+        $fileName = '/htaccesstest.txt';
1243
+        $testFile = $config->getSystemValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $fileName;
1244
+
1245
+        // accessing the file via http
1246
+        $url = \OC::$server->getURLGenerator()->getAbsoluteURL(OC::$WEBROOT . '/data' . $fileName);
1247
+        try {
1248
+            $content = \OC::$server->getHTTPClientService()->newClient()->get($url)->getBody();
1249
+        } catch (\Exception $e) {
1250
+            $content = false;
1251
+        }
1252
+
1253
+        if (strpos($url, 'https:') === 0) {
1254
+            $url = 'http:' . substr($url, 6);
1255
+        } else {
1256
+            $url = 'https:' . substr($url, 5);
1257
+        }
1258
+
1259
+        try {
1260
+            $fallbackContent = \OC::$server->getHTTPClientService()->newClient()->get($url)->getBody();
1261
+        } catch (\Exception $e) {
1262
+            $fallbackContent = false;
1263
+        }
1264
+
1265
+        // cleanup
1266
+        @unlink($testFile);
1267
+
1268
+        /*
1269 1269
 		 * If the content is not equal to test content our .htaccess
1270 1270
 		 * is working as required
1271 1271
 		 */
1272
-		return $content !== $testContent && $fallbackContent !== $testContent;
1273
-	}
1274
-
1275
-	/**
1276
-	 * Check if the setlocal call does not work. This can happen if the right
1277
-	 * local packages are not available on the server.
1278
-	 *
1279
-	 * @return bool
1280
-	 */
1281
-	public static function isSetLocaleWorking() {
1282
-		\Patchwork\Utf8\Bootup::initLocale();
1283
-		if ('' === basename('§')) {
1284
-			return false;
1285
-		}
1286
-		return true;
1287
-	}
1288
-
1289
-	/**
1290
-	 * Check if it's possible to get the inline annotations
1291
-	 *
1292
-	 * @return bool
1293
-	 */
1294
-	public static function isAnnotationsWorking() {
1295
-		$reflection = new \ReflectionMethod(__METHOD__);
1296
-		$docs = $reflection->getDocComment();
1297
-
1298
-		return (is_string($docs) && strlen($docs) > 50);
1299
-	}
1300
-
1301
-	/**
1302
-	 * Check if the PHP module fileinfo is loaded.
1303
-	 *
1304
-	 * @return bool
1305
-	 */
1306
-	public static function fileInfoLoaded() {
1307
-		return function_exists('finfo_open');
1308
-	}
1309
-
1310
-	/**
1311
-	 * clear all levels of output buffering
1312
-	 *
1313
-	 * @return void
1314
-	 */
1315
-	public static function obEnd() {
1316
-		while (ob_get_level()) {
1317
-			ob_end_clean();
1318
-		}
1319
-	}
1320
-
1321
-	/**
1322
-	 * Checks whether the server is running on Mac OS X
1323
-	 *
1324
-	 * @return bool true if running on Mac OS X, false otherwise
1325
-	 */
1326
-	public static function runningOnMac() {
1327
-		return (strtoupper(substr(PHP_OS, 0, 6)) === 'DARWIN');
1328
-	}
1329
-
1330
-	/**
1331
-	 * Handles the case that there may not be a theme, then check if a "default"
1332
-	 * theme exists and take that one
1333
-	 *
1334
-	 * @return string the theme
1335
-	 */
1336
-	public static function getTheme() {
1337
-		$theme = \OC::$server->getSystemConfig()->getValue("theme", '');
1338
-
1339
-		if ($theme === '') {
1340
-			if (is_dir(OC::$SERVERROOT . '/themes/default')) {
1341
-				$theme = 'default';
1342
-			}
1343
-		}
1344
-
1345
-		return $theme;
1346
-	}
1347
-
1348
-	/**
1349
-	 * Normalize a unicode string
1350
-	 *
1351
-	 * @param string $value a not normalized string
1352
-	 * @return bool|string
1353
-	 */
1354
-	public static function normalizeUnicode($value) {
1355
-		if(Normalizer::isNormalized($value)) {
1356
-			return $value;
1357
-		}
1358
-
1359
-		$normalizedValue = Normalizer::normalize($value);
1360
-		if ($normalizedValue === null || $normalizedValue === false) {
1361
-			\OC::$server->getLogger()->warning('normalizing failed for "' . $value . '"', ['app' => 'core']);
1362
-			return $value;
1363
-		}
1364
-
1365
-		return $normalizedValue;
1366
-	}
1367
-
1368
-	/**
1369
-	 * A human readable string is generated based on version and build number
1370
-	 *
1371
-	 * @return string
1372
-	 */
1373
-	public static function getHumanVersion() {
1374
-		$version = OC_Util::getVersionString();
1375
-		$build = OC_Util::getBuild();
1376
-		if (!empty($build) and OC_Util::getChannel() === 'daily') {
1377
-			$version .= ' Build:' . $build;
1378
-		}
1379
-		return $version;
1380
-	}
1381
-
1382
-	/**
1383
-	 * Returns whether the given file name is valid
1384
-	 *
1385
-	 * @param string $file file name to check
1386
-	 * @return bool true if the file name is valid, false otherwise
1387
-	 * @deprecated use \OC\Files\View::verifyPath()
1388
-	 */
1389
-	public static function isValidFileName($file) {
1390
-		$trimmed = trim($file);
1391
-		if ($trimmed === '') {
1392
-			return false;
1393
-		}
1394
-		if (\OC\Files\Filesystem::isIgnoredDir($trimmed)) {
1395
-			return false;
1396
-		}
1397
-
1398
-		// detect part files
1399
-		if (preg_match('/' . \OCP\Files\FileInfo::BLACKLIST_FILES_REGEX . '/', $trimmed) !== 0) {
1400
-			return false;
1401
-		}
1402
-
1403
-		foreach (str_split($trimmed) as $char) {
1404
-			if (strpos(\OCP\Constants::FILENAME_INVALID_CHARS, $char) !== false) {
1405
-				return false;
1406
-			}
1407
-		}
1408
-		return true;
1409
-	}
1410
-
1411
-	/**
1412
-	 * Check whether the instance needs to perform an upgrade,
1413
-	 * either when the core version is higher or any app requires
1414
-	 * an upgrade.
1415
-	 *
1416
-	 * @param \OC\SystemConfig $config
1417
-	 * @return bool whether the core or any app needs an upgrade
1418
-	 * @throws \OC\HintException When the upgrade from the given version is not allowed
1419
-	 */
1420
-	public static function needUpgrade(\OC\SystemConfig $config) {
1421
-		if ($config->getValue('installed', false)) {
1422
-			$installedVersion = $config->getValue('version', '0.0.0');
1423
-			$currentVersion = implode('.', \OCP\Util::getVersion());
1424
-			$versionDiff = version_compare($currentVersion, $installedVersion);
1425
-			if ($versionDiff > 0) {
1426
-				return true;
1427
-			} else if ($config->getValue('debug', false) && $versionDiff < 0) {
1428
-				// downgrade with debug
1429
-				$installedMajor = explode('.', $installedVersion);
1430
-				$installedMajor = $installedMajor[0] . '.' . $installedMajor[1];
1431
-				$currentMajor = explode('.', $currentVersion);
1432
-				$currentMajor = $currentMajor[0] . '.' . $currentMajor[1];
1433
-				if ($installedMajor === $currentMajor) {
1434
-					// Same major, allow downgrade for developers
1435
-					return true;
1436
-				} else {
1437
-					// downgrade attempt, throw exception
1438
-					throw new \OC\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')');
1439
-				}
1440
-			} else if ($versionDiff < 0) {
1441
-				// downgrade attempt, throw exception
1442
-				throw new \OC\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')');
1443
-			}
1444
-
1445
-			// also check for upgrades for apps (independently from the user)
1446
-			$apps = \OC_App::getEnabledApps(false, true);
1447
-			$shouldUpgrade = false;
1448
-			foreach ($apps as $app) {
1449
-				if (\OC_App::shouldUpgrade($app)) {
1450
-					$shouldUpgrade = true;
1451
-					break;
1452
-				}
1453
-			}
1454
-			return $shouldUpgrade;
1455
-		} else {
1456
-			return false;
1457
-		}
1458
-	}
1459
-
1460
-	/**
1461
-	 * is this Internet explorer ?
1462
-	 *
1463
-	 * @return boolean
1464
-	 */
1465
-	public static function isIe() {
1466
-		if (!isset($_SERVER['HTTP_USER_AGENT'])) {
1467
-			return false;
1468
-		}
1469
-
1470
-		return preg_match(Request::USER_AGENT_IE, $_SERVER['HTTP_USER_AGENT']) === 1;
1471
-	}
1272
+        return $content !== $testContent && $fallbackContent !== $testContent;
1273
+    }
1274
+
1275
+    /**
1276
+     * Check if the setlocal call does not work. This can happen if the right
1277
+     * local packages are not available on the server.
1278
+     *
1279
+     * @return bool
1280
+     */
1281
+    public static function isSetLocaleWorking() {
1282
+        \Patchwork\Utf8\Bootup::initLocale();
1283
+        if ('' === basename('§')) {
1284
+            return false;
1285
+        }
1286
+        return true;
1287
+    }
1288
+
1289
+    /**
1290
+     * Check if it's possible to get the inline annotations
1291
+     *
1292
+     * @return bool
1293
+     */
1294
+    public static function isAnnotationsWorking() {
1295
+        $reflection = new \ReflectionMethod(__METHOD__);
1296
+        $docs = $reflection->getDocComment();
1297
+
1298
+        return (is_string($docs) && strlen($docs) > 50);
1299
+    }
1300
+
1301
+    /**
1302
+     * Check if the PHP module fileinfo is loaded.
1303
+     *
1304
+     * @return bool
1305
+     */
1306
+    public static function fileInfoLoaded() {
1307
+        return function_exists('finfo_open');
1308
+    }
1309
+
1310
+    /**
1311
+     * clear all levels of output buffering
1312
+     *
1313
+     * @return void
1314
+     */
1315
+    public static function obEnd() {
1316
+        while (ob_get_level()) {
1317
+            ob_end_clean();
1318
+        }
1319
+    }
1320
+
1321
+    /**
1322
+     * Checks whether the server is running on Mac OS X
1323
+     *
1324
+     * @return bool true if running on Mac OS X, false otherwise
1325
+     */
1326
+    public static function runningOnMac() {
1327
+        return (strtoupper(substr(PHP_OS, 0, 6)) === 'DARWIN');
1328
+    }
1329
+
1330
+    /**
1331
+     * Handles the case that there may not be a theme, then check if a "default"
1332
+     * theme exists and take that one
1333
+     *
1334
+     * @return string the theme
1335
+     */
1336
+    public static function getTheme() {
1337
+        $theme = \OC::$server->getSystemConfig()->getValue("theme", '');
1338
+
1339
+        if ($theme === '') {
1340
+            if (is_dir(OC::$SERVERROOT . '/themes/default')) {
1341
+                $theme = 'default';
1342
+            }
1343
+        }
1344
+
1345
+        return $theme;
1346
+    }
1347
+
1348
+    /**
1349
+     * Normalize a unicode string
1350
+     *
1351
+     * @param string $value a not normalized string
1352
+     * @return bool|string
1353
+     */
1354
+    public static function normalizeUnicode($value) {
1355
+        if(Normalizer::isNormalized($value)) {
1356
+            return $value;
1357
+        }
1358
+
1359
+        $normalizedValue = Normalizer::normalize($value);
1360
+        if ($normalizedValue === null || $normalizedValue === false) {
1361
+            \OC::$server->getLogger()->warning('normalizing failed for "' . $value . '"', ['app' => 'core']);
1362
+            return $value;
1363
+        }
1364
+
1365
+        return $normalizedValue;
1366
+    }
1367
+
1368
+    /**
1369
+     * A human readable string is generated based on version and build number
1370
+     *
1371
+     * @return string
1372
+     */
1373
+    public static function getHumanVersion() {
1374
+        $version = OC_Util::getVersionString();
1375
+        $build = OC_Util::getBuild();
1376
+        if (!empty($build) and OC_Util::getChannel() === 'daily') {
1377
+            $version .= ' Build:' . $build;
1378
+        }
1379
+        return $version;
1380
+    }
1381
+
1382
+    /**
1383
+     * Returns whether the given file name is valid
1384
+     *
1385
+     * @param string $file file name to check
1386
+     * @return bool true if the file name is valid, false otherwise
1387
+     * @deprecated use \OC\Files\View::verifyPath()
1388
+     */
1389
+    public static function isValidFileName($file) {
1390
+        $trimmed = trim($file);
1391
+        if ($trimmed === '') {
1392
+            return false;
1393
+        }
1394
+        if (\OC\Files\Filesystem::isIgnoredDir($trimmed)) {
1395
+            return false;
1396
+        }
1397
+
1398
+        // detect part files
1399
+        if (preg_match('/' . \OCP\Files\FileInfo::BLACKLIST_FILES_REGEX . '/', $trimmed) !== 0) {
1400
+            return false;
1401
+        }
1402
+
1403
+        foreach (str_split($trimmed) as $char) {
1404
+            if (strpos(\OCP\Constants::FILENAME_INVALID_CHARS, $char) !== false) {
1405
+                return false;
1406
+            }
1407
+        }
1408
+        return true;
1409
+    }
1410
+
1411
+    /**
1412
+     * Check whether the instance needs to perform an upgrade,
1413
+     * either when the core version is higher or any app requires
1414
+     * an upgrade.
1415
+     *
1416
+     * @param \OC\SystemConfig $config
1417
+     * @return bool whether the core or any app needs an upgrade
1418
+     * @throws \OC\HintException When the upgrade from the given version is not allowed
1419
+     */
1420
+    public static function needUpgrade(\OC\SystemConfig $config) {
1421
+        if ($config->getValue('installed', false)) {
1422
+            $installedVersion = $config->getValue('version', '0.0.0');
1423
+            $currentVersion = implode('.', \OCP\Util::getVersion());
1424
+            $versionDiff = version_compare($currentVersion, $installedVersion);
1425
+            if ($versionDiff > 0) {
1426
+                return true;
1427
+            } else if ($config->getValue('debug', false) && $versionDiff < 0) {
1428
+                // downgrade with debug
1429
+                $installedMajor = explode('.', $installedVersion);
1430
+                $installedMajor = $installedMajor[0] . '.' . $installedMajor[1];
1431
+                $currentMajor = explode('.', $currentVersion);
1432
+                $currentMajor = $currentMajor[0] . '.' . $currentMajor[1];
1433
+                if ($installedMajor === $currentMajor) {
1434
+                    // Same major, allow downgrade for developers
1435
+                    return true;
1436
+                } else {
1437
+                    // downgrade attempt, throw exception
1438
+                    throw new \OC\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')');
1439
+                }
1440
+            } else if ($versionDiff < 0) {
1441
+                // downgrade attempt, throw exception
1442
+                throw new \OC\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')');
1443
+            }
1444
+
1445
+            // also check for upgrades for apps (independently from the user)
1446
+            $apps = \OC_App::getEnabledApps(false, true);
1447
+            $shouldUpgrade = false;
1448
+            foreach ($apps as $app) {
1449
+                if (\OC_App::shouldUpgrade($app)) {
1450
+                    $shouldUpgrade = true;
1451
+                    break;
1452
+                }
1453
+            }
1454
+            return $shouldUpgrade;
1455
+        } else {
1456
+            return false;
1457
+        }
1458
+    }
1459
+
1460
+    /**
1461
+     * is this Internet explorer ?
1462
+     *
1463
+     * @return boolean
1464
+     */
1465
+    public static function isIe() {
1466
+        if (!isset($_SERVER['HTTP_USER_AGENT'])) {
1467
+            return false;
1468
+        }
1469
+
1470
+        return preg_match(Request::USER_AGENT_IE, $_SERVER['HTTP_USER_AGENT']) === 1;
1471
+    }
1472 1472
 
1473 1473
 }
Please login to merge, or discard this patch.
lib/private/Contacts/ContactsMenu/ContactsStore.php 1 patch
Indentation   +223 added lines, -223 removed lines patch added patch discarded remove patch
@@ -38,228 +38,228 @@
 block discarded – undo
38 38
 
39 39
 class ContactsStore implements IContactsStore {
40 40
 
41
-	/** @var IManager */
42
-	private $contactsManager;
43
-
44
-	/** @var IConfig */
45
-	private $config;
46
-
47
-	/** @var IUserManager */
48
-	private $userManager;
49
-
50
-	/** @var IGroupManager */
51
-	private $groupManager;
52
-
53
-	/**
54
-	 * @param IManager $contactsManager
55
-	 * @param IConfig $config
56
-	 * @param IUserManager $userManager
57
-	 * @param IGroupManager $groupManager
58
-	 */
59
-	public function __construct(IManager $contactsManager,
60
-								IConfig $config,
61
-								IUserManager $userManager,
62
-								IGroupManager $groupManager) {
63
-		$this->contactsManager = $contactsManager;
64
-		$this->config = $config;
65
-		$this->userManager = $userManager;
66
-		$this->groupManager = $groupManager;
67
-	}
68
-
69
-	/**
70
-	 * @param IUser $user
71
-	 * @param string|null $filter
72
-	 * @return IEntry[]
73
-	 */
74
-	public function getContacts(IUser $user, $filter) {
75
-		$allContacts = $this->contactsManager->search($filter ?: '', [
76
-			'FN',
77
-			'EMAIL'
78
-		]);
79
-
80
-		$entries = array_map(function(array $contact) {
81
-			return $this->contactArrayToEntry($contact);
82
-		}, $allContacts);
83
-		return $this->filterContacts(
84
-			$user,
85
-			$entries,
86
-			$filter
87
-		);
88
-	}
89
-
90
-	/**
91
-	 * Filters the contacts. Applies 3 filters:
92
-	 *  1. filter the current user
93
-	 *  2. if the `shareapi_allow_share_dialog_user_enumeration` config option is
94
-	 * enabled it will filter all local users
95
-	 *  3. if the `shareapi_exclude_groups` config option is enabled and the
96
-	 * current user is in an excluded group it will filter all local users.
97
-	 *  4. if the `shareapi_only_share_with_group_members` config option is
98
-	 * enabled it will filter all users which doens't have a common group
99
-	 * with the current user.
100
-	 *
101
-	 * @param IUser $self
102
-	 * @param Entry[] $entries
103
-	 * @param string $filter
104
-	 * @return Entry[] the filtered contacts
105
-	 */
106
-	private function filterContacts(IUser $self,
107
-									array $entries,
108
-									$filter) {
109
-		$disallowEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') !== 'yes';
110
-		$restrictEnumeration = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'yes') === 'yes';
111
-		$excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes';
112
-
113
-		// whether to filter out local users
114
-		$skipLocal = false;
115
-		// whether to filter out all users which doesn't have the same group as the current user
116
-		$ownGroupsOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes' || $restrictEnumeration;
117
-
118
-		$selfGroups = $this->groupManager->getUserGroupIds($self);
119
-
120
-		if ($excludedGroups) {
121
-			$excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
122
-			$decodedExcludeGroups = json_decode($excludedGroups, true);
123
-			$excludeGroupsList = ($decodedExcludeGroups !== null) ? $decodedExcludeGroups :  [];
124
-
125
-			if (count(array_intersect($excludeGroupsList, $selfGroups)) !== 0) {
126
-				// a group of the current user is excluded -> filter all local users
127
-				$skipLocal = true;
128
-			}
129
-		}
130
-
131
-		$selfUID = $self->getUID();
132
-
133
-		return array_values(array_filter($entries, function(IEntry $entry) use ($self, $skipLocal, $ownGroupsOnly, $selfGroups, $selfUID, $disallowEnumeration, $filter) {
134
-			if ($skipLocal && $entry->getProperty('isLocalSystemBook') === true) {
135
-				return false;
136
-			}
137
-
138
-			// Prevent enumerating local users
139
-			if($disallowEnumeration && $entry->getProperty('isLocalSystemBook')) {
140
-				$filterUser = true;
141
-
142
-				$mailAddresses = $entry->getEMailAddresses();
143
-				foreach($mailAddresses as $mailAddress) {
144
-					if($mailAddress === $filter) {
145
-						$filterUser = false;
146
-						break;
147
-					}
148
-				}
149
-
150
-				if($entry->getProperty('UID') && $entry->getProperty('UID') === $filter) {
151
-					$filterUser = false;
152
-				}
153
-
154
-				if($filterUser) {
155
-					return false;
156
-				}
157
-			}
158
-
159
-			if ($ownGroupsOnly && $entry->getProperty('isLocalSystemBook') === true) {
160
-				$uid = $this->userManager->get($entry->getProperty('UID'));
161
-
162
-				if ($uid === null) {
163
-					return false;
164
-				}
165
-
166
-				$contactGroups = $this->groupManager->getUserGroupIds($uid);
167
-				if (count(array_intersect($contactGroups, $selfGroups)) === 0) {
168
-					// no groups in common, so shouldn't see the contact
169
-					return false;
170
-				}
171
-			}
172
-
173
-			return $entry->getProperty('UID') !== $selfUID;
174
-		}));
175
-	}
176
-
177
-	/**
178
-	 * @param IUser $user
179
-	 * @param integer $shareType
180
-	 * @param string $shareWith
181
-	 * @return IEntry|null
182
-	 */
183
-	public function findOne(IUser $user, $shareType, $shareWith) {
184
-		switch($shareType) {
185
-			case 0:
186
-			case 6:
187
-				$filter = ['UID'];
188
-				break;
189
-			case 4:
190
-				$filter = ['EMAIL'];
191
-				break;
192
-			default:
193
-				return null;
194
-		}
195
-
196
-		$userId = $user->getUID();
197
-		$allContacts = $this->contactsManager->search($shareWith, $filter);
198
-		$contacts = array_filter($allContacts, function($contact) use ($userId) {
199
-			return $contact['UID'] !== $userId;
200
-		});
201
-		$match = null;
202
-
203
-		foreach ($contacts as $contact) {
204
-			if ($shareType === 4 && isset($contact['EMAIL'])) {
205
-				if (in_array($shareWith, $contact['EMAIL'])) {
206
-					$match = $contact;
207
-					break;
208
-				}
209
-			}
210
-			if ($shareType === 0 || $shareType === 6) {
211
-				$isLocal = $contact['isLocalSystemBook'] ?? false;
212
-				if ($contact['UID'] === $shareWith && $isLocal === true) {
213
-					$match = $contact;
214
-					break;
215
-				}
216
-			}
217
-		}
218
-
219
-		if ($match) {
220
-			$match = $this->filterContacts($user, [$this->contactArrayToEntry($match)], $shareWith);
221
-			if (count($match) === 1) {
222
-				$match = $match[0];
223
-			} else {
224
-				$match = null;
225
-			}
226
-
227
-		}
228
-
229
-		return $match;
230
-	}
231
-
232
-	/**
233
-	 * @param array $contact
234
-	 * @return Entry
235
-	 */
236
-	private function contactArrayToEntry(array $contact) {
237
-		$entry = new Entry();
238
-
239
-		if (isset($contact['id'])) {
240
-			$entry->setId($contact['id']);
241
-		}
242
-
243
-		if (isset($contact['FN'])) {
244
-			$entry->setFullName($contact['FN']);
245
-		}
246
-
247
-		$avatarPrefix = "VALUE=uri:";
248
-		if (isset($contact['PHOTO']) && strpos($contact['PHOTO'], $avatarPrefix) === 0) {
249
-			$entry->setAvatar(substr($contact['PHOTO'], strlen($avatarPrefix)));
250
-		}
251
-
252
-		if (isset($contact['EMAIL'])) {
253
-			foreach ($contact['EMAIL'] as $email) {
254
-				$entry->addEMailAddress($email);
255
-			}
256
-		}
257
-
258
-		// Attach all other properties to the entry too because some
259
-		// providers might make use of it.
260
-		$entry->setProperties($contact);
261
-
262
-		return $entry;
263
-	}
41
+    /** @var IManager */
42
+    private $contactsManager;
43
+
44
+    /** @var IConfig */
45
+    private $config;
46
+
47
+    /** @var IUserManager */
48
+    private $userManager;
49
+
50
+    /** @var IGroupManager */
51
+    private $groupManager;
52
+
53
+    /**
54
+     * @param IManager $contactsManager
55
+     * @param IConfig $config
56
+     * @param IUserManager $userManager
57
+     * @param IGroupManager $groupManager
58
+     */
59
+    public function __construct(IManager $contactsManager,
60
+                                IConfig $config,
61
+                                IUserManager $userManager,
62
+                                IGroupManager $groupManager) {
63
+        $this->contactsManager = $contactsManager;
64
+        $this->config = $config;
65
+        $this->userManager = $userManager;
66
+        $this->groupManager = $groupManager;
67
+    }
68
+
69
+    /**
70
+     * @param IUser $user
71
+     * @param string|null $filter
72
+     * @return IEntry[]
73
+     */
74
+    public function getContacts(IUser $user, $filter) {
75
+        $allContacts = $this->contactsManager->search($filter ?: '', [
76
+            'FN',
77
+            'EMAIL'
78
+        ]);
79
+
80
+        $entries = array_map(function(array $contact) {
81
+            return $this->contactArrayToEntry($contact);
82
+        }, $allContacts);
83
+        return $this->filterContacts(
84
+            $user,
85
+            $entries,
86
+            $filter
87
+        );
88
+    }
89
+
90
+    /**
91
+     * Filters the contacts. Applies 3 filters:
92
+     *  1. filter the current user
93
+     *  2. if the `shareapi_allow_share_dialog_user_enumeration` config option is
94
+     * enabled it will filter all local users
95
+     *  3. if the `shareapi_exclude_groups` config option is enabled and the
96
+     * current user is in an excluded group it will filter all local users.
97
+     *  4. if the `shareapi_only_share_with_group_members` config option is
98
+     * enabled it will filter all users which doens't have a common group
99
+     * with the current user.
100
+     *
101
+     * @param IUser $self
102
+     * @param Entry[] $entries
103
+     * @param string $filter
104
+     * @return Entry[] the filtered contacts
105
+     */
106
+    private function filterContacts(IUser $self,
107
+                                    array $entries,
108
+                                    $filter) {
109
+        $disallowEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') !== 'yes';
110
+        $restrictEnumeration = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'yes') === 'yes';
111
+        $excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes';
112
+
113
+        // whether to filter out local users
114
+        $skipLocal = false;
115
+        // whether to filter out all users which doesn't have the same group as the current user
116
+        $ownGroupsOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes' || $restrictEnumeration;
117
+
118
+        $selfGroups = $this->groupManager->getUserGroupIds($self);
119
+
120
+        if ($excludedGroups) {
121
+            $excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
122
+            $decodedExcludeGroups = json_decode($excludedGroups, true);
123
+            $excludeGroupsList = ($decodedExcludeGroups !== null) ? $decodedExcludeGroups :  [];
124
+
125
+            if (count(array_intersect($excludeGroupsList, $selfGroups)) !== 0) {
126
+                // a group of the current user is excluded -> filter all local users
127
+                $skipLocal = true;
128
+            }
129
+        }
130
+
131
+        $selfUID = $self->getUID();
132
+
133
+        return array_values(array_filter($entries, function(IEntry $entry) use ($self, $skipLocal, $ownGroupsOnly, $selfGroups, $selfUID, $disallowEnumeration, $filter) {
134
+            if ($skipLocal && $entry->getProperty('isLocalSystemBook') === true) {
135
+                return false;
136
+            }
137
+
138
+            // Prevent enumerating local users
139
+            if($disallowEnumeration && $entry->getProperty('isLocalSystemBook')) {
140
+                $filterUser = true;
141
+
142
+                $mailAddresses = $entry->getEMailAddresses();
143
+                foreach($mailAddresses as $mailAddress) {
144
+                    if($mailAddress === $filter) {
145
+                        $filterUser = false;
146
+                        break;
147
+                    }
148
+                }
149
+
150
+                if($entry->getProperty('UID') && $entry->getProperty('UID') === $filter) {
151
+                    $filterUser = false;
152
+                }
153
+
154
+                if($filterUser) {
155
+                    return false;
156
+                }
157
+            }
158
+
159
+            if ($ownGroupsOnly && $entry->getProperty('isLocalSystemBook') === true) {
160
+                $uid = $this->userManager->get($entry->getProperty('UID'));
161
+
162
+                if ($uid === null) {
163
+                    return false;
164
+                }
165
+
166
+                $contactGroups = $this->groupManager->getUserGroupIds($uid);
167
+                if (count(array_intersect($contactGroups, $selfGroups)) === 0) {
168
+                    // no groups in common, so shouldn't see the contact
169
+                    return false;
170
+                }
171
+            }
172
+
173
+            return $entry->getProperty('UID') !== $selfUID;
174
+        }));
175
+    }
176
+
177
+    /**
178
+     * @param IUser $user
179
+     * @param integer $shareType
180
+     * @param string $shareWith
181
+     * @return IEntry|null
182
+     */
183
+    public function findOne(IUser $user, $shareType, $shareWith) {
184
+        switch($shareType) {
185
+            case 0:
186
+            case 6:
187
+                $filter = ['UID'];
188
+                break;
189
+            case 4:
190
+                $filter = ['EMAIL'];
191
+                break;
192
+            default:
193
+                return null;
194
+        }
195
+
196
+        $userId = $user->getUID();
197
+        $allContacts = $this->contactsManager->search($shareWith, $filter);
198
+        $contacts = array_filter($allContacts, function($contact) use ($userId) {
199
+            return $contact['UID'] !== $userId;
200
+        });
201
+        $match = null;
202
+
203
+        foreach ($contacts as $contact) {
204
+            if ($shareType === 4 && isset($contact['EMAIL'])) {
205
+                if (in_array($shareWith, $contact['EMAIL'])) {
206
+                    $match = $contact;
207
+                    break;
208
+                }
209
+            }
210
+            if ($shareType === 0 || $shareType === 6) {
211
+                $isLocal = $contact['isLocalSystemBook'] ?? false;
212
+                if ($contact['UID'] === $shareWith && $isLocal === true) {
213
+                    $match = $contact;
214
+                    break;
215
+                }
216
+            }
217
+        }
218
+
219
+        if ($match) {
220
+            $match = $this->filterContacts($user, [$this->contactArrayToEntry($match)], $shareWith);
221
+            if (count($match) === 1) {
222
+                $match = $match[0];
223
+            } else {
224
+                $match = null;
225
+            }
226
+
227
+        }
228
+
229
+        return $match;
230
+    }
231
+
232
+    /**
233
+     * @param array $contact
234
+     * @return Entry
235
+     */
236
+    private function contactArrayToEntry(array $contact) {
237
+        $entry = new Entry();
238
+
239
+        if (isset($contact['id'])) {
240
+            $entry->setId($contact['id']);
241
+        }
242
+
243
+        if (isset($contact['FN'])) {
244
+            $entry->setFullName($contact['FN']);
245
+        }
246
+
247
+        $avatarPrefix = "VALUE=uri:";
248
+        if (isset($contact['PHOTO']) && strpos($contact['PHOTO'], $avatarPrefix) === 0) {
249
+            $entry->setAvatar(substr($contact['PHOTO'], strlen($avatarPrefix)));
250
+        }
251
+
252
+        if (isset($contact['EMAIL'])) {
253
+            foreach ($contact['EMAIL'] as $email) {
254
+                $entry->addEMailAddress($email);
255
+            }
256
+        }
257
+
258
+        // Attach all other properties to the entry too because some
259
+        // providers might make use of it.
260
+        $entry->setProperties($contact);
261
+
262
+        return $entry;
263
+    }
264 264
 
265 265
 }
Please login to merge, or discard this patch.
lib/private/Template/JSCombiner.php 1 patch
Indentation   +220 added lines, -220 removed lines patch added patch discarded remove patch
@@ -38,224 +38,224 @@
 block discarded – undo
38 38
 
39 39
 class JSCombiner {
40 40
 
41
-	/** @var IAppData */
42
-	protected $appData;
43
-
44
-	/** @var IURLGenerator */
45
-	protected $urlGenerator;
46
-
47
-	/** @var ICache */
48
-	protected $depsCache;
49
-
50
-	/** @var SystemConfig */
51
-	protected $config;
52
-
53
-	/** @var ILogger */
54
-	protected $logger;
55
-
56
-	/** @var ICacheFactory */
57
-	private $cacheFactory;
58
-
59
-	/**
60
-	 * @param IAppData $appData
61
-	 * @param IURLGenerator $urlGenerator
62
-	 * @param ICacheFactory $cacheFactory
63
-	 * @param SystemConfig $config
64
-	 * @param ILogger $logger
65
-	 */
66
-	public function __construct(IAppData $appData,
67
-								IURLGenerator $urlGenerator,
68
-								ICacheFactory $cacheFactory,
69
-								SystemConfig $config,
70
-								ILogger $logger) {
71
-		$this->appData = $appData;
72
-		$this->urlGenerator = $urlGenerator;
73
-		$this->cacheFactory = $cacheFactory;
74
-		$this->depsCache = $this->cacheFactory->createDistributed('JS-' . md5($this->urlGenerator->getBaseUrl()));
75
-		$this->config = $config;
76
-		$this->logger = $logger;
77
-	}
78
-
79
-	/**
80
-	 * @param string $root
81
-	 * @param string $file
82
-	 * @param string $app
83
-	 * @return bool
84
-	 */
85
-	public function process($root, $file, $app) {
86
-		if ($this->config->getValue('debug') || !$this->config->getValue('installed')) {
87
-			return false;
88
-		}
89
-
90
-		$path = explode('/', $root . '/' . $file);
91
-
92
-		$fileName = array_pop($path);
93
-		$path = implode('/', $path);
94
-
95
-		try {
96
-			$folder = $this->appData->getFolder($app);
97
-		} catch(NotFoundException $e) {
98
-			// creating css appdata folder
99
-			$folder = $this->appData->newFolder($app);
100
-		}
101
-
102
-		if($this->isCached($fileName, $folder)) {
103
-			return true;
104
-		}
105
-		return $this->cache($path, $fileName, $folder);
106
-	}
107
-
108
-	/**
109
-	 * @param string $fileName
110
-	 * @param ISimpleFolder $folder
111
-	 * @return bool
112
-	 */
113
-	protected function isCached($fileName, ISimpleFolder $folder) {
114
-		$fileName = str_replace('.json', '.js', $fileName);
115
-
116
-		if (!$folder->fileExists($fileName)) {
117
-			return false;
118
-		}
119
-
120
-		$fileName = $fileName . '.deps';
121
-		try {
122
-			$deps = $this->depsCache->get($folder->getName() . '-' . $fileName);
123
-			if ($deps === null || $deps === '') {
124
-				$depFile = $folder->getFile($fileName);
125
-				$deps = $depFile->getContent();
126
-			}
127
-
128
-			// check again
129
-			if ($deps === null || $deps === '') {
130
-				$this->logger->info('JSCombiner: deps file empty: ' . $fileName);
131
-				return false;
132
-			}
133
-
134
-			$deps = json_decode($deps, true);
135
-
136
-			if ($deps === null) {
137
-				return false;
138
-			}
139
-
140
-			foreach ($deps as $file=>$mtime) {
141
-				if (!file_exists($file) || filemtime($file) > $mtime) {
142
-					return false;
143
-				}
144
-			}
145
-
146
-			return true;
147
-		} catch(NotFoundException $e) {
148
-			return false;
149
-		}
150
-	}
151
-
152
-	/**
153
-	 * @param string $path
154
-	 * @param string $fileName
155
-	 * @param ISimpleFolder $folder
156
-	 * @return bool
157
-	 */
158
-	protected function cache($path, $fileName, ISimpleFolder $folder) {
159
-		$deps = [];
160
-		$fullPath = $path . '/' . $fileName;
161
-		$data = json_decode(file_get_contents($fullPath));
162
-		$deps[$fullPath] = filemtime($fullPath);
163
-
164
-		$res = '';
165
-		foreach ($data as $file) {
166
-			$filePath = $path . '/' . $file;
167
-
168
-			if (is_file($filePath)) {
169
-				$res .= file_get_contents($filePath);
170
-				$res .= PHP_EOL . PHP_EOL;
171
-				$deps[$filePath] = filemtime($filePath);
172
-			}
173
-		}
174
-
175
-		$fileName = str_replace('.json', '.js', $fileName);
176
-		try {
177
-			$cachedfile = $folder->getFile($fileName);
178
-		} catch(NotFoundException $e) {
179
-			$cachedfile = $folder->newFile($fileName);
180
-		}
181
-
182
-		$depFileName = $fileName . '.deps';
183
-		try {
184
-			$depFile = $folder->getFile($depFileName);
185
-		} catch (NotFoundException $e) {
186
-			$depFile = $folder->newFile($depFileName);
187
-		}
188
-
189
-		try {
190
-			$gzipFile = $folder->getFile($fileName . '.gzip'); # Safari doesn't like .gz
191
-		} catch (NotFoundException $e) {
192
-			$gzipFile = $folder->newFile($fileName . '.gzip'); # Safari doesn't like .gz
193
-		}
194
-
195
-		try {
196
-			$cachedfile->putContent($res);
197
-			$deps = json_encode($deps);
198
-			$depFile->putContent($deps);
199
-			$this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
200
-			$gzipFile->putContent(gzencode($res, 9));
201
-			$this->logger->debug('JSCombiner: successfully cached: ' . $fileName);
202
-			return true;
203
-		} catch (NotPermittedException $e) {
204
-			$this->logger->error('JSCombiner: unable to cache: ' . $fileName);
205
-			return false;
206
-		}
207
-	}
208
-
209
-	/**
210
-	 * @param string $appName
211
-	 * @param string $fileName
212
-	 * @return string
213
-	 */
214
-	public function getCachedJS($appName, $fileName) {
215
-		$tmpfileLoc = explode('/', $fileName);
216
-		$fileName = array_pop($tmpfileLoc);
217
-		$fileName = str_replace('.json', '.js', $fileName);
218
-
219
-		return substr($this->urlGenerator->linkToRoute('core.Js.getJs', array('fileName' => $fileName, 'appName' => $appName)), strlen(\OC::$WEBROOT) + 1);
220
-	}
221
-
222
-	/**
223
-	 * @param string $root
224
-	 * @param string $file
225
-	 * @return string[]
226
-	 */
227
-	public function getContent($root, $file) {
228
-		/** @var array $data */
229
-		$data = json_decode(file_get_contents($root . '/' . $file));
230
-		if(!is_array($data)) {
231
-			return [];
232
-		}
233
-
234
-		$path = explode('/', $file);
235
-		array_pop($path);
236
-		$path = implode('/', $path);
237
-
238
-		$result = [];
239
-		foreach ($data as $f) {
240
-			$result[] = $path . '/' . $f;
241
-		}
242
-
243
-		return $result;
244
-	}
245
-
246
-
247
-	/**
248
-	 * Clear cache with combined javascript files
249
-	 *
250
-	 * @throws NotFoundException
251
-	 */
252
-	public function resetCache() {
253
-		$this->cacheFactory->createDistributed('JS-')->clear();
254
-		$appDirectory = $this->appData->getDirectoryListing();
255
-		foreach ($appDirectory as $folder) {
256
-			foreach ($folder->getDirectoryListing() as $file) {
257
-				$file->delete();
258
-			}
259
-		}
260
-	}
41
+    /** @var IAppData */
42
+    protected $appData;
43
+
44
+    /** @var IURLGenerator */
45
+    protected $urlGenerator;
46
+
47
+    /** @var ICache */
48
+    protected $depsCache;
49
+
50
+    /** @var SystemConfig */
51
+    protected $config;
52
+
53
+    /** @var ILogger */
54
+    protected $logger;
55
+
56
+    /** @var ICacheFactory */
57
+    private $cacheFactory;
58
+
59
+    /**
60
+     * @param IAppData $appData
61
+     * @param IURLGenerator $urlGenerator
62
+     * @param ICacheFactory $cacheFactory
63
+     * @param SystemConfig $config
64
+     * @param ILogger $logger
65
+     */
66
+    public function __construct(IAppData $appData,
67
+                                IURLGenerator $urlGenerator,
68
+                                ICacheFactory $cacheFactory,
69
+                                SystemConfig $config,
70
+                                ILogger $logger) {
71
+        $this->appData = $appData;
72
+        $this->urlGenerator = $urlGenerator;
73
+        $this->cacheFactory = $cacheFactory;
74
+        $this->depsCache = $this->cacheFactory->createDistributed('JS-' . md5($this->urlGenerator->getBaseUrl()));
75
+        $this->config = $config;
76
+        $this->logger = $logger;
77
+    }
78
+
79
+    /**
80
+     * @param string $root
81
+     * @param string $file
82
+     * @param string $app
83
+     * @return bool
84
+     */
85
+    public function process($root, $file, $app) {
86
+        if ($this->config->getValue('debug') || !$this->config->getValue('installed')) {
87
+            return false;
88
+        }
89
+
90
+        $path = explode('/', $root . '/' . $file);
91
+
92
+        $fileName = array_pop($path);
93
+        $path = implode('/', $path);
94
+
95
+        try {
96
+            $folder = $this->appData->getFolder($app);
97
+        } catch(NotFoundException $e) {
98
+            // creating css appdata folder
99
+            $folder = $this->appData->newFolder($app);
100
+        }
101
+
102
+        if($this->isCached($fileName, $folder)) {
103
+            return true;
104
+        }
105
+        return $this->cache($path, $fileName, $folder);
106
+    }
107
+
108
+    /**
109
+     * @param string $fileName
110
+     * @param ISimpleFolder $folder
111
+     * @return bool
112
+     */
113
+    protected function isCached($fileName, ISimpleFolder $folder) {
114
+        $fileName = str_replace('.json', '.js', $fileName);
115
+
116
+        if (!$folder->fileExists($fileName)) {
117
+            return false;
118
+        }
119
+
120
+        $fileName = $fileName . '.deps';
121
+        try {
122
+            $deps = $this->depsCache->get($folder->getName() . '-' . $fileName);
123
+            if ($deps === null || $deps === '') {
124
+                $depFile = $folder->getFile($fileName);
125
+                $deps = $depFile->getContent();
126
+            }
127
+
128
+            // check again
129
+            if ($deps === null || $deps === '') {
130
+                $this->logger->info('JSCombiner: deps file empty: ' . $fileName);
131
+                return false;
132
+            }
133
+
134
+            $deps = json_decode($deps, true);
135
+
136
+            if ($deps === null) {
137
+                return false;
138
+            }
139
+
140
+            foreach ($deps as $file=>$mtime) {
141
+                if (!file_exists($file) || filemtime($file) > $mtime) {
142
+                    return false;
143
+                }
144
+            }
145
+
146
+            return true;
147
+        } catch(NotFoundException $e) {
148
+            return false;
149
+        }
150
+    }
151
+
152
+    /**
153
+     * @param string $path
154
+     * @param string $fileName
155
+     * @param ISimpleFolder $folder
156
+     * @return bool
157
+     */
158
+    protected function cache($path, $fileName, ISimpleFolder $folder) {
159
+        $deps = [];
160
+        $fullPath = $path . '/' . $fileName;
161
+        $data = json_decode(file_get_contents($fullPath));
162
+        $deps[$fullPath] = filemtime($fullPath);
163
+
164
+        $res = '';
165
+        foreach ($data as $file) {
166
+            $filePath = $path . '/' . $file;
167
+
168
+            if (is_file($filePath)) {
169
+                $res .= file_get_contents($filePath);
170
+                $res .= PHP_EOL . PHP_EOL;
171
+                $deps[$filePath] = filemtime($filePath);
172
+            }
173
+        }
174
+
175
+        $fileName = str_replace('.json', '.js', $fileName);
176
+        try {
177
+            $cachedfile = $folder->getFile($fileName);
178
+        } catch(NotFoundException $e) {
179
+            $cachedfile = $folder->newFile($fileName);
180
+        }
181
+
182
+        $depFileName = $fileName . '.deps';
183
+        try {
184
+            $depFile = $folder->getFile($depFileName);
185
+        } catch (NotFoundException $e) {
186
+            $depFile = $folder->newFile($depFileName);
187
+        }
188
+
189
+        try {
190
+            $gzipFile = $folder->getFile($fileName . '.gzip'); # Safari doesn't like .gz
191
+        } catch (NotFoundException $e) {
192
+            $gzipFile = $folder->newFile($fileName . '.gzip'); # Safari doesn't like .gz
193
+        }
194
+
195
+        try {
196
+            $cachedfile->putContent($res);
197
+            $deps = json_encode($deps);
198
+            $depFile->putContent($deps);
199
+            $this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
200
+            $gzipFile->putContent(gzencode($res, 9));
201
+            $this->logger->debug('JSCombiner: successfully cached: ' . $fileName);
202
+            return true;
203
+        } catch (NotPermittedException $e) {
204
+            $this->logger->error('JSCombiner: unable to cache: ' . $fileName);
205
+            return false;
206
+        }
207
+    }
208
+
209
+    /**
210
+     * @param string $appName
211
+     * @param string $fileName
212
+     * @return string
213
+     */
214
+    public function getCachedJS($appName, $fileName) {
215
+        $tmpfileLoc = explode('/', $fileName);
216
+        $fileName = array_pop($tmpfileLoc);
217
+        $fileName = str_replace('.json', '.js', $fileName);
218
+
219
+        return substr($this->urlGenerator->linkToRoute('core.Js.getJs', array('fileName' => $fileName, 'appName' => $appName)), strlen(\OC::$WEBROOT) + 1);
220
+    }
221
+
222
+    /**
223
+     * @param string $root
224
+     * @param string $file
225
+     * @return string[]
226
+     */
227
+    public function getContent($root, $file) {
228
+        /** @var array $data */
229
+        $data = json_decode(file_get_contents($root . '/' . $file));
230
+        if(!is_array($data)) {
231
+            return [];
232
+        }
233
+
234
+        $path = explode('/', $file);
235
+        array_pop($path);
236
+        $path = implode('/', $path);
237
+
238
+        $result = [];
239
+        foreach ($data as $f) {
240
+            $result[] = $path . '/' . $f;
241
+        }
242
+
243
+        return $result;
244
+    }
245
+
246
+
247
+    /**
248
+     * Clear cache with combined javascript files
249
+     *
250
+     * @throws NotFoundException
251
+     */
252
+    public function resetCache() {
253
+        $this->cacheFactory->createDistributed('JS-')->clear();
254
+        $appDirectory = $this->appData->getDirectoryListing();
255
+        foreach ($appDirectory as $folder) {
256
+            foreach ($folder->getDirectoryListing() as $file) {
257
+                $file->delete();
258
+            }
259
+        }
260
+    }
261 261
 }
Please login to merge, or discard this patch.
lib/private/Files/Cache/Wrapper/CacheJail.php 1 patch
Indentation   +292 added lines, -292 removed lines patch added patch discarded remove patch
@@ -37,296 +37,296 @@
 block discarded – undo
37 37
  * Jail to a subdirectory of the wrapped cache
38 38
  */
39 39
 class CacheJail extends CacheWrapper {
40
-	/**
41
-	 * @var string
42
-	 */
43
-	protected $root;
44
-
45
-	/**
46
-	 * @param \OCP\Files\Cache\ICache $cache
47
-	 * @param string $root
48
-	 */
49
-	public function __construct($cache, $root) {
50
-		parent::__construct($cache);
51
-		$this->root = $root;
52
-	}
53
-
54
-	protected function getRoot() {
55
-		return $this->root;
56
-	}
57
-
58
-	protected function getSourcePath($path) {
59
-		if ($path === '') {
60
-			return $this->getRoot();
61
-		} else {
62
-			return $this->getRoot() . '/' . ltrim($path, '/');
63
-		}
64
-	}
65
-
66
-	/**
67
-	 * @param string $path
68
-	 * @return null|string the jailed path or null if the path is outside the jail
69
-	 */
70
-	protected function getJailedPath($path) {
71
-		if ($this->getRoot() === '') {
72
-			return $path;
73
-		}
74
-		$rootLength = strlen($this->getRoot()) + 1;
75
-		if ($path === $this->getRoot()) {
76
-			return '';
77
-		} else if (substr($path, 0, $rootLength) === $this->getRoot() . '/') {
78
-			return substr($path, $rootLength);
79
-		} else {
80
-			return null;
81
-		}
82
-	}
83
-
84
-	/**
85
-	 * @param ICacheEntry|array $entry
86
-	 * @return array
87
-	 */
88
-	protected function formatCacheEntry($entry) {
89
-		if (isset($entry['path'])) {
90
-			$entry['path'] = $this->getJailedPath($entry['path']);
91
-		}
92
-		return $entry;
93
-	}
94
-
95
-	protected function filterCacheEntry($entry) {
96
-		$rootLength = strlen($this->getRoot()) + 1;
97
-		return $rootLength === 1 || ($entry['path'] === $this->getRoot()) || (substr($entry['path'], 0, $rootLength) === $this->getRoot() . '/');
98
-	}
99
-
100
-	/**
101
-	 * get the stored metadata of a file or folder
102
-	 *
103
-	 * @param string /int $file
104
-	 * @return ICacheEntry|false
105
-	 */
106
-	public function get($file) {
107
-		if (is_string($file) or $file == '') {
108
-			$file = $this->getSourcePath($file);
109
-		}
110
-		return parent::get($file);
111
-	}
112
-
113
-	/**
114
-	 * insert meta data for a new file or folder
115
-	 *
116
-	 * @param string $file
117
-	 * @param array $data
118
-	 *
119
-	 * @return int file id
120
-	 * @throws \RuntimeException
121
-	 */
122
-	public function insert($file, array $data) {
123
-		return $this->getCache()->insert($this->getSourcePath($file), $data);
124
-	}
125
-
126
-	/**
127
-	 * update the metadata in the cache
128
-	 *
129
-	 * @param int $id
130
-	 * @param array $data
131
-	 */
132
-	public function update($id, array $data) {
133
-		$this->getCache()->update($id, $data);
134
-	}
135
-
136
-	/**
137
-	 * get the file id for a file
138
-	 *
139
-	 * @param string $file
140
-	 * @return int
141
-	 */
142
-	public function getId($file) {
143
-		return $this->getCache()->getId($this->getSourcePath($file));
144
-	}
145
-
146
-	/**
147
-	 * get the id of the parent folder of a file
148
-	 *
149
-	 * @param string $file
150
-	 * @return int
151
-	 */
152
-	public function getParentId($file) {
153
-		return $this->getCache()->getParentId($this->getSourcePath($file));
154
-	}
155
-
156
-	/**
157
-	 * check if a file is available in the cache
158
-	 *
159
-	 * @param string $file
160
-	 * @return bool
161
-	 */
162
-	public function inCache($file) {
163
-		return $this->getCache()->inCache($this->getSourcePath($file));
164
-	}
165
-
166
-	/**
167
-	 * remove a file or folder from the cache
168
-	 *
169
-	 * @param string $file
170
-	 */
171
-	public function remove($file) {
172
-		$this->getCache()->remove($this->getSourcePath($file));
173
-	}
174
-
175
-	/**
176
-	 * Move a file or folder in the cache
177
-	 *
178
-	 * @param string $source
179
-	 * @param string $target
180
-	 */
181
-	public function move($source, $target) {
182
-		$this->getCache()->move($this->getSourcePath($source), $this->getSourcePath($target));
183
-	}
184
-
185
-	/**
186
-	 * Get the storage id and path needed for a move
187
-	 *
188
-	 * @param string $path
189
-	 * @return array [$storageId, $internalPath]
190
-	 */
191
-	protected function getMoveInfo($path) {
192
-		return [$this->getNumericStorageId(), $this->getSourcePath($path)];
193
-	}
194
-
195
-	/**
196
-	 * remove all entries for files that are stored on the storage from the cache
197
-	 */
198
-	public function clear() {
199
-		$this->getCache()->remove($this->getRoot());
200
-	}
201
-
202
-	/**
203
-	 * @param string $file
204
-	 *
205
-	 * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
206
-	 */
207
-	public function getStatus($file) {
208
-		return $this->getCache()->getStatus($this->getSourcePath($file));
209
-	}
210
-
211
-	private function formatSearchResults($results) {
212
-		$results = array_filter($results, array($this, 'filterCacheEntry'));
213
-		$results = array_values($results);
214
-		return array_map(array($this, 'formatCacheEntry'), $results);
215
-	}
216
-
217
-	/**
218
-	 * search for files matching $pattern
219
-	 *
220
-	 * @param string $pattern
221
-	 * @return array an array of file data
222
-	 */
223
-	public function search($pattern) {
224
-		$results = $this->getCache()->search($pattern);
225
-		return $this->formatSearchResults($results);
226
-	}
227
-
228
-	/**
229
-	 * search for files by mimetype
230
-	 *
231
-	 * @param string $mimetype
232
-	 * @return array
233
-	 */
234
-	public function searchByMime($mimetype) {
235
-		$results = $this->getCache()->searchByMime($mimetype);
236
-		return $this->formatSearchResults($results);
237
-	}
238
-
239
-	public function searchQuery(ISearchQuery $query) {
240
-		$simpleQuery = new SearchQuery($query->getSearchOperation(), 0, 0, $query->getOrder(), $query->getUser());
241
-		$results = $this->getCache()->searchQuery($simpleQuery);
242
-		$results = $this->formatSearchResults($results);
243
-
244
-		$limit = $query->getLimit() === 0 ? null : $query->getLimit();
245
-		$results = array_slice($results, $query->getOffset(), $limit);
246
-
247
-		return $results;
248
-	}
249
-
250
-	/**
251
-	 * update the folder size and the size of all parent folders
252
-	 *
253
-	 * @param string|boolean $path
254
-	 * @param array $data (optional) meta data of the folder
255
-	 */
256
-	public function correctFolderSize($path, $data = null, $isBackgroundSize = false) {
257
-		if ($this->getCache() instanceof Cache) {
258
-			$this->getCache()->correctFolderSize($this->getSourcePath($path), $data, $isBackgroundSize);
259
-		}
260
-	}
261
-
262
-	/**
263
-	 * get the size of a folder and set it in the cache
264
-	 *
265
-	 * @param string $path
266
-	 * @param array $entry (optional) meta data of the folder
267
-	 * @return int
268
-	 */
269
-	public function calculateFolderSize($path, $entry = null) {
270
-		if ($this->getCache() instanceof Cache) {
271
-			return $this->getCache()->calculateFolderSize($this->getSourcePath($path), $entry);
272
-		} else {
273
-			return 0;
274
-		}
275
-
276
-	}
277
-
278
-	/**
279
-	 * get all file ids on the files on the storage
280
-	 *
281
-	 * @return int[]
282
-	 */
283
-	public function getAll() {
284
-		// not supported
285
-		return array();
286
-	}
287
-
288
-	/**
289
-	 * find a folder in the cache which has not been fully scanned
290
-	 *
291
-	 * If multiply incomplete folders are in the cache, the one with the highest id will be returned,
292
-	 * use the one with the highest id gives the best result with the background scanner, since that is most
293
-	 * likely the folder where we stopped scanning previously
294
-	 *
295
-	 * @return string|bool the path of the folder or false when no folder matched
296
-	 */
297
-	public function getIncomplete() {
298
-		// not supported
299
-		return false;
300
-	}
301
-
302
-	/**
303
-	 * get the path of a file on this storage by it's id
304
-	 *
305
-	 * @param int $id
306
-	 * @return string|null
307
-	 */
308
-	public function getPathById($id) {
309
-		$path = $this->getCache()->getPathById($id);
310
-		if ($path === null) {
311
-			return null;
312
-		}
313
-
314
-		return $this->getJailedPath($path);
315
-	}
316
-
317
-	/**
318
-	 * Move a file or folder in the cache
319
-	 *
320
-	 * Note that this should make sure the entries are removed from the source cache
321
-	 *
322
-	 * @param \OCP\Files\Cache\ICache $sourceCache
323
-	 * @param string $sourcePath
324
-	 * @param string $targetPath
325
-	 */
326
-	public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath, $targetPath) {
327
-		if ($sourceCache === $this) {
328
-			return $this->move($sourcePath, $targetPath);
329
-		}
330
-		return $this->getCache()->moveFromCache($sourceCache, $sourcePath, $this->getSourcePath($targetPath));
331
-	}
40
+    /**
41
+     * @var string
42
+     */
43
+    protected $root;
44
+
45
+    /**
46
+     * @param \OCP\Files\Cache\ICache $cache
47
+     * @param string $root
48
+     */
49
+    public function __construct($cache, $root) {
50
+        parent::__construct($cache);
51
+        $this->root = $root;
52
+    }
53
+
54
+    protected function getRoot() {
55
+        return $this->root;
56
+    }
57
+
58
+    protected function getSourcePath($path) {
59
+        if ($path === '') {
60
+            return $this->getRoot();
61
+        } else {
62
+            return $this->getRoot() . '/' . ltrim($path, '/');
63
+        }
64
+    }
65
+
66
+    /**
67
+     * @param string $path
68
+     * @return null|string the jailed path or null if the path is outside the jail
69
+     */
70
+    protected function getJailedPath($path) {
71
+        if ($this->getRoot() === '') {
72
+            return $path;
73
+        }
74
+        $rootLength = strlen($this->getRoot()) + 1;
75
+        if ($path === $this->getRoot()) {
76
+            return '';
77
+        } else if (substr($path, 0, $rootLength) === $this->getRoot() . '/') {
78
+            return substr($path, $rootLength);
79
+        } else {
80
+            return null;
81
+        }
82
+    }
83
+
84
+    /**
85
+     * @param ICacheEntry|array $entry
86
+     * @return array
87
+     */
88
+    protected function formatCacheEntry($entry) {
89
+        if (isset($entry['path'])) {
90
+            $entry['path'] = $this->getJailedPath($entry['path']);
91
+        }
92
+        return $entry;
93
+    }
94
+
95
+    protected function filterCacheEntry($entry) {
96
+        $rootLength = strlen($this->getRoot()) + 1;
97
+        return $rootLength === 1 || ($entry['path'] === $this->getRoot()) || (substr($entry['path'], 0, $rootLength) === $this->getRoot() . '/');
98
+    }
99
+
100
+    /**
101
+     * get the stored metadata of a file or folder
102
+     *
103
+     * @param string /int $file
104
+     * @return ICacheEntry|false
105
+     */
106
+    public function get($file) {
107
+        if (is_string($file) or $file == '') {
108
+            $file = $this->getSourcePath($file);
109
+        }
110
+        return parent::get($file);
111
+    }
112
+
113
+    /**
114
+     * insert meta data for a new file or folder
115
+     *
116
+     * @param string $file
117
+     * @param array $data
118
+     *
119
+     * @return int file id
120
+     * @throws \RuntimeException
121
+     */
122
+    public function insert($file, array $data) {
123
+        return $this->getCache()->insert($this->getSourcePath($file), $data);
124
+    }
125
+
126
+    /**
127
+     * update the metadata in the cache
128
+     *
129
+     * @param int $id
130
+     * @param array $data
131
+     */
132
+    public function update($id, array $data) {
133
+        $this->getCache()->update($id, $data);
134
+    }
135
+
136
+    /**
137
+     * get the file id for a file
138
+     *
139
+     * @param string $file
140
+     * @return int
141
+     */
142
+    public function getId($file) {
143
+        return $this->getCache()->getId($this->getSourcePath($file));
144
+    }
145
+
146
+    /**
147
+     * get the id of the parent folder of a file
148
+     *
149
+     * @param string $file
150
+     * @return int
151
+     */
152
+    public function getParentId($file) {
153
+        return $this->getCache()->getParentId($this->getSourcePath($file));
154
+    }
155
+
156
+    /**
157
+     * check if a file is available in the cache
158
+     *
159
+     * @param string $file
160
+     * @return bool
161
+     */
162
+    public function inCache($file) {
163
+        return $this->getCache()->inCache($this->getSourcePath($file));
164
+    }
165
+
166
+    /**
167
+     * remove a file or folder from the cache
168
+     *
169
+     * @param string $file
170
+     */
171
+    public function remove($file) {
172
+        $this->getCache()->remove($this->getSourcePath($file));
173
+    }
174
+
175
+    /**
176
+     * Move a file or folder in the cache
177
+     *
178
+     * @param string $source
179
+     * @param string $target
180
+     */
181
+    public function move($source, $target) {
182
+        $this->getCache()->move($this->getSourcePath($source), $this->getSourcePath($target));
183
+    }
184
+
185
+    /**
186
+     * Get the storage id and path needed for a move
187
+     *
188
+     * @param string $path
189
+     * @return array [$storageId, $internalPath]
190
+     */
191
+    protected function getMoveInfo($path) {
192
+        return [$this->getNumericStorageId(), $this->getSourcePath($path)];
193
+    }
194
+
195
+    /**
196
+     * remove all entries for files that are stored on the storage from the cache
197
+     */
198
+    public function clear() {
199
+        $this->getCache()->remove($this->getRoot());
200
+    }
201
+
202
+    /**
203
+     * @param string $file
204
+     *
205
+     * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
206
+     */
207
+    public function getStatus($file) {
208
+        return $this->getCache()->getStatus($this->getSourcePath($file));
209
+    }
210
+
211
+    private function formatSearchResults($results) {
212
+        $results = array_filter($results, array($this, 'filterCacheEntry'));
213
+        $results = array_values($results);
214
+        return array_map(array($this, 'formatCacheEntry'), $results);
215
+    }
216
+
217
+    /**
218
+     * search for files matching $pattern
219
+     *
220
+     * @param string $pattern
221
+     * @return array an array of file data
222
+     */
223
+    public function search($pattern) {
224
+        $results = $this->getCache()->search($pattern);
225
+        return $this->formatSearchResults($results);
226
+    }
227
+
228
+    /**
229
+     * search for files by mimetype
230
+     *
231
+     * @param string $mimetype
232
+     * @return array
233
+     */
234
+    public function searchByMime($mimetype) {
235
+        $results = $this->getCache()->searchByMime($mimetype);
236
+        return $this->formatSearchResults($results);
237
+    }
238
+
239
+    public function searchQuery(ISearchQuery $query) {
240
+        $simpleQuery = new SearchQuery($query->getSearchOperation(), 0, 0, $query->getOrder(), $query->getUser());
241
+        $results = $this->getCache()->searchQuery($simpleQuery);
242
+        $results = $this->formatSearchResults($results);
243
+
244
+        $limit = $query->getLimit() === 0 ? null : $query->getLimit();
245
+        $results = array_slice($results, $query->getOffset(), $limit);
246
+
247
+        return $results;
248
+    }
249
+
250
+    /**
251
+     * update the folder size and the size of all parent folders
252
+     *
253
+     * @param string|boolean $path
254
+     * @param array $data (optional) meta data of the folder
255
+     */
256
+    public function correctFolderSize($path, $data = null, $isBackgroundSize = false) {
257
+        if ($this->getCache() instanceof Cache) {
258
+            $this->getCache()->correctFolderSize($this->getSourcePath($path), $data, $isBackgroundSize);
259
+        }
260
+    }
261
+
262
+    /**
263
+     * get the size of a folder and set it in the cache
264
+     *
265
+     * @param string $path
266
+     * @param array $entry (optional) meta data of the folder
267
+     * @return int
268
+     */
269
+    public function calculateFolderSize($path, $entry = null) {
270
+        if ($this->getCache() instanceof Cache) {
271
+            return $this->getCache()->calculateFolderSize($this->getSourcePath($path), $entry);
272
+        } else {
273
+            return 0;
274
+        }
275
+
276
+    }
277
+
278
+    /**
279
+     * get all file ids on the files on the storage
280
+     *
281
+     * @return int[]
282
+     */
283
+    public function getAll() {
284
+        // not supported
285
+        return array();
286
+    }
287
+
288
+    /**
289
+     * find a folder in the cache which has not been fully scanned
290
+     *
291
+     * If multiply incomplete folders are in the cache, the one with the highest id will be returned,
292
+     * use the one with the highest id gives the best result with the background scanner, since that is most
293
+     * likely the folder where we stopped scanning previously
294
+     *
295
+     * @return string|bool the path of the folder or false when no folder matched
296
+     */
297
+    public function getIncomplete() {
298
+        // not supported
299
+        return false;
300
+    }
301
+
302
+    /**
303
+     * get the path of a file on this storage by it's id
304
+     *
305
+     * @param int $id
306
+     * @return string|null
307
+     */
308
+    public function getPathById($id) {
309
+        $path = $this->getCache()->getPathById($id);
310
+        if ($path === null) {
311
+            return null;
312
+        }
313
+
314
+        return $this->getJailedPath($path);
315
+    }
316
+
317
+    /**
318
+     * Move a file or folder in the cache
319
+     *
320
+     * Note that this should make sure the entries are removed from the source cache
321
+     *
322
+     * @param \OCP\Files\Cache\ICache $sourceCache
323
+     * @param string $sourcePath
324
+     * @param string $targetPath
325
+     */
326
+    public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath, $targetPath) {
327
+        if ($sourceCache === $this) {
328
+            return $this->move($sourcePath, $targetPath);
329
+        }
330
+        return $this->getCache()->moveFromCache($sourceCache, $sourcePath, $this->getSourcePath($targetPath));
331
+    }
332 332
 }
Please login to merge, or discard this patch.
lib/public/Util.php 1 patch
Indentation   +469 added lines, -469 removed lines patch added patch discarded remove patch
@@ -56,473 +56,473 @@
 block discarded – undo
56 56
  * @since 4.0.0
57 57
  */
58 58
 class Util {
59
-	/**
60
-	 * @deprecated 14.0.0 use \OCP\ILogger::DEBUG
61
-	 */
62
-	const DEBUG=0;
63
-	/**
64
-	 * @deprecated 14.0.0 use \OCP\ILogger::INFO
65
-	 */
66
-	const INFO=1;
67
-	/**
68
-	 * @deprecated 14.0.0 use \OCP\ILogger::WARN
69
-	 */
70
-	const WARN=2;
71
-	/**
72
-	 * @deprecated 14.0.0 use \OCP\ILogger::ERROR
73
-	 */
74
-	const ERROR=3;
75
-	/**
76
-	 * @deprecated 14.0.0 use \OCP\ILogger::FATAL
77
-	 */
78
-	const FATAL=4;
79
-
80
-	/** \OCP\Share\IManager */
81
-	private static $shareManager;
82
-
83
-	/**
84
-	 * get the current installed version of Nextcloud
85
-	 * @return array
86
-	 * @since 4.0.0
87
-	 */
88
-	public static function getVersion() {
89
-		return \OC_Util::getVersion();
90
-	}
91
-
92
-	/**
93
-	 * @since 17.0.0
94
-	 */
95
-	public static function hasExtendedSupport(): bool {
96
-		try {
97
-			/** @var \OCP\Support\Subscription\IRegistry */
98
-			$subscriptionRegistry = \OC::$server->query(\OCP\Support\Subscription\IRegistry::class);
99
-			return $subscriptionRegistry->delegateHasExtendedSupport();
100
-		} catch (AppFramework\QueryException $e) {}
101
-		return \OC::$server->getConfig()->getSystemValueBool('extendedSupport', false);
102
-	}
103
-
104
-	/**
105
-	 * Set current update channel
106
-	 * @param string $channel
107
-	 * @since 8.1.0
108
-	 */
109
-	public static function setChannel($channel) {
110
-		\OC::$server->getConfig()->setSystemValue('updater.release.channel', $channel);
111
-	}
112
-
113
-	/**
114
-	 * Get current update channel
115
-	 * @return string
116
-	 * @since 8.1.0
117
-	 */
118
-	public static function getChannel() {
119
-		return \OC_Util::getChannel();
120
-	}
121
-
122
-	/**
123
-	 * write a message in the log
124
-	 * @param string $app
125
-	 * @param string $message
126
-	 * @param int $level
127
-	 * @since 4.0.0
128
-	 * @deprecated 13.0.0 use log of \OCP\ILogger
129
-	 */
130
-	public static function writeLog( $app, $message, $level ) {
131
-		$context = ['app' => $app];
132
-		\OC::$server->getLogger()->log($level, $message, $context);
133
-	}
134
-
135
-	/**
136
-	 * check if sharing is disabled for the current user
137
-	 *
138
-	 * @return boolean
139
-	 * @since 7.0.0
140
-	 * @deprecated 9.1.0 Use \OC::$server->getShareManager()->sharingDisabledForUser
141
-	 */
142
-	public static function isSharingDisabledForUser() {
143
-		if (self::$shareManager === null) {
144
-			self::$shareManager = \OC::$server->getShareManager();
145
-		}
146
-
147
-		$user = \OC::$server->getUserSession()->getUser();
148
-		if ($user !== null) {
149
-			$user = $user->getUID();
150
-		}
151
-
152
-		return self::$shareManager->sharingDisabledForUser($user);
153
-	}
154
-
155
-	/**
156
-	 * get l10n object
157
-	 * @param string $application
158
-	 * @param string|null $language
159
-	 * @return \OCP\IL10N
160
-	 * @since 6.0.0 - parameter $language was added in 8.0.0
161
-	 */
162
-	public static function getL10N($application, $language = null) {
163
-		return \OC::$server->getL10N($application, $language);
164
-	}
165
-
166
-	/**
167
-	 * add a css file
168
-	 * @param string $application
169
-	 * @param string $file
170
-	 * @since 4.0.0
171
-	 */
172
-	public static function addStyle( $application, $file = null ) {
173
-		\OC_Util::addStyle( $application, $file );
174
-	}
175
-
176
-	/**
177
-	 * add a javascript file
178
-	 * @param string $application
179
-	 * @param string $file
180
-	 * @since 4.0.0
181
-	 */
182
-	public static function addScript( $application, $file = null ) {
183
-		\OC_Util::addScript( $application, $file );
184
-	}
185
-
186
-	/**
187
-	 * Add a translation JS file
188
-	 * @param string $application application id
189
-	 * @param string $languageCode language code, defaults to the current locale
190
-	 * @since 8.0.0
191
-	 */
192
-	public static function addTranslations($application, $languageCode = null) {
193
-		\OC_Util::addTranslations($application, $languageCode);
194
-	}
195
-
196
-	/**
197
-	 * Add a custom element to the header
198
-	 * If $text is null then the element will be written as empty element.
199
-	 * So use "" to get a closing tag.
200
-	 * @param string $tag tag name of the element
201
-	 * @param array $attributes array of attributes for the element
202
-	 * @param string $text the text content for the element
203
-	 * @since 4.0.0
204
-	 */
205
-	public static function addHeader($tag, $attributes, $text=null) {
206
-		\OC_Util::addHeader($tag, $attributes, $text);
207
-	}
208
-
209
-	/**
210
-	 * Creates an absolute url to the given app and file.
211
-	 * @param string $app app
212
-	 * @param string $file file
213
-	 * @param array $args array with param=>value, will be appended to the returned url
214
-	 * 	The value of $args will be urlencoded
215
-	 * @return string the url
216
-	 * @since 4.0.0 - parameter $args was added in 4.5.0
217
-	 */
218
-	public static function linkToAbsolute( $app, $file, $args = array() ) {
219
-		$urlGenerator = \OC::$server->getURLGenerator();
220
-		return $urlGenerator->getAbsoluteURL(
221
-			$urlGenerator->linkTo($app, $file, $args)
222
-		);
223
-	}
224
-
225
-	/**
226
-	 * Creates an absolute url for remote use.
227
-	 * @param string $service id
228
-	 * @return string the url
229
-	 * @since 4.0.0
230
-	 */
231
-	public static function linkToRemote( $service ) {
232
-		$urlGenerator = \OC::$server->getURLGenerator();
233
-		$remoteBase = $urlGenerator->linkTo('', 'remote.php') . '/' . $service;
234
-		return $urlGenerator->getAbsoluteURL(
235
-			$remoteBase . (($service[strlen($service) - 1] != '/') ? '/' : '')
236
-		);
237
-	}
238
-
239
-	/**
240
-	 * Creates an absolute url for public use
241
-	 * @param string $service id
242
-	 * @return string the url
243
-	 * @since 4.5.0
244
-	 * @deprecated 15.0.0 - use OCP\IURLGenerator
245
-	 */
246
-	public static function linkToPublic($service) {
247
-		$urlGenerator = \OC::$server->getURLGenerator();
248
-		if ($service === 'files') {
249
-			return $urlGenerator->getAbsoluteURL('/s');
250
-		}
251
-		return $urlGenerator->getAbsoluteURL($urlGenerator->linkTo('', 'public.php').'?service='.$service);
252
-	}
253
-
254
-	/**
255
-	 * Returns the server host name without an eventual port number
256
-	 * @return string the server hostname
257
-	 * @since 5.0.0
258
-	 */
259
-	public static function getServerHostName() {
260
-		$host_name = \OC::$server->getRequest()->getServerHost();
261
-		// strip away port number (if existing)
262
-		$colon_pos = strpos($host_name, ':');
263
-		if ($colon_pos != false) {
264
-			$host_name = substr($host_name, 0, $colon_pos);
265
-		}
266
-		return $host_name;
267
-	}
268
-
269
-	/**
270
-	 * Returns the default email address
271
-	 * @param string $user_part the user part of the address
272
-	 * @return string the default email address
273
-	 *
274
-	 * Assembles a default email address (using the server hostname
275
-	 * and the given user part, and returns it
276
-	 * Example: when given lostpassword-noreply as $user_part param,
277
-	 *     and is currently accessed via http(s)://example.com/,
278
-	 *     it would return '[email protected]'
279
-	 *
280
-	 * If the configuration value 'mail_from_address' is set in
281
-	 * config.php, this value will override the $user_part that
282
-	 * is passed to this function
283
-	 * @since 5.0.0
284
-	 */
285
-	public static function getDefaultEmailAddress($user_part) {
286
-		$config = \OC::$server->getConfig();
287
-		$user_part = $config->getSystemValue('mail_from_address', $user_part);
288
-		$host_name = self::getServerHostName();
289
-		$host_name = $config->getSystemValue('mail_domain', $host_name);
290
-		$defaultEmailAddress = $user_part.'@'.$host_name;
291
-
292
-		$mailer = \OC::$server->getMailer();
293
-		if ($mailer->validateMailAddress($defaultEmailAddress)) {
294
-			return $defaultEmailAddress;
295
-		}
296
-
297
-		// in case we cannot build a valid email address from the hostname let's fallback to 'localhost.localdomain'
298
-		return $user_part.'@localhost.localdomain';
299
-	}
300
-
301
-	/**
302
-	 * Make a human file size (2048 to 2 kB)
303
-	 * @param int $bytes file size in bytes
304
-	 * @return string a human readable file size
305
-	 * @since 4.0.0
306
-	 */
307
-	public static function humanFileSize($bytes) {
308
-		return \OC_Helper::humanFileSize($bytes);
309
-	}
310
-
311
-	/**
312
-	 * Make a computer file size (2 kB to 2048)
313
-	 * @param string $str file size in a fancy format
314
-	 * @return float a file size in bytes
315
-	 *
316
-	 * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418
317
-	 * @since 4.0.0
318
-	 */
319
-	public static function computerFileSize($str) {
320
-		return \OC_Helper::computerFileSize($str);
321
-	}
322
-
323
-	/**
324
-	 * connects a function to a hook
325
-	 *
326
-	 * @param string $signalClass class name of emitter
327
-	 * @param string $signalName name of signal
328
-	 * @param string|object $slotClass class name of slot
329
-	 * @param string $slotName name of slot
330
-	 * @return bool
331
-	 *
332
-	 * This function makes it very easy to connect to use hooks.
333
-	 *
334
-	 * TODO: write example
335
-	 * @since 4.0.0
336
-	 */
337
-	static public function connectHook($signalClass, $signalName, $slotClass, $slotName) {
338
-		return \OC_Hook::connect($signalClass, $signalName, $slotClass, $slotName);
339
-	}
340
-
341
-	/**
342
-	 * Emits a signal. To get data from the slot use references!
343
-	 * @param string $signalclass class name of emitter
344
-	 * @param string $signalname name of signal
345
-	 * @param array $params default: array() array with additional data
346
-	 * @return bool true if slots exists or false if not
347
-	 *
348
-	 * TODO: write example
349
-	 * @since 4.0.0
350
-	 */
351
-	static public function emitHook($signalclass, $signalname, $params = array()) {
352
-		return \OC_Hook::emit($signalclass, $signalname, $params);
353
-	}
354
-
355
-	/**
356
-	 * Cached encrypted CSRF token. Some static unit-tests of ownCloud compare
357
-	 * multiple OC_Template elements which invoke `callRegister`. If the value
358
-	 * would not be cached these unit-tests would fail.
359
-	 * @var string
360
-	 */
361
-	private static $token = '';
362
-
363
-	/**
364
-	 * Register an get/post call. This is important to prevent CSRF attacks
365
-	 * @since 4.5.0
366
-	 */
367
-	public static function callRegister() {
368
-		if(self::$token === '') {
369
-			self::$token = \OC::$server->getCsrfTokenManager()->getToken()->getEncryptedValue();
370
-		}
371
-		return self::$token;
372
-	}
373
-
374
-	/**
375
-	 * Used to sanitize HTML
376
-	 *
377
-	 * This function is used to sanitize HTML and should be applied on any
378
-	 * string or array of strings before displaying it on a web page.
379
-	 *
380
-	 * @param string|array $value
381
-	 * @return string|array an array of sanitized strings or a single sanitized string, depends on the input parameter.
382
-	 * @since 4.5.0
383
-	 */
384
-	public static function sanitizeHTML($value) {
385
-		return \OC_Util::sanitizeHTML($value);
386
-	}
387
-
388
-	/**
389
-	 * Public function to encode url parameters
390
-	 *
391
-	 * This function is used to encode path to file before output.
392
-	 * Encoding is done according to RFC 3986 with one exception:
393
-	 * Character '/' is preserved as is.
394
-	 *
395
-	 * @param string $component part of URI to encode
396
-	 * @return string
397
-	 * @since 6.0.0
398
-	 */
399
-	public static function encodePath($component) {
400
-		return \OC_Util::encodePath($component);
401
-	}
402
-
403
-	/**
404
-	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
405
-	 *
406
-	 * @param array $input The array to work on
407
-	 * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default)
408
-	 * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8
409
-	 * @return array
410
-	 * @since 4.5.0
411
-	 */
412
-	public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
413
-		return \OC_Helper::mb_array_change_key_case($input, $case, $encoding);
414
-	}
415
-
416
-	/**
417
-	 * performs a search in a nested array
418
-	 *
419
-	 * @param array $haystack the array to be searched
420
-	 * @param string $needle the search string
421
-	 * @param mixed $index optional, only search this key name
422
-	 * @return mixed the key of the matching field, otherwise false
423
-	 * @since 4.5.0
424
-	 * @deprecated 15.0.0
425
-	 */
426
-	public static function recursiveArraySearch($haystack, $needle, $index = null) {
427
-		return \OC_Helper::recursiveArraySearch($haystack, $needle, $index);
428
-	}
429
-
430
-	/**
431
-	 * calculates the maximum upload size respecting system settings, free space and user quota
432
-	 *
433
-	 * @param string $dir the current folder where the user currently operates
434
-	 * @param int $free the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly
435
-	 * @return int number of bytes representing
436
-	 * @since 5.0.0
437
-	 */
438
-	public static function maxUploadFilesize($dir, $free = null) {
439
-		return \OC_Helper::maxUploadFilesize($dir, $free);
440
-	}
441
-
442
-	/**
443
-	 * Calculate free space left within user quota
444
-	 * @param string $dir the current folder where the user currently operates
445
-	 * @return int number of bytes representing
446
-	 * @since 7.0.0
447
-	 */
448
-	public static function freeSpace($dir) {
449
-		return \OC_Helper::freeSpace($dir);
450
-	}
451
-
452
-	/**
453
-	 * Calculate PHP upload limit
454
-	 *
455
-	 * @return int number of bytes representing
456
-	 * @since 7.0.0
457
-	 */
458
-	public static function uploadLimit() {
459
-		return \OC_Helper::uploadLimit();
460
-	}
461
-
462
-	/**
463
-	 * Returns whether the given file name is valid
464
-	 * @param string $file file name to check
465
-	 * @return bool true if the file name is valid, false otherwise
466
-	 * @deprecated 8.1.0 use \OC\Files\View::verifyPath()
467
-	 * @since 7.0.0
468
-	 * @suppress PhanDeprecatedFunction
469
-	 */
470
-	public static function isValidFileName($file) {
471
-		return \OC_Util::isValidFileName($file);
472
-	}
473
-
474
-	/**
475
-	 * Compare two strings to provide a natural sort
476
-	 * @param string $a first string to compare
477
-	 * @param string $b second string to compare
478
-	 * @return int -1 if $b comes before $a, 1 if $a comes before $b
479
-	 * or 0 if the strings are identical
480
-	 * @since 7.0.0
481
-	 */
482
-	public static function naturalSortCompare($a, $b) {
483
-		return \OC\NaturalSort::getInstance()->compare($a, $b);
484
-	}
485
-
486
-	/**
487
-	 * check if a password is required for each public link
488
-	 * @return boolean
489
-	 * @since 7.0.0
490
-	 */
491
-	public static function isPublicLinkPasswordRequired() {
492
-		return \OC_Util::isPublicLinkPasswordRequired();
493
-	}
494
-
495
-	/**
496
-	 * check if share API enforces a default expire date
497
-	 * @return boolean
498
-	 * @since 8.0.0
499
-	 */
500
-	public static function isDefaultExpireDateEnforced() {
501
-		return \OC_Util::isDefaultExpireDateEnforced();
502
-	}
503
-
504
-	protected static $needUpgradeCache = null;
505
-
506
-	/**
507
-	 * Checks whether the current version needs upgrade.
508
-	 *
509
-	 * @return bool true if upgrade is needed, false otherwise
510
-	 * @since 7.0.0
511
-	 */
512
-	public static function needUpgrade() {
513
-		if (!isset(self::$needUpgradeCache)) {
514
-			self::$needUpgradeCache=\OC_Util::needUpgrade(\OC::$server->getSystemConfig());
515
-		}
516
-		return self::$needUpgradeCache;
517
-	}
518
-
519
-	/**
520
-	 * is this Internet explorer ?
521
-	 *
522
-	 * @return boolean
523
-	 * @since 14.0.0
524
-	 */
525
-	public static function isIe() {
526
-		return \OC_Util::isIe();
527
-	}
59
+    /**
60
+     * @deprecated 14.0.0 use \OCP\ILogger::DEBUG
61
+     */
62
+    const DEBUG=0;
63
+    /**
64
+     * @deprecated 14.0.0 use \OCP\ILogger::INFO
65
+     */
66
+    const INFO=1;
67
+    /**
68
+     * @deprecated 14.0.0 use \OCP\ILogger::WARN
69
+     */
70
+    const WARN=2;
71
+    /**
72
+     * @deprecated 14.0.0 use \OCP\ILogger::ERROR
73
+     */
74
+    const ERROR=3;
75
+    /**
76
+     * @deprecated 14.0.0 use \OCP\ILogger::FATAL
77
+     */
78
+    const FATAL=4;
79
+
80
+    /** \OCP\Share\IManager */
81
+    private static $shareManager;
82
+
83
+    /**
84
+     * get the current installed version of Nextcloud
85
+     * @return array
86
+     * @since 4.0.0
87
+     */
88
+    public static function getVersion() {
89
+        return \OC_Util::getVersion();
90
+    }
91
+
92
+    /**
93
+     * @since 17.0.0
94
+     */
95
+    public static function hasExtendedSupport(): bool {
96
+        try {
97
+            /** @var \OCP\Support\Subscription\IRegistry */
98
+            $subscriptionRegistry = \OC::$server->query(\OCP\Support\Subscription\IRegistry::class);
99
+            return $subscriptionRegistry->delegateHasExtendedSupport();
100
+        } catch (AppFramework\QueryException $e) {}
101
+        return \OC::$server->getConfig()->getSystemValueBool('extendedSupport', false);
102
+    }
103
+
104
+    /**
105
+     * Set current update channel
106
+     * @param string $channel
107
+     * @since 8.1.0
108
+     */
109
+    public static function setChannel($channel) {
110
+        \OC::$server->getConfig()->setSystemValue('updater.release.channel', $channel);
111
+    }
112
+
113
+    /**
114
+     * Get current update channel
115
+     * @return string
116
+     * @since 8.1.0
117
+     */
118
+    public static function getChannel() {
119
+        return \OC_Util::getChannel();
120
+    }
121
+
122
+    /**
123
+     * write a message in the log
124
+     * @param string $app
125
+     * @param string $message
126
+     * @param int $level
127
+     * @since 4.0.0
128
+     * @deprecated 13.0.0 use log of \OCP\ILogger
129
+     */
130
+    public static function writeLog( $app, $message, $level ) {
131
+        $context = ['app' => $app];
132
+        \OC::$server->getLogger()->log($level, $message, $context);
133
+    }
134
+
135
+    /**
136
+     * check if sharing is disabled for the current user
137
+     *
138
+     * @return boolean
139
+     * @since 7.0.0
140
+     * @deprecated 9.1.0 Use \OC::$server->getShareManager()->sharingDisabledForUser
141
+     */
142
+    public static function isSharingDisabledForUser() {
143
+        if (self::$shareManager === null) {
144
+            self::$shareManager = \OC::$server->getShareManager();
145
+        }
146
+
147
+        $user = \OC::$server->getUserSession()->getUser();
148
+        if ($user !== null) {
149
+            $user = $user->getUID();
150
+        }
151
+
152
+        return self::$shareManager->sharingDisabledForUser($user);
153
+    }
154
+
155
+    /**
156
+     * get l10n object
157
+     * @param string $application
158
+     * @param string|null $language
159
+     * @return \OCP\IL10N
160
+     * @since 6.0.0 - parameter $language was added in 8.0.0
161
+     */
162
+    public static function getL10N($application, $language = null) {
163
+        return \OC::$server->getL10N($application, $language);
164
+    }
165
+
166
+    /**
167
+     * add a css file
168
+     * @param string $application
169
+     * @param string $file
170
+     * @since 4.0.0
171
+     */
172
+    public static function addStyle( $application, $file = null ) {
173
+        \OC_Util::addStyle( $application, $file );
174
+    }
175
+
176
+    /**
177
+     * add a javascript file
178
+     * @param string $application
179
+     * @param string $file
180
+     * @since 4.0.0
181
+     */
182
+    public static function addScript( $application, $file = null ) {
183
+        \OC_Util::addScript( $application, $file );
184
+    }
185
+
186
+    /**
187
+     * Add a translation JS file
188
+     * @param string $application application id
189
+     * @param string $languageCode language code, defaults to the current locale
190
+     * @since 8.0.0
191
+     */
192
+    public static function addTranslations($application, $languageCode = null) {
193
+        \OC_Util::addTranslations($application, $languageCode);
194
+    }
195
+
196
+    /**
197
+     * Add a custom element to the header
198
+     * If $text is null then the element will be written as empty element.
199
+     * So use "" to get a closing tag.
200
+     * @param string $tag tag name of the element
201
+     * @param array $attributes array of attributes for the element
202
+     * @param string $text the text content for the element
203
+     * @since 4.0.0
204
+     */
205
+    public static function addHeader($tag, $attributes, $text=null) {
206
+        \OC_Util::addHeader($tag, $attributes, $text);
207
+    }
208
+
209
+    /**
210
+     * Creates an absolute url to the given app and file.
211
+     * @param string $app app
212
+     * @param string $file file
213
+     * @param array $args array with param=>value, will be appended to the returned url
214
+     * 	The value of $args will be urlencoded
215
+     * @return string the url
216
+     * @since 4.0.0 - parameter $args was added in 4.5.0
217
+     */
218
+    public static function linkToAbsolute( $app, $file, $args = array() ) {
219
+        $urlGenerator = \OC::$server->getURLGenerator();
220
+        return $urlGenerator->getAbsoluteURL(
221
+            $urlGenerator->linkTo($app, $file, $args)
222
+        );
223
+    }
224
+
225
+    /**
226
+     * Creates an absolute url for remote use.
227
+     * @param string $service id
228
+     * @return string the url
229
+     * @since 4.0.0
230
+     */
231
+    public static function linkToRemote( $service ) {
232
+        $urlGenerator = \OC::$server->getURLGenerator();
233
+        $remoteBase = $urlGenerator->linkTo('', 'remote.php') . '/' . $service;
234
+        return $urlGenerator->getAbsoluteURL(
235
+            $remoteBase . (($service[strlen($service) - 1] != '/') ? '/' : '')
236
+        );
237
+    }
238
+
239
+    /**
240
+     * Creates an absolute url for public use
241
+     * @param string $service id
242
+     * @return string the url
243
+     * @since 4.5.0
244
+     * @deprecated 15.0.0 - use OCP\IURLGenerator
245
+     */
246
+    public static function linkToPublic($service) {
247
+        $urlGenerator = \OC::$server->getURLGenerator();
248
+        if ($service === 'files') {
249
+            return $urlGenerator->getAbsoluteURL('/s');
250
+        }
251
+        return $urlGenerator->getAbsoluteURL($urlGenerator->linkTo('', 'public.php').'?service='.$service);
252
+    }
253
+
254
+    /**
255
+     * Returns the server host name without an eventual port number
256
+     * @return string the server hostname
257
+     * @since 5.0.0
258
+     */
259
+    public static function getServerHostName() {
260
+        $host_name = \OC::$server->getRequest()->getServerHost();
261
+        // strip away port number (if existing)
262
+        $colon_pos = strpos($host_name, ':');
263
+        if ($colon_pos != false) {
264
+            $host_name = substr($host_name, 0, $colon_pos);
265
+        }
266
+        return $host_name;
267
+    }
268
+
269
+    /**
270
+     * Returns the default email address
271
+     * @param string $user_part the user part of the address
272
+     * @return string the default email address
273
+     *
274
+     * Assembles a default email address (using the server hostname
275
+     * and the given user part, and returns it
276
+     * Example: when given lostpassword-noreply as $user_part param,
277
+     *     and is currently accessed via http(s)://example.com/,
278
+     *     it would return '[email protected]'
279
+     *
280
+     * If the configuration value 'mail_from_address' is set in
281
+     * config.php, this value will override the $user_part that
282
+     * is passed to this function
283
+     * @since 5.0.0
284
+     */
285
+    public static function getDefaultEmailAddress($user_part) {
286
+        $config = \OC::$server->getConfig();
287
+        $user_part = $config->getSystemValue('mail_from_address', $user_part);
288
+        $host_name = self::getServerHostName();
289
+        $host_name = $config->getSystemValue('mail_domain', $host_name);
290
+        $defaultEmailAddress = $user_part.'@'.$host_name;
291
+
292
+        $mailer = \OC::$server->getMailer();
293
+        if ($mailer->validateMailAddress($defaultEmailAddress)) {
294
+            return $defaultEmailAddress;
295
+        }
296
+
297
+        // in case we cannot build a valid email address from the hostname let's fallback to 'localhost.localdomain'
298
+        return $user_part.'@localhost.localdomain';
299
+    }
300
+
301
+    /**
302
+     * Make a human file size (2048 to 2 kB)
303
+     * @param int $bytes file size in bytes
304
+     * @return string a human readable file size
305
+     * @since 4.0.0
306
+     */
307
+    public static function humanFileSize($bytes) {
308
+        return \OC_Helper::humanFileSize($bytes);
309
+    }
310
+
311
+    /**
312
+     * Make a computer file size (2 kB to 2048)
313
+     * @param string $str file size in a fancy format
314
+     * @return float a file size in bytes
315
+     *
316
+     * Inspired by: http://www.php.net/manual/en/function.filesize.php#92418
317
+     * @since 4.0.0
318
+     */
319
+    public static function computerFileSize($str) {
320
+        return \OC_Helper::computerFileSize($str);
321
+    }
322
+
323
+    /**
324
+     * connects a function to a hook
325
+     *
326
+     * @param string $signalClass class name of emitter
327
+     * @param string $signalName name of signal
328
+     * @param string|object $slotClass class name of slot
329
+     * @param string $slotName name of slot
330
+     * @return bool
331
+     *
332
+     * This function makes it very easy to connect to use hooks.
333
+     *
334
+     * TODO: write example
335
+     * @since 4.0.0
336
+     */
337
+    static public function connectHook($signalClass, $signalName, $slotClass, $slotName) {
338
+        return \OC_Hook::connect($signalClass, $signalName, $slotClass, $slotName);
339
+    }
340
+
341
+    /**
342
+     * Emits a signal. To get data from the slot use references!
343
+     * @param string $signalclass class name of emitter
344
+     * @param string $signalname name of signal
345
+     * @param array $params default: array() array with additional data
346
+     * @return bool true if slots exists or false if not
347
+     *
348
+     * TODO: write example
349
+     * @since 4.0.0
350
+     */
351
+    static public function emitHook($signalclass, $signalname, $params = array()) {
352
+        return \OC_Hook::emit($signalclass, $signalname, $params);
353
+    }
354
+
355
+    /**
356
+     * Cached encrypted CSRF token. Some static unit-tests of ownCloud compare
357
+     * multiple OC_Template elements which invoke `callRegister`. If the value
358
+     * would not be cached these unit-tests would fail.
359
+     * @var string
360
+     */
361
+    private static $token = '';
362
+
363
+    /**
364
+     * Register an get/post call. This is important to prevent CSRF attacks
365
+     * @since 4.5.0
366
+     */
367
+    public static function callRegister() {
368
+        if(self::$token === '') {
369
+            self::$token = \OC::$server->getCsrfTokenManager()->getToken()->getEncryptedValue();
370
+        }
371
+        return self::$token;
372
+    }
373
+
374
+    /**
375
+     * Used to sanitize HTML
376
+     *
377
+     * This function is used to sanitize HTML and should be applied on any
378
+     * string or array of strings before displaying it on a web page.
379
+     *
380
+     * @param string|array $value
381
+     * @return string|array an array of sanitized strings or a single sanitized string, depends on the input parameter.
382
+     * @since 4.5.0
383
+     */
384
+    public static function sanitizeHTML($value) {
385
+        return \OC_Util::sanitizeHTML($value);
386
+    }
387
+
388
+    /**
389
+     * Public function to encode url parameters
390
+     *
391
+     * This function is used to encode path to file before output.
392
+     * Encoding is done according to RFC 3986 with one exception:
393
+     * Character '/' is preserved as is.
394
+     *
395
+     * @param string $component part of URI to encode
396
+     * @return string
397
+     * @since 6.0.0
398
+     */
399
+    public static function encodePath($component) {
400
+        return \OC_Util::encodePath($component);
401
+    }
402
+
403
+    /**
404
+     * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
405
+     *
406
+     * @param array $input The array to work on
407
+     * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default)
408
+     * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8
409
+     * @return array
410
+     * @since 4.5.0
411
+     */
412
+    public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
413
+        return \OC_Helper::mb_array_change_key_case($input, $case, $encoding);
414
+    }
415
+
416
+    /**
417
+     * performs a search in a nested array
418
+     *
419
+     * @param array $haystack the array to be searched
420
+     * @param string $needle the search string
421
+     * @param mixed $index optional, only search this key name
422
+     * @return mixed the key of the matching field, otherwise false
423
+     * @since 4.5.0
424
+     * @deprecated 15.0.0
425
+     */
426
+    public static function recursiveArraySearch($haystack, $needle, $index = null) {
427
+        return \OC_Helper::recursiveArraySearch($haystack, $needle, $index);
428
+    }
429
+
430
+    /**
431
+     * calculates the maximum upload size respecting system settings, free space and user quota
432
+     *
433
+     * @param string $dir the current folder where the user currently operates
434
+     * @param int $free the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly
435
+     * @return int number of bytes representing
436
+     * @since 5.0.0
437
+     */
438
+    public static function maxUploadFilesize($dir, $free = null) {
439
+        return \OC_Helper::maxUploadFilesize($dir, $free);
440
+    }
441
+
442
+    /**
443
+     * Calculate free space left within user quota
444
+     * @param string $dir the current folder where the user currently operates
445
+     * @return int number of bytes representing
446
+     * @since 7.0.0
447
+     */
448
+    public static function freeSpace($dir) {
449
+        return \OC_Helper::freeSpace($dir);
450
+    }
451
+
452
+    /**
453
+     * Calculate PHP upload limit
454
+     *
455
+     * @return int number of bytes representing
456
+     * @since 7.0.0
457
+     */
458
+    public static function uploadLimit() {
459
+        return \OC_Helper::uploadLimit();
460
+    }
461
+
462
+    /**
463
+     * Returns whether the given file name is valid
464
+     * @param string $file file name to check
465
+     * @return bool true if the file name is valid, false otherwise
466
+     * @deprecated 8.1.0 use \OC\Files\View::verifyPath()
467
+     * @since 7.0.0
468
+     * @suppress PhanDeprecatedFunction
469
+     */
470
+    public static function isValidFileName($file) {
471
+        return \OC_Util::isValidFileName($file);
472
+    }
473
+
474
+    /**
475
+     * Compare two strings to provide a natural sort
476
+     * @param string $a first string to compare
477
+     * @param string $b second string to compare
478
+     * @return int -1 if $b comes before $a, 1 if $a comes before $b
479
+     * or 0 if the strings are identical
480
+     * @since 7.0.0
481
+     */
482
+    public static function naturalSortCompare($a, $b) {
483
+        return \OC\NaturalSort::getInstance()->compare($a, $b);
484
+    }
485
+
486
+    /**
487
+     * check if a password is required for each public link
488
+     * @return boolean
489
+     * @since 7.0.0
490
+     */
491
+    public static function isPublicLinkPasswordRequired() {
492
+        return \OC_Util::isPublicLinkPasswordRequired();
493
+    }
494
+
495
+    /**
496
+     * check if share API enforces a default expire date
497
+     * @return boolean
498
+     * @since 8.0.0
499
+     */
500
+    public static function isDefaultExpireDateEnforced() {
501
+        return \OC_Util::isDefaultExpireDateEnforced();
502
+    }
503
+
504
+    protected static $needUpgradeCache = null;
505
+
506
+    /**
507
+     * Checks whether the current version needs upgrade.
508
+     *
509
+     * @return bool true if upgrade is needed, false otherwise
510
+     * @since 7.0.0
511
+     */
512
+    public static function needUpgrade() {
513
+        if (!isset(self::$needUpgradeCache)) {
514
+            self::$needUpgradeCache=\OC_Util::needUpgrade(\OC::$server->getSystemConfig());
515
+        }
516
+        return self::$needUpgradeCache;
517
+    }
518
+
519
+    /**
520
+     * is this Internet explorer ?
521
+     *
522
+     * @return boolean
523
+     * @since 14.0.0
524
+     */
525
+    public static function isIe() {
526
+        return \OC_Util::isIe();
527
+    }
528 528
 }
Please login to merge, or discard this patch.