Passed
Push — master ( 071a38...06ae9c )
by Roeland
14:21 queued 11s
created
lib/private/Share20/DefaultShareProvider.php 1 patch
Indentation   +1402 added lines, -1402 removed lines patch added patch discarded remove patch
@@ -63,1442 +63,1442 @@
 block discarded – undo
63 63
  */
64 64
 class DefaultShareProvider implements IShareProvider {
65 65
 
66
-	// Special share type for user modified group shares
67
-	public const SHARE_TYPE_USERGROUP = 2;
68
-
69
-	/** @var IDBConnection */
70
-	private $dbConn;
71
-
72
-	/** @var IUserManager */
73
-	private $userManager;
74
-
75
-	/** @var IGroupManager */
76
-	private $groupManager;
77
-
78
-	/** @var IRootFolder */
79
-	private $rootFolder;
80
-
81
-	/** @var IMailer */
82
-	private $mailer;
83
-
84
-	/** @var Defaults */
85
-	private $defaults;
86
-
87
-	/** @var IFactory */
88
-	private $l10nFactory;
89
-
90
-	/** @var IURLGenerator */
91
-	private $urlGenerator;
92
-
93
-	/** @var IConfig */
94
-	private $config;
95
-
96
-	public function __construct(
97
-			IDBConnection $connection,
98
-			IUserManager $userManager,
99
-			IGroupManager $groupManager,
100
-			IRootFolder $rootFolder,
101
-			IMailer $mailer,
102
-			Defaults $defaults,
103
-			IFactory $l10nFactory,
104
-			IURLGenerator $urlGenerator,
105
-			IConfig $config) {
106
-		$this->dbConn = $connection;
107
-		$this->userManager = $userManager;
108
-		$this->groupManager = $groupManager;
109
-		$this->rootFolder = $rootFolder;
110
-		$this->mailer = $mailer;
111
-		$this->defaults = $defaults;
112
-		$this->l10nFactory = $l10nFactory;
113
-		$this->urlGenerator = $urlGenerator;
114
-		$this->config = $config;
115
-	}
116
-
117
-	/**
118
-	 * Return the identifier of this provider.
119
-	 *
120
-	 * @return string Containing only [a-zA-Z0-9]
121
-	 */
122
-	public function identifier() {
123
-		return 'ocinternal';
124
-	}
125
-
126
-	/**
127
-	 * Share a path
128
-	 *
129
-	 * @param \OCP\Share\IShare $share
130
-	 * @return \OCP\Share\IShare The share object
131
-	 * @throws ShareNotFound
132
-	 * @throws \Exception
133
-	 */
134
-	public function create(\OCP\Share\IShare $share) {
135
-		$qb = $this->dbConn->getQueryBuilder();
136
-
137
-		$qb->insert('share');
138
-		$qb->setValue('share_type', $qb->createNamedParameter($share->getShareType()));
139
-
140
-		if ($share->getShareType() === IShare::TYPE_USER) {
141
-			//Set the UID of the user we share with
142
-			$qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
143
-			$qb->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_PENDING));
144
-
145
-			//If an expiration date is set store it
146
-			if ($share->getExpirationDate() !== null) {
147
-				$qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
148
-			}
149
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
150
-			//Set the GID of the group we share with
151
-			$qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
152
-
153
-			//If an expiration date is set store it
154
-			if ($share->getExpirationDate() !== null) {
155
-				$qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
156
-			}
157
-		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
158
-			//set label for public link
159
-			$qb->setValue('label', $qb->createNamedParameter($share->getLabel()));
160
-			//Set the token of the share
161
-			$qb->setValue('token', $qb->createNamedParameter($share->getToken()));
162
-
163
-			//If a password is set store it
164
-			if ($share->getPassword() !== null) {
165
-				$qb->setValue('password', $qb->createNamedParameter($share->getPassword()));
166
-			}
167
-
168
-			$qb->setValue('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL));
169
-
170
-			//If an expiration date is set store it
171
-			if ($share->getExpirationDate() !== null) {
172
-				$qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
173
-			}
174
-
175
-			if (method_exists($share, 'getParent')) {
176
-				$qb->setValue('parent', $qb->createNamedParameter($share->getParent()));
177
-			}
178
-		} else {
179
-			throw new \Exception('invalid share type!');
180
-		}
181
-
182
-		// Set what is shares
183
-		$qb->setValue('item_type', $qb->createParameter('itemType'));
184
-		if ($share->getNode() instanceof \OCP\Files\File) {
185
-			$qb->setParameter('itemType', 'file');
186
-		} else {
187
-			$qb->setParameter('itemType', 'folder');
188
-		}
189
-
190
-		// Set the file id
191
-		$qb->setValue('item_source', $qb->createNamedParameter($share->getNode()->getId()));
192
-		$qb->setValue('file_source', $qb->createNamedParameter($share->getNode()->getId()));
193
-
194
-		// set the permissions
195
-		$qb->setValue('permissions', $qb->createNamedParameter($share->getPermissions()));
196
-
197
-		// Set who created this share
198
-		$qb->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()));
199
-
200
-		// Set who is the owner of this file/folder (and this the owner of the share)
201
-		$qb->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()));
202
-
203
-		// Set the file target
204
-		$qb->setValue('file_target', $qb->createNamedParameter($share->getTarget()));
205
-
206
-		// Set the time this share was created
207
-		$qb->setValue('stime', $qb->createNamedParameter(time()));
208
-
209
-		// insert the data and fetch the id of the share
210
-		$this->dbConn->beginTransaction();
211
-		$qb->execute();
212
-		$id = $this->dbConn->lastInsertId('*PREFIX*share');
213
-
214
-		// Now fetch the inserted share and create a complete share object
215
-		$qb = $this->dbConn->getQueryBuilder();
216
-		$qb->select('*')
217
-			->from('share')
218
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
219
-
220
-		$cursor = $qb->execute();
221
-		$data = $cursor->fetch();
222
-		$this->dbConn->commit();
223
-		$cursor->closeCursor();
224
-
225
-		if ($data === false) {
226
-			throw new ShareNotFound();
227
-		}
228
-
229
-		$mailSendValue = $share->getMailSend();
230
-		$data['mail_send'] = ($mailSendValue === null) ? true : $mailSendValue;
231
-
232
-		$share = $this->createShare($data);
233
-		return $share;
234
-	}
235
-
236
-	/**
237
-	 * Update a share
238
-	 *
239
-	 * @param \OCP\Share\IShare $share
240
-	 * @return \OCP\Share\IShare The share object
241
-	 * @throws ShareNotFound
242
-	 * @throws \OCP\Files\InvalidPathException
243
-	 * @throws \OCP\Files\NotFoundException
244
-	 */
245
-	public function update(\OCP\Share\IShare $share) {
246
-		$originalShare = $this->getShareById($share->getId());
247
-
248
-		if ($share->getShareType() === IShare::TYPE_USER) {
249
-			/*
66
+    // Special share type for user modified group shares
67
+    public const SHARE_TYPE_USERGROUP = 2;
68
+
69
+    /** @var IDBConnection */
70
+    private $dbConn;
71
+
72
+    /** @var IUserManager */
73
+    private $userManager;
74
+
75
+    /** @var IGroupManager */
76
+    private $groupManager;
77
+
78
+    /** @var IRootFolder */
79
+    private $rootFolder;
80
+
81
+    /** @var IMailer */
82
+    private $mailer;
83
+
84
+    /** @var Defaults */
85
+    private $defaults;
86
+
87
+    /** @var IFactory */
88
+    private $l10nFactory;
89
+
90
+    /** @var IURLGenerator */
91
+    private $urlGenerator;
92
+
93
+    /** @var IConfig */
94
+    private $config;
95
+
96
+    public function __construct(
97
+            IDBConnection $connection,
98
+            IUserManager $userManager,
99
+            IGroupManager $groupManager,
100
+            IRootFolder $rootFolder,
101
+            IMailer $mailer,
102
+            Defaults $defaults,
103
+            IFactory $l10nFactory,
104
+            IURLGenerator $urlGenerator,
105
+            IConfig $config) {
106
+        $this->dbConn = $connection;
107
+        $this->userManager = $userManager;
108
+        $this->groupManager = $groupManager;
109
+        $this->rootFolder = $rootFolder;
110
+        $this->mailer = $mailer;
111
+        $this->defaults = $defaults;
112
+        $this->l10nFactory = $l10nFactory;
113
+        $this->urlGenerator = $urlGenerator;
114
+        $this->config = $config;
115
+    }
116
+
117
+    /**
118
+     * Return the identifier of this provider.
119
+     *
120
+     * @return string Containing only [a-zA-Z0-9]
121
+     */
122
+    public function identifier() {
123
+        return 'ocinternal';
124
+    }
125
+
126
+    /**
127
+     * Share a path
128
+     *
129
+     * @param \OCP\Share\IShare $share
130
+     * @return \OCP\Share\IShare The share object
131
+     * @throws ShareNotFound
132
+     * @throws \Exception
133
+     */
134
+    public function create(\OCP\Share\IShare $share) {
135
+        $qb = $this->dbConn->getQueryBuilder();
136
+
137
+        $qb->insert('share');
138
+        $qb->setValue('share_type', $qb->createNamedParameter($share->getShareType()));
139
+
140
+        if ($share->getShareType() === IShare::TYPE_USER) {
141
+            //Set the UID of the user we share with
142
+            $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
143
+            $qb->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_PENDING));
144
+
145
+            //If an expiration date is set store it
146
+            if ($share->getExpirationDate() !== null) {
147
+                $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
148
+            }
149
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
150
+            //Set the GID of the group we share with
151
+            $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()));
152
+
153
+            //If an expiration date is set store it
154
+            if ($share->getExpirationDate() !== null) {
155
+                $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
156
+            }
157
+        } elseif ($share->getShareType() === IShare::TYPE_LINK) {
158
+            //set label for public link
159
+            $qb->setValue('label', $qb->createNamedParameter($share->getLabel()));
160
+            //Set the token of the share
161
+            $qb->setValue('token', $qb->createNamedParameter($share->getToken()));
162
+
163
+            //If a password is set store it
164
+            if ($share->getPassword() !== null) {
165
+                $qb->setValue('password', $qb->createNamedParameter($share->getPassword()));
166
+            }
167
+
168
+            $qb->setValue('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL));
169
+
170
+            //If an expiration date is set store it
171
+            if ($share->getExpirationDate() !== null) {
172
+                $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime'));
173
+            }
174
+
175
+            if (method_exists($share, 'getParent')) {
176
+                $qb->setValue('parent', $qb->createNamedParameter($share->getParent()));
177
+            }
178
+        } else {
179
+            throw new \Exception('invalid share type!');
180
+        }
181
+
182
+        // Set what is shares
183
+        $qb->setValue('item_type', $qb->createParameter('itemType'));
184
+        if ($share->getNode() instanceof \OCP\Files\File) {
185
+            $qb->setParameter('itemType', 'file');
186
+        } else {
187
+            $qb->setParameter('itemType', 'folder');
188
+        }
189
+
190
+        // Set the file id
191
+        $qb->setValue('item_source', $qb->createNamedParameter($share->getNode()->getId()));
192
+        $qb->setValue('file_source', $qb->createNamedParameter($share->getNode()->getId()));
193
+
194
+        // set the permissions
195
+        $qb->setValue('permissions', $qb->createNamedParameter($share->getPermissions()));
196
+
197
+        // Set who created this share
198
+        $qb->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()));
199
+
200
+        // Set who is the owner of this file/folder (and this the owner of the share)
201
+        $qb->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()));
202
+
203
+        // Set the file target
204
+        $qb->setValue('file_target', $qb->createNamedParameter($share->getTarget()));
205
+
206
+        // Set the time this share was created
207
+        $qb->setValue('stime', $qb->createNamedParameter(time()));
208
+
209
+        // insert the data and fetch the id of the share
210
+        $this->dbConn->beginTransaction();
211
+        $qb->execute();
212
+        $id = $this->dbConn->lastInsertId('*PREFIX*share');
213
+
214
+        // Now fetch the inserted share and create a complete share object
215
+        $qb = $this->dbConn->getQueryBuilder();
216
+        $qb->select('*')
217
+            ->from('share')
218
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
219
+
220
+        $cursor = $qb->execute();
221
+        $data = $cursor->fetch();
222
+        $this->dbConn->commit();
223
+        $cursor->closeCursor();
224
+
225
+        if ($data === false) {
226
+            throw new ShareNotFound();
227
+        }
228
+
229
+        $mailSendValue = $share->getMailSend();
230
+        $data['mail_send'] = ($mailSendValue === null) ? true : $mailSendValue;
231
+
232
+        $share = $this->createShare($data);
233
+        return $share;
234
+    }
235
+
236
+    /**
237
+     * Update a share
238
+     *
239
+     * @param \OCP\Share\IShare $share
240
+     * @return \OCP\Share\IShare The share object
241
+     * @throws ShareNotFound
242
+     * @throws \OCP\Files\InvalidPathException
243
+     * @throws \OCP\Files\NotFoundException
244
+     */
245
+    public function update(\OCP\Share\IShare $share) {
246
+        $originalShare = $this->getShareById($share->getId());
247
+
248
+        if ($share->getShareType() === IShare::TYPE_USER) {
249
+            /*
250 250
 			 * We allow updating the recipient on user shares.
251 251
 			 */
252
-			$qb = $this->dbConn->getQueryBuilder();
253
-			$qb->update('share')
254
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
255
-				->set('share_with', $qb->createNamedParameter($share->getSharedWith()))
256
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
257
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
258
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
259
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
260
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
261
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
262
-				->set('note', $qb->createNamedParameter($share->getNote()))
263
-				->set('accepted', $qb->createNamedParameter($share->getStatus()))
264
-				->execute();
265
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
266
-			$qb = $this->dbConn->getQueryBuilder();
267
-			$qb->update('share')
268
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
269
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
270
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
271
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
272
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
273
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
274
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
275
-				->set('note', $qb->createNamedParameter($share->getNote()))
276
-				->execute();
277
-
278
-			/*
252
+            $qb = $this->dbConn->getQueryBuilder();
253
+            $qb->update('share')
254
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
255
+                ->set('share_with', $qb->createNamedParameter($share->getSharedWith()))
256
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
257
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
258
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
259
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
260
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
261
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
262
+                ->set('note', $qb->createNamedParameter($share->getNote()))
263
+                ->set('accepted', $qb->createNamedParameter($share->getStatus()))
264
+                ->execute();
265
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
266
+            $qb = $this->dbConn->getQueryBuilder();
267
+            $qb->update('share')
268
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
269
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
270
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
271
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
272
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
273
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
274
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
275
+                ->set('note', $qb->createNamedParameter($share->getNote()))
276
+                ->execute();
277
+
278
+            /*
279 279
 			 * Update all user defined group shares
280 280
 			 */
281
-			$qb = $this->dbConn->getQueryBuilder();
282
-			$qb->update('share')
283
-				->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
284
-				->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
285
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
286
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
287
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
288
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
289
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
290
-				->set('note', $qb->createNamedParameter($share->getNote()))
291
-				->execute();
292
-
293
-			/*
281
+            $qb = $this->dbConn->getQueryBuilder();
282
+            $qb->update('share')
283
+                ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
284
+                ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
285
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
286
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
287
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
288
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
289
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
290
+                ->set('note', $qb->createNamedParameter($share->getNote()))
291
+                ->execute();
292
+
293
+            /*
294 294
 			 * Now update the permissions for all children that have not set it to 0
295 295
 			 */
296
-			$qb = $this->dbConn->getQueryBuilder();
297
-			$qb->update('share')
298
-				->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
299
-				->andWhere($qb->expr()->neq('permissions', $qb->createNamedParameter(0)))
300
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
301
-				->execute();
302
-		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
303
-			$qb = $this->dbConn->getQueryBuilder();
304
-			$qb->update('share')
305
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
306
-				->set('password', $qb->createNamedParameter($share->getPassword()))
307
-				->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
308
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
309
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
310
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
311
-				->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
312
-				->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
313
-				->set('token', $qb->createNamedParameter($share->getToken()))
314
-				->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
315
-				->set('note', $qb->createNamedParameter($share->getNote()))
316
-				->set('label', $qb->createNamedParameter($share->getLabel()))
317
-				->set('hide_download', $qb->createNamedParameter($share->getHideDownload() ? 1 : 0), IQueryBuilder::PARAM_INT)
318
-				->execute();
319
-		}
320
-
321
-		if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
322
-			$this->propagateNote($share);
323
-		}
324
-
325
-
326
-		return $share;
327
-	}
328
-
329
-	/**
330
-	 * Accept a share.
331
-	 *
332
-	 * @param IShare $share
333
-	 * @param string $recipient
334
-	 * @return IShare The share object
335
-	 * @since 9.0.0
336
-	 */
337
-	public function acceptShare(IShare $share, string $recipient): IShare {
338
-		if ($share->getShareType() === IShare::TYPE_GROUP) {
339
-			$group = $this->groupManager->get($share->getSharedWith());
340
-			$user = $this->userManager->get($recipient);
341
-
342
-			if (is_null($group)) {
343
-				throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
344
-			}
345
-
346
-			if (!$group->inGroup($user)) {
347
-				throw new ProviderException('Recipient not in receiving group');
348
-			}
349
-
350
-			// Try to fetch user specific share
351
-			$qb = $this->dbConn->getQueryBuilder();
352
-			$stmt = $qb->select('*')
353
-				->from('share')
354
-				->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
355
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
356
-				->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
357
-				->andWhere($qb->expr()->orX(
358
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
359
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
360
-				))
361
-				->execute();
362
-
363
-			$data = $stmt->fetch();
364
-			$stmt->closeCursor();
365
-
366
-			/*
296
+            $qb = $this->dbConn->getQueryBuilder();
297
+            $qb->update('share')
298
+                ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
299
+                ->andWhere($qb->expr()->neq('permissions', $qb->createNamedParameter(0)))
300
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
301
+                ->execute();
302
+        } elseif ($share->getShareType() === IShare::TYPE_LINK) {
303
+            $qb = $this->dbConn->getQueryBuilder();
304
+            $qb->update('share')
305
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
306
+                ->set('password', $qb->createNamedParameter($share->getPassword()))
307
+                ->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
308
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
309
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
310
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
311
+                ->set('item_source', $qb->createNamedParameter($share->getNode()->getId()))
312
+                ->set('file_source', $qb->createNamedParameter($share->getNode()->getId()))
313
+                ->set('token', $qb->createNamedParameter($share->getToken()))
314
+                ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
315
+                ->set('note', $qb->createNamedParameter($share->getNote()))
316
+                ->set('label', $qb->createNamedParameter($share->getLabel()))
317
+                ->set('hide_download', $qb->createNamedParameter($share->getHideDownload() ? 1 : 0), IQueryBuilder::PARAM_INT)
318
+                ->execute();
319
+        }
320
+
321
+        if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
322
+            $this->propagateNote($share);
323
+        }
324
+
325
+
326
+        return $share;
327
+    }
328
+
329
+    /**
330
+     * Accept a share.
331
+     *
332
+     * @param IShare $share
333
+     * @param string $recipient
334
+     * @return IShare The share object
335
+     * @since 9.0.0
336
+     */
337
+    public function acceptShare(IShare $share, string $recipient): IShare {
338
+        if ($share->getShareType() === IShare::TYPE_GROUP) {
339
+            $group = $this->groupManager->get($share->getSharedWith());
340
+            $user = $this->userManager->get($recipient);
341
+
342
+            if (is_null($group)) {
343
+                throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
344
+            }
345
+
346
+            if (!$group->inGroup($user)) {
347
+                throw new ProviderException('Recipient not in receiving group');
348
+            }
349
+
350
+            // Try to fetch user specific share
351
+            $qb = $this->dbConn->getQueryBuilder();
352
+            $stmt = $qb->select('*')
353
+                ->from('share')
354
+                ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
355
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
356
+                ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
357
+                ->andWhere($qb->expr()->orX(
358
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
359
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
360
+                ))
361
+                ->execute();
362
+
363
+            $data = $stmt->fetch();
364
+            $stmt->closeCursor();
365
+
366
+            /*
367 367
 			 * Check if there already is a user specific group share.
368 368
 			 * If there is update it (if required).
369 369
 			 */
370
-			if ($data === false) {
371
-				$id = $this->createUserSpecificGroupShare($share, $recipient);
372
-			} else {
373
-				$id = $data['id'];
374
-			}
375
-		} elseif ($share->getShareType() === IShare::TYPE_USER) {
376
-			if ($share->getSharedWith() !== $recipient) {
377
-				throw new ProviderException('Recipient does not match');
378
-			}
379
-
380
-			$id = $share->getId();
381
-		} else {
382
-			throw new ProviderException('Invalid shareType');
383
-		}
384
-
385
-		$qb = $this->dbConn->getQueryBuilder();
386
-		$qb->update('share')
387
-			->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
388
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
389
-			->execute();
390
-
391
-		return $share;
392
-	}
393
-
394
-	/**
395
-	 * Get all children of this share
396
-	 * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
397
-	 *
398
-	 * @param \OCP\Share\IShare $parent
399
-	 * @return \OCP\Share\IShare[]
400
-	 */
401
-	public function getChildren(\OCP\Share\IShare $parent) {
402
-		$children = [];
403
-
404
-		$qb = $this->dbConn->getQueryBuilder();
405
-		$qb->select('*')
406
-			->from('share')
407
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
408
-			->andWhere(
409
-				$qb->expr()->in(
410
-					'share_type',
411
-					$qb->createNamedParameter([
412
-						IShare::TYPE_USER,
413
-						IShare::TYPE_GROUP,
414
-						IShare::TYPE_LINK,
415
-					], IQueryBuilder::PARAM_INT_ARRAY)
416
-				)
417
-			)
418
-			->andWhere($qb->expr()->orX(
419
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
420
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
421
-			))
422
-			->orderBy('id');
423
-
424
-		$cursor = $qb->execute();
425
-		while ($data = $cursor->fetch()) {
426
-			$children[] = $this->createShare($data);
427
-		}
428
-		$cursor->closeCursor();
429
-
430
-		return $children;
431
-	}
432
-
433
-	/**
434
-	 * Delete a share
435
-	 *
436
-	 * @param \OCP\Share\IShare $share
437
-	 */
438
-	public function delete(\OCP\Share\IShare $share) {
439
-		$qb = $this->dbConn->getQueryBuilder();
440
-		$qb->delete('share')
441
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())));
442
-
443
-		/*
370
+            if ($data === false) {
371
+                $id = $this->createUserSpecificGroupShare($share, $recipient);
372
+            } else {
373
+                $id = $data['id'];
374
+            }
375
+        } elseif ($share->getShareType() === IShare::TYPE_USER) {
376
+            if ($share->getSharedWith() !== $recipient) {
377
+                throw new ProviderException('Recipient does not match');
378
+            }
379
+
380
+            $id = $share->getId();
381
+        } else {
382
+            throw new ProviderException('Invalid shareType');
383
+        }
384
+
385
+        $qb = $this->dbConn->getQueryBuilder();
386
+        $qb->update('share')
387
+            ->set('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED))
388
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
389
+            ->execute();
390
+
391
+        return $share;
392
+    }
393
+
394
+    /**
395
+     * Get all children of this share
396
+     * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
397
+     *
398
+     * @param \OCP\Share\IShare $parent
399
+     * @return \OCP\Share\IShare[]
400
+     */
401
+    public function getChildren(\OCP\Share\IShare $parent) {
402
+        $children = [];
403
+
404
+        $qb = $this->dbConn->getQueryBuilder();
405
+        $qb->select('*')
406
+            ->from('share')
407
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
408
+            ->andWhere(
409
+                $qb->expr()->in(
410
+                    'share_type',
411
+                    $qb->createNamedParameter([
412
+                        IShare::TYPE_USER,
413
+                        IShare::TYPE_GROUP,
414
+                        IShare::TYPE_LINK,
415
+                    ], IQueryBuilder::PARAM_INT_ARRAY)
416
+                )
417
+            )
418
+            ->andWhere($qb->expr()->orX(
419
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
420
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
421
+            ))
422
+            ->orderBy('id');
423
+
424
+        $cursor = $qb->execute();
425
+        while ($data = $cursor->fetch()) {
426
+            $children[] = $this->createShare($data);
427
+        }
428
+        $cursor->closeCursor();
429
+
430
+        return $children;
431
+    }
432
+
433
+    /**
434
+     * Delete a share
435
+     *
436
+     * @param \OCP\Share\IShare $share
437
+     */
438
+    public function delete(\OCP\Share\IShare $share) {
439
+        $qb = $this->dbConn->getQueryBuilder();
440
+        $qb->delete('share')
441
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())));
442
+
443
+        /*
444 444
 		 * If the share is a group share delete all possible
445 445
 		 * user defined groups shares.
446 446
 		 */
447
-		if ($share->getShareType() === IShare::TYPE_GROUP) {
448
-			$qb->orWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())));
449
-		}
450
-
451
-		$qb->execute();
452
-	}
453
-
454
-	/**
455
-	 * Unshare a share from the recipient. If this is a group share
456
-	 * this means we need a special entry in the share db.
457
-	 *
458
-	 * @param IShare $share
459
-	 * @param string $recipient UserId of recipient
460
-	 * @throws BackendError
461
-	 * @throws ProviderException
462
-	 */
463
-	public function deleteFromSelf(IShare $share, $recipient) {
464
-		if ($share->getShareType() === IShare::TYPE_GROUP) {
465
-			$group = $this->groupManager->get($share->getSharedWith());
466
-			$user = $this->userManager->get($recipient);
467
-
468
-			if (is_null($group)) {
469
-				throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
470
-			}
471
-
472
-			if (!$group->inGroup($user)) {
473
-				// nothing left to do
474
-				return;
475
-			}
476
-
477
-			// Try to fetch user specific share
478
-			$qb = $this->dbConn->getQueryBuilder();
479
-			$stmt = $qb->select('*')
480
-				->from('share')
481
-				->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
482
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
483
-				->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
484
-				->andWhere($qb->expr()->orX(
485
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
486
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
487
-				))
488
-				->execute();
489
-
490
-			$data = $stmt->fetch();
491
-
492
-			/*
447
+        if ($share->getShareType() === IShare::TYPE_GROUP) {
448
+            $qb->orWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())));
449
+        }
450
+
451
+        $qb->execute();
452
+    }
453
+
454
+    /**
455
+     * Unshare a share from the recipient. If this is a group share
456
+     * this means we need a special entry in the share db.
457
+     *
458
+     * @param IShare $share
459
+     * @param string $recipient UserId of recipient
460
+     * @throws BackendError
461
+     * @throws ProviderException
462
+     */
463
+    public function deleteFromSelf(IShare $share, $recipient) {
464
+        if ($share->getShareType() === IShare::TYPE_GROUP) {
465
+            $group = $this->groupManager->get($share->getSharedWith());
466
+            $user = $this->userManager->get($recipient);
467
+
468
+            if (is_null($group)) {
469
+                throw new ProviderException('Group "' . $share->getSharedWith() . '" does not exist');
470
+            }
471
+
472
+            if (!$group->inGroup($user)) {
473
+                // nothing left to do
474
+                return;
475
+            }
476
+
477
+            // Try to fetch user specific share
478
+            $qb = $this->dbConn->getQueryBuilder();
479
+            $stmt = $qb->select('*')
480
+                ->from('share')
481
+                ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
482
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
483
+                ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
484
+                ->andWhere($qb->expr()->orX(
485
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
486
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
487
+                ))
488
+                ->execute();
489
+
490
+            $data = $stmt->fetch();
491
+
492
+            /*
493 493
 			 * Check if there already is a user specific group share.
494 494
 			 * If there is update it (if required).
495 495
 			 */
496
-			if ($data === false) {
497
-				$id = $this->createUserSpecificGroupShare($share, $recipient);
498
-				$permissions = $share->getPermissions();
499
-			} else {
500
-				$permissions = $data['permissions'];
501
-				$id = $data['id'];
502
-			}
503
-
504
-			if ($permissions !== 0) {
505
-				// Update existing usergroup share
506
-				$qb = $this->dbConn->getQueryBuilder();
507
-				$qb->update('share')
508
-					->set('permissions', $qb->createNamedParameter(0))
509
-					->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
510
-					->execute();
511
-			}
512
-		} elseif ($share->getShareType() === IShare::TYPE_USER) {
513
-			if ($share->getSharedWith() !== $recipient) {
514
-				throw new ProviderException('Recipient does not match');
515
-			}
516
-
517
-			// We can just delete user and link shares
518
-			$this->delete($share);
519
-		} else {
520
-			throw new ProviderException('Invalid shareType');
521
-		}
522
-	}
523
-
524
-	protected function createUserSpecificGroupShare(IShare $share, string $recipient): int {
525
-		$type = $share->getNodeType();
526
-
527
-		$qb = $this->dbConn->getQueryBuilder();
528
-		$qb->insert('share')
529
-			->values([
530
-				'share_type' => $qb->createNamedParameter(IShare::TYPE_USERGROUP),
531
-				'share_with' => $qb->createNamedParameter($recipient),
532
-				'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
533
-				'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
534
-				'parent' => $qb->createNamedParameter($share->getId()),
535
-				'item_type' => $qb->createNamedParameter($type),
536
-				'item_source' => $qb->createNamedParameter($share->getNodeId()),
537
-				'file_source' => $qb->createNamedParameter($share->getNodeId()),
538
-				'file_target' => $qb->createNamedParameter($share->getTarget()),
539
-				'permissions' => $qb->createNamedParameter($share->getPermissions()),
540
-				'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
541
-			])->execute();
542
-
543
-		return $qb->getLastInsertId();
544
-	}
545
-
546
-	/**
547
-	 * @inheritdoc
548
-	 *
549
-	 * For now this only works for group shares
550
-	 * If this gets implemented for normal shares we have to extend it
551
-	 */
552
-	public function restore(IShare $share, string $recipient): IShare {
553
-		$qb = $this->dbConn->getQueryBuilder();
554
-		$qb->select('permissions')
555
-			->from('share')
556
-			->where(
557
-				$qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))
558
-			);
559
-		$cursor = $qb->execute();
560
-		$data = $cursor->fetch();
561
-		$cursor->closeCursor();
562
-
563
-		$originalPermission = $data['permissions'];
564
-
565
-		$qb = $this->dbConn->getQueryBuilder();
566
-		$qb->update('share')
567
-			->set('permissions', $qb->createNamedParameter($originalPermission))
568
-			->where(
569
-				$qb->expr()->eq('parent', $qb->createNamedParameter($share->getParent()))
570
-			)->andWhere(
571
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP))
572
-			)->andWhere(
573
-				$qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))
574
-			);
575
-
576
-		$qb->execute();
577
-
578
-		return $this->getShareById($share->getId(), $recipient);
579
-	}
580
-
581
-	/**
582
-	 * @inheritdoc
583
-	 */
584
-	public function move(\OCP\Share\IShare $share, $recipient) {
585
-		if ($share->getShareType() === IShare::TYPE_USER) {
586
-			// Just update the target
587
-			$qb = $this->dbConn->getQueryBuilder();
588
-			$qb->update('share')
589
-				->set('file_target', $qb->createNamedParameter($share->getTarget()))
590
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
591
-				->execute();
592
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
593
-
594
-			// Check if there is a usergroup share
595
-			$qb = $this->dbConn->getQueryBuilder();
596
-			$stmt = $qb->select('id')
597
-				->from('share')
598
-				->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
599
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
600
-				->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
601
-				->andWhere($qb->expr()->orX(
602
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
603
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
604
-				))
605
-				->setMaxResults(1)
606
-				->execute();
607
-
608
-			$data = $stmt->fetch();
609
-			$stmt->closeCursor();
610
-
611
-			if ($data === false) {
612
-				// No usergroup share yet. Create one.
613
-				$qb = $this->dbConn->getQueryBuilder();
614
-				$qb->insert('share')
615
-					->values([
616
-						'share_type' => $qb->createNamedParameter(IShare::TYPE_USERGROUP),
617
-						'share_with' => $qb->createNamedParameter($recipient),
618
-						'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
619
-						'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
620
-						'parent' => $qb->createNamedParameter($share->getId()),
621
-						'item_type' => $qb->createNamedParameter($share->getNodeType()),
622
-						'item_source' => $qb->createNamedParameter($share->getNodeId()),
623
-						'file_source' => $qb->createNamedParameter($share->getNodeId()),
624
-						'file_target' => $qb->createNamedParameter($share->getTarget()),
625
-						'permissions' => $qb->createNamedParameter($share->getPermissions()),
626
-						'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
627
-					])->execute();
628
-			} else {
629
-				// Already a usergroup share. Update it.
630
-				$qb = $this->dbConn->getQueryBuilder();
631
-				$qb->update('share')
632
-					->set('file_target', $qb->createNamedParameter($share->getTarget()))
633
-					->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
634
-					->execute();
635
-			}
636
-		}
637
-
638
-		return $share;
639
-	}
640
-
641
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
642
-		$qb = $this->dbConn->getQueryBuilder();
643
-		$qb->select('*')
644
-			->from('share', 's')
645
-			->andWhere($qb->expr()->orX(
646
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
647
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
648
-			));
649
-
650
-		$qb->andWhere($qb->expr()->orX(
651
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)),
652
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)),
653
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK))
654
-		));
655
-
656
-		/**
657
-		 * Reshares for this user are shares where they are the owner.
658
-		 */
659
-		if ($reshares === false) {
660
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
661
-		} else {
662
-			$qb->andWhere(
663
-				$qb->expr()->orX(
664
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
665
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
666
-				)
667
-			);
668
-		}
669
-
670
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
671
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
672
-
673
-		$qb->orderBy('id');
674
-
675
-		$cursor = $qb->execute();
676
-		$shares = [];
677
-		while ($data = $cursor->fetch()) {
678
-			$shares[$data['fileid']][] = $this->createShare($data);
679
-		}
680
-		$cursor->closeCursor();
681
-
682
-		return $shares;
683
-	}
684
-
685
-	/**
686
-	 * @inheritdoc
687
-	 */
688
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
689
-		$qb = $this->dbConn->getQueryBuilder();
690
-		$qb->select('*')
691
-			->from('share')
692
-			->andWhere($qb->expr()->orX(
693
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
694
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
695
-			));
696
-
697
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType)));
698
-
699
-		/**
700
-		 * Reshares for this user are shares where they are the owner.
701
-		 */
702
-		if ($reshares === false) {
703
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
704
-		} else {
705
-			if ($node === null) {
706
-				$qb->andWhere(
707
-					$qb->expr()->orX(
708
-						$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
709
-						$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
710
-					)
711
-				);
712
-			}
713
-		}
714
-
715
-		if ($node !== null) {
716
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
717
-		}
718
-
719
-		if ($limit !== -1) {
720
-			$qb->setMaxResults($limit);
721
-		}
722
-
723
-		$qb->setFirstResult($offset);
724
-		$qb->orderBy('id');
725
-
726
-		$cursor = $qb->execute();
727
-		$shares = [];
728
-		while ($data = $cursor->fetch()) {
729
-			$shares[] = $this->createShare($data);
730
-		}
731
-		$cursor->closeCursor();
732
-
733
-		return $shares;
734
-	}
735
-
736
-	/**
737
-	 * @inheritdoc
738
-	 */
739
-	public function getShareById($id, $recipientId = null) {
740
-		$qb = $this->dbConn->getQueryBuilder();
741
-
742
-		$qb->select('*')
743
-			->from('share')
744
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
745
-			->andWhere(
746
-				$qb->expr()->in(
747
-					'share_type',
748
-					$qb->createNamedParameter([
749
-						IShare::TYPE_USER,
750
-						IShare::TYPE_GROUP,
751
-						IShare::TYPE_LINK,
752
-					], IQueryBuilder::PARAM_INT_ARRAY)
753
-				)
754
-			)
755
-			->andWhere($qb->expr()->orX(
756
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
757
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
758
-			));
759
-
760
-		$cursor = $qb->execute();
761
-		$data = $cursor->fetch();
762
-		$cursor->closeCursor();
763
-
764
-		if ($data === false) {
765
-			throw new ShareNotFound();
766
-		}
767
-
768
-		try {
769
-			$share = $this->createShare($data);
770
-		} catch (InvalidShare $e) {
771
-			throw new ShareNotFound();
772
-		}
773
-
774
-		// If the recipient is set for a group share resolve to that user
775
-		if ($recipientId !== null && $share->getShareType() === IShare::TYPE_GROUP) {
776
-			$share = $this->resolveGroupShares([$share], $recipientId)[0];
777
-		}
778
-
779
-		return $share;
780
-	}
781
-
782
-	/**
783
-	 * Get shares for a given path
784
-	 *
785
-	 * @param \OCP\Files\Node $path
786
-	 * @return \OCP\Share\IShare[]
787
-	 */
788
-	public function getSharesByPath(Node $path) {
789
-		$qb = $this->dbConn->getQueryBuilder();
790
-
791
-		$cursor = $qb->select('*')
792
-			->from('share')
793
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
794
-			->andWhere(
795
-				$qb->expr()->orX(
796
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)),
797
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP))
798
-				)
799
-			)
800
-			->andWhere($qb->expr()->orX(
801
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
802
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
803
-			))
804
-			->execute();
805
-
806
-		$shares = [];
807
-		while ($data = $cursor->fetch()) {
808
-			$shares[] = $this->createShare($data);
809
-		}
810
-		$cursor->closeCursor();
811
-
812
-		return $shares;
813
-	}
814
-
815
-	/**
816
-	 * Returns whether the given database result can be interpreted as
817
-	 * a share with accessible file (not trashed, not deleted)
818
-	 */
819
-	private function isAccessibleResult($data) {
820
-		// exclude shares leading to deleted file entries
821
-		if ($data['fileid'] === null || $data['path'] === null) {
822
-			return false;
823
-		}
824
-
825
-		// exclude shares leading to trashbin on home storages
826
-		$pathSections = explode('/', $data['path'], 2);
827
-		// FIXME: would not detect rare md5'd home storage case properly
828
-		if ($pathSections[0] !== 'files'
829
-			&& (strpos($data['storage_string_id'], 'home::') === 0 || strpos($data['storage_string_id'], 'object::user') === 0)) {
830
-			return false;
831
-		}
832
-		return true;
833
-	}
834
-
835
-	/**
836
-	 * @inheritdoc
837
-	 */
838
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
839
-		/** @var Share[] $shares */
840
-		$shares = [];
841
-
842
-		if ($shareType === IShare::TYPE_USER) {
843
-			//Get shares directly with this user
844
-			$qb = $this->dbConn->getQueryBuilder();
845
-			$qb->select('s.*',
846
-				'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
847
-				'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
848
-				'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
849
-			)
850
-				->selectAlias('st.id', 'storage_string_id')
851
-				->from('share', 's')
852
-				->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
853
-				->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'));
854
-
855
-			// Order by id
856
-			$qb->orderBy('s.id');
857
-
858
-			// Set limit and offset
859
-			if ($limit !== -1) {
860
-				$qb->setMaxResults($limit);
861
-			}
862
-			$qb->setFirstResult($offset);
863
-
864
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)))
865
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
866
-				->andWhere($qb->expr()->orX(
867
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
868
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
869
-				));
870
-
871
-			// Filter by node if provided
872
-			if ($node !== null) {
873
-				$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
874
-			}
875
-
876
-			$cursor = $qb->execute();
877
-
878
-			while ($data = $cursor->fetch()) {
879
-				if ($data['fileid'] && $data['path'] === null) {
880
-					$data['path'] = (string) $data['path'];
881
-					$data['name'] = (string) $data['name'];
882
-					$data['checksum'] = (string) $data['checksum'];
883
-				}
884
-				if ($this->isAccessibleResult($data)) {
885
-					$shares[] = $this->createShare($data);
886
-				}
887
-			}
888
-			$cursor->closeCursor();
889
-		} elseif ($shareType === IShare::TYPE_GROUP) {
890
-			$user = $this->userManager->get($userId);
891
-			$allGroups = ($user instanceof IUser) ? $this->groupManager->getUserGroupIds($user) : [];
892
-
893
-			/** @var Share[] $shares2 */
894
-			$shares2 = [];
895
-
896
-			$start = 0;
897
-			while (true) {
898
-				$groups = array_slice($allGroups, $start, 100);
899
-				$start += 100;
900
-
901
-				if ($groups === []) {
902
-					break;
903
-				}
904
-
905
-				$qb = $this->dbConn->getQueryBuilder();
906
-				$qb->select('s.*',
907
-					'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
908
-					'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
909
-					'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
910
-				)
911
-					->selectAlias('st.id', 'storage_string_id')
912
-					->from('share', 's')
913
-					->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
914
-					->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'))
915
-					->orderBy('s.id')
916
-					->setFirstResult(0);
917
-
918
-				if ($limit !== -1) {
919
-					$qb->setMaxResults($limit - count($shares));
920
-				}
921
-
922
-				// Filter by node if provided
923
-				if ($node !== null) {
924
-					$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
925
-				}
926
-
927
-
928
-				$groups = array_filter($groups);
929
-
930
-				$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
931
-					->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter(
932
-						$groups,
933
-						IQueryBuilder::PARAM_STR_ARRAY
934
-					)))
935
-					->andWhere($qb->expr()->orX(
936
-						$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
937
-						$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
938
-					));
939
-
940
-				$cursor = $qb->execute();
941
-				while ($data = $cursor->fetch()) {
942
-					if ($offset > 0) {
943
-						$offset--;
944
-						continue;
945
-					}
946
-
947
-					if ($this->isAccessibleResult($data)) {
948
-						$shares2[] = $this->createShare($data);
949
-					}
950
-				}
951
-				$cursor->closeCursor();
952
-			}
953
-
954
-			/*
496
+            if ($data === false) {
497
+                $id = $this->createUserSpecificGroupShare($share, $recipient);
498
+                $permissions = $share->getPermissions();
499
+            } else {
500
+                $permissions = $data['permissions'];
501
+                $id = $data['id'];
502
+            }
503
+
504
+            if ($permissions !== 0) {
505
+                // Update existing usergroup share
506
+                $qb = $this->dbConn->getQueryBuilder();
507
+                $qb->update('share')
508
+                    ->set('permissions', $qb->createNamedParameter(0))
509
+                    ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
510
+                    ->execute();
511
+            }
512
+        } elseif ($share->getShareType() === IShare::TYPE_USER) {
513
+            if ($share->getSharedWith() !== $recipient) {
514
+                throw new ProviderException('Recipient does not match');
515
+            }
516
+
517
+            // We can just delete user and link shares
518
+            $this->delete($share);
519
+        } else {
520
+            throw new ProviderException('Invalid shareType');
521
+        }
522
+    }
523
+
524
+    protected function createUserSpecificGroupShare(IShare $share, string $recipient): int {
525
+        $type = $share->getNodeType();
526
+
527
+        $qb = $this->dbConn->getQueryBuilder();
528
+        $qb->insert('share')
529
+            ->values([
530
+                'share_type' => $qb->createNamedParameter(IShare::TYPE_USERGROUP),
531
+                'share_with' => $qb->createNamedParameter($recipient),
532
+                'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
533
+                'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
534
+                'parent' => $qb->createNamedParameter($share->getId()),
535
+                'item_type' => $qb->createNamedParameter($type),
536
+                'item_source' => $qb->createNamedParameter($share->getNodeId()),
537
+                'file_source' => $qb->createNamedParameter($share->getNodeId()),
538
+                'file_target' => $qb->createNamedParameter($share->getTarget()),
539
+                'permissions' => $qb->createNamedParameter($share->getPermissions()),
540
+                'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
541
+            ])->execute();
542
+
543
+        return $qb->getLastInsertId();
544
+    }
545
+
546
+    /**
547
+     * @inheritdoc
548
+     *
549
+     * For now this only works for group shares
550
+     * If this gets implemented for normal shares we have to extend it
551
+     */
552
+    public function restore(IShare $share, string $recipient): IShare {
553
+        $qb = $this->dbConn->getQueryBuilder();
554
+        $qb->select('permissions')
555
+            ->from('share')
556
+            ->where(
557
+                $qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))
558
+            );
559
+        $cursor = $qb->execute();
560
+        $data = $cursor->fetch();
561
+        $cursor->closeCursor();
562
+
563
+        $originalPermission = $data['permissions'];
564
+
565
+        $qb = $this->dbConn->getQueryBuilder();
566
+        $qb->update('share')
567
+            ->set('permissions', $qb->createNamedParameter($originalPermission))
568
+            ->where(
569
+                $qb->expr()->eq('parent', $qb->createNamedParameter($share->getParent()))
570
+            )->andWhere(
571
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP))
572
+            )->andWhere(
573
+                $qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))
574
+            );
575
+
576
+        $qb->execute();
577
+
578
+        return $this->getShareById($share->getId(), $recipient);
579
+    }
580
+
581
+    /**
582
+     * @inheritdoc
583
+     */
584
+    public function move(\OCP\Share\IShare $share, $recipient) {
585
+        if ($share->getShareType() === IShare::TYPE_USER) {
586
+            // Just update the target
587
+            $qb = $this->dbConn->getQueryBuilder();
588
+            $qb->update('share')
589
+                ->set('file_target', $qb->createNamedParameter($share->getTarget()))
590
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
591
+                ->execute();
592
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
593
+
594
+            // Check if there is a usergroup share
595
+            $qb = $this->dbConn->getQueryBuilder();
596
+            $stmt = $qb->select('id')
597
+                ->from('share')
598
+                ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
599
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)))
600
+                ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
601
+                ->andWhere($qb->expr()->orX(
602
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
603
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
604
+                ))
605
+                ->setMaxResults(1)
606
+                ->execute();
607
+
608
+            $data = $stmt->fetch();
609
+            $stmt->closeCursor();
610
+
611
+            if ($data === false) {
612
+                // No usergroup share yet. Create one.
613
+                $qb = $this->dbConn->getQueryBuilder();
614
+                $qb->insert('share')
615
+                    ->values([
616
+                        'share_type' => $qb->createNamedParameter(IShare::TYPE_USERGROUP),
617
+                        'share_with' => $qb->createNamedParameter($recipient),
618
+                        'uid_owner' => $qb->createNamedParameter($share->getShareOwner()),
619
+                        'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()),
620
+                        'parent' => $qb->createNamedParameter($share->getId()),
621
+                        'item_type' => $qb->createNamedParameter($share->getNodeType()),
622
+                        'item_source' => $qb->createNamedParameter($share->getNodeId()),
623
+                        'file_source' => $qb->createNamedParameter($share->getNodeId()),
624
+                        'file_target' => $qb->createNamedParameter($share->getTarget()),
625
+                        'permissions' => $qb->createNamedParameter($share->getPermissions()),
626
+                        'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()),
627
+                    ])->execute();
628
+            } else {
629
+                // Already a usergroup share. Update it.
630
+                $qb = $this->dbConn->getQueryBuilder();
631
+                $qb->update('share')
632
+                    ->set('file_target', $qb->createNamedParameter($share->getTarget()))
633
+                    ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id'])))
634
+                    ->execute();
635
+            }
636
+        }
637
+
638
+        return $share;
639
+    }
640
+
641
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
642
+        $qb = $this->dbConn->getQueryBuilder();
643
+        $qb->select('*')
644
+            ->from('share', 's')
645
+            ->andWhere($qb->expr()->orX(
646
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
647
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
648
+            ));
649
+
650
+        $qb->andWhere($qb->expr()->orX(
651
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)),
652
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)),
653
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK))
654
+        ));
655
+
656
+        /**
657
+         * Reshares for this user are shares where they are the owner.
658
+         */
659
+        if ($reshares === false) {
660
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
661
+        } else {
662
+            $qb->andWhere(
663
+                $qb->expr()->orX(
664
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
665
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
666
+                )
667
+            );
668
+        }
669
+
670
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
671
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
672
+
673
+        $qb->orderBy('id');
674
+
675
+        $cursor = $qb->execute();
676
+        $shares = [];
677
+        while ($data = $cursor->fetch()) {
678
+            $shares[$data['fileid']][] = $this->createShare($data);
679
+        }
680
+        $cursor->closeCursor();
681
+
682
+        return $shares;
683
+    }
684
+
685
+    /**
686
+     * @inheritdoc
687
+     */
688
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
689
+        $qb = $this->dbConn->getQueryBuilder();
690
+        $qb->select('*')
691
+            ->from('share')
692
+            ->andWhere($qb->expr()->orX(
693
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
694
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
695
+            ));
696
+
697
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter($shareType)));
698
+
699
+        /**
700
+         * Reshares for this user are shares where they are the owner.
701
+         */
702
+        if ($reshares === false) {
703
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
704
+        } else {
705
+            if ($node === null) {
706
+                $qb->andWhere(
707
+                    $qb->expr()->orX(
708
+                        $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
709
+                        $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
710
+                    )
711
+                );
712
+            }
713
+        }
714
+
715
+        if ($node !== null) {
716
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
717
+        }
718
+
719
+        if ($limit !== -1) {
720
+            $qb->setMaxResults($limit);
721
+        }
722
+
723
+        $qb->setFirstResult($offset);
724
+        $qb->orderBy('id');
725
+
726
+        $cursor = $qb->execute();
727
+        $shares = [];
728
+        while ($data = $cursor->fetch()) {
729
+            $shares[] = $this->createShare($data);
730
+        }
731
+        $cursor->closeCursor();
732
+
733
+        return $shares;
734
+    }
735
+
736
+    /**
737
+     * @inheritdoc
738
+     */
739
+    public function getShareById($id, $recipientId = null) {
740
+        $qb = $this->dbConn->getQueryBuilder();
741
+
742
+        $qb->select('*')
743
+            ->from('share')
744
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
745
+            ->andWhere(
746
+                $qb->expr()->in(
747
+                    'share_type',
748
+                    $qb->createNamedParameter([
749
+                        IShare::TYPE_USER,
750
+                        IShare::TYPE_GROUP,
751
+                        IShare::TYPE_LINK,
752
+                    ], IQueryBuilder::PARAM_INT_ARRAY)
753
+                )
754
+            )
755
+            ->andWhere($qb->expr()->orX(
756
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
757
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
758
+            ));
759
+
760
+        $cursor = $qb->execute();
761
+        $data = $cursor->fetch();
762
+        $cursor->closeCursor();
763
+
764
+        if ($data === false) {
765
+            throw new ShareNotFound();
766
+        }
767
+
768
+        try {
769
+            $share = $this->createShare($data);
770
+        } catch (InvalidShare $e) {
771
+            throw new ShareNotFound();
772
+        }
773
+
774
+        // If the recipient is set for a group share resolve to that user
775
+        if ($recipientId !== null && $share->getShareType() === IShare::TYPE_GROUP) {
776
+            $share = $this->resolveGroupShares([$share], $recipientId)[0];
777
+        }
778
+
779
+        return $share;
780
+    }
781
+
782
+    /**
783
+     * Get shares for a given path
784
+     *
785
+     * @param \OCP\Files\Node $path
786
+     * @return \OCP\Share\IShare[]
787
+     */
788
+    public function getSharesByPath(Node $path) {
789
+        $qb = $this->dbConn->getQueryBuilder();
790
+
791
+        $cursor = $qb->select('*')
792
+            ->from('share')
793
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
794
+            ->andWhere(
795
+                $qb->expr()->orX(
796
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)),
797
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP))
798
+                )
799
+            )
800
+            ->andWhere($qb->expr()->orX(
801
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
802
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
803
+            ))
804
+            ->execute();
805
+
806
+        $shares = [];
807
+        while ($data = $cursor->fetch()) {
808
+            $shares[] = $this->createShare($data);
809
+        }
810
+        $cursor->closeCursor();
811
+
812
+        return $shares;
813
+    }
814
+
815
+    /**
816
+     * Returns whether the given database result can be interpreted as
817
+     * a share with accessible file (not trashed, not deleted)
818
+     */
819
+    private function isAccessibleResult($data) {
820
+        // exclude shares leading to deleted file entries
821
+        if ($data['fileid'] === null || $data['path'] === null) {
822
+            return false;
823
+        }
824
+
825
+        // exclude shares leading to trashbin on home storages
826
+        $pathSections = explode('/', $data['path'], 2);
827
+        // FIXME: would not detect rare md5'd home storage case properly
828
+        if ($pathSections[0] !== 'files'
829
+            && (strpos($data['storage_string_id'], 'home::') === 0 || strpos($data['storage_string_id'], 'object::user') === 0)) {
830
+            return false;
831
+        }
832
+        return true;
833
+    }
834
+
835
+    /**
836
+     * @inheritdoc
837
+     */
838
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
839
+        /** @var Share[] $shares */
840
+        $shares = [];
841
+
842
+        if ($shareType === IShare::TYPE_USER) {
843
+            //Get shares directly with this user
844
+            $qb = $this->dbConn->getQueryBuilder();
845
+            $qb->select('s.*',
846
+                'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
847
+                'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
848
+                'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
849
+            )
850
+                ->selectAlias('st.id', 'storage_string_id')
851
+                ->from('share', 's')
852
+                ->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
853
+                ->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'));
854
+
855
+            // Order by id
856
+            $qb->orderBy('s.id');
857
+
858
+            // Set limit and offset
859
+            if ($limit !== -1) {
860
+                $qb->setMaxResults($limit);
861
+            }
862
+            $qb->setFirstResult($offset);
863
+
864
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)))
865
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
866
+                ->andWhere($qb->expr()->orX(
867
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
868
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
869
+                ));
870
+
871
+            // Filter by node if provided
872
+            if ($node !== null) {
873
+                $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
874
+            }
875
+
876
+            $cursor = $qb->execute();
877
+
878
+            while ($data = $cursor->fetch()) {
879
+                if ($data['fileid'] && $data['path'] === null) {
880
+                    $data['path'] = (string) $data['path'];
881
+                    $data['name'] = (string) $data['name'];
882
+                    $data['checksum'] = (string) $data['checksum'];
883
+                }
884
+                if ($this->isAccessibleResult($data)) {
885
+                    $shares[] = $this->createShare($data);
886
+                }
887
+            }
888
+            $cursor->closeCursor();
889
+        } elseif ($shareType === IShare::TYPE_GROUP) {
890
+            $user = $this->userManager->get($userId);
891
+            $allGroups = ($user instanceof IUser) ? $this->groupManager->getUserGroupIds($user) : [];
892
+
893
+            /** @var Share[] $shares2 */
894
+            $shares2 = [];
895
+
896
+            $start = 0;
897
+            while (true) {
898
+                $groups = array_slice($allGroups, $start, 100);
899
+                $start += 100;
900
+
901
+                if ($groups === []) {
902
+                    break;
903
+                }
904
+
905
+                $qb = $this->dbConn->getQueryBuilder();
906
+                $qb->select('s.*',
907
+                    'f.fileid', 'f.path', 'f.permissions AS f_permissions', 'f.storage', 'f.path_hash',
908
+                    'f.parent AS f_parent', 'f.name', 'f.mimetype', 'f.mimepart', 'f.size', 'f.mtime', 'f.storage_mtime',
909
+                    'f.encrypted', 'f.unencrypted_size', 'f.etag', 'f.checksum'
910
+                )
911
+                    ->selectAlias('st.id', 'storage_string_id')
912
+                    ->from('share', 's')
913
+                    ->leftJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'))
914
+                    ->leftJoin('f', 'storages', 'st', $qb->expr()->eq('f.storage', 'st.numeric_id'))
915
+                    ->orderBy('s.id')
916
+                    ->setFirstResult(0);
917
+
918
+                if ($limit !== -1) {
919
+                    $qb->setMaxResults($limit - count($shares));
920
+                }
921
+
922
+                // Filter by node if provided
923
+                if ($node !== null) {
924
+                    $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
925
+                }
926
+
927
+
928
+                $groups = array_filter($groups);
929
+
930
+                $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
931
+                    ->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter(
932
+                        $groups,
933
+                        IQueryBuilder::PARAM_STR_ARRAY
934
+                    )))
935
+                    ->andWhere($qb->expr()->orX(
936
+                        $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
937
+                        $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
938
+                    ));
939
+
940
+                $cursor = $qb->execute();
941
+                while ($data = $cursor->fetch()) {
942
+                    if ($offset > 0) {
943
+                        $offset--;
944
+                        continue;
945
+                    }
946
+
947
+                    if ($this->isAccessibleResult($data)) {
948
+                        $shares2[] = $this->createShare($data);
949
+                    }
950
+                }
951
+                $cursor->closeCursor();
952
+            }
953
+
954
+            /*
955 955
 			 * Resolve all group shares to user specific shares
956 956
 			 */
957
-			$shares = $this->resolveGroupShares($shares2, $userId);
958
-		} else {
959
-			throw new BackendError('Invalid backend');
960
-		}
961
-
962
-
963
-		return $shares;
964
-	}
965
-
966
-	/**
967
-	 * Get a share by token
968
-	 *
969
-	 * @param string $token
970
-	 * @return \OCP\Share\IShare
971
-	 * @throws ShareNotFound
972
-	 */
973
-	public function getShareByToken($token) {
974
-		$qb = $this->dbConn->getQueryBuilder();
975
-
976
-		$cursor = $qb->select('*')
977
-			->from('share')
978
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK)))
979
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
980
-			->andWhere($qb->expr()->orX(
981
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
982
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
983
-			))
984
-			->execute();
985
-
986
-		$data = $cursor->fetch();
987
-
988
-		if ($data === false) {
989
-			throw new ShareNotFound();
990
-		}
991
-
992
-		try {
993
-			$share = $this->createShare($data);
994
-		} catch (InvalidShare $e) {
995
-			throw new ShareNotFound();
996
-		}
997
-
998
-		return $share;
999
-	}
1000
-
1001
-	/**
1002
-	 * Create a share object from an database row
1003
-	 *
1004
-	 * @param mixed[] $data
1005
-	 * @return \OCP\Share\IShare
1006
-	 * @throws InvalidShare
1007
-	 */
1008
-	private function createShare($data) {
1009
-		$share = new Share($this->rootFolder, $this->userManager);
1010
-		$share->setId((int)$data['id'])
1011
-			->setShareType((int)$data['share_type'])
1012
-			->setPermissions((int)$data['permissions'])
1013
-			->setTarget($data['file_target'])
1014
-			->setNote((string)$data['note'])
1015
-			->setMailSend((bool)$data['mail_send'])
1016
-			->setStatus((int)$data['accepted'])
1017
-			->setLabel($data['label']);
1018
-
1019
-		$shareTime = new \DateTime();
1020
-		$shareTime->setTimestamp((int)$data['stime']);
1021
-		$share->setShareTime($shareTime);
1022
-
1023
-		if ($share->getShareType() === IShare::TYPE_USER) {
1024
-			$share->setSharedWith($data['share_with']);
1025
-			$user = $this->userManager->get($data['share_with']);
1026
-			if ($user !== null) {
1027
-				$share->setSharedWithDisplayName($user->getDisplayName());
1028
-			}
1029
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
1030
-			$share->setSharedWith($data['share_with']);
1031
-		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
1032
-			$share->setPassword($data['password']);
1033
-			$share->setSendPasswordByTalk((bool)$data['password_by_talk']);
1034
-			$share->setToken($data['token']);
1035
-		}
1036
-
1037
-		$share->setSharedBy($data['uid_initiator']);
1038
-		$share->setShareOwner($data['uid_owner']);
1039
-
1040
-		$share->setNodeId((int)$data['file_source']);
1041
-		$share->setNodeType($data['item_type']);
1042
-
1043
-		if ($data['expiration'] !== null) {
1044
-			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
1045
-			$share->setExpirationDate($expiration);
1046
-		}
1047
-
1048
-		if (isset($data['f_permissions'])) {
1049
-			$entryData = $data;
1050
-			$entryData['permissions'] = $entryData['f_permissions'];
1051
-			$entryData['parent'] = $entryData['f_parent'];
1052
-			$share->setNodeCacheEntry(Cache::cacheEntryFromData($entryData,
1053
-				\OC::$server->getMimeTypeLoader()));
1054
-		}
1055
-
1056
-		$share->setProviderId($this->identifier());
1057
-		$share->setHideDownload((int)$data['hide_download'] === 1);
1058
-
1059
-		return $share;
1060
-	}
1061
-
1062
-	/**
1063
-	 * @param Share[] $shares
1064
-	 * @param $userId
1065
-	 * @return Share[] The updates shares if no update is found for a share return the original
1066
-	 */
1067
-	private function resolveGroupShares($shares, $userId) {
1068
-		$result = [];
1069
-
1070
-		$start = 0;
1071
-		while (true) {
1072
-			/** @var Share[] $shareSlice */
1073
-			$shareSlice = array_slice($shares, $start, 100);
1074
-			$start += 100;
1075
-
1076
-			if ($shareSlice === []) {
1077
-				break;
1078
-			}
1079
-
1080
-			/** @var int[] $ids */
1081
-			$ids = [];
1082
-			/** @var Share[] $shareMap */
1083
-			$shareMap = [];
1084
-
1085
-			foreach ($shareSlice as $share) {
1086
-				$ids[] = (int)$share->getId();
1087
-				$shareMap[$share->getId()] = $share;
1088
-			}
1089
-
1090
-			$qb = $this->dbConn->getQueryBuilder();
1091
-
1092
-			$query = $qb->select('*')
1093
-				->from('share')
1094
-				->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1095
-				->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
1096
-				->andWhere($qb->expr()->orX(
1097
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1098
-					$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1099
-				));
1100
-
1101
-			$stmt = $query->execute();
1102
-
1103
-			while ($data = $stmt->fetch()) {
1104
-				$shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
1105
-				$shareMap[$data['parent']]->setStatus((int)$data['accepted']);
1106
-				$shareMap[$data['parent']]->setTarget($data['file_target']);
1107
-				$shareMap[$data['parent']]->setParent($data['parent']);
1108
-			}
1109
-
1110
-			$stmt->closeCursor();
1111
-
1112
-			foreach ($shareMap as $share) {
1113
-				$result[] = $share;
1114
-			}
1115
-		}
1116
-
1117
-		return $result;
1118
-	}
1119
-
1120
-	/**
1121
-	 * A user is deleted from the system
1122
-	 * So clean up the relevant shares.
1123
-	 *
1124
-	 * @param string $uid
1125
-	 * @param int $shareType
1126
-	 */
1127
-	public function userDeleted($uid, $shareType) {
1128
-		$qb = $this->dbConn->getQueryBuilder();
1129
-
1130
-		$qb->delete('share');
1131
-
1132
-		if ($shareType === IShare::TYPE_USER) {
1133
-			/*
957
+            $shares = $this->resolveGroupShares($shares2, $userId);
958
+        } else {
959
+            throw new BackendError('Invalid backend');
960
+        }
961
+
962
+
963
+        return $shares;
964
+    }
965
+
966
+    /**
967
+     * Get a share by token
968
+     *
969
+     * @param string $token
970
+     * @return \OCP\Share\IShare
971
+     * @throws ShareNotFound
972
+     */
973
+    public function getShareByToken($token) {
974
+        $qb = $this->dbConn->getQueryBuilder();
975
+
976
+        $cursor = $qb->select('*')
977
+            ->from('share')
978
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK)))
979
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
980
+            ->andWhere($qb->expr()->orX(
981
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
982
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
983
+            ))
984
+            ->execute();
985
+
986
+        $data = $cursor->fetch();
987
+
988
+        if ($data === false) {
989
+            throw new ShareNotFound();
990
+        }
991
+
992
+        try {
993
+            $share = $this->createShare($data);
994
+        } catch (InvalidShare $e) {
995
+            throw new ShareNotFound();
996
+        }
997
+
998
+        return $share;
999
+    }
1000
+
1001
+    /**
1002
+     * Create a share object from an database row
1003
+     *
1004
+     * @param mixed[] $data
1005
+     * @return \OCP\Share\IShare
1006
+     * @throws InvalidShare
1007
+     */
1008
+    private function createShare($data) {
1009
+        $share = new Share($this->rootFolder, $this->userManager);
1010
+        $share->setId((int)$data['id'])
1011
+            ->setShareType((int)$data['share_type'])
1012
+            ->setPermissions((int)$data['permissions'])
1013
+            ->setTarget($data['file_target'])
1014
+            ->setNote((string)$data['note'])
1015
+            ->setMailSend((bool)$data['mail_send'])
1016
+            ->setStatus((int)$data['accepted'])
1017
+            ->setLabel($data['label']);
1018
+
1019
+        $shareTime = new \DateTime();
1020
+        $shareTime->setTimestamp((int)$data['stime']);
1021
+        $share->setShareTime($shareTime);
1022
+
1023
+        if ($share->getShareType() === IShare::TYPE_USER) {
1024
+            $share->setSharedWith($data['share_with']);
1025
+            $user = $this->userManager->get($data['share_with']);
1026
+            if ($user !== null) {
1027
+                $share->setSharedWithDisplayName($user->getDisplayName());
1028
+            }
1029
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
1030
+            $share->setSharedWith($data['share_with']);
1031
+        } elseif ($share->getShareType() === IShare::TYPE_LINK) {
1032
+            $share->setPassword($data['password']);
1033
+            $share->setSendPasswordByTalk((bool)$data['password_by_talk']);
1034
+            $share->setToken($data['token']);
1035
+        }
1036
+
1037
+        $share->setSharedBy($data['uid_initiator']);
1038
+        $share->setShareOwner($data['uid_owner']);
1039
+
1040
+        $share->setNodeId((int)$data['file_source']);
1041
+        $share->setNodeType($data['item_type']);
1042
+
1043
+        if ($data['expiration'] !== null) {
1044
+            $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
1045
+            $share->setExpirationDate($expiration);
1046
+        }
1047
+
1048
+        if (isset($data['f_permissions'])) {
1049
+            $entryData = $data;
1050
+            $entryData['permissions'] = $entryData['f_permissions'];
1051
+            $entryData['parent'] = $entryData['f_parent'];
1052
+            $share->setNodeCacheEntry(Cache::cacheEntryFromData($entryData,
1053
+                \OC::$server->getMimeTypeLoader()));
1054
+        }
1055
+
1056
+        $share->setProviderId($this->identifier());
1057
+        $share->setHideDownload((int)$data['hide_download'] === 1);
1058
+
1059
+        return $share;
1060
+    }
1061
+
1062
+    /**
1063
+     * @param Share[] $shares
1064
+     * @param $userId
1065
+     * @return Share[] The updates shares if no update is found for a share return the original
1066
+     */
1067
+    private function resolveGroupShares($shares, $userId) {
1068
+        $result = [];
1069
+
1070
+        $start = 0;
1071
+        while (true) {
1072
+            /** @var Share[] $shareSlice */
1073
+            $shareSlice = array_slice($shares, $start, 100);
1074
+            $start += 100;
1075
+
1076
+            if ($shareSlice === []) {
1077
+                break;
1078
+            }
1079
+
1080
+            /** @var int[] $ids */
1081
+            $ids = [];
1082
+            /** @var Share[] $shareMap */
1083
+            $shareMap = [];
1084
+
1085
+            foreach ($shareSlice as $share) {
1086
+                $ids[] = (int)$share->getId();
1087
+                $shareMap[$share->getId()] = $share;
1088
+            }
1089
+
1090
+            $qb = $this->dbConn->getQueryBuilder();
1091
+
1092
+            $query = $qb->select('*')
1093
+                ->from('share')
1094
+                ->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1095
+                ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)))
1096
+                ->andWhere($qb->expr()->orX(
1097
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1098
+                    $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1099
+                ));
1100
+
1101
+            $stmt = $query->execute();
1102
+
1103
+            while ($data = $stmt->fetch()) {
1104
+                $shareMap[$data['parent']]->setPermissions((int)$data['permissions']);
1105
+                $shareMap[$data['parent']]->setStatus((int)$data['accepted']);
1106
+                $shareMap[$data['parent']]->setTarget($data['file_target']);
1107
+                $shareMap[$data['parent']]->setParent($data['parent']);
1108
+            }
1109
+
1110
+            $stmt->closeCursor();
1111
+
1112
+            foreach ($shareMap as $share) {
1113
+                $result[] = $share;
1114
+            }
1115
+        }
1116
+
1117
+        return $result;
1118
+    }
1119
+
1120
+    /**
1121
+     * A user is deleted from the system
1122
+     * So clean up the relevant shares.
1123
+     *
1124
+     * @param string $uid
1125
+     * @param int $shareType
1126
+     */
1127
+    public function userDeleted($uid, $shareType) {
1128
+        $qb = $this->dbConn->getQueryBuilder();
1129
+
1130
+        $qb->delete('share');
1131
+
1132
+        if ($shareType === IShare::TYPE_USER) {
1133
+            /*
1134 1134
 			 * Delete all user shares that are owned by this user
1135 1135
 			 * or that are received by this user
1136 1136
 			 */
1137 1137
 
1138
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)));
1138
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)));
1139 1139
 
1140
-			$qb->andWhere(
1141
-				$qb->expr()->orX(
1142
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1143
-					$qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1144
-				)
1145
-			);
1146
-		} elseif ($shareType === IShare::TYPE_GROUP) {
1147
-			/*
1140
+            $qb->andWhere(
1141
+                $qb->expr()->orX(
1142
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1143
+                    $qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1144
+                )
1145
+            );
1146
+        } elseif ($shareType === IShare::TYPE_GROUP) {
1147
+            /*
1148 1148
 			 * Delete all group shares that are owned by this user
1149 1149
 			 * Or special user group shares that are received by this user
1150 1150
 			 */
1151
-			$qb->where(
1152
-				$qb->expr()->andX(
1153
-					$qb->expr()->orX(
1154
-						$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)),
1155
-						$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP))
1156
-					),
1157
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))
1158
-				)
1159
-			);
1160
-
1161
-			$qb->orWhere(
1162
-				$qb->expr()->andX(
1163
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)),
1164
-					$qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1165
-				)
1166
-			);
1167
-		} elseif ($shareType === IShare::TYPE_LINK) {
1168
-			/*
1151
+            $qb->where(
1152
+                $qb->expr()->andX(
1153
+                    $qb->expr()->orX(
1154
+                        $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)),
1155
+                        $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP))
1156
+                    ),
1157
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))
1158
+                )
1159
+            );
1160
+
1161
+            $qb->orWhere(
1162
+                $qb->expr()->andX(
1163
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)),
1164
+                    $qb->expr()->eq('share_with', $qb->createNamedParameter($uid))
1165
+                )
1166
+            );
1167
+        } elseif ($shareType === IShare::TYPE_LINK) {
1168
+            /*
1169 1169
 			 * Delete all link shares owned by this user.
1170 1170
 			 * And all link shares initiated by this user (until #22327 is in)
1171 1171
 			 */
1172
-			$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK)));
1173
-
1174
-			$qb->andWhere(
1175
-				$qb->expr()->orX(
1176
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1177
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($uid))
1178
-				)
1179
-			);
1180
-		} else {
1181
-			\OC::$server->getLogger()->logException(new \InvalidArgumentException('Default share provider tried to delete all shares for type: ' . $shareType));
1182
-			return;
1183
-		}
1184
-
1185
-		$qb->execute();
1186
-	}
1187
-
1188
-	/**
1189
-	 * Delete all shares received by this group. As well as any custom group
1190
-	 * shares for group members.
1191
-	 *
1192
-	 * @param string $gid
1193
-	 */
1194
-	public function groupDeleted($gid) {
1195
-		/*
1172
+            $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK)));
1173
+
1174
+            $qb->andWhere(
1175
+                $qb->expr()->orX(
1176
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)),
1177
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($uid))
1178
+                )
1179
+            );
1180
+        } else {
1181
+            \OC::$server->getLogger()->logException(new \InvalidArgumentException('Default share provider tried to delete all shares for type: ' . $shareType));
1182
+            return;
1183
+        }
1184
+
1185
+        $qb->execute();
1186
+    }
1187
+
1188
+    /**
1189
+     * Delete all shares received by this group. As well as any custom group
1190
+     * shares for group members.
1191
+     *
1192
+     * @param string $gid
1193
+     */
1194
+    public function groupDeleted($gid) {
1195
+        /*
1196 1196
 		 * First delete all custom group shares for group members
1197 1197
 		 */
1198
-		$qb = $this->dbConn->getQueryBuilder();
1199
-		$qb->select('id')
1200
-			->from('share')
1201
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
1202
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1203
-
1204
-		$cursor = $qb->execute();
1205
-		$ids = [];
1206
-		while ($row = $cursor->fetch()) {
1207
-			$ids[] = (int)$row['id'];
1208
-		}
1209
-		$cursor->closeCursor();
1210
-
1211
-		if (!empty($ids)) {
1212
-			$chunks = array_chunk($ids, 100);
1213
-			foreach ($chunks as $chunk) {
1214
-				$qb->delete('share')
1215
-					->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
1216
-					->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1217
-				$qb->execute();
1218
-			}
1219
-		}
1220
-
1221
-		/*
1198
+        $qb = $this->dbConn->getQueryBuilder();
1199
+        $qb->select('id')
1200
+            ->from('share')
1201
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
1202
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1203
+
1204
+        $cursor = $qb->execute();
1205
+        $ids = [];
1206
+        while ($row = $cursor->fetch()) {
1207
+            $ids[] = (int)$row['id'];
1208
+        }
1209
+        $cursor->closeCursor();
1210
+
1211
+        if (!empty($ids)) {
1212
+            $chunks = array_chunk($ids, 100);
1213
+            foreach ($chunks as $chunk) {
1214
+                $qb->delete('share')
1215
+                    ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
1216
+                    ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1217
+                $qb->execute();
1218
+            }
1219
+        }
1220
+
1221
+        /*
1222 1222
 		 * Now delete all the group shares
1223 1223
 		 */
1224
-		$qb = $this->dbConn->getQueryBuilder();
1225
-		$qb->delete('share')
1226
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
1227
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1228
-		$qb->execute();
1229
-	}
1230
-
1231
-	/**
1232
-	 * Delete custom group shares to this group for this user
1233
-	 *
1234
-	 * @param string $uid
1235
-	 * @param string $gid
1236
-	 */
1237
-	public function userDeletedFromGroup($uid, $gid) {
1238
-		/*
1224
+        $qb = $this->dbConn->getQueryBuilder();
1225
+        $qb->delete('share')
1226
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
1227
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1228
+        $qb->execute();
1229
+    }
1230
+
1231
+    /**
1232
+     * Delete custom group shares to this group for this user
1233
+     *
1234
+     * @param string $uid
1235
+     * @param string $gid
1236
+     */
1237
+    public function userDeletedFromGroup($uid, $gid) {
1238
+        /*
1239 1239
 		 * Get all group shares
1240 1240
 		 */
1241
-		$qb = $this->dbConn->getQueryBuilder();
1242
-		$qb->select('id')
1243
-			->from('share')
1244
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
1245
-			->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1246
-
1247
-		$cursor = $qb->execute();
1248
-		$ids = [];
1249
-		while ($row = $cursor->fetch()) {
1250
-			$ids[] = (int)$row['id'];
1251
-		}
1252
-		$cursor->closeCursor();
1253
-
1254
-		if (!empty($ids)) {
1255
-			$chunks = array_chunk($ids, 100);
1256
-			foreach ($chunks as $chunk) {
1257
-				/*
1241
+        $qb = $this->dbConn->getQueryBuilder();
1242
+        $qb->select('id')
1243
+            ->from('share')
1244
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)))
1245
+            ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($gid)));
1246
+
1247
+        $cursor = $qb->execute();
1248
+        $ids = [];
1249
+        while ($row = $cursor->fetch()) {
1250
+            $ids[] = (int)$row['id'];
1251
+        }
1252
+        $cursor->closeCursor();
1253
+
1254
+        if (!empty($ids)) {
1255
+            $chunks = array_chunk($ids, 100);
1256
+            foreach ($chunks as $chunk) {
1257
+                /*
1258 1258
 				 * Delete all special shares wit this users for the found group shares
1259 1259
 				 */
1260
-				$qb->delete('share')
1261
-					->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
1262
-					->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($uid)))
1263
-					->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1264
-				$qb->execute();
1265
-			}
1266
-		}
1267
-	}
1268
-
1269
-	/**
1270
-	 * @inheritdoc
1271
-	 */
1272
-	public function getAccessList($nodes, $currentAccess) {
1273
-		$ids = [];
1274
-		foreach ($nodes as $node) {
1275
-			$ids[] = $node->getId();
1276
-		}
1277
-
1278
-		$qb = $this->dbConn->getQueryBuilder();
1279
-
1280
-		$or = $qb->expr()->orX(
1281
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)),
1282
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)),
1283
-			$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK))
1284
-		);
1285
-
1286
-		if ($currentAccess) {
1287
-			$or->add($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)));
1288
-		}
1289
-
1290
-		$qb->select('id', 'parent', 'share_type', 'share_with', 'file_source', 'file_target', 'permissions')
1291
-			->from('share')
1292
-			->where(
1293
-				$or
1294
-			)
1295
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1296
-			->andWhere($qb->expr()->orX(
1297
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1298
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1299
-			));
1300
-		$cursor = $qb->execute();
1301
-
1302
-		$users = [];
1303
-		$link = false;
1304
-		while ($row = $cursor->fetch()) {
1305
-			$type = (int)$row['share_type'];
1306
-			if ($type === IShare::TYPE_USER) {
1307
-				$uid = $row['share_with'];
1308
-				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1309
-				$users[$uid][$row['id']] = $row;
1310
-			} elseif ($type === IShare::TYPE_GROUP) {
1311
-				$gid = $row['share_with'];
1312
-				$group = $this->groupManager->get($gid);
1313
-
1314
-				if ($group === null) {
1315
-					continue;
1316
-				}
1317
-
1318
-				$userList = $group->getUsers();
1319
-				foreach ($userList as $user) {
1320
-					$uid = $user->getUID();
1321
-					$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1322
-					$users[$uid][$row['id']] = $row;
1323
-				}
1324
-			} elseif ($type === IShare::TYPE_LINK) {
1325
-				$link = true;
1326
-			} elseif ($type === IShare::TYPE_USERGROUP && $currentAccess === true) {
1327
-				$uid = $row['share_with'];
1328
-				$users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1329
-				$users[$uid][$row['id']] = $row;
1330
-			}
1331
-		}
1332
-		$cursor->closeCursor();
1333
-
1334
-		if ($currentAccess === true) {
1335
-			$users = array_map([$this, 'filterSharesOfUser'], $users);
1336
-			$users = array_filter($users);
1337
-		} else {
1338
-			$users = array_keys($users);
1339
-		}
1340
-
1341
-		return ['users' => $users, 'public' => $link];
1342
-	}
1343
-
1344
-	/**
1345
-	 * For each user the path with the fewest slashes is returned
1346
-	 * @param array $shares
1347
-	 * @return array
1348
-	 */
1349
-	protected function filterSharesOfUser(array $shares) {
1350
-		// Group shares when the user has a share exception
1351
-		foreach ($shares as $id => $share) {
1352
-			$type = (int) $share['share_type'];
1353
-			$permissions = (int) $share['permissions'];
1354
-
1355
-			if ($type === IShare::TYPE_USERGROUP) {
1356
-				unset($shares[$share['parent']]);
1357
-
1358
-				if ($permissions === 0) {
1359
-					unset($shares[$id]);
1360
-				}
1361
-			}
1362
-		}
1363
-
1364
-		$best = [];
1365
-		$bestDepth = 0;
1366
-		foreach ($shares as $id => $share) {
1367
-			$depth = substr_count($share['file_target'], '/');
1368
-			if (empty($best) || $depth < $bestDepth) {
1369
-				$bestDepth = $depth;
1370
-				$best = [
1371
-					'node_id' => $share['file_source'],
1372
-					'node_path' => $share['file_target'],
1373
-				];
1374
-			}
1375
-		}
1376
-
1377
-		return $best;
1378
-	}
1379
-
1380
-	/**
1381
-	 * propagate notes to the recipients
1382
-	 *
1383
-	 * @param IShare $share
1384
-	 * @throws \OCP\Files\NotFoundException
1385
-	 */
1386
-	private function propagateNote(IShare $share) {
1387
-		if ($share->getShareType() === IShare::TYPE_USER) {
1388
-			$user = $this->userManager->get($share->getSharedWith());
1389
-			$this->sendNote([$user], $share);
1390
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
1391
-			$group = $this->groupManager->get($share->getSharedWith());
1392
-			$groupMembers = $group->getUsers();
1393
-			$this->sendNote($groupMembers, $share);
1394
-		}
1395
-	}
1396
-
1397
-	/**
1398
-	 * send note by mail
1399
-	 *
1400
-	 * @param array $recipients
1401
-	 * @param IShare $share
1402
-	 * @throws \OCP\Files\NotFoundException
1403
-	 */
1404
-	private function sendNote(array $recipients, IShare $share) {
1405
-		$toListByLanguage = [];
1406
-
1407
-		foreach ($recipients as $recipient) {
1408
-			/** @var IUser $recipient */
1409
-			$email = $recipient->getEMailAddress();
1410
-			if ($email) {
1411
-				$language = $this->l10nFactory->getUserLanguage($recipient);
1412
-				if (!isset($toListByLanguage[$language])) {
1413
-					$toListByLanguage[$language] = [];
1414
-				}
1415
-				$toListByLanguage[$language][$email] = $recipient->getDisplayName();
1416
-			}
1417
-		}
1418
-
1419
-		if (empty($toListByLanguage)) {
1420
-			return;
1421
-		}
1422
-
1423
-		foreach ($toListByLanguage as $l10n => $toList) {
1424
-			$filename = $share->getNode()->getName();
1425
-			$initiator = $share->getSharedBy();
1426
-			$note = $share->getNote();
1427
-
1428
-			$l = $this->l10nFactory->get('lib', $l10n);
1429
-
1430
-			$initiatorUser = $this->userManager->get($initiator);
1431
-			$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
1432
-			$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
1433
-			$plainHeading = $l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
1434
-			$htmlHeading = $l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
1435
-			$message = $this->mailer->createMessage();
1436
-
1437
-			$emailTemplate = $this->mailer->createEMailTemplate('defaultShareProvider.sendNote');
1438
-
1439
-			$emailTemplate->setSubject($l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
1440
-			$emailTemplate->addHeader();
1441
-			$emailTemplate->addHeading($htmlHeading, $plainHeading);
1442
-			$emailTemplate->addBodyText(htmlspecialchars($note), $note);
1443
-
1444
-			$link = $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]);
1445
-			$emailTemplate->addBodyButton(
1446
-				$l->t('Open »%s«', [$filename]),
1447
-				$link
1448
-			);
1449
-
1450
-
1451
-			// The "From" contains the sharers name
1452
-			$instanceName = $this->defaults->getName();
1453
-			$senderName = $l->t(
1454
-				'%1$s via %2$s',
1455
-				[
1456
-					$initiatorDisplayName,
1457
-					$instanceName
1458
-				]
1459
-			);
1460
-			$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
1461
-			if ($initiatorEmailAddress !== null) {
1462
-				$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
1463
-				$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
1464
-			} else {
1465
-				$emailTemplate->addFooter();
1466
-			}
1467
-
1468
-			if (count($toList) === 1) {
1469
-				$message->setTo($toList);
1470
-			} else {
1471
-				$message->setTo([]);
1472
-				$message->setBcc($toList);
1473
-			}
1474
-			$message->useTemplate($emailTemplate);
1475
-			$this->mailer->send($message);
1476
-		}
1477
-	}
1478
-
1479
-	public function getAllShares(): iterable {
1480
-		$qb = $this->dbConn->getQueryBuilder();
1481
-
1482
-		$qb->select('*')
1483
-			->from('share')
1484
-			->where(
1485
-				$qb->expr()->orX(
1486
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_USER)),
1487
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_GROUP)),
1488
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_LINK))
1489
-				)
1490
-			);
1491
-
1492
-		$cursor = $qb->execute();
1493
-		while ($data = $cursor->fetch()) {
1494
-			try {
1495
-				$share = $this->createShare($data);
1496
-			} catch (InvalidShare $e) {
1497
-				continue;
1498
-			}
1499
-
1500
-			yield $share;
1501
-		}
1502
-		$cursor->closeCursor();
1503
-	}
1260
+                $qb->delete('share')
1261
+                    ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)))
1262
+                    ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($uid)))
1263
+                    ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
1264
+                $qb->execute();
1265
+            }
1266
+        }
1267
+    }
1268
+
1269
+    /**
1270
+     * @inheritdoc
1271
+     */
1272
+    public function getAccessList($nodes, $currentAccess) {
1273
+        $ids = [];
1274
+        foreach ($nodes as $node) {
1275
+            $ids[] = $node->getId();
1276
+        }
1277
+
1278
+        $qb = $this->dbConn->getQueryBuilder();
1279
+
1280
+        $or = $qb->expr()->orX(
1281
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)),
1282
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_GROUP)),
1283
+            $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_LINK))
1284
+        );
1285
+
1286
+        if ($currentAccess) {
1287
+            $or->add($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)));
1288
+        }
1289
+
1290
+        $qb->select('id', 'parent', 'share_type', 'share_with', 'file_source', 'file_target', 'permissions')
1291
+            ->from('share')
1292
+            ->where(
1293
+                $or
1294
+            )
1295
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1296
+            ->andWhere($qb->expr()->orX(
1297
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1298
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1299
+            ));
1300
+        $cursor = $qb->execute();
1301
+
1302
+        $users = [];
1303
+        $link = false;
1304
+        while ($row = $cursor->fetch()) {
1305
+            $type = (int)$row['share_type'];
1306
+            if ($type === IShare::TYPE_USER) {
1307
+                $uid = $row['share_with'];
1308
+                $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1309
+                $users[$uid][$row['id']] = $row;
1310
+            } elseif ($type === IShare::TYPE_GROUP) {
1311
+                $gid = $row['share_with'];
1312
+                $group = $this->groupManager->get($gid);
1313
+
1314
+                if ($group === null) {
1315
+                    continue;
1316
+                }
1317
+
1318
+                $userList = $group->getUsers();
1319
+                foreach ($userList as $user) {
1320
+                    $uid = $user->getUID();
1321
+                    $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1322
+                    $users[$uid][$row['id']] = $row;
1323
+                }
1324
+            } elseif ($type === IShare::TYPE_LINK) {
1325
+                $link = true;
1326
+            } elseif ($type === IShare::TYPE_USERGROUP && $currentAccess === true) {
1327
+                $uid = $row['share_with'];
1328
+                $users[$uid] = isset($users[$uid]) ? $users[$uid] : [];
1329
+                $users[$uid][$row['id']] = $row;
1330
+            }
1331
+        }
1332
+        $cursor->closeCursor();
1333
+
1334
+        if ($currentAccess === true) {
1335
+            $users = array_map([$this, 'filterSharesOfUser'], $users);
1336
+            $users = array_filter($users);
1337
+        } else {
1338
+            $users = array_keys($users);
1339
+        }
1340
+
1341
+        return ['users' => $users, 'public' => $link];
1342
+    }
1343
+
1344
+    /**
1345
+     * For each user the path with the fewest slashes is returned
1346
+     * @param array $shares
1347
+     * @return array
1348
+     */
1349
+    protected function filterSharesOfUser(array $shares) {
1350
+        // Group shares when the user has a share exception
1351
+        foreach ($shares as $id => $share) {
1352
+            $type = (int) $share['share_type'];
1353
+            $permissions = (int) $share['permissions'];
1354
+
1355
+            if ($type === IShare::TYPE_USERGROUP) {
1356
+                unset($shares[$share['parent']]);
1357
+
1358
+                if ($permissions === 0) {
1359
+                    unset($shares[$id]);
1360
+                }
1361
+            }
1362
+        }
1363
+
1364
+        $best = [];
1365
+        $bestDepth = 0;
1366
+        foreach ($shares as $id => $share) {
1367
+            $depth = substr_count($share['file_target'], '/');
1368
+            if (empty($best) || $depth < $bestDepth) {
1369
+                $bestDepth = $depth;
1370
+                $best = [
1371
+                    'node_id' => $share['file_source'],
1372
+                    'node_path' => $share['file_target'],
1373
+                ];
1374
+            }
1375
+        }
1376
+
1377
+        return $best;
1378
+    }
1379
+
1380
+    /**
1381
+     * propagate notes to the recipients
1382
+     *
1383
+     * @param IShare $share
1384
+     * @throws \OCP\Files\NotFoundException
1385
+     */
1386
+    private function propagateNote(IShare $share) {
1387
+        if ($share->getShareType() === IShare::TYPE_USER) {
1388
+            $user = $this->userManager->get($share->getSharedWith());
1389
+            $this->sendNote([$user], $share);
1390
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
1391
+            $group = $this->groupManager->get($share->getSharedWith());
1392
+            $groupMembers = $group->getUsers();
1393
+            $this->sendNote($groupMembers, $share);
1394
+        }
1395
+    }
1396
+
1397
+    /**
1398
+     * send note by mail
1399
+     *
1400
+     * @param array $recipients
1401
+     * @param IShare $share
1402
+     * @throws \OCP\Files\NotFoundException
1403
+     */
1404
+    private function sendNote(array $recipients, IShare $share) {
1405
+        $toListByLanguage = [];
1406
+
1407
+        foreach ($recipients as $recipient) {
1408
+            /** @var IUser $recipient */
1409
+            $email = $recipient->getEMailAddress();
1410
+            if ($email) {
1411
+                $language = $this->l10nFactory->getUserLanguage($recipient);
1412
+                if (!isset($toListByLanguage[$language])) {
1413
+                    $toListByLanguage[$language] = [];
1414
+                }
1415
+                $toListByLanguage[$language][$email] = $recipient->getDisplayName();
1416
+            }
1417
+        }
1418
+
1419
+        if (empty($toListByLanguage)) {
1420
+            return;
1421
+        }
1422
+
1423
+        foreach ($toListByLanguage as $l10n => $toList) {
1424
+            $filename = $share->getNode()->getName();
1425
+            $initiator = $share->getSharedBy();
1426
+            $note = $share->getNote();
1427
+
1428
+            $l = $this->l10nFactory->get('lib', $l10n);
1429
+
1430
+            $initiatorUser = $this->userManager->get($initiator);
1431
+            $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
1432
+            $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
1433
+            $plainHeading = $l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
1434
+            $htmlHeading = $l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
1435
+            $message = $this->mailer->createMessage();
1436
+
1437
+            $emailTemplate = $this->mailer->createEMailTemplate('defaultShareProvider.sendNote');
1438
+
1439
+            $emailTemplate->setSubject($l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
1440
+            $emailTemplate->addHeader();
1441
+            $emailTemplate->addHeading($htmlHeading, $plainHeading);
1442
+            $emailTemplate->addBodyText(htmlspecialchars($note), $note);
1443
+
1444
+            $link = $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]);
1445
+            $emailTemplate->addBodyButton(
1446
+                $l->t('Open »%s«', [$filename]),
1447
+                $link
1448
+            );
1449
+
1450
+
1451
+            // The "From" contains the sharers name
1452
+            $instanceName = $this->defaults->getName();
1453
+            $senderName = $l->t(
1454
+                '%1$s via %2$s',
1455
+                [
1456
+                    $initiatorDisplayName,
1457
+                    $instanceName
1458
+                ]
1459
+            );
1460
+            $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
1461
+            if ($initiatorEmailAddress !== null) {
1462
+                $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
1463
+                $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
1464
+            } else {
1465
+                $emailTemplate->addFooter();
1466
+            }
1467
+
1468
+            if (count($toList) === 1) {
1469
+                $message->setTo($toList);
1470
+            } else {
1471
+                $message->setTo([]);
1472
+                $message->setBcc($toList);
1473
+            }
1474
+            $message->useTemplate($emailTemplate);
1475
+            $this->mailer->send($message);
1476
+        }
1477
+    }
1478
+
1479
+    public function getAllShares(): iterable {
1480
+        $qb = $this->dbConn->getQueryBuilder();
1481
+
1482
+        $qb->select('*')
1483
+            ->from('share')
1484
+            ->where(
1485
+                $qb->expr()->orX(
1486
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_USER)),
1487
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_GROUP)),
1488
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_LINK))
1489
+                )
1490
+            );
1491
+
1492
+        $cursor = $qb->execute();
1493
+        while ($data = $cursor->fetch()) {
1494
+            try {
1495
+                $share = $this->createShare($data);
1496
+            } catch (InvalidShare $e) {
1497
+                continue;
1498
+            }
1499
+
1500
+            yield $share;
1501
+        }
1502
+        $cursor->closeCursor();
1503
+    }
1504 1504
 }
Please login to merge, or discard this patch.