Completed
Push — master ( 0913bc...b754a2 )
by Lukas
13:23
created
apps/dav/lib/Connector/Sabre/SharesPlugin.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -148,7 +148,7 @@  discard block
 block discarded – undo
148 148
 
149 149
 		$shareTypesByFileId = [];
150 150
 
151
-		foreach($shares as $fileId => $sharesForFile) {
151
+		foreach ($shares as $fileId => $sharesForFile) {
152 152
 			$types = array_map(function(IShare $share) {
153 153
 				return $share->getShareType();
154 154
 			}, $sharesForFile);
@@ -189,7 +189,7 @@  discard block
 block discarded – undo
189 189
 			}
190 190
 		}
191 191
 
192
-		$propFind->handle(self::SHARETYPES_PROPERTYNAME, function () use ($sabreNode) {
192
+		$propFind->handle(self::SHARETYPES_PROPERTYNAME, function() use ($sabreNode) {
193 193
 			if (isset($this->cachedShareTypes[$sabreNode->getId()])) {
194 194
 				$shareTypes = $this->cachedShareTypes[$sabreNode->getId()];
195 195
 			} else {
Please login to merge, or discard this patch.
Indentation   +177 added lines, -177 removed lines patch added patch discarded remove patch
@@ -32,181 +32,181 @@
 block discarded – undo
32 32
  */
33 33
 class SharesPlugin extends \Sabre\DAV\ServerPlugin {
34 34
 
35
-	const NS_OWNCLOUD = 'http://owncloud.org/ns';
36
-	const SHARETYPES_PROPERTYNAME = '{http://owncloud.org/ns}share-types';
37
-
38
-	/**
39
-	 * Reference to main server object
40
-	 *
41
-	 * @var \Sabre\DAV\Server
42
-	 */
43
-	private $server;
44
-
45
-	/**
46
-	 * @var \OCP\Share\IManager
47
-	 */
48
-	private $shareManager;
49
-
50
-	/**
51
-	 * @var \Sabre\DAV\Tree
52
-	 */
53
-	private $tree;
54
-
55
-	/**
56
-	 * @var string
57
-	 */
58
-	private $userId;
59
-
60
-	/**
61
-	 * @var \OCP\Files\Folder
62
-	 */
63
-	private $userFolder;
64
-
65
-	/**
66
-	 * @var IShare[]
67
-	 */
68
-	private $cachedShareTypes;
69
-
70
-	private $cachedFolders = [];
71
-
72
-	/**
73
-	 * @param \Sabre\DAV\Tree $tree tree
74
-	 * @param IUserSession $userSession user session
75
-	 * @param \OCP\Files\Folder $userFolder user home folder
76
-	 * @param \OCP\Share\IManager $shareManager share manager
77
-	 */
78
-	public function __construct(
79
-		\Sabre\DAV\Tree $tree,
80
-		IUserSession $userSession,
81
-		\OCP\Files\Folder $userFolder,
82
-		\OCP\Share\IManager $shareManager
83
-	) {
84
-		$this->tree = $tree;
85
-		$this->shareManager = $shareManager;
86
-		$this->userFolder = $userFolder;
87
-		$this->userId = $userSession->getUser()->getUID();
88
-		$this->cachedShareTypes = [];
89
-	}
90
-
91
-	/**
92
-	 * This initializes the plugin.
93
-	 *
94
-	 * This function is called by \Sabre\DAV\Server, after
95
-	 * addPlugin is called.
96
-	 *
97
-	 * This method should set up the required event subscriptions.
98
-	 *
99
-	 * @param \Sabre\DAV\Server $server
100
-	 */
101
-	public function initialize(\Sabre\DAV\Server $server) {
102
-		$server->xml->namespacesMap[self::NS_OWNCLOUD] = 'oc';
103
-		$server->xml->elementMap[self::SHARETYPES_PROPERTYNAME] = 'OCA\\DAV\\Connector\\Sabre\\ShareTypeList';
104
-		$server->protectedProperties[] = self::SHARETYPES_PROPERTYNAME;
105
-
106
-		$this->server = $server;
107
-		$this->server->on('propFind', array($this, 'handleGetProperties'));
108
-	}
109
-
110
-	/**
111
-	 * Return a list of share types for outgoing shares
112
-	 *
113
-	 * @param \OCP\Files\Node $node file node
114
-	 *
115
-	 * @return int[] array of share types
116
-	 */
117
-	private function getShareTypes(\OCP\Files\Node $node) {
118
-		$shareTypes = [];
119
-		$requestedShareTypes = [
120
-			\OCP\Share::SHARE_TYPE_USER,
121
-			\OCP\Share::SHARE_TYPE_GROUP,
122
-			\OCP\Share::SHARE_TYPE_LINK,
123
-			\OCP\Share::SHARE_TYPE_REMOTE,
124
-			\OCP\Share::SHARE_TYPE_EMAIL,
125
-		];
126
-		foreach ($requestedShareTypes as $requestedShareType) {
127
-			// one of each type is enough to find out about the types
128
-			$shares = $this->shareManager->getSharesBy(
129
-				$this->userId,
130
-				$requestedShareType,
131
-				$node,
132
-				false,
133
-				1
134
-			);
135
-			if (!empty($shares)) {
136
-				$shareTypes[] = $requestedShareType;
137
-			}
138
-		}
139
-		return $shareTypes;
140
-	}
141
-
142
-	private function getSharesTypesInFolder(\OCP\Files\Folder $node) {
143
-		$shares = $this->shareManager->getSharesInFolder(
144
-			$this->userId,
145
-			$node,
146
-			true
147
-		);
148
-
149
-		$shareTypesByFileId = [];
150
-
151
-		foreach($shares as $fileId => $sharesForFile) {
152
-			$types = array_map(function(IShare $share) {
153
-				return $share->getShareType();
154
-			}, $sharesForFile);
155
-			$types = array_unique($types);
156
-			sort($types);
157
-			$shareTypesByFileId[$fileId] = $types;
158
-		}
159
-
160
-		return $shareTypesByFileId;
161
-	}
162
-
163
-	/**
164
-	 * Adds shares to propfind response
165
-	 *
166
-	 * @param PropFind $propFind propfind object
167
-	 * @param \Sabre\DAV\INode $sabreNode sabre node
168
-	 */
169
-	public function handleGetProperties(
170
-		PropFind $propFind,
171
-		\Sabre\DAV\INode $sabreNode
172
-	) {
173
-		if (!($sabreNode instanceof \OCA\DAV\Connector\Sabre\Node)) {
174
-			return;
175
-		}
176
-
177
-		// need prefetch ?
178
-		if ($sabreNode instanceof \OCA\DAV\Connector\Sabre\Directory
179
-			&& $propFind->getDepth() !== 0
180
-			&& !is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME))
181
-		) {
182
-			$folderNode = $this->userFolder->get($sabreNode->getPath());
183
-
184
-			$childShares = $this->getSharesTypesInFolder($folderNode);
185
-			$this->cachedFolders[] = $sabreNode->getPath();
186
-			$this->cachedShareTypes[$folderNode->getId()] = $this->getShareTypes($folderNode);
187
-			foreach ($childShares as $id => $shares) {
188
-				$this->cachedShareTypes[$id] = $shares;
189
-			}
190
-		}
191
-
192
-		$propFind->handle(self::SHARETYPES_PROPERTYNAME, function () use ($sabreNode) {
193
-			if (isset($this->cachedShareTypes[$sabreNode->getId()])) {
194
-				$shareTypes = $this->cachedShareTypes[$sabreNode->getId()];
195
-			} else {
196
-				list($parentPath,) = \Sabre\Uri\split($sabreNode->getPath());
197
-				if ($parentPath === '') {
198
-					$parentPath = '/';
199
-				}
200
-				// if we already cached the folder this file is in we know there are no shares for this file
201
-				if (array_search($parentPath, $this->cachedFolders) === false) {
202
-					$node = $this->userFolder->get($sabreNode->getPath());
203
-					$shareTypes = $this->getShareTypes($node);
204
-				} else {
205
-					return [];
206
-				}
207
-			}
208
-
209
-			return new ShareTypeList($shareTypes);
210
-		});
211
-	}
35
+    const NS_OWNCLOUD = 'http://owncloud.org/ns';
36
+    const SHARETYPES_PROPERTYNAME = '{http://owncloud.org/ns}share-types';
37
+
38
+    /**
39
+     * Reference to main server object
40
+     *
41
+     * @var \Sabre\DAV\Server
42
+     */
43
+    private $server;
44
+
45
+    /**
46
+     * @var \OCP\Share\IManager
47
+     */
48
+    private $shareManager;
49
+
50
+    /**
51
+     * @var \Sabre\DAV\Tree
52
+     */
53
+    private $tree;
54
+
55
+    /**
56
+     * @var string
57
+     */
58
+    private $userId;
59
+
60
+    /**
61
+     * @var \OCP\Files\Folder
62
+     */
63
+    private $userFolder;
64
+
65
+    /**
66
+     * @var IShare[]
67
+     */
68
+    private $cachedShareTypes;
69
+
70
+    private $cachedFolders = [];
71
+
72
+    /**
73
+     * @param \Sabre\DAV\Tree $tree tree
74
+     * @param IUserSession $userSession user session
75
+     * @param \OCP\Files\Folder $userFolder user home folder
76
+     * @param \OCP\Share\IManager $shareManager share manager
77
+     */
78
+    public function __construct(
79
+        \Sabre\DAV\Tree $tree,
80
+        IUserSession $userSession,
81
+        \OCP\Files\Folder $userFolder,
82
+        \OCP\Share\IManager $shareManager
83
+    ) {
84
+        $this->tree = $tree;
85
+        $this->shareManager = $shareManager;
86
+        $this->userFolder = $userFolder;
87
+        $this->userId = $userSession->getUser()->getUID();
88
+        $this->cachedShareTypes = [];
89
+    }
90
+
91
+    /**
92
+     * This initializes the plugin.
93
+     *
94
+     * This function is called by \Sabre\DAV\Server, after
95
+     * addPlugin is called.
96
+     *
97
+     * This method should set up the required event subscriptions.
98
+     *
99
+     * @param \Sabre\DAV\Server $server
100
+     */
101
+    public function initialize(\Sabre\DAV\Server $server) {
102
+        $server->xml->namespacesMap[self::NS_OWNCLOUD] = 'oc';
103
+        $server->xml->elementMap[self::SHARETYPES_PROPERTYNAME] = 'OCA\\DAV\\Connector\\Sabre\\ShareTypeList';
104
+        $server->protectedProperties[] = self::SHARETYPES_PROPERTYNAME;
105
+
106
+        $this->server = $server;
107
+        $this->server->on('propFind', array($this, 'handleGetProperties'));
108
+    }
109
+
110
+    /**
111
+     * Return a list of share types for outgoing shares
112
+     *
113
+     * @param \OCP\Files\Node $node file node
114
+     *
115
+     * @return int[] array of share types
116
+     */
117
+    private function getShareTypes(\OCP\Files\Node $node) {
118
+        $shareTypes = [];
119
+        $requestedShareTypes = [
120
+            \OCP\Share::SHARE_TYPE_USER,
121
+            \OCP\Share::SHARE_TYPE_GROUP,
122
+            \OCP\Share::SHARE_TYPE_LINK,
123
+            \OCP\Share::SHARE_TYPE_REMOTE,
124
+            \OCP\Share::SHARE_TYPE_EMAIL,
125
+        ];
126
+        foreach ($requestedShareTypes as $requestedShareType) {
127
+            // one of each type is enough to find out about the types
128
+            $shares = $this->shareManager->getSharesBy(
129
+                $this->userId,
130
+                $requestedShareType,
131
+                $node,
132
+                false,
133
+                1
134
+            );
135
+            if (!empty($shares)) {
136
+                $shareTypes[] = $requestedShareType;
137
+            }
138
+        }
139
+        return $shareTypes;
140
+    }
141
+
142
+    private function getSharesTypesInFolder(\OCP\Files\Folder $node) {
143
+        $shares = $this->shareManager->getSharesInFolder(
144
+            $this->userId,
145
+            $node,
146
+            true
147
+        );
148
+
149
+        $shareTypesByFileId = [];
150
+
151
+        foreach($shares as $fileId => $sharesForFile) {
152
+            $types = array_map(function(IShare $share) {
153
+                return $share->getShareType();
154
+            }, $sharesForFile);
155
+            $types = array_unique($types);
156
+            sort($types);
157
+            $shareTypesByFileId[$fileId] = $types;
158
+        }
159
+
160
+        return $shareTypesByFileId;
161
+    }
162
+
163
+    /**
164
+     * Adds shares to propfind response
165
+     *
166
+     * @param PropFind $propFind propfind object
167
+     * @param \Sabre\DAV\INode $sabreNode sabre node
168
+     */
169
+    public function handleGetProperties(
170
+        PropFind $propFind,
171
+        \Sabre\DAV\INode $sabreNode
172
+    ) {
173
+        if (!($sabreNode instanceof \OCA\DAV\Connector\Sabre\Node)) {
174
+            return;
175
+        }
176
+
177
+        // need prefetch ?
178
+        if ($sabreNode instanceof \OCA\DAV\Connector\Sabre\Directory
179
+            && $propFind->getDepth() !== 0
180
+            && !is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME))
181
+        ) {
182
+            $folderNode = $this->userFolder->get($sabreNode->getPath());
183
+
184
+            $childShares = $this->getSharesTypesInFolder($folderNode);
185
+            $this->cachedFolders[] = $sabreNode->getPath();
186
+            $this->cachedShareTypes[$folderNode->getId()] = $this->getShareTypes($folderNode);
187
+            foreach ($childShares as $id => $shares) {
188
+                $this->cachedShareTypes[$id] = $shares;
189
+            }
190
+        }
191
+
192
+        $propFind->handle(self::SHARETYPES_PROPERTYNAME, function () use ($sabreNode) {
193
+            if (isset($this->cachedShareTypes[$sabreNode->getId()])) {
194
+                $shareTypes = $this->cachedShareTypes[$sabreNode->getId()];
195
+            } else {
196
+                list($parentPath,) = \Sabre\Uri\split($sabreNode->getPath());
197
+                if ($parentPath === '') {
198
+                    $parentPath = '/';
199
+                }
200
+                // if we already cached the folder this file is in we know there are no shares for this file
201
+                if (array_search($parentPath, $this->cachedFolders) === false) {
202
+                    $node = $this->userFolder->get($sabreNode->getPath());
203
+                    $shareTypes = $this->getShareTypes($node);
204
+                } else {
205
+                    return [];
206
+                }
207
+            }
208
+
209
+            return new ShareTypeList($shareTypes);
210
+        });
211
+    }
212 212
 }
Please login to merge, or discard this patch.
apps/dav/lib/Connector/Sabre/FilesPlugin.php 4 patches
Braces   +3 added lines, -1 removed lines patch added patch discarded remove patch
@@ -245,7 +245,9 @@
 block discarded – undo
245 245
 	function httpGet(RequestInterface $request, ResponseInterface $response) {
246 246
 		// Only handle valid files
247 247
 		$node = $this->tree->getNodeForPath($request->getPath());
248
-		if (!($node instanceof IFile)) return;
248
+		if (!($node instanceof IFile)) {
249
+		    return;
250
+		}
249 251
 
250 252
 		// adds a 'Content-Disposition: attachment' header in case no disposition
251 253
 		// header has been set before
Please login to merge, or discard this patch.
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -448,7 +448,7 @@
 block discarded – undo
448 448
 	 *
449 449
 	 * @param string $path source path
450 450
 	 * @param string $destination destination path
451
-	 * @return bool|void false to stop handling, void to skip this handler
451
+	 * @return null|false false to stop handling, void to skip this handler
452 452
 	 */
453 453
 	public function beforeMoveFutureFile($path, $destination) {
454 454
 		$sourceNode = $this->tree->getNodeForPath($path);
Please login to merge, or discard this patch.
Indentation   +444 added lines, -444 removed lines patch added patch discarded remove patch
@@ -49,453 +49,453 @@
 block discarded – undo
49 49
 
50 50
 class FilesPlugin extends ServerPlugin {
51 51
 
52
-	// namespace
53
-	const NS_OWNCLOUD = 'http://owncloud.org/ns';
54
-	const NS_NEXTCLOUD = 'http://nextcloud.org/ns';
55
-	const FILEID_PROPERTYNAME = '{http://owncloud.org/ns}id';
56
-	const INTERNAL_FILEID_PROPERTYNAME = '{http://owncloud.org/ns}fileid';
57
-	const PERMISSIONS_PROPERTYNAME = '{http://owncloud.org/ns}permissions';
58
-	const SHARE_PERMISSIONS_PROPERTYNAME = '{http://open-collaboration-services.org/ns}share-permissions';
59
-	const DOWNLOADURL_PROPERTYNAME = '{http://owncloud.org/ns}downloadURL';
60
-	const SIZE_PROPERTYNAME = '{http://owncloud.org/ns}size';
61
-	const GETETAG_PROPERTYNAME = '{DAV:}getetag';
62
-	const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified';
63
-	const OWNER_ID_PROPERTYNAME = '{http://owncloud.org/ns}owner-id';
64
-	const OWNER_DISPLAY_NAME_PROPERTYNAME = '{http://owncloud.org/ns}owner-display-name';
65
-	const CHECKSUMS_PROPERTYNAME = '{http://owncloud.org/ns}checksums';
66
-	const DATA_FINGERPRINT_PROPERTYNAME = '{http://owncloud.org/ns}data-fingerprint';
67
-	const HAS_PREVIEW_PROPERTYNAME = '{http://nextcloud.org/ns}has-preview';
68
-	const MOUNT_TYPE_PROPERTYNAME = '{http://nextcloud.org/ns}mount-type';
69
-	const IS_ENCRYPTED_PROPERTYNAME = '{http://nextcloud.org/ns}is-encrypted';
70
-
71
-	/**
72
-	 * Reference to main server object
73
-	 *
74
-	 * @var \Sabre\DAV\Server
75
-	 */
76
-	private $server;
77
-
78
-	/**
79
-	 * @var Tree
80
-	 */
81
-	private $tree;
82
-
83
-	/**
84
-	 * Whether this is public webdav.
85
-	 * If true, some returned information will be stripped off.
86
-	 *
87
-	 * @var bool
88
-	 */
89
-	private $isPublic;
90
-
91
-	/**
92
-	 * @var View
93
-	 */
94
-	private $fileView;
95
-
96
-	/**
97
-	 * @var bool
98
-	 */
99
-	private $downloadAttachment;
100
-
101
-	/**
102
-	 * @var IConfig
103
-	 */
104
-	private $config;
105
-
106
-	/**
107
-	 * @var IRequest
108
-	 */
109
-	private $request;
110
-
111
-	/**
112
-	 * @var IPreview
113
-	 */
114
-	private $previewManager;
115
-
116
-	/**
117
-	 * @param Tree $tree
118
-	 * @param IConfig $config
119
-	 * @param IRequest $request
120
-	 * @param IPreview $previewManager
121
-	 * @param bool $isPublic
122
-	 * @param bool $downloadAttachment
123
-	 */
124
-	public function __construct(Tree $tree,
125
-								IConfig $config,
126
-								IRequest $request,
127
-								IPreview $previewManager,
128
-								$isPublic = false,
129
-								$downloadAttachment = true) {
130
-		$this->tree = $tree;
131
-		$this->config = $config;
132
-		$this->request = $request;
133
-		$this->isPublic = $isPublic;
134
-		$this->downloadAttachment = $downloadAttachment;
135
-		$this->previewManager = $previewManager;
136
-	}
137
-
138
-	/**
139
-	 * This initializes the plugin.
140
-	 *
141
-	 * This function is called by \Sabre\DAV\Server, after
142
-	 * addPlugin is called.
143
-	 *
144
-	 * This method should set up the required event subscriptions.
145
-	 *
146
-	 * @param \Sabre\DAV\Server $server
147
-	 * @return void
148
-	 */
149
-	public function initialize(\Sabre\DAV\Server $server) {
150
-		$server->xml->namespaceMap[self::NS_OWNCLOUD] = 'oc';
151
-		$server->xml->namespaceMap[self::NS_NEXTCLOUD] = 'nc';
152
-		$server->protectedProperties[] = self::FILEID_PROPERTYNAME;
153
-		$server->protectedProperties[] = self::INTERNAL_FILEID_PROPERTYNAME;
154
-		$server->protectedProperties[] = self::PERMISSIONS_PROPERTYNAME;
155
-		$server->protectedProperties[] = self::SHARE_PERMISSIONS_PROPERTYNAME;
156
-		$server->protectedProperties[] = self::SIZE_PROPERTYNAME;
157
-		$server->protectedProperties[] = self::DOWNLOADURL_PROPERTYNAME;
158
-		$server->protectedProperties[] = self::OWNER_ID_PROPERTYNAME;
159
-		$server->protectedProperties[] = self::OWNER_DISPLAY_NAME_PROPERTYNAME;
160
-		$server->protectedProperties[] = self::CHECKSUMS_PROPERTYNAME;
161
-		$server->protectedProperties[] = self::DATA_FINGERPRINT_PROPERTYNAME;
162
-		$server->protectedProperties[] = self::HAS_PREVIEW_PROPERTYNAME;
163
-		$server->protectedProperties[] = self::MOUNT_TYPE_PROPERTYNAME;
164
-		$server->protectedProperties[] = self::IS_ENCRYPTED_PROPERTYNAME;
165
-
166
-		// normally these cannot be changed (RFC4918), but we want them modifiable through PROPPATCH
167
-		$allowedProperties = ['{DAV:}getetag'];
168
-		$server->protectedProperties = array_diff($server->protectedProperties, $allowedProperties);
169
-
170
-		$this->server = $server;
171
-		$this->server->on('propFind', array($this, 'handleGetProperties'));
172
-		$this->server->on('propPatch', array($this, 'handleUpdateProperties'));
173
-		$this->server->on('afterBind', array($this, 'sendFileIdHeader'));
174
-		$this->server->on('afterWriteContent', array($this, 'sendFileIdHeader'));
175
-		$this->server->on('afterMethod:GET', [$this,'httpGet']);
176
-		$this->server->on('afterMethod:GET', array($this, 'handleDownloadToken'));
177
-		$this->server->on('afterResponse', function($request, ResponseInterface $response) {
178
-			$body = $response->getBody();
179
-			if (is_resource($body)) {
180
-				fclose($body);
181
-			}
182
-		});
183
-		$this->server->on('beforeMove', [$this, 'checkMove']);
184
-		$this->server->on('beforeMove', [$this, 'beforeMoveFutureFile']);
185
-	}
186
-
187
-	/**
188
-	 * Plugin that checks if a move can actually be performed.
189
-	 *
190
-	 * @param string $source source path
191
-	 * @param string $destination destination path
192
-	 * @throws Forbidden
193
-	 * @throws NotFound
194
-	 */
195
-	function checkMove($source, $destination) {
196
-		$sourceNode = $this->tree->getNodeForPath($source);
197
-		if (!$sourceNode instanceof Node) {
198
-			return;
199
-		}
200
-		list($sourceDir,) = \Sabre\Uri\split($source);
201
-		list($destinationDir,) = \Sabre\Uri\split($destination);
202
-
203
-		if ($sourceDir !== $destinationDir) {
204
-			$sourceNodeFileInfo = $sourceNode->getFileInfo();
205
-			if ($sourceNodeFileInfo === null) {
206
-				throw new NotFound($source . ' does not exist');
207
- 			}
208
-
209
-			if (!$sourceNodeFileInfo->isDeletable()) {
210
-				throw new Forbidden($source . " cannot be deleted");
211
-			}
212
-		}
213
-	}
214
-
215
-	/**
216
-	 * This sets a cookie to be able to recognize the start of the download
217
-	 * the content must not be longer than 32 characters and must only contain
218
-	 * alphanumeric characters
219
-	 *
220
-	 * @param RequestInterface $request
221
-	 * @param ResponseInterface $response
222
-	 */
223
-	function handleDownloadToken(RequestInterface $request, ResponseInterface $response) {
224
-		$queryParams = $request->getQueryParameters();
225
-
226
-		/**
227
-		 * this sets a cookie to be able to recognize the start of the download
228
-		 * the content must not be longer than 32 characters and must only contain
229
-		 * alphanumeric characters
230
-		 */
231
-		if (isset($queryParams['downloadStartSecret'])) {
232
-			$token = $queryParams['downloadStartSecret'];
233
-			if (!isset($token[32])
234
-				&& preg_match('!^[a-zA-Z0-9]+$!', $token) === 1) {
235
-				// FIXME: use $response->setHeader() instead
236
-				setcookie('ocDownloadStarted', $token, time() + 20, '/');
237
-			}
238
-		}
239
-	}
240
-
241
-	/**
242
-	 * Add headers to file download
243
-	 *
244
-	 * @param RequestInterface $request
245
-	 * @param ResponseInterface $response
246
-	 */
247
-	function httpGet(RequestInterface $request, ResponseInterface $response) {
248
-		// Only handle valid files
249
-		$node = $this->tree->getNodeForPath($request->getPath());
250
-		if (!($node instanceof IFile)) return;
251
-
252
-		// adds a 'Content-Disposition: attachment' header in case no disposition
253
-		// header has been set before
254
-		if ($this->downloadAttachment &&
255
-			$response->getHeader('Content-Disposition') === null) {
256
-			$filename = $node->getName();
257
-			if ($this->request->isUserAgent(
258
-				[
259
-					\OC\AppFramework\Http\Request::USER_AGENT_IE,
260
-					\OC\AppFramework\Http\Request::USER_AGENT_ANDROID_MOBILE_CHROME,
261
-					\OC\AppFramework\Http\Request::USER_AGENT_FREEBOX,
262
-				])) {
263
-				$response->addHeader('Content-Disposition', 'attachment; filename="' . rawurlencode($filename) . '"');
264
-			} else {
265
-				$response->addHeader('Content-Disposition', 'attachment; filename*=UTF-8\'\'' . rawurlencode($filename)
266
-													 . '; filename="' . rawurlencode($filename) . '"');
267
-			}
268
-		}
269
-
270
-		if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
271
-			//Add OC-Checksum header
272
-			/** @var $node File */
273
-			$checksum = $node->getChecksum();
274
-			if ($checksum !== null && $checksum !== '') {
275
-				$response->addHeader('OC-Checksum', $checksum);
276
-			}
277
-		}
278
-	}
279
-
280
-	/**
281
-	 * Adds all ownCloud-specific properties
282
-	 *
283
-	 * @param PropFind $propFind
284
-	 * @param \Sabre\DAV\INode $node
285
-	 * @return void
286
-	 */
287
-	public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node) {
288
-
289
-		$httpRequest = $this->server->httpRequest;
290
-
291
-		if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
292
-			/**
293
-			 * This was disabled, because it made dir listing throw an exception,
294
-			 * so users were unable to navigate into folders where one subitem
295
-			 * is blocked by the files_accesscontrol app, see:
296
-			 * https://github.com/nextcloud/files_accesscontrol/issues/65
52
+    // namespace
53
+    const NS_OWNCLOUD = 'http://owncloud.org/ns';
54
+    const NS_NEXTCLOUD = 'http://nextcloud.org/ns';
55
+    const FILEID_PROPERTYNAME = '{http://owncloud.org/ns}id';
56
+    const INTERNAL_FILEID_PROPERTYNAME = '{http://owncloud.org/ns}fileid';
57
+    const PERMISSIONS_PROPERTYNAME = '{http://owncloud.org/ns}permissions';
58
+    const SHARE_PERMISSIONS_PROPERTYNAME = '{http://open-collaboration-services.org/ns}share-permissions';
59
+    const DOWNLOADURL_PROPERTYNAME = '{http://owncloud.org/ns}downloadURL';
60
+    const SIZE_PROPERTYNAME = '{http://owncloud.org/ns}size';
61
+    const GETETAG_PROPERTYNAME = '{DAV:}getetag';
62
+    const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified';
63
+    const OWNER_ID_PROPERTYNAME = '{http://owncloud.org/ns}owner-id';
64
+    const OWNER_DISPLAY_NAME_PROPERTYNAME = '{http://owncloud.org/ns}owner-display-name';
65
+    const CHECKSUMS_PROPERTYNAME = '{http://owncloud.org/ns}checksums';
66
+    const DATA_FINGERPRINT_PROPERTYNAME = '{http://owncloud.org/ns}data-fingerprint';
67
+    const HAS_PREVIEW_PROPERTYNAME = '{http://nextcloud.org/ns}has-preview';
68
+    const MOUNT_TYPE_PROPERTYNAME = '{http://nextcloud.org/ns}mount-type';
69
+    const IS_ENCRYPTED_PROPERTYNAME = '{http://nextcloud.org/ns}is-encrypted';
70
+
71
+    /**
72
+     * Reference to main server object
73
+     *
74
+     * @var \Sabre\DAV\Server
75
+     */
76
+    private $server;
77
+
78
+    /**
79
+     * @var Tree
80
+     */
81
+    private $tree;
82
+
83
+    /**
84
+     * Whether this is public webdav.
85
+     * If true, some returned information will be stripped off.
86
+     *
87
+     * @var bool
88
+     */
89
+    private $isPublic;
90
+
91
+    /**
92
+     * @var View
93
+     */
94
+    private $fileView;
95
+
96
+    /**
97
+     * @var bool
98
+     */
99
+    private $downloadAttachment;
100
+
101
+    /**
102
+     * @var IConfig
103
+     */
104
+    private $config;
105
+
106
+    /**
107
+     * @var IRequest
108
+     */
109
+    private $request;
110
+
111
+    /**
112
+     * @var IPreview
113
+     */
114
+    private $previewManager;
115
+
116
+    /**
117
+     * @param Tree $tree
118
+     * @param IConfig $config
119
+     * @param IRequest $request
120
+     * @param IPreview $previewManager
121
+     * @param bool $isPublic
122
+     * @param bool $downloadAttachment
123
+     */
124
+    public function __construct(Tree $tree,
125
+                                IConfig $config,
126
+                                IRequest $request,
127
+                                IPreview $previewManager,
128
+                                $isPublic = false,
129
+                                $downloadAttachment = true) {
130
+        $this->tree = $tree;
131
+        $this->config = $config;
132
+        $this->request = $request;
133
+        $this->isPublic = $isPublic;
134
+        $this->downloadAttachment = $downloadAttachment;
135
+        $this->previewManager = $previewManager;
136
+    }
137
+
138
+    /**
139
+     * This initializes the plugin.
140
+     *
141
+     * This function is called by \Sabre\DAV\Server, after
142
+     * addPlugin is called.
143
+     *
144
+     * This method should set up the required event subscriptions.
145
+     *
146
+     * @param \Sabre\DAV\Server $server
147
+     * @return void
148
+     */
149
+    public function initialize(\Sabre\DAV\Server $server) {
150
+        $server->xml->namespaceMap[self::NS_OWNCLOUD] = 'oc';
151
+        $server->xml->namespaceMap[self::NS_NEXTCLOUD] = 'nc';
152
+        $server->protectedProperties[] = self::FILEID_PROPERTYNAME;
153
+        $server->protectedProperties[] = self::INTERNAL_FILEID_PROPERTYNAME;
154
+        $server->protectedProperties[] = self::PERMISSIONS_PROPERTYNAME;
155
+        $server->protectedProperties[] = self::SHARE_PERMISSIONS_PROPERTYNAME;
156
+        $server->protectedProperties[] = self::SIZE_PROPERTYNAME;
157
+        $server->protectedProperties[] = self::DOWNLOADURL_PROPERTYNAME;
158
+        $server->protectedProperties[] = self::OWNER_ID_PROPERTYNAME;
159
+        $server->protectedProperties[] = self::OWNER_DISPLAY_NAME_PROPERTYNAME;
160
+        $server->protectedProperties[] = self::CHECKSUMS_PROPERTYNAME;
161
+        $server->protectedProperties[] = self::DATA_FINGERPRINT_PROPERTYNAME;
162
+        $server->protectedProperties[] = self::HAS_PREVIEW_PROPERTYNAME;
163
+        $server->protectedProperties[] = self::MOUNT_TYPE_PROPERTYNAME;
164
+        $server->protectedProperties[] = self::IS_ENCRYPTED_PROPERTYNAME;
165
+
166
+        // normally these cannot be changed (RFC4918), but we want them modifiable through PROPPATCH
167
+        $allowedProperties = ['{DAV:}getetag'];
168
+        $server->protectedProperties = array_diff($server->protectedProperties, $allowedProperties);
169
+
170
+        $this->server = $server;
171
+        $this->server->on('propFind', array($this, 'handleGetProperties'));
172
+        $this->server->on('propPatch', array($this, 'handleUpdateProperties'));
173
+        $this->server->on('afterBind', array($this, 'sendFileIdHeader'));
174
+        $this->server->on('afterWriteContent', array($this, 'sendFileIdHeader'));
175
+        $this->server->on('afterMethod:GET', [$this,'httpGet']);
176
+        $this->server->on('afterMethod:GET', array($this, 'handleDownloadToken'));
177
+        $this->server->on('afterResponse', function($request, ResponseInterface $response) {
178
+            $body = $response->getBody();
179
+            if (is_resource($body)) {
180
+                fclose($body);
181
+            }
182
+        });
183
+        $this->server->on('beforeMove', [$this, 'checkMove']);
184
+        $this->server->on('beforeMove', [$this, 'beforeMoveFutureFile']);
185
+    }
186
+
187
+    /**
188
+     * Plugin that checks if a move can actually be performed.
189
+     *
190
+     * @param string $source source path
191
+     * @param string $destination destination path
192
+     * @throws Forbidden
193
+     * @throws NotFound
194
+     */
195
+    function checkMove($source, $destination) {
196
+        $sourceNode = $this->tree->getNodeForPath($source);
197
+        if (!$sourceNode instanceof Node) {
198
+            return;
199
+        }
200
+        list($sourceDir,) = \Sabre\Uri\split($source);
201
+        list($destinationDir,) = \Sabre\Uri\split($destination);
202
+
203
+        if ($sourceDir !== $destinationDir) {
204
+            $sourceNodeFileInfo = $sourceNode->getFileInfo();
205
+            if ($sourceNodeFileInfo === null) {
206
+                throw new NotFound($source . ' does not exist');
207
+                }
208
+
209
+            if (!$sourceNodeFileInfo->isDeletable()) {
210
+                throw new Forbidden($source . " cannot be deleted");
211
+            }
212
+        }
213
+    }
214
+
215
+    /**
216
+     * This sets a cookie to be able to recognize the start of the download
217
+     * the content must not be longer than 32 characters and must only contain
218
+     * alphanumeric characters
219
+     *
220
+     * @param RequestInterface $request
221
+     * @param ResponseInterface $response
222
+     */
223
+    function handleDownloadToken(RequestInterface $request, ResponseInterface $response) {
224
+        $queryParams = $request->getQueryParameters();
225
+
226
+        /**
227
+         * this sets a cookie to be able to recognize the start of the download
228
+         * the content must not be longer than 32 characters and must only contain
229
+         * alphanumeric characters
230
+         */
231
+        if (isset($queryParams['downloadStartSecret'])) {
232
+            $token = $queryParams['downloadStartSecret'];
233
+            if (!isset($token[32])
234
+                && preg_match('!^[a-zA-Z0-9]+$!', $token) === 1) {
235
+                // FIXME: use $response->setHeader() instead
236
+                setcookie('ocDownloadStarted', $token, time() + 20, '/');
237
+            }
238
+        }
239
+    }
240
+
241
+    /**
242
+     * Add headers to file download
243
+     *
244
+     * @param RequestInterface $request
245
+     * @param ResponseInterface $response
246
+     */
247
+    function httpGet(RequestInterface $request, ResponseInterface $response) {
248
+        // Only handle valid files
249
+        $node = $this->tree->getNodeForPath($request->getPath());
250
+        if (!($node instanceof IFile)) return;
251
+
252
+        // adds a 'Content-Disposition: attachment' header in case no disposition
253
+        // header has been set before
254
+        if ($this->downloadAttachment &&
255
+            $response->getHeader('Content-Disposition') === null) {
256
+            $filename = $node->getName();
257
+            if ($this->request->isUserAgent(
258
+                [
259
+                    \OC\AppFramework\Http\Request::USER_AGENT_IE,
260
+                    \OC\AppFramework\Http\Request::USER_AGENT_ANDROID_MOBILE_CHROME,
261
+                    \OC\AppFramework\Http\Request::USER_AGENT_FREEBOX,
262
+                ])) {
263
+                $response->addHeader('Content-Disposition', 'attachment; filename="' . rawurlencode($filename) . '"');
264
+            } else {
265
+                $response->addHeader('Content-Disposition', 'attachment; filename*=UTF-8\'\'' . rawurlencode($filename)
266
+                                                        . '; filename="' . rawurlencode($filename) . '"');
267
+            }
268
+        }
269
+
270
+        if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
271
+            //Add OC-Checksum header
272
+            /** @var $node File */
273
+            $checksum = $node->getChecksum();
274
+            if ($checksum !== null && $checksum !== '') {
275
+                $response->addHeader('OC-Checksum', $checksum);
276
+            }
277
+        }
278
+    }
279
+
280
+    /**
281
+     * Adds all ownCloud-specific properties
282
+     *
283
+     * @param PropFind $propFind
284
+     * @param \Sabre\DAV\INode $node
285
+     * @return void
286
+     */
287
+    public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node) {
288
+
289
+        $httpRequest = $this->server->httpRequest;
290
+
291
+        if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
292
+            /**
293
+             * This was disabled, because it made dir listing throw an exception,
294
+             * so users were unable to navigate into folders where one subitem
295
+             * is blocked by the files_accesscontrol app, see:
296
+             * https://github.com/nextcloud/files_accesscontrol/issues/65
297 297
 			if (!$node->getFileInfo()->isReadable()) {
298 298
 				// avoid detecting files through this means
299 299
 				throw new NotFound();
300 300
 			}
301
-			 */
302
-
303
-			$propFind->handle(self::FILEID_PROPERTYNAME, function() use ($node) {
304
-				return $node->getFileId();
305
-			});
306
-
307
-			$propFind->handle(self::INTERNAL_FILEID_PROPERTYNAME, function() use ($node) {
308
-				return $node->getInternalFileId();
309
-			});
310
-
311
-			$propFind->handle(self::PERMISSIONS_PROPERTYNAME, function() use ($node) {
312
-				$perms = $node->getDavPermissions();
313
-				if ($this->isPublic) {
314
-					// remove mount information
315
-					$perms = str_replace(['S', 'M'], '', $perms);
316
-				}
317
-				return $perms;
318
-			});
319
-
320
-			$propFind->handle(self::SHARE_PERMISSIONS_PROPERTYNAME, function() use ($node, $httpRequest) {
321
-				return $node->getSharePermissions(
322
-					$httpRequest->getRawServerValue('PHP_AUTH_USER')
323
-				);
324
-			});
325
-
326
-			$propFind->handle(self::GETETAG_PROPERTYNAME, function() use ($node) {
327
-				return $node->getETag();
328
-			});
329
-
330
-			$propFind->handle(self::OWNER_ID_PROPERTYNAME, function() use ($node) {
331
-				$owner = $node->getOwner();
332
-				if (!$owner) {
333
-					return null;
334
-				} else {
335
-					return $owner->getUID();
336
-				}
337
-			});
338
-			$propFind->handle(self::OWNER_DISPLAY_NAME_PROPERTYNAME, function() use ($node) {
339
-				$owner = $node->getOwner();
340
-				if (!$owner) {
341
-					return null;
342
-				} else {
343
-					return $owner->getDisplayName();
344
-				}
345
-			});
346
-
347
-			$propFind->handle(self::IS_ENCRYPTED_PROPERTYNAME, function() use ($node) {
348
-				$result = $node->getFileInfo()->isEncrypted() ? '1' : '0';
349
-				return $result;
350
-			});
351
-
352
-			$propFind->handle(self::HAS_PREVIEW_PROPERTYNAME, function () use ($node) {
353
-				return json_encode($this->previewManager->isAvailable($node->getFileInfo()));
354
-			});
355
-			$propFind->handle(self::SIZE_PROPERTYNAME, function() use ($node) {
356
-				return $node->getSize();
357
-			});
358
-			$propFind->handle(self::MOUNT_TYPE_PROPERTYNAME, function () use ($node) {
359
-				return $node->getFileInfo()->getMountPoint()->getMountType();
360
-			});
361
-		}
362
-
363
-		if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
364
-			$propFind->handle(self::DATA_FINGERPRINT_PROPERTYNAME, function() use ($node) {
365
-				return $this->config->getSystemValue('data-fingerprint', '');
366
-			});
367
-		}
368
-
369
-		if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
370
-			$propFind->handle(self::DOWNLOADURL_PROPERTYNAME, function() use ($node) {
371
-				/** @var $node \OCA\DAV\Connector\Sabre\File */
372
-				try {
373
-					$directDownloadUrl = $node->getDirectDownload();
374
-					if (isset($directDownloadUrl['url'])) {
375
-						return $directDownloadUrl['url'];
376
-					}
377
-				} catch (StorageNotAvailableException $e) {
378
-					return false;
379
-				} catch (ForbiddenException $e) {
380
-					return false;
381
-				}
382
-				return false;
383
-			});
384
-
385
-			$propFind->handle(self::CHECKSUMS_PROPERTYNAME, function() use ($node) {
386
-				$checksum = $node->getChecksum();
387
-				if ($checksum === NULL || $checksum === '') {
388
-					return null;
389
-				}
390
-
391
-				return new ChecksumList($checksum);
392
-			});
393
-
394
-		}
395
-
396
-		if ($node instanceof \OCA\DAV\Connector\Sabre\Directory) {
397
-			$propFind->handle(self::SIZE_PROPERTYNAME, function() use ($node) {
398
-				return $node->getSize();
399
-			});
400
-		}
401
-	}
402
-
403
-	/**
404
-	 * Update ownCloud-specific properties
405
-	 *
406
-	 * @param string $path
407
-	 * @param PropPatch $propPatch
408
-	 *
409
-	 * @return void
410
-	 */
411
-	public function handleUpdateProperties($path, PropPatch $propPatch) {
412
-		$node = $this->tree->getNodeForPath($path);
413
-		if (!($node instanceof \OCA\DAV\Connector\Sabre\Node)) {
414
-			return;
415
-		}
416
-
417
-		$propPatch->handle(self::LASTMODIFIED_PROPERTYNAME, function($time) use ($node) {
418
-			if (empty($time)) {
419
-				return false;
420
-			}
421
-			$node->touch($time);
422
-			return true;
423
-		});
424
-		$propPatch->handle(self::GETETAG_PROPERTYNAME, function($etag) use ($node) {
425
-			if (empty($etag)) {
426
-				return false;
427
-			}
428
-			if ($node->setEtag($etag) !== -1) {
429
-				return true;
430
-			}
431
-			return false;
432
-		});
433
-	}
434
-
435
-	/**
436
-	 * @param string $filePath
437
-	 * @param \Sabre\DAV\INode $node
438
-	 * @throws \Sabre\DAV\Exception\BadRequest
439
-	 */
440
-	public function sendFileIdHeader($filePath, \Sabre\DAV\INode $node = null) {
441
-		// chunked upload handling
442
-		if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
443
-			list($path, $name) = \Sabre\Uri\split($filePath);
444
-			$info = \OC_FileChunking::decodeName($name);
445
-			if (!empty($info)) {
446
-				$filePath = $path . '/' . $info['name'];
447
-			}
448
-		}
449
-
450
-		// we get the node for the given $filePath here because in case of afterCreateFile $node is the parent folder
451
-		if (!$this->server->tree->nodeExists($filePath)) {
452
-			return;
453
-		}
454
-		$node = $this->server->tree->getNodeForPath($filePath);
455
-		if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
456
-			$fileId = $node->getFileId();
457
-			if (!is_null($fileId)) {
458
-				$this->server->httpResponse->setHeader('OC-FileId', $fileId);
459
-			}
460
-		}
461
-	}
462
-
463
-	/**
464
-	 * Move handler for future file.
465
-	 *
466
-	 * This overrides the default move behavior to prevent Sabre
467
-	 * to delete the target file before moving. Because deleting would
468
-	 * lose the file id and metadata.
469
-	 *
470
-	 * @param string $path source path
471
-	 * @param string $destination destination path
472
-	 * @return bool|void false to stop handling, void to skip this handler
473
-	 */
474
-	public function beforeMoveFutureFile($path, $destination) {
475
-		$sourceNode = $this->tree->getNodeForPath($path);
476
-		if (!$sourceNode instanceof FutureFile) {
477
-			// skip handling as the source is not a chunked FutureFile
478
-			return;
479
-		}
480
-
481
-		if (!$this->tree->nodeExists($destination)) {
482
-			// skip and let the default handler do its work
483
-			return;
484
-		}
485
-
486
-		// do a move manually, skipping Sabre's default "delete" for existing nodes
487
-		$this->tree->move($path, $destination);
488
-
489
-		// trigger all default events (copied from CorePlugin::move)
490
-		$this->server->emit('afterMove', [$path, $destination]);
491
-		$this->server->emit('afterUnbind', [$path]);
492
-		$this->server->emit('afterBind', [$destination]);
493
-
494
-		$response = $this->server->httpResponse;
495
-		$response->setHeader('Content-Length', '0');
496
-		$response->setStatus(204);
497
-
498
-		return false;
499
-	}
301
+             */
302
+
303
+            $propFind->handle(self::FILEID_PROPERTYNAME, function() use ($node) {
304
+                return $node->getFileId();
305
+            });
306
+
307
+            $propFind->handle(self::INTERNAL_FILEID_PROPERTYNAME, function() use ($node) {
308
+                return $node->getInternalFileId();
309
+            });
310
+
311
+            $propFind->handle(self::PERMISSIONS_PROPERTYNAME, function() use ($node) {
312
+                $perms = $node->getDavPermissions();
313
+                if ($this->isPublic) {
314
+                    // remove mount information
315
+                    $perms = str_replace(['S', 'M'], '', $perms);
316
+                }
317
+                return $perms;
318
+            });
319
+
320
+            $propFind->handle(self::SHARE_PERMISSIONS_PROPERTYNAME, function() use ($node, $httpRequest) {
321
+                return $node->getSharePermissions(
322
+                    $httpRequest->getRawServerValue('PHP_AUTH_USER')
323
+                );
324
+            });
325
+
326
+            $propFind->handle(self::GETETAG_PROPERTYNAME, function() use ($node) {
327
+                return $node->getETag();
328
+            });
329
+
330
+            $propFind->handle(self::OWNER_ID_PROPERTYNAME, function() use ($node) {
331
+                $owner = $node->getOwner();
332
+                if (!$owner) {
333
+                    return null;
334
+                } else {
335
+                    return $owner->getUID();
336
+                }
337
+            });
338
+            $propFind->handle(self::OWNER_DISPLAY_NAME_PROPERTYNAME, function() use ($node) {
339
+                $owner = $node->getOwner();
340
+                if (!$owner) {
341
+                    return null;
342
+                } else {
343
+                    return $owner->getDisplayName();
344
+                }
345
+            });
346
+
347
+            $propFind->handle(self::IS_ENCRYPTED_PROPERTYNAME, function() use ($node) {
348
+                $result = $node->getFileInfo()->isEncrypted() ? '1' : '0';
349
+                return $result;
350
+            });
351
+
352
+            $propFind->handle(self::HAS_PREVIEW_PROPERTYNAME, function () use ($node) {
353
+                return json_encode($this->previewManager->isAvailable($node->getFileInfo()));
354
+            });
355
+            $propFind->handle(self::SIZE_PROPERTYNAME, function() use ($node) {
356
+                return $node->getSize();
357
+            });
358
+            $propFind->handle(self::MOUNT_TYPE_PROPERTYNAME, function () use ($node) {
359
+                return $node->getFileInfo()->getMountPoint()->getMountType();
360
+            });
361
+        }
362
+
363
+        if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
364
+            $propFind->handle(self::DATA_FINGERPRINT_PROPERTYNAME, function() use ($node) {
365
+                return $this->config->getSystemValue('data-fingerprint', '');
366
+            });
367
+        }
368
+
369
+        if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
370
+            $propFind->handle(self::DOWNLOADURL_PROPERTYNAME, function() use ($node) {
371
+                /** @var $node \OCA\DAV\Connector\Sabre\File */
372
+                try {
373
+                    $directDownloadUrl = $node->getDirectDownload();
374
+                    if (isset($directDownloadUrl['url'])) {
375
+                        return $directDownloadUrl['url'];
376
+                    }
377
+                } catch (StorageNotAvailableException $e) {
378
+                    return false;
379
+                } catch (ForbiddenException $e) {
380
+                    return false;
381
+                }
382
+                return false;
383
+            });
384
+
385
+            $propFind->handle(self::CHECKSUMS_PROPERTYNAME, function() use ($node) {
386
+                $checksum = $node->getChecksum();
387
+                if ($checksum === NULL || $checksum === '') {
388
+                    return null;
389
+                }
390
+
391
+                return new ChecksumList($checksum);
392
+            });
393
+
394
+        }
395
+
396
+        if ($node instanceof \OCA\DAV\Connector\Sabre\Directory) {
397
+            $propFind->handle(self::SIZE_PROPERTYNAME, function() use ($node) {
398
+                return $node->getSize();
399
+            });
400
+        }
401
+    }
402
+
403
+    /**
404
+     * Update ownCloud-specific properties
405
+     *
406
+     * @param string $path
407
+     * @param PropPatch $propPatch
408
+     *
409
+     * @return void
410
+     */
411
+    public function handleUpdateProperties($path, PropPatch $propPatch) {
412
+        $node = $this->tree->getNodeForPath($path);
413
+        if (!($node instanceof \OCA\DAV\Connector\Sabre\Node)) {
414
+            return;
415
+        }
416
+
417
+        $propPatch->handle(self::LASTMODIFIED_PROPERTYNAME, function($time) use ($node) {
418
+            if (empty($time)) {
419
+                return false;
420
+            }
421
+            $node->touch($time);
422
+            return true;
423
+        });
424
+        $propPatch->handle(self::GETETAG_PROPERTYNAME, function($etag) use ($node) {
425
+            if (empty($etag)) {
426
+                return false;
427
+            }
428
+            if ($node->setEtag($etag) !== -1) {
429
+                return true;
430
+            }
431
+            return false;
432
+        });
433
+    }
434
+
435
+    /**
436
+     * @param string $filePath
437
+     * @param \Sabre\DAV\INode $node
438
+     * @throws \Sabre\DAV\Exception\BadRequest
439
+     */
440
+    public function sendFileIdHeader($filePath, \Sabre\DAV\INode $node = null) {
441
+        // chunked upload handling
442
+        if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
443
+            list($path, $name) = \Sabre\Uri\split($filePath);
444
+            $info = \OC_FileChunking::decodeName($name);
445
+            if (!empty($info)) {
446
+                $filePath = $path . '/' . $info['name'];
447
+            }
448
+        }
449
+
450
+        // we get the node for the given $filePath here because in case of afterCreateFile $node is the parent folder
451
+        if (!$this->server->tree->nodeExists($filePath)) {
452
+            return;
453
+        }
454
+        $node = $this->server->tree->getNodeForPath($filePath);
455
+        if ($node instanceof \OCA\DAV\Connector\Sabre\Node) {
456
+            $fileId = $node->getFileId();
457
+            if (!is_null($fileId)) {
458
+                $this->server->httpResponse->setHeader('OC-FileId', $fileId);
459
+            }
460
+        }
461
+    }
462
+
463
+    /**
464
+     * Move handler for future file.
465
+     *
466
+     * This overrides the default move behavior to prevent Sabre
467
+     * to delete the target file before moving. Because deleting would
468
+     * lose the file id and metadata.
469
+     *
470
+     * @param string $path source path
471
+     * @param string $destination destination path
472
+     * @return bool|void false to stop handling, void to skip this handler
473
+     */
474
+    public function beforeMoveFutureFile($path, $destination) {
475
+        $sourceNode = $this->tree->getNodeForPath($path);
476
+        if (!$sourceNode instanceof FutureFile) {
477
+            // skip handling as the source is not a chunked FutureFile
478
+            return;
479
+        }
480
+
481
+        if (!$this->tree->nodeExists($destination)) {
482
+            // skip and let the default handler do its work
483
+            return;
484
+        }
485
+
486
+        // do a move manually, skipping Sabre's default "delete" for existing nodes
487
+        $this->tree->move($path, $destination);
488
+
489
+        // trigger all default events (copied from CorePlugin::move)
490
+        $this->server->emit('afterMove', [$path, $destination]);
491
+        $this->server->emit('afterUnbind', [$path]);
492
+        $this->server->emit('afterBind', [$destination]);
493
+
494
+        $response = $this->server->httpResponse;
495
+        $response->setHeader('Content-Length', '0');
496
+        $response->setStatus(204);
497
+
498
+        return false;
499
+    }
500 500
 
501 501
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -172,7 +172,7 @@  discard block
 block discarded – undo
172 172
 		$this->server->on('propPatch', array($this, 'handleUpdateProperties'));
173 173
 		$this->server->on('afterBind', array($this, 'sendFileIdHeader'));
174 174
 		$this->server->on('afterWriteContent', array($this, 'sendFileIdHeader'));
175
-		$this->server->on('afterMethod:GET', [$this,'httpGet']);
175
+		$this->server->on('afterMethod:GET', [$this, 'httpGet']);
176 176
 		$this->server->on('afterMethod:GET', array($this, 'handleDownloadToken'));
177 177
 		$this->server->on('afterResponse', function($request, ResponseInterface $response) {
178 178
 			$body = $response->getBody();
@@ -203,11 +203,11 @@  discard block
 block discarded – undo
203 203
 		if ($sourceDir !== $destinationDir) {
204 204
 			$sourceNodeFileInfo = $sourceNode->getFileInfo();
205 205
 			if ($sourceNodeFileInfo === null) {
206
-				throw new NotFound($source . ' does not exist');
206
+				throw new NotFound($source.' does not exist');
207 207
  			}
208 208
 
209 209
 			if (!$sourceNodeFileInfo->isDeletable()) {
210
-				throw new Forbidden($source . " cannot be deleted");
210
+				throw new Forbidden($source." cannot be deleted");
211 211
 			}
212 212
 		}
213 213
 	}
@@ -260,10 +260,10 @@  discard block
 block discarded – undo
260 260
 					\OC\AppFramework\Http\Request::USER_AGENT_ANDROID_MOBILE_CHROME,
261 261
 					\OC\AppFramework\Http\Request::USER_AGENT_FREEBOX,
262 262
 				])) {
263
-				$response->addHeader('Content-Disposition', 'attachment; filename="' . rawurlencode($filename) . '"');
263
+				$response->addHeader('Content-Disposition', 'attachment; filename="'.rawurlencode($filename).'"');
264 264
 			} else {
265
-				$response->addHeader('Content-Disposition', 'attachment; filename*=UTF-8\'\'' . rawurlencode($filename)
266
-													 . '; filename="' . rawurlencode($filename) . '"');
265
+				$response->addHeader('Content-Disposition', 'attachment; filename*=UTF-8\'\''.rawurlencode($filename)
266
+													 . '; filename="'.rawurlencode($filename).'"');
267 267
 			}
268 268
 		}
269 269
 
@@ -349,13 +349,13 @@  discard block
 block discarded – undo
349 349
 				return $result;
350 350
 			});
351 351
 
352
-			$propFind->handle(self::HAS_PREVIEW_PROPERTYNAME, function () use ($node) {
352
+			$propFind->handle(self::HAS_PREVIEW_PROPERTYNAME, function() use ($node) {
353 353
 				return json_encode($this->previewManager->isAvailable($node->getFileInfo()));
354 354
 			});
355 355
 			$propFind->handle(self::SIZE_PROPERTYNAME, function() use ($node) {
356 356
 				return $node->getSize();
357 357
 			});
358
-			$propFind->handle(self::MOUNT_TYPE_PROPERTYNAME, function () use ($node) {
358
+			$propFind->handle(self::MOUNT_TYPE_PROPERTYNAME, function() use ($node) {
359 359
 				return $node->getFileInfo()->getMountPoint()->getMountType();
360 360
 			});
361 361
 		}
@@ -443,7 +443,7 @@  discard block
 block discarded – undo
443 443
 			list($path, $name) = \Sabre\Uri\split($filePath);
444 444
 			$info = \OC_FileChunking::decodeName($name);
445 445
 			if (!empty($info)) {
446
-				$filePath = $path . '/' . $info['name'];
446
+				$filePath = $path.'/'.$info['name'];
447 447
 			}
448 448
 		}
449 449
 
Please login to merge, or discard this patch.
apps/dav/lib/Connector/LegacyDAVACL.php 3 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -60,9 +60,9 @@
 block discarded – undo
60 60
 
61 61
 	public function propFind(PropFind $propFind, INode $node) {
62 62
 		/* Overload current-user-principal */
63
-		$propFind->handle('{DAV:}current-user-principal', function () {
63
+		$propFind->handle('{DAV:}current-user-principal', function() {
64 64
 			if ($url = parent::getCurrentUserPrincipal()) {
65
-				return new Principal(Principal::HREF, $url . '/');
65
+				return new Principal(Principal::HREF, $url.'/');
66 66
 			} else {
67 67
 				return new Principal(Principal::UNAUTHENTICATED);
68 68
 			}
Please login to merge, or discard this patch.
Braces   +3 added lines, -1 removed lines patch added patch discarded remove patch
@@ -38,7 +38,9 @@
 block discarded – undo
38 38
 	public function getCurrentUserPrincipals() {
39 39
 		$principalV2 = $this->getCurrentUserPrincipal();
40 40
 
41
-		if (is_null($principalV2)) return [];
41
+		if (is_null($principalV2)) {
42
+		    return [];
43
+		}
42 44
 
43 45
 		$principalV1 = $this->convertPrincipal($principalV2, false);
44 46
 		return array_merge(
Please login to merge, or discard this patch.
Indentation   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -32,42 +32,42 @@
 block discarded – undo
32 32
 
33 33
 class LegacyDAVACL extends DavAclPlugin {
34 34
 
35
-	/**
36
-	 * @inheritdoc
37
-	 */
38
-	public function getCurrentUserPrincipals() {
39
-		$principalV2 = $this->getCurrentUserPrincipal();
35
+    /**
36
+     * @inheritdoc
37
+     */
38
+    public function getCurrentUserPrincipals() {
39
+        $principalV2 = $this->getCurrentUserPrincipal();
40 40
 
41
-		if (is_null($principalV2)) return [];
41
+        if (is_null($principalV2)) return [];
42 42
 
43
-		$principalV1 = $this->convertPrincipal($principalV2, false);
44
-		return array_merge(
45
-			[
46
-				$principalV2,
47
-				$principalV1
48
-			],
49
-			$this->getPrincipalMembership($principalV1)
50
-		);
51
-	}
43
+        $principalV1 = $this->convertPrincipal($principalV2, false);
44
+        return array_merge(
45
+            [
46
+                $principalV2,
47
+                $principalV1
48
+            ],
49
+            $this->getPrincipalMembership($principalV1)
50
+        );
51
+    }
52 52
 
53
-	private function convertPrincipal($principal, $toV2) {
54
-		list(, $name) = \Sabre\Uri\split($principal);
55
-		if ($toV2) {
56
-			return "principals/users/$name";
57
-		}
58
-		return "principals/$name";
59
-	}
53
+    private function convertPrincipal($principal, $toV2) {
54
+        list(, $name) = \Sabre\Uri\split($principal);
55
+        if ($toV2) {
56
+            return "principals/users/$name";
57
+        }
58
+        return "principals/$name";
59
+    }
60 60
 
61
-	public function propFind(PropFind $propFind, INode $node) {
62
-		/* Overload current-user-principal */
63
-		$propFind->handle('{DAV:}current-user-principal', function () {
64
-			if ($url = parent::getCurrentUserPrincipal()) {
65
-				return new Principal(Principal::HREF, $url . '/');
66
-			} else {
67
-				return new Principal(Principal::UNAUTHENTICATED);
68
-			}
69
-		});
61
+    public function propFind(PropFind $propFind, INode $node) {
62
+        /* Overload current-user-principal */
63
+        $propFind->handle('{DAV:}current-user-principal', function () {
64
+            if ($url = parent::getCurrentUserPrincipal()) {
65
+                return new Principal(Principal::HREF, $url . '/');
66
+            } else {
67
+                return new Principal(Principal::UNAUTHENTICATED);
68
+            }
69
+        });
70 70
 
71
-		return parent::propFind($propFind, $node);
72
-	}
71
+        return parent::propFind($propFind, $node);
72
+    }
73 73
 }
Please login to merge, or discard this patch.
apps/dav/lib/AppInfo/Application.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -70,7 +70,7 @@
 block discarded – undo
70 70
 		$dispatcher = $this->getContainer()->getServer()->getEventDispatcher();
71 71
 
72 72
 		// first time login event setup
73
-		$dispatcher->addListener(IUser::class . '::firstLogin', function ($event) use ($hm) {
73
+		$dispatcher->addListener(IUser::class.'::firstLogin', function($event) use ($hm) {
74 74
 			if ($event instanceof GenericEvent) {
75 75
 				$hm->firstLogin($event->getSubject());
76 76
 			}
Please login to merge, or discard this patch.
Indentation   +149 added lines, -149 removed lines patch added patch discarded remove patch
@@ -40,156 +40,156 @@
 block discarded – undo
40 40
 
41 41
 class Application extends App {
42 42
 
43
-	/**
44
-	 * Application constructor.
45
-	 */
46
-	public function __construct() {
47
-		parent::__construct('dav');
48
-
49
-		$container = $this->getContainer();
50
-		$server = $container->getServer();
51
-
52
-		$container->registerService(PhotoCache::class, function(SimpleContainer $s) use ($server) {
53
-			return new PhotoCache(
54
-				$server->getAppDataDir('dav-photocache')
55
-			);
56
-		});
57
-
58
-		/*
43
+    /**
44
+     * Application constructor.
45
+     */
46
+    public function __construct() {
47
+        parent::__construct('dav');
48
+
49
+        $container = $this->getContainer();
50
+        $server = $container->getServer();
51
+
52
+        $container->registerService(PhotoCache::class, function(SimpleContainer $s) use ($server) {
53
+            return new PhotoCache(
54
+                $server->getAppDataDir('dav-photocache')
55
+            );
56
+        });
57
+
58
+        /*
59 59
 		 * Register capabilities
60 60
 		 */
61
-		$container->registerCapability(Capabilities::class);
62
-	}
63
-
64
-	/**
65
-	 * @param IManager $contactsManager
66
-	 * @param string $userID
67
-	 */
68
-	public function setupContactsProvider(IManager $contactsManager, $userID) {
69
-		/** @var ContactsManager $cm */
70
-		$cm = $this->getContainer()->query(ContactsManager::class);
71
-		$urlGenerator = $this->getContainer()->getServer()->getURLGenerator();
72
-		$cm->setupContactsProvider($contactsManager, $userID, $urlGenerator);
73
-	}
74
-
75
-	public function registerHooks() {
76
-		/** @var HookManager $hm */
77
-		$hm = $this->getContainer()->query(HookManager::class);
78
-		$hm->setup();
79
-
80
-		$dispatcher = $this->getContainer()->getServer()->getEventDispatcher();
81
-
82
-		// first time login event setup
83
-		$dispatcher->addListener(IUser::class . '::firstLogin', function ($event) use ($hm) {
84
-			if ($event instanceof GenericEvent) {
85
-				$hm->firstLogin($event->getSubject());
86
-			}
87
-		});
88
-
89
-		// carddav/caldav sync event setup
90
-		$listener = function($event) {
91
-			if ($event instanceof GenericEvent) {
92
-				/** @var BirthdayService $b */
93
-				$b = $this->getContainer()->query(BirthdayService::class);
94
-				$b->onCardChanged(
95
-					$event->getArgument('addressBookId'),
96
-					$event->getArgument('cardUri'),
97
-					$event->getArgument('cardData')
98
-				);
99
-			}
100
-		};
101
-
102
-		$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::createCard', $listener);
103
-		$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $listener);
104
-		$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', function($event) {
105
-			if ($event instanceof GenericEvent) {
106
-				/** @var BirthdayService $b */
107
-				$b = $this->getContainer()->query(BirthdayService::class);
108
-				$b->onCardDeleted(
109
-					$event->getArgument('addressBookId'),
110
-					$event->getArgument('cardUri')
111
-				);
112
-			}
113
-		});
114
-
115
-		$clearPhotoCache = function($event) {
116
-			if ($event instanceof GenericEvent) {
117
-				/** @var PhotoCache $p */
118
-				$p = $this->getContainer()->query(PhotoCache::class);
119
-				$p->delete(
120
-					$event->getArgument('addressBookId'),
121
-					$event->getArgument('cardUri')
122
-				);
123
-			}
124
-		};
125
-		$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $clearPhotoCache);
126
-		$dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', $clearPhotoCache);
127
-
128
-		$dispatcher->addListener('OC\AccountManager::userUpdated', function(GenericEvent $event) {
129
-			$user = $event->getSubject();
130
-			$syncService = $this->getContainer()->query(SyncService::class);
131
-			$syncService->updateUser($user);
132
-		});
133
-
134
-		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createCalendar', function(GenericEvent $event) {
135
-			/** @var Backend $backend */
136
-			$backend = $this->getContainer()->query(Backend::class);
137
-			$backend->onCalendarAdd(
138
-				$event->getArgument('calendarData')
139
-			);
140
-		});
141
-		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateCalendar', function(GenericEvent $event) {
142
-			/** @var Backend $backend */
143
-			$backend = $this->getContainer()->query(Backend::class);
144
-			$backend->onCalendarUpdate(
145
-				$event->getArgument('calendarData'),
146
-				$event->getArgument('shares'),
147
-				$event->getArgument('propertyMutations')
148
-			);
149
-		});
150
-		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar', function(GenericEvent $event) {
151
-			/** @var Backend $backend */
152
-			$backend = $this->getContainer()->query(Backend::class);
153
-			$backend->onCalendarDelete(
154
-				$event->getArgument('calendarData'),
155
-				$event->getArgument('shares')
156
-			);
157
-		});
158
-		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateShares', function(GenericEvent $event) {
159
-			/** @var Backend $backend */
160
-			$backend = $this->getContainer()->query(Backend::class);
161
-			$backend->onCalendarUpdateShares(
162
-				$event->getArgument('calendarData'),
163
-				$event->getArgument('shares'),
164
-				$event->getArgument('add'),
165
-				$event->getArgument('remove')
166
-			);
167
-		});
168
-
169
-		$listener = function(GenericEvent $event, $eventName) {
170
-			/** @var Backend $backend */
171
-			$backend = $this->getContainer()->query(Backend::class);
172
-
173
-			$subject = Event::SUBJECT_OBJECT_ADD;
174
-			if ($eventName === '\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject') {
175
-				$subject = Event::SUBJECT_OBJECT_UPDATE;
176
-			} else if ($eventName === '\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject') {
177
-				$subject = Event::SUBJECT_OBJECT_DELETE;
178
-			}
179
-			$backend->onTouchCalendarObject(
180
-				$subject,
181
-				$event->getArgument('calendarData'),
182
-				$event->getArgument('shares'),
183
-				$event->getArgument('objectData')
184
-			);
185
-		};
186
-		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', $listener);
187
-		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject', $listener);
188
-		$dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject', $listener);
189
-	}
190
-
191
-	public function getSyncService() {
192
-		return $this->getContainer()->query(SyncService::class);
193
-	}
61
+        $container->registerCapability(Capabilities::class);
62
+    }
63
+
64
+    /**
65
+     * @param IManager $contactsManager
66
+     * @param string $userID
67
+     */
68
+    public function setupContactsProvider(IManager $contactsManager, $userID) {
69
+        /** @var ContactsManager $cm */
70
+        $cm = $this->getContainer()->query(ContactsManager::class);
71
+        $urlGenerator = $this->getContainer()->getServer()->getURLGenerator();
72
+        $cm->setupContactsProvider($contactsManager, $userID, $urlGenerator);
73
+    }
74
+
75
+    public function registerHooks() {
76
+        /** @var HookManager $hm */
77
+        $hm = $this->getContainer()->query(HookManager::class);
78
+        $hm->setup();
79
+
80
+        $dispatcher = $this->getContainer()->getServer()->getEventDispatcher();
81
+
82
+        // first time login event setup
83
+        $dispatcher->addListener(IUser::class . '::firstLogin', function ($event) use ($hm) {
84
+            if ($event instanceof GenericEvent) {
85
+                $hm->firstLogin($event->getSubject());
86
+            }
87
+        });
88
+
89
+        // carddav/caldav sync event setup
90
+        $listener = function($event) {
91
+            if ($event instanceof GenericEvent) {
92
+                /** @var BirthdayService $b */
93
+                $b = $this->getContainer()->query(BirthdayService::class);
94
+                $b->onCardChanged(
95
+                    $event->getArgument('addressBookId'),
96
+                    $event->getArgument('cardUri'),
97
+                    $event->getArgument('cardData')
98
+                );
99
+            }
100
+        };
101
+
102
+        $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::createCard', $listener);
103
+        $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $listener);
104
+        $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', function($event) {
105
+            if ($event instanceof GenericEvent) {
106
+                /** @var BirthdayService $b */
107
+                $b = $this->getContainer()->query(BirthdayService::class);
108
+                $b->onCardDeleted(
109
+                    $event->getArgument('addressBookId'),
110
+                    $event->getArgument('cardUri')
111
+                );
112
+            }
113
+        });
114
+
115
+        $clearPhotoCache = function($event) {
116
+            if ($event instanceof GenericEvent) {
117
+                /** @var PhotoCache $p */
118
+                $p = $this->getContainer()->query(PhotoCache::class);
119
+                $p->delete(
120
+                    $event->getArgument('addressBookId'),
121
+                    $event->getArgument('cardUri')
122
+                );
123
+            }
124
+        };
125
+        $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $clearPhotoCache);
126
+        $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', $clearPhotoCache);
127
+
128
+        $dispatcher->addListener('OC\AccountManager::userUpdated', function(GenericEvent $event) {
129
+            $user = $event->getSubject();
130
+            $syncService = $this->getContainer()->query(SyncService::class);
131
+            $syncService->updateUser($user);
132
+        });
133
+
134
+        $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createCalendar', function(GenericEvent $event) {
135
+            /** @var Backend $backend */
136
+            $backend = $this->getContainer()->query(Backend::class);
137
+            $backend->onCalendarAdd(
138
+                $event->getArgument('calendarData')
139
+            );
140
+        });
141
+        $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateCalendar', function(GenericEvent $event) {
142
+            /** @var Backend $backend */
143
+            $backend = $this->getContainer()->query(Backend::class);
144
+            $backend->onCalendarUpdate(
145
+                $event->getArgument('calendarData'),
146
+                $event->getArgument('shares'),
147
+                $event->getArgument('propertyMutations')
148
+            );
149
+        });
150
+        $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendar', function(GenericEvent $event) {
151
+            /** @var Backend $backend */
152
+            $backend = $this->getContainer()->query(Backend::class);
153
+            $backend->onCalendarDelete(
154
+                $event->getArgument('calendarData'),
155
+                $event->getArgument('shares')
156
+            );
157
+        });
158
+        $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateShares', function(GenericEvent $event) {
159
+            /** @var Backend $backend */
160
+            $backend = $this->getContainer()->query(Backend::class);
161
+            $backend->onCalendarUpdateShares(
162
+                $event->getArgument('calendarData'),
163
+                $event->getArgument('shares'),
164
+                $event->getArgument('add'),
165
+                $event->getArgument('remove')
166
+            );
167
+        });
168
+
169
+        $listener = function(GenericEvent $event, $eventName) {
170
+            /** @var Backend $backend */
171
+            $backend = $this->getContainer()->query(Backend::class);
172
+
173
+            $subject = Event::SUBJECT_OBJECT_ADD;
174
+            if ($eventName === '\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject') {
175
+                $subject = Event::SUBJECT_OBJECT_UPDATE;
176
+            } else if ($eventName === '\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject') {
177
+                $subject = Event::SUBJECT_OBJECT_DELETE;
178
+            }
179
+            $backend->onTouchCalendarObject(
180
+                $subject,
181
+                $event->getArgument('calendarData'),
182
+                $event->getArgument('shares'),
183
+                $event->getArgument('objectData')
184
+            );
185
+        };
186
+        $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', $listener);
187
+        $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::updateCalendarObject', $listener);
188
+        $dispatcher->addListener('\OCA\DAV\CalDAV\CalDavBackend::deleteCalendarObject', $listener);
189
+    }
190
+
191
+    public function getSyncService() {
192
+        return $this->getContainer()->query(SyncService::class);
193
+    }
194 194
 
195 195
 }
Please login to merge, or discard this patch.
apps/dav/lib/Migration/FixBirthdayCalendarComponent.php 1 patch
Indentation   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -28,35 +28,35 @@
 block discarded – undo
28 28
 
29 29
 class FixBirthdayCalendarComponent implements IRepairStep {
30 30
 
31
-	/** @var IDBConnection */
32
-	private $connection;
33
-
34
-	/**
35
-	 * FixBirthdayCalendarComponent constructor.
36
-	 *
37
-	 * @param IDBConnection $connection
38
-	 */
39
-	public function __construct(IDBConnection $connection) {
40
-		$this->connection = $connection;
41
-	}
42
-
43
-	/**
44
-	 * @inheritdoc
45
-	 */
46
-	public function getName() {
47
-		return 'Fix component of birthday calendars';
48
-	}
49
-
50
-	/**
51
-	 * @inheritdoc
52
-	 */
53
-	public function run(IOutput $output) {
54
-		$query = $this->connection->getQueryBuilder();
55
-		$updated = $query->update('calendars')
56
-			->set('components', $query->createNamedParameter('VEVENT'))
57
-			->where($query->expr()->eq('uri', $query->createNamedParameter(BirthdayService::BIRTHDAY_CALENDAR_URI)))
58
-			->execute();
59
-
60
-		$output->info("$updated birthday calendars updated.");
61
-	}
31
+    /** @var IDBConnection */
32
+    private $connection;
33
+
34
+    /**
35
+     * FixBirthdayCalendarComponent constructor.
36
+     *
37
+     * @param IDBConnection $connection
38
+     */
39
+    public function __construct(IDBConnection $connection) {
40
+        $this->connection = $connection;
41
+    }
42
+
43
+    /**
44
+     * @inheritdoc
45
+     */
46
+    public function getName() {
47
+        return 'Fix component of birthday calendars';
48
+    }
49
+
50
+    /**
51
+     * @inheritdoc
52
+     */
53
+    public function run(IOutput $output) {
54
+        $query = $this->connection->getQueryBuilder();
55
+        $updated = $query->update('calendars')
56
+            ->set('components', $query->createNamedParameter('VEVENT'))
57
+            ->where($query->expr()->eq('uri', $query->createNamedParameter(BirthdayService::BIRTHDAY_CALENDAR_URI)))
58
+            ->execute();
59
+
60
+        $output->info("$updated birthday calendars updated.");
61
+    }
62 62
 }
Please login to merge, or discard this patch.
apps/dav/lib/Command/SyncBirthdayCalendar.php 1 patch
Indentation   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -33,55 +33,55 @@
 block discarded – undo
33 33
 
34 34
 class SyncBirthdayCalendar extends Command {
35 35
 
36
-	/** @var BirthdayService */
37
-	private $birthdayService;
36
+    /** @var BirthdayService */
37
+    private $birthdayService;
38 38
 
39
-	/** @var IUserManager */
40
-	private $userManager;
39
+    /** @var IUserManager */
40
+    private $userManager;
41 41
 
42
-	/**
43
-	 * @param IUserManager $userManager
44
-	 * @param BirthdayService $birthdayService
45
-	 */
46
-	function __construct(IUserManager $userManager, BirthdayService $birthdayService) {
47
-		parent::__construct();
48
-		$this->birthdayService = $birthdayService;
49
-		$this->userManager = $userManager;
50
-	}
42
+    /**
43
+     * @param IUserManager $userManager
44
+     * @param BirthdayService $birthdayService
45
+     */
46
+    function __construct(IUserManager $userManager, BirthdayService $birthdayService) {
47
+        parent::__construct();
48
+        $this->birthdayService = $birthdayService;
49
+        $this->userManager = $userManager;
50
+    }
51 51
 
52
-	protected function configure() {
53
-		$this
54
-			->setName('dav:sync-birthday-calendar')
55
-			->setDescription('Synchronizes the birthday calendar')
56
-			->addArgument('user',
57
-				InputArgument::OPTIONAL,
58
-				'User for whom the birthday calendar will be synchronized');
59
-	}
52
+    protected function configure() {
53
+        $this
54
+            ->setName('dav:sync-birthday-calendar')
55
+            ->setDescription('Synchronizes the birthday calendar')
56
+            ->addArgument('user',
57
+                InputArgument::OPTIONAL,
58
+                'User for whom the birthday calendar will be synchronized');
59
+    }
60 60
 
61
-	/**
62
-	 * @param InputInterface $input
63
-	 * @param OutputInterface $output
64
-	 */
65
-	protected function execute(InputInterface $input, OutputInterface $output) {
66
-		$user = $input->getArgument('user');
67
-		if (!is_null($user)) {
68
-			if (!$this->userManager->userExists($user)) {
69
-				throw new \InvalidArgumentException("User <$user> in unknown.");
70
-			}
71
-			$output->writeln("Start birthday calendar sync for $user");
72
-			$this->birthdayService->syncUser($user);
73
-			return;
74
-		}
75
-		$output->writeln("Start birthday calendar sync for all users ...");
76
-		$p = new ProgressBar($output);
77
-		$p->start();
78
-		$this->userManager->callForAllUsers(function($user) use ($p)  {
79
-			$p->advance();
80
-			/** @var IUser $user */
81
-			$this->birthdayService->syncUser($user->getUID());
82
-		});
61
+    /**
62
+     * @param InputInterface $input
63
+     * @param OutputInterface $output
64
+     */
65
+    protected function execute(InputInterface $input, OutputInterface $output) {
66
+        $user = $input->getArgument('user');
67
+        if (!is_null($user)) {
68
+            if (!$this->userManager->userExists($user)) {
69
+                throw new \InvalidArgumentException("User <$user> in unknown.");
70
+            }
71
+            $output->writeln("Start birthday calendar sync for $user");
72
+            $this->birthdayService->syncUser($user);
73
+            return;
74
+        }
75
+        $output->writeln("Start birthday calendar sync for all users ...");
76
+        $p = new ProgressBar($output);
77
+        $p->start();
78
+        $this->userManager->callForAllUsers(function($user) use ($p)  {
79
+            $p->advance();
80
+            /** @var IUser $user */
81
+            $this->birthdayService->syncUser($user->getUID());
82
+        });
83 83
 
84
-		$p->finish();
85
-		$output->writeln('');
86
-	}
84
+        $p->finish();
85
+        $output->writeln('');
86
+    }
87 87
 }
Please login to merge, or discard this patch.
apps/dav/lib/Command/SyncSystemAddressBook.php 1 patch
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -31,36 +31,36 @@
 block discarded – undo
31 31
 
32 32
 class SyncSystemAddressBook extends Command {
33 33
 
34
-	/** @var SyncService */
35
-	private $syncService;
34
+    /** @var SyncService */
35
+    private $syncService;
36 36
 
37
-	/**
38
-	 * @param SyncService $syncService
39
-	 */
40
-	function __construct(SyncService $syncService) {
41
-		parent::__construct();
42
-		$this->syncService = $syncService;
43
-	}
37
+    /**
38
+     * @param SyncService $syncService
39
+     */
40
+    function __construct(SyncService $syncService) {
41
+        parent::__construct();
42
+        $this->syncService = $syncService;
43
+    }
44 44
 
45
-	protected function configure() {
46
-		$this
47
-			->setName('dav:sync-system-addressbook')
48
-			->setDescription('Synchronizes users to the system addressbook');
49
-	}
45
+    protected function configure() {
46
+        $this
47
+            ->setName('dav:sync-system-addressbook')
48
+            ->setDescription('Synchronizes users to the system addressbook');
49
+    }
50 50
 
51
-	/**
52
-	 * @param InputInterface $input
53
-	 * @param OutputInterface $output
54
-	 */
55
-	protected function execute(InputInterface $input, OutputInterface $output) {
56
-		$output->writeln('Syncing users ...');
57
-		$progress = new ProgressBar($output);
58
-		$progress->start();
59
-		$this->syncService->syncInstance(function() use ($progress) {
60
-			$progress->advance();
61
-		});
51
+    /**
52
+     * @param InputInterface $input
53
+     * @param OutputInterface $output
54
+     */
55
+    protected function execute(InputInterface $input, OutputInterface $output) {
56
+        $output->writeln('Syncing users ...');
57
+        $progress = new ProgressBar($output);
58
+        $progress->start();
59
+        $this->syncService->syncInstance(function() use ($progress) {
60
+            $progress->advance();
61
+        });
62 62
 
63
-		$progress->finish();
64
-		$output->writeln('');
65
-	}
63
+        $progress->finish();
64
+        $output->writeln('');
65
+    }
66 66
 }
Please login to merge, or discard this patch.
apps/dav/lib/Command/CreateAddressBook.php 1 patch
Indentation   +34 added lines, -34 removed lines patch added patch discarded remove patch
@@ -36,43 +36,43 @@
 block discarded – undo
36 36
 
37 37
 class CreateAddressBook extends Command {
38 38
 
39
-	/** @var IUserManager */
40
-	private $userManager;
39
+    /** @var IUserManager */
40
+    private $userManager;
41 41
 
42
-	/** @var CardDavBackend */
43
-	private $cardDavBackend;
42
+    /** @var CardDavBackend */
43
+    private $cardDavBackend;
44 44
 
45
-	/**
46
-	 * @param IUserManager $userManager
47
-	 * @param CardDavBackend $cardDavBackend
48
-	 */
49
-	function __construct(IUserManager $userManager,
50
-						 CardDavBackend $cardDavBackend
51
-	) {
52
-		parent::__construct();
53
-		$this->userManager = $userManager;
54
-		$this->cardDavBackend = $cardDavBackend;
55
-	}
45
+    /**
46
+     * @param IUserManager $userManager
47
+     * @param CardDavBackend $cardDavBackend
48
+     */
49
+    function __construct(IUserManager $userManager,
50
+                            CardDavBackend $cardDavBackend
51
+    ) {
52
+        parent::__construct();
53
+        $this->userManager = $userManager;
54
+        $this->cardDavBackend = $cardDavBackend;
55
+    }
56 56
 
57
-	protected function configure() {
58
-		$this
59
-				->setName('dav:create-addressbook')
60
-				->setDescription('Create a dav addressbook')
61
-				->addArgument('user',
62
-						InputArgument::REQUIRED,
63
-						'User for whom the addressbook will be created')
64
-				->addArgument('name',
65
-						InputArgument::REQUIRED,
66
-						'Name of the addressbook');
67
-	}
57
+    protected function configure() {
58
+        $this
59
+                ->setName('dav:create-addressbook')
60
+                ->setDescription('Create a dav addressbook')
61
+                ->addArgument('user',
62
+                        InputArgument::REQUIRED,
63
+                        'User for whom the addressbook will be created')
64
+                ->addArgument('name',
65
+                        InputArgument::REQUIRED,
66
+                        'Name of the addressbook');
67
+    }
68 68
 
69
-	protected function execute(InputInterface $input, OutputInterface $output) {
70
-		$user = $input->getArgument('user');
71
-		if (!$this->userManager->userExists($user)) {
72
-			throw new \InvalidArgumentException("User <$user> in unknown.");
73
-		}
69
+    protected function execute(InputInterface $input, OutputInterface $output) {
70
+        $user = $input->getArgument('user');
71
+        if (!$this->userManager->userExists($user)) {
72
+            throw new \InvalidArgumentException("User <$user> in unknown.");
73
+        }
74 74
 
75
-		$name = $input->getArgument('name');
76
-		$this->cardDavBackend->createAddressBook("principals/users/$user", $name, []);
77
-	}
75
+        $name = $input->getArgument('name');
76
+        $this->cardDavBackend->createAddressBook("principals/users/$user", $name, []);
77
+    }
78 78
 }
Please login to merge, or discard this patch.
apps/dav/lib/Capabilities.php 1 patch
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -26,11 +26,11 @@
 block discarded – undo
26 26
 
27 27
 class Capabilities implements ICapability {
28 28
 
29
-	public function getCapabilities() {
30
-		return [
31
-			'dav' => [
32
-				'chunking' => '1.0',
33
-			]
34
-		];
35
-	}
29
+    public function getCapabilities() {
30
+        return [
31
+            'dav' => [
32
+                'chunking' => '1.0',
33
+            ]
34
+        ];
35
+    }
36 36
 }
Please login to merge, or discard this patch.