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