Passed
Push — master ( f72674...fb5eeb )
by Roeland
11:55
created
lib/private/Collaboration/Resources/Manager.php 2 patches
Indentation   +489 added lines, -489 removed lines patch added patch discarded remove patch
@@ -38,493 +38,493 @@
 block discarded – undo
38 38
 
39 39
 class Manager implements IManager {
40 40
 
41
-	public const TABLE_COLLECTIONS = 'collres_collections';
42
-	public const TABLE_RESOURCES = 'collres_resources';
43
-	public const TABLE_ACCESS_CACHE = 'collres_accesscache';
44
-
45
-	/** @var IDBConnection */
46
-	protected $connection;
47
-	/** @var ILogger */
48
-	protected $logger;
49
-
50
-	/** @var string[] */
51
-	protected $providers = [];
52
-
53
-	/** @var IProvider[] */
54
-	protected $providerInstances = [];
55
-
56
-	public function __construct(IDBConnection $connection, ILogger $logger) {
57
-		$this->connection = $connection;
58
-		$this->logger = $logger;
59
-	}
60
-
61
-	/**
62
-	 * @param int $id
63
-	 * @return ICollection
64
-	 * @throws CollectionException when the collection could not be found
65
-	 * @since 16.0.0
66
-	 */
67
-	public function getCollection(int $id): ICollection {
68
-		$query = $this->connection->getQueryBuilder();
69
-		$query->select('*')
70
-			->from(self::TABLE_COLLECTIONS)
71
-			->where($query->expr()->eq('id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
72
-		$result = $query->execute();
73
-		$row = $result->fetch();
74
-		$result->closeCursor();
75
-
76
-		if (!$row) {
77
-			throw new CollectionException('Collection not found');
78
-		}
79
-
80
-		return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name']);
81
-	}
82
-
83
-	/**
84
-	 * @param int $id
85
-	 * @param IUser|null $user
86
-	 * @return ICollection
87
-	 * @throws CollectionException when the collection could not be found
88
-	 * @since 16.0.0
89
-	 */
90
-	public function getCollectionForUser(int $id, ?IUser $user): ICollection {
91
-		$query = $this->connection->getQueryBuilder();
92
-		$userId = $user instanceof IUser ? $user->getUID() : '';
93
-
94
-		$query->select('*')
95
-			->from(self::TABLE_COLLECTIONS, 'c')
96
-			->leftJoin(
97
-				'c', self::TABLE_ACCESS_CACHE, 'a',
98
-				$query->expr()->andX(
99
-					$query->expr()->eq('c.id', 'a.collection_id'),
100
-					$query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
101
-				)
102
-			)
103
-			->where($query->expr()->eq('c.id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
104
-		$result = $query->execute();
105
-		$row = $result->fetch();
106
-		$result->closeCursor();
107
-
108
-		if (!$row) {
109
-			throw new CollectionException('Collection not found');
110
-		}
111
-
112
-		$access = $row['access'] === null ? null : (bool) $row['access'];
113
-		if ($user instanceof IUser) {
114
-			return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name'], $user, $access);
115
-		}
116
-
117
-		return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name'], $user, $access);
118
-	}
119
-
120
-	/**
121
-	 * @param IUser $user
122
-	 * @param string $filter
123
-	 * @param int $limit
124
-	 * @param int $start
125
-	 * @return ICollection[]
126
-	 * @since 16.0.0
127
-	 */
128
-	public function searchCollections(IUser $user, string $filter, int $limit = 50, int $start = 0): array {
129
-		$query = $this->connection->getQueryBuilder();
130
-		$userId = $user instanceof IUser ? $user->getUID() : '';
131
-
132
-		$query->select('c.*', 'a.access')
133
-			->from(self::TABLE_COLLECTIONS, 'c')
134
-			->leftJoin(
135
-				'c', self::TABLE_ACCESS_CACHE, 'a',
136
-				$query->expr()->andX(
137
-					$query->expr()->eq('c.id', 'a.collection_id'),
138
-					$query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
139
-				)
140
-			)
141
-			->where($query->expr()->eq('a.access', $query->createNamedParameter(1, IQueryBuilder::PARAM_INT)))
142
-			->orderBy('c.id')
143
-			->setMaxResults($limit)
144
-			->setFirstResult($start);
145
-
146
-		if ($filter !== '') {
147
-			$query->where($query->expr()->iLike('c.name', $query->createNamedParameter('%' . $this->connection->escapeLikeParameter($filter) . '%')));
148
-		}
149
-
150
-		$result = $query->execute();
151
-		$collections = [];
152
-
153
-		$foundResults = 0;
154
-		while ($row = $result->fetch()) {
155
-			$foundResults++;
156
-			$access = $row['access'] === null ? null : (bool) $row['access'];
157
-			$collection = new Collection($this, $this->connection, (int)$row['id'], (string)$row['name'], $user, $access);
158
-			if ($collection->canAccess($user)) {
159
-				$collections[] = $collection;
160
-			}
161
-		}
162
-		$result->closeCursor();
163
-
164
-		if (empty($collections) && $foundResults === $limit) {
165
-			return $this->searchCollections($user, $filter, $limit, $start + $limit);
166
-		}
167
-
168
-		return $collections;
169
-	}
170
-
171
-	/**
172
-	 * @param string $name
173
-	 * @return ICollection
174
-	 * @since 16.0.0
175
-	 */
176
-	public function newCollection(string $name): ICollection {
177
-		$query = $this->connection->getQueryBuilder();
178
-		$query->insert(self::TABLE_COLLECTIONS)
179
-			->values([
180
-				'name' => $query->createNamedParameter($name),
181
-			]);
182
-		$query->execute();
183
-
184
-		return new Collection($this, $this->connection, $query->getLastInsertId(), $name);
185
-	}
186
-
187
-	/**
188
-	 * @param string $type
189
-	 * @param string $id
190
-	 * @return IResource
191
-	 * @since 16.0.0
192
-	 */
193
-	public function createResource(string $type, string $id): IResource {
194
-		return new Resource($this, $this->connection, $type, $id);
195
-	}
196
-
197
-	/**
198
-	 * @param string $type
199
-	 * @param string $id
200
-	 * @param IUser|null $user
201
-	 * @return IResource
202
-	 * @throws ResourceException
203
-	 * @since 16.0.0
204
-	 */
205
-	public function getResourceForUser(string $type, string $id, ?IUser $user): IResource {
206
-		$query = $this->connection->getQueryBuilder();
207
-		$userId = $user instanceof IUser ? $user->getUID() : '';
208
-
209
-		$query->select('r.*', 'a.access')
210
-			->from(self::TABLE_RESOURCES, 'r')
211
-			->leftJoin(
212
-				'r', self::TABLE_ACCESS_CACHE, 'a',
213
-				$query->expr()->andX(
214
-					$query->expr()->eq('r.resource_id', 'a.resource_id'),
215
-					$query->expr()->eq('r.resource_type', 'a.resource_type'),
216
-					$query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
217
-				)
218
-			)
219
-			->where($query->expr()->eq('r.resource_type', $query->createNamedParameter($type, IQueryBuilder::PARAM_STR)))
220
-			->andWhere($query->expr()->eq('r.resource_id', $query->createNamedParameter($id, IQueryBuilder::PARAM_STR)));
221
-		$result = $query->execute();
222
-		$row = $result->fetch();
223
-		$result->closeCursor();
224
-
225
-		if (!$row) {
226
-			throw new ResourceException('Resource not found');
227
-		}
228
-
229
-		$access = $row['access'] === null ? null : (bool) $row['access'];
230
-		if ($user instanceof IUser) {
231
-			return new Resource($this, $this->connection, $type, $id, $user, $access);
232
-		}
233
-
234
-		return new Resource($this, $this->connection, $type, $id, null, $access);
235
-	}
236
-
237
-	/**
238
-	 * @param ICollection $collection
239
-	 * @param IUser|null $user
240
-	 * @return IResource[]
241
-	 * @since 16.0.0
242
-	 */
243
-	public function getResourcesByCollectionForUser(ICollection $collection, ?IUser $user): array {
244
-		$query = $this->connection->getQueryBuilder();
245
-		$userId = $user instanceof IUser ? $user->getUID() : '';
246
-
247
-		$query->select('r.*', 'a.access')
248
-			->from(self::TABLE_RESOURCES, 'r')
249
-			->leftJoin(
250
-				'r', self::TABLE_ACCESS_CACHE, 'a',
251
-				$query->expr()->andX(
252
-					$query->expr()->eq('r.resource_id', 'a.resource_id'),
253
-					$query->expr()->eq('r.resource_type', 'a.resource_type'),
254
-					$query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
255
-				)
256
-			)
257
-			->where($query->expr()->eq('r.collection_id', $query->createNamedParameter($collection->getId(), IQueryBuilder::PARAM_INT)));
258
-
259
-		$resources = [];
260
-		$result = $query->execute();
261
-		while ($row = $result->fetch()) {
262
-			$access = $row['access'] === null ? null : (bool) $row['access'];
263
-			$resources[] = new Resource($this, $this->connection, $row['resource_type'], $row['resource_id'], $user, $access);
264
-		}
265
-		$result->closeCursor();
266
-
267
-		return $resources;
268
-	}
269
-
270
-	/**
271
-	 * @return IProvider[]
272
-	 * @since 16.0.0
273
-	 */
274
-	public function getProviders(): array {
275
-		if (!empty($this->providers)) {
276
-			foreach ($this->providers as $provider) {
277
-				try {
278
-					$this->providerInstances[] = \OC::$server->query($provider);
279
-				} catch (QueryException $e) {
280
-					$this->logger->logException($e, [
281
-						'message' => 'Error when instantiating resource provider'
282
-					]);
283
-				}
284
-			}
285
-			$this->providers = [];
286
-		}
287
-
288
-		return $this->providerInstances;
289
-	}
290
-
291
-	/**
292
-	 * Get the rich object data of a resource
293
-	 *
294
-	 * @param IResource $resource
295
-	 * @return array
296
-	 * @since 16.0.0
297
-	 */
298
-	public function getResourceRichObject(IResource $resource): array {
299
-		foreach ($this->getProviders() as $provider) {
300
-			if ($provider->getType() === $resource->getType()) {
301
-				try {
302
-					return $provider->getResourceRichObject($resource);
303
-				} catch (ResourceException $e) {
304
-				}
305
-			}
306
-		}
307
-
308
-		return [];
309
-	}
310
-
311
-	/**
312
-	 * Can a user/guest access the collection
313
-	 *
314
-	 * @param IResource $resource
315
-	 * @param IUser|null $user
316
-	 * @return bool
317
-	 * @since 16.0.0
318
-	 */
319
-	public function canAccessResource(IResource $resource, ?IUser $user): bool {
320
-		$access = $this->checkAccessCacheForUserByResource($resource, $user);
321
-		if (\is_bool($access)) {
322
-			return $access;
323
-		}
324
-
325
-		$access = false;
326
-		foreach ($this->getProviders() as $provider) {
327
-			if ($provider->getType() === $resource->getType()) {
328
-				try {
329
-					if ($provider->canAccessResource($resource, $user)) {
330
-						$access = true;
331
-						break;
332
-					}
333
-				} catch (ResourceException $e) {
334
-				}
335
-			}
336
-		}
337
-
338
-		$this->cacheAccessForResource($resource, $user, $access);
339
-		return $access;
340
-	}
341
-
342
-	/**
343
-	 * Can a user/guest access the collection
344
-	 *
345
-	 * @param ICollection $collection
346
-	 * @param IUser|null $user
347
-	 * @return bool
348
-	 * @since 16.0.0
349
-	 */
350
-	public function canAccessCollection(ICollection $collection, ?IUser $user): bool {
351
-		$access = $this->checkAccessCacheForUserByCollection($collection, $user);
352
-		if (\is_bool($access)) {
353
-			return $access;
354
-		}
355
-
356
-		$access = false;
357
-		foreach ($collection->getResources() as $resource) {
358
-			if ($resource->canAccess($user)) {
359
-				$access = true;
360
-				break;
361
-			}
362
-		}
363
-
364
-		$this->cacheAccessForCollection($collection, $user, $access);
365
-		return $access;
366
-	}
367
-
368
-	protected function checkAccessCacheForUserByResource(IResource $resource, ?IUser $user): ?bool {
369
-		$query = $this->connection->getQueryBuilder();
370
-		$userId = $user instanceof IUser ? $user->getUID() : '';
371
-
372
-		$query->select('access')
373
-			->from(self::TABLE_ACCESS_CACHE)
374
-			->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId(), IQueryBuilder::PARAM_STR)))
375
-			->andWhere($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType(), IQueryBuilder::PARAM_STR)))
376
-			->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
377
-			->setMaxResults(1);
378
-
379
-		$hasAccess = null;
380
-		$result = $query->execute();
381
-		if ($row = $result->fetch()) {
382
-			$hasAccess = (bool) $row['access'];
383
-		}
384
-		$result->closeCursor();
385
-
386
-		return $hasAccess;
387
-	}
388
-
389
-	protected function checkAccessCacheForUserByCollection(ICollection $collection, ?IUser $user): ?bool {
390
-		$query = $this->connection->getQueryBuilder();
391
-		$userId = $user instanceof IUser ? $user->getUID() : '';
392
-
393
-		$query->select('access')
394
-			->from(self::TABLE_ACCESS_CACHE)
395
-			->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId(), IQueryBuilder::PARAM_INT)))
396
-			->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
397
-			->setMaxResults(1);
398
-
399
-		$hasAccess = null;
400
-		$result = $query->execute();
401
-		if ($row = $result->fetch()) {
402
-			$hasAccess = (bool) $row['access'];
403
-		}
404
-		$result->closeCursor();
405
-
406
-		return $hasAccess;
407
-	}
408
-
409
-	public function cacheAccessForResource(IResource $resource, ?IUser $user, bool $access): void {
410
-		$query = $this->connection->getQueryBuilder();
411
-		$userId = $user instanceof IUser ? $user->getUID() : '';
412
-
413
-		$query->insert(self::TABLE_ACCESS_CACHE)
414
-			->values([
415
-				'user_id' => $query->createNamedParameter($userId),
416
-				'resource_id' => $query->createNamedParameter($resource->getId()),
417
-				'resource_type' => $query->createNamedParameter($resource->getType()),
418
-				'access' => $query->createNamedParameter($access, IQueryBuilder::PARAM_BOOL),
419
-			]);
420
-		try {
421
-			$query->execute();
422
-		} catch (UniqueConstraintViolationException $e) {
423
-		}
424
-	}
425
-
426
-	public function cacheAccessForCollection(ICollection $collection, ?IUser $user, bool $access): void {
427
-		$query = $this->connection->getQueryBuilder();
428
-		$userId = $user instanceof IUser ? $user->getUID() : '';
429
-
430
-		$query->insert(self::TABLE_ACCESS_CACHE)
431
-			->values([
432
-				'user_id' => $query->createNamedParameter($userId),
433
-				'collection_id' => $query->createNamedParameter($collection->getId()),
434
-				'access' => $query->createNamedParameter($access),
435
-			]);
436
-		try {
437
-			$query->execute();
438
-		} catch (UniqueConstraintViolationException $e) {
439
-		}
440
-	}
441
-
442
-	public function invalidateAccessCacheForUser(?IUser $user): void {
443
-		$query = $this->connection->getQueryBuilder();
444
-		$userId = $user instanceof IUser ? $user->getUID() : '';
445
-
446
-		$query->delete(self::TABLE_ACCESS_CACHE)
447
-			->where($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
448
-		$query->execute();
449
-	}
450
-
451
-	public function invalidateAccessCacheForResource(IResource $resource): void {
452
-		$query = $this->connection->getQueryBuilder();
453
-
454
-		$query->delete(self::TABLE_ACCESS_CACHE)
455
-			->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId())))
456
-			->andWhere($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType(), IQueryBuilder::PARAM_STR)));
457
-		$query->execute();
458
-
459
-		foreach ($resource->getCollections() as $collection) {
460
-			$this->invalidateAccessCacheForCollection($collection);
461
-		}
462
-	}
463
-
464
-	public function invalidateAccessCacheForCollection(ICollection $collection): void {
465
-		$query = $this->connection->getQueryBuilder();
466
-
467
-		$query->delete(self::TABLE_ACCESS_CACHE)
468
-			->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId())));
469
-		$query->execute();
470
-	}
471
-
472
-	public function invalidateAccessCacheForProvider(IProvider $provider): void {
473
-		$query = $this->connection->getQueryBuilder();
474
-
475
-		$query->delete(self::TABLE_ACCESS_CACHE)
476
-			->where($query->expr()->eq('resource_type', $query->createNamedParameter($provider->getType(), IQueryBuilder::PARAM_STR)));
477
-		$query->execute();
478
-	}
479
-
480
-	public function invalidateAccessCacheForResourceByUser(IResource $resource, ?IUser $user): void {
481
-		$query = $this->connection->getQueryBuilder();
482
-		$userId = $user instanceof IUser ? $user->getUID() : '';
483
-
484
-		$query->delete(self::TABLE_ACCESS_CACHE)
485
-			->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId())))
486
-			->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
487
-		$query->execute();
488
-
489
-		foreach ($resource->getCollections() as $collection) {
490
-			$this->invalidateAccessCacheForCollectionByUser($collection, $user);
491
-		}
492
-	}
493
-
494
-	protected function invalidateAccessCacheForCollectionByUser(ICollection $collection, ?IUser $user): void {
495
-		$query = $this->connection->getQueryBuilder();
496
-		$userId = $user instanceof IUser ? $user->getUID() : '';
497
-
498
-		$query->delete(self::TABLE_ACCESS_CACHE)
499
-			->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId())))
500
-			->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
501
-		$query->execute();
502
-	}
503
-
504
-	public function invalidateAccessCacheForProviderByUser(IProvider $provider, ?IUser $user): void {
505
-		$query = $this->connection->getQueryBuilder();
506
-		$userId = $user instanceof IUser ? $user->getUID() : '';
507
-
508
-		$query->delete(self::TABLE_ACCESS_CACHE)
509
-			->where($query->expr()->eq('resource_type', $query->createNamedParameter($provider->getType(), IQueryBuilder::PARAM_STR)))
510
-			->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
511
-		$query->execute();
512
-	}
513
-
514
-	/**
515
-	 * @param string $provider
516
-	 */
517
-	public function registerResourceProvider(string $provider): void {
518
-		$this->providers[] = $provider;
519
-	}
520
-
521
-	/**
522
-	 * Get the resource type of the provider
523
-	 *
524
-	 * @return string
525
-	 * @since 16.0.0
526
-	 */
527
-	public function getType(): string {
528
-		return '';
529
-	}
41
+    public const TABLE_COLLECTIONS = 'collres_collections';
42
+    public const TABLE_RESOURCES = 'collres_resources';
43
+    public const TABLE_ACCESS_CACHE = 'collres_accesscache';
44
+
45
+    /** @var IDBConnection */
46
+    protected $connection;
47
+    /** @var ILogger */
48
+    protected $logger;
49
+
50
+    /** @var string[] */
51
+    protected $providers = [];
52
+
53
+    /** @var IProvider[] */
54
+    protected $providerInstances = [];
55
+
56
+    public function __construct(IDBConnection $connection, ILogger $logger) {
57
+        $this->connection = $connection;
58
+        $this->logger = $logger;
59
+    }
60
+
61
+    /**
62
+     * @param int $id
63
+     * @return ICollection
64
+     * @throws CollectionException when the collection could not be found
65
+     * @since 16.0.0
66
+     */
67
+    public function getCollection(int $id): ICollection {
68
+        $query = $this->connection->getQueryBuilder();
69
+        $query->select('*')
70
+            ->from(self::TABLE_COLLECTIONS)
71
+            ->where($query->expr()->eq('id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
72
+        $result = $query->execute();
73
+        $row = $result->fetch();
74
+        $result->closeCursor();
75
+
76
+        if (!$row) {
77
+            throw new CollectionException('Collection not found');
78
+        }
79
+
80
+        return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name']);
81
+    }
82
+
83
+    /**
84
+     * @param int $id
85
+     * @param IUser|null $user
86
+     * @return ICollection
87
+     * @throws CollectionException when the collection could not be found
88
+     * @since 16.0.0
89
+     */
90
+    public function getCollectionForUser(int $id, ?IUser $user): ICollection {
91
+        $query = $this->connection->getQueryBuilder();
92
+        $userId = $user instanceof IUser ? $user->getUID() : '';
93
+
94
+        $query->select('*')
95
+            ->from(self::TABLE_COLLECTIONS, 'c')
96
+            ->leftJoin(
97
+                'c', self::TABLE_ACCESS_CACHE, 'a',
98
+                $query->expr()->andX(
99
+                    $query->expr()->eq('c.id', 'a.collection_id'),
100
+                    $query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
101
+                )
102
+            )
103
+            ->where($query->expr()->eq('c.id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
104
+        $result = $query->execute();
105
+        $row = $result->fetch();
106
+        $result->closeCursor();
107
+
108
+        if (!$row) {
109
+            throw new CollectionException('Collection not found');
110
+        }
111
+
112
+        $access = $row['access'] === null ? null : (bool) $row['access'];
113
+        if ($user instanceof IUser) {
114
+            return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name'], $user, $access);
115
+        }
116
+
117
+        return new Collection($this, $this->connection, (int) $row['id'], (string) $row['name'], $user, $access);
118
+    }
119
+
120
+    /**
121
+     * @param IUser $user
122
+     * @param string $filter
123
+     * @param int $limit
124
+     * @param int $start
125
+     * @return ICollection[]
126
+     * @since 16.0.0
127
+     */
128
+    public function searchCollections(IUser $user, string $filter, int $limit = 50, int $start = 0): array {
129
+        $query = $this->connection->getQueryBuilder();
130
+        $userId = $user instanceof IUser ? $user->getUID() : '';
131
+
132
+        $query->select('c.*', 'a.access')
133
+            ->from(self::TABLE_COLLECTIONS, 'c')
134
+            ->leftJoin(
135
+                'c', self::TABLE_ACCESS_CACHE, 'a',
136
+                $query->expr()->andX(
137
+                    $query->expr()->eq('c.id', 'a.collection_id'),
138
+                    $query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
139
+                )
140
+            )
141
+            ->where($query->expr()->eq('a.access', $query->createNamedParameter(1, IQueryBuilder::PARAM_INT)))
142
+            ->orderBy('c.id')
143
+            ->setMaxResults($limit)
144
+            ->setFirstResult($start);
145
+
146
+        if ($filter !== '') {
147
+            $query->where($query->expr()->iLike('c.name', $query->createNamedParameter('%' . $this->connection->escapeLikeParameter($filter) . '%')));
148
+        }
149
+
150
+        $result = $query->execute();
151
+        $collections = [];
152
+
153
+        $foundResults = 0;
154
+        while ($row = $result->fetch()) {
155
+            $foundResults++;
156
+            $access = $row['access'] === null ? null : (bool) $row['access'];
157
+            $collection = new Collection($this, $this->connection, (int)$row['id'], (string)$row['name'], $user, $access);
158
+            if ($collection->canAccess($user)) {
159
+                $collections[] = $collection;
160
+            }
161
+        }
162
+        $result->closeCursor();
163
+
164
+        if (empty($collections) && $foundResults === $limit) {
165
+            return $this->searchCollections($user, $filter, $limit, $start + $limit);
166
+        }
167
+
168
+        return $collections;
169
+    }
170
+
171
+    /**
172
+     * @param string $name
173
+     * @return ICollection
174
+     * @since 16.0.0
175
+     */
176
+    public function newCollection(string $name): ICollection {
177
+        $query = $this->connection->getQueryBuilder();
178
+        $query->insert(self::TABLE_COLLECTIONS)
179
+            ->values([
180
+                'name' => $query->createNamedParameter($name),
181
+            ]);
182
+        $query->execute();
183
+
184
+        return new Collection($this, $this->connection, $query->getLastInsertId(), $name);
185
+    }
186
+
187
+    /**
188
+     * @param string $type
189
+     * @param string $id
190
+     * @return IResource
191
+     * @since 16.0.0
192
+     */
193
+    public function createResource(string $type, string $id): IResource {
194
+        return new Resource($this, $this->connection, $type, $id);
195
+    }
196
+
197
+    /**
198
+     * @param string $type
199
+     * @param string $id
200
+     * @param IUser|null $user
201
+     * @return IResource
202
+     * @throws ResourceException
203
+     * @since 16.0.0
204
+     */
205
+    public function getResourceForUser(string $type, string $id, ?IUser $user): IResource {
206
+        $query = $this->connection->getQueryBuilder();
207
+        $userId = $user instanceof IUser ? $user->getUID() : '';
208
+
209
+        $query->select('r.*', 'a.access')
210
+            ->from(self::TABLE_RESOURCES, 'r')
211
+            ->leftJoin(
212
+                'r', self::TABLE_ACCESS_CACHE, 'a',
213
+                $query->expr()->andX(
214
+                    $query->expr()->eq('r.resource_id', 'a.resource_id'),
215
+                    $query->expr()->eq('r.resource_type', 'a.resource_type'),
216
+                    $query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
217
+                )
218
+            )
219
+            ->where($query->expr()->eq('r.resource_type', $query->createNamedParameter($type, IQueryBuilder::PARAM_STR)))
220
+            ->andWhere($query->expr()->eq('r.resource_id', $query->createNamedParameter($id, IQueryBuilder::PARAM_STR)));
221
+        $result = $query->execute();
222
+        $row = $result->fetch();
223
+        $result->closeCursor();
224
+
225
+        if (!$row) {
226
+            throw new ResourceException('Resource not found');
227
+        }
228
+
229
+        $access = $row['access'] === null ? null : (bool) $row['access'];
230
+        if ($user instanceof IUser) {
231
+            return new Resource($this, $this->connection, $type, $id, $user, $access);
232
+        }
233
+
234
+        return new Resource($this, $this->connection, $type, $id, null, $access);
235
+    }
236
+
237
+    /**
238
+     * @param ICollection $collection
239
+     * @param IUser|null $user
240
+     * @return IResource[]
241
+     * @since 16.0.0
242
+     */
243
+    public function getResourcesByCollectionForUser(ICollection $collection, ?IUser $user): array {
244
+        $query = $this->connection->getQueryBuilder();
245
+        $userId = $user instanceof IUser ? $user->getUID() : '';
246
+
247
+        $query->select('r.*', 'a.access')
248
+            ->from(self::TABLE_RESOURCES, 'r')
249
+            ->leftJoin(
250
+                'r', self::TABLE_ACCESS_CACHE, 'a',
251
+                $query->expr()->andX(
252
+                    $query->expr()->eq('r.resource_id', 'a.resource_id'),
253
+                    $query->expr()->eq('r.resource_type', 'a.resource_type'),
254
+                    $query->expr()->eq('a.user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR))
255
+                )
256
+            )
257
+            ->where($query->expr()->eq('r.collection_id', $query->createNamedParameter($collection->getId(), IQueryBuilder::PARAM_INT)));
258
+
259
+        $resources = [];
260
+        $result = $query->execute();
261
+        while ($row = $result->fetch()) {
262
+            $access = $row['access'] === null ? null : (bool) $row['access'];
263
+            $resources[] = new Resource($this, $this->connection, $row['resource_type'], $row['resource_id'], $user, $access);
264
+        }
265
+        $result->closeCursor();
266
+
267
+        return $resources;
268
+    }
269
+
270
+    /**
271
+     * @return IProvider[]
272
+     * @since 16.0.0
273
+     */
274
+    public function getProviders(): array {
275
+        if (!empty($this->providers)) {
276
+            foreach ($this->providers as $provider) {
277
+                try {
278
+                    $this->providerInstances[] = \OC::$server->query($provider);
279
+                } catch (QueryException $e) {
280
+                    $this->logger->logException($e, [
281
+                        'message' => 'Error when instantiating resource provider'
282
+                    ]);
283
+                }
284
+            }
285
+            $this->providers = [];
286
+        }
287
+
288
+        return $this->providerInstances;
289
+    }
290
+
291
+    /**
292
+     * Get the rich object data of a resource
293
+     *
294
+     * @param IResource $resource
295
+     * @return array
296
+     * @since 16.0.0
297
+     */
298
+    public function getResourceRichObject(IResource $resource): array {
299
+        foreach ($this->getProviders() as $provider) {
300
+            if ($provider->getType() === $resource->getType()) {
301
+                try {
302
+                    return $provider->getResourceRichObject($resource);
303
+                } catch (ResourceException $e) {
304
+                }
305
+            }
306
+        }
307
+
308
+        return [];
309
+    }
310
+
311
+    /**
312
+     * Can a user/guest access the collection
313
+     *
314
+     * @param IResource $resource
315
+     * @param IUser|null $user
316
+     * @return bool
317
+     * @since 16.0.0
318
+     */
319
+    public function canAccessResource(IResource $resource, ?IUser $user): bool {
320
+        $access = $this->checkAccessCacheForUserByResource($resource, $user);
321
+        if (\is_bool($access)) {
322
+            return $access;
323
+        }
324
+
325
+        $access = false;
326
+        foreach ($this->getProviders() as $provider) {
327
+            if ($provider->getType() === $resource->getType()) {
328
+                try {
329
+                    if ($provider->canAccessResource($resource, $user)) {
330
+                        $access = true;
331
+                        break;
332
+                    }
333
+                } catch (ResourceException $e) {
334
+                }
335
+            }
336
+        }
337
+
338
+        $this->cacheAccessForResource($resource, $user, $access);
339
+        return $access;
340
+    }
341
+
342
+    /**
343
+     * Can a user/guest access the collection
344
+     *
345
+     * @param ICollection $collection
346
+     * @param IUser|null $user
347
+     * @return bool
348
+     * @since 16.0.0
349
+     */
350
+    public function canAccessCollection(ICollection $collection, ?IUser $user): bool {
351
+        $access = $this->checkAccessCacheForUserByCollection($collection, $user);
352
+        if (\is_bool($access)) {
353
+            return $access;
354
+        }
355
+
356
+        $access = false;
357
+        foreach ($collection->getResources() as $resource) {
358
+            if ($resource->canAccess($user)) {
359
+                $access = true;
360
+                break;
361
+            }
362
+        }
363
+
364
+        $this->cacheAccessForCollection($collection, $user, $access);
365
+        return $access;
366
+    }
367
+
368
+    protected function checkAccessCacheForUserByResource(IResource $resource, ?IUser $user): ?bool {
369
+        $query = $this->connection->getQueryBuilder();
370
+        $userId = $user instanceof IUser ? $user->getUID() : '';
371
+
372
+        $query->select('access')
373
+            ->from(self::TABLE_ACCESS_CACHE)
374
+            ->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId(), IQueryBuilder::PARAM_STR)))
375
+            ->andWhere($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType(), IQueryBuilder::PARAM_STR)))
376
+            ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
377
+            ->setMaxResults(1);
378
+
379
+        $hasAccess = null;
380
+        $result = $query->execute();
381
+        if ($row = $result->fetch()) {
382
+            $hasAccess = (bool) $row['access'];
383
+        }
384
+        $result->closeCursor();
385
+
386
+        return $hasAccess;
387
+    }
388
+
389
+    protected function checkAccessCacheForUserByCollection(ICollection $collection, ?IUser $user): ?bool {
390
+        $query = $this->connection->getQueryBuilder();
391
+        $userId = $user instanceof IUser ? $user->getUID() : '';
392
+
393
+        $query->select('access')
394
+            ->from(self::TABLE_ACCESS_CACHE)
395
+            ->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId(), IQueryBuilder::PARAM_INT)))
396
+            ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
397
+            ->setMaxResults(1);
398
+
399
+        $hasAccess = null;
400
+        $result = $query->execute();
401
+        if ($row = $result->fetch()) {
402
+            $hasAccess = (bool) $row['access'];
403
+        }
404
+        $result->closeCursor();
405
+
406
+        return $hasAccess;
407
+    }
408
+
409
+    public function cacheAccessForResource(IResource $resource, ?IUser $user, bool $access): void {
410
+        $query = $this->connection->getQueryBuilder();
411
+        $userId = $user instanceof IUser ? $user->getUID() : '';
412
+
413
+        $query->insert(self::TABLE_ACCESS_CACHE)
414
+            ->values([
415
+                'user_id' => $query->createNamedParameter($userId),
416
+                'resource_id' => $query->createNamedParameter($resource->getId()),
417
+                'resource_type' => $query->createNamedParameter($resource->getType()),
418
+                'access' => $query->createNamedParameter($access, IQueryBuilder::PARAM_BOOL),
419
+            ]);
420
+        try {
421
+            $query->execute();
422
+        } catch (UniqueConstraintViolationException $e) {
423
+        }
424
+    }
425
+
426
+    public function cacheAccessForCollection(ICollection $collection, ?IUser $user, bool $access): void {
427
+        $query = $this->connection->getQueryBuilder();
428
+        $userId = $user instanceof IUser ? $user->getUID() : '';
429
+
430
+        $query->insert(self::TABLE_ACCESS_CACHE)
431
+            ->values([
432
+                'user_id' => $query->createNamedParameter($userId),
433
+                'collection_id' => $query->createNamedParameter($collection->getId()),
434
+                'access' => $query->createNamedParameter($access),
435
+            ]);
436
+        try {
437
+            $query->execute();
438
+        } catch (UniqueConstraintViolationException $e) {
439
+        }
440
+    }
441
+
442
+    public function invalidateAccessCacheForUser(?IUser $user): void {
443
+        $query = $this->connection->getQueryBuilder();
444
+        $userId = $user instanceof IUser ? $user->getUID() : '';
445
+
446
+        $query->delete(self::TABLE_ACCESS_CACHE)
447
+            ->where($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
448
+        $query->execute();
449
+    }
450
+
451
+    public function invalidateAccessCacheForResource(IResource $resource): void {
452
+        $query = $this->connection->getQueryBuilder();
453
+
454
+        $query->delete(self::TABLE_ACCESS_CACHE)
455
+            ->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId())))
456
+            ->andWhere($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType(), IQueryBuilder::PARAM_STR)));
457
+        $query->execute();
458
+
459
+        foreach ($resource->getCollections() as $collection) {
460
+            $this->invalidateAccessCacheForCollection($collection);
461
+        }
462
+    }
463
+
464
+    public function invalidateAccessCacheForCollection(ICollection $collection): void {
465
+        $query = $this->connection->getQueryBuilder();
466
+
467
+        $query->delete(self::TABLE_ACCESS_CACHE)
468
+            ->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId())));
469
+        $query->execute();
470
+    }
471
+
472
+    public function invalidateAccessCacheForProvider(IProvider $provider): void {
473
+        $query = $this->connection->getQueryBuilder();
474
+
475
+        $query->delete(self::TABLE_ACCESS_CACHE)
476
+            ->where($query->expr()->eq('resource_type', $query->createNamedParameter($provider->getType(), IQueryBuilder::PARAM_STR)));
477
+        $query->execute();
478
+    }
479
+
480
+    public function invalidateAccessCacheForResourceByUser(IResource $resource, ?IUser $user): void {
481
+        $query = $this->connection->getQueryBuilder();
482
+        $userId = $user instanceof IUser ? $user->getUID() : '';
483
+
484
+        $query->delete(self::TABLE_ACCESS_CACHE)
485
+            ->where($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId())))
486
+            ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
487
+        $query->execute();
488
+
489
+        foreach ($resource->getCollections() as $collection) {
490
+            $this->invalidateAccessCacheForCollectionByUser($collection, $user);
491
+        }
492
+    }
493
+
494
+    protected function invalidateAccessCacheForCollectionByUser(ICollection $collection, ?IUser $user): void {
495
+        $query = $this->connection->getQueryBuilder();
496
+        $userId = $user instanceof IUser ? $user->getUID() : '';
497
+
498
+        $query->delete(self::TABLE_ACCESS_CACHE)
499
+            ->where($query->expr()->eq('collection_id', $query->createNamedParameter($collection->getId())))
500
+            ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
501
+        $query->execute();
502
+    }
503
+
504
+    public function invalidateAccessCacheForProviderByUser(IProvider $provider, ?IUser $user): void {
505
+        $query = $this->connection->getQueryBuilder();
506
+        $userId = $user instanceof IUser ? $user->getUID() : '';
507
+
508
+        $query->delete(self::TABLE_ACCESS_CACHE)
509
+            ->where($query->expr()->eq('resource_type', $query->createNamedParameter($provider->getType(), IQueryBuilder::PARAM_STR)))
510
+            ->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
511
+        $query->execute();
512
+    }
513
+
514
+    /**
515
+     * @param string $provider
516
+     */
517
+    public function registerResourceProvider(string $provider): void {
518
+        $this->providers[] = $provider;
519
+    }
520
+
521
+    /**
522
+     * Get the resource type of the provider
523
+     *
524
+     * @return string
525
+     * @since 16.0.0
526
+     */
527
+    public function getType(): string {
528
+        return '';
529
+    }
530 530
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
 			->setFirstResult($start);
145 145
 
146 146
 		if ($filter !== '') {
147
-			$query->where($query->expr()->iLike('c.name', $query->createNamedParameter('%' . $this->connection->escapeLikeParameter($filter) . '%')));
147
+			$query->where($query->expr()->iLike('c.name', $query->createNamedParameter('%'.$this->connection->escapeLikeParameter($filter).'%')));
148 148
 		}
149 149
 
150 150
 		$result = $query->execute();
@@ -154,7 +154,7 @@  discard block
 block discarded – undo
154 154
 		while ($row = $result->fetch()) {
155 155
 			$foundResults++;
156 156
 			$access = $row['access'] === null ? null : (bool) $row['access'];
157
-			$collection = new Collection($this, $this->connection, (int)$row['id'], (string)$row['name'], $user, $access);
157
+			$collection = new Collection($this, $this->connection, (int) $row['id'], (string) $row['name'], $user, $access);
158 158
 			if ($collection->canAccess($user)) {
159 159
 				$collections[] = $collection;
160 160
 			}
Please login to merge, or discard this patch.
core/Controller/CollaborationResourcesController.php 1 patch
Indentation   +252 added lines, -252 removed lines patch added patch discarded remove patch
@@ -37,256 +37,256 @@
 block discarded – undo
37 37
 
38 38
 class CollaborationResourcesController extends OCSController {
39 39
 
40
-	/** @var IManager */
41
-	private $manager;
42
-	/** @var IUserSession */
43
-	private $userSession;
44
-	/** @var ILogger */
45
-	private $logger;
46
-
47
-	public function __construct(
48
-		string $appName,
49
-		IRequest $request,
50
-		IManager $manager,
51
-		IUserSession $userSession,
52
-		ILogger $logger
53
-	) {
54
-		parent::__construct($appName, $request);
55
-
56
-		$this->manager = $manager;
57
-		$this->userSession = $userSession;
58
-		$this->logger = $logger;
59
-	}
60
-
61
-	/**
62
-	 * @param int $collectionId
63
-	 * @return ICollection
64
-	 * @throws CollectionException when the collection was not found for the user
65
-	 */
66
-	protected function getCollection(int $collectionId): ICollection {
67
-		$collection = $this->manager->getCollectionForUser($collectionId, $this->userSession->getUser());
68
-
69
-		if (!$collection->canAccess($this->userSession->getUser())) {
70
-			throw new CollectionException('Not found');
71
-		}
72
-
73
-		return $collection;
74
-	}
75
-
76
-	/**
77
-	 * @NoAdminRequired
78
-	 *
79
-	 * @param int $collectionId
80
-	 * @return DataResponse
81
-	 */
82
-	public function listCollection(int $collectionId): DataResponse {
83
-		try {
84
-			$collection = $this->getCollection($collectionId);
85
-		} catch (CollectionException $e) {
86
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
87
-		}
88
-
89
-		return $this->respondCollection($collection);
90
-	}
91
-
92
-	/**
93
-	 * @NoAdminRequired
94
-	 *
95
-	 * @param string $filter
96
-	 * @return DataResponse
97
-	 */
98
-	public function searchCollections(string $filter): DataResponse {
99
-		try {
100
-			$collections = $this->manager->searchCollections($this->userSession->getUser(), $filter);
101
-		} catch (CollectionException $e) {
102
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
103
-		}
104
-
105
-		return new DataResponse($this->prepareCollections($collections));
106
-	}
107
-
108
-	/**
109
-	 * @NoAdminRequired
110
-	 *
111
-	 * @param int $collectionId
112
-	 * @param string $resourceType
113
-	 * @param string $resourceId
114
-	 * @return DataResponse
115
-	 */
116
-	public function addResource(int $collectionId, string $resourceType, string $resourceId): DataResponse {
117
-		try {
118
-			$collection = $this->getCollection($collectionId);
119
-		} catch (CollectionException $e) {
120
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
121
-		}
122
-
123
-		$resource = $this->manager->createResource($resourceType, $resourceId);
124
-
125
-		if (!$resource->canAccess($this->userSession->getUser())) {
126
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
127
-		}
128
-
129
-		try {
130
-			$collection->addResource($resource);
131
-		} catch (ResourceException $e) {
132
-		}
133
-
134
-		return $this->respondCollection($collection);
135
-	}
136
-
137
-	/**
138
-	 * @NoAdminRequired
139
-	 *
140
-	 * @param int $collectionId
141
-	 * @param string $resourceType
142
-	 * @param string $resourceId
143
-	 * @return DataResponse
144
-	 */
145
-	public function removeResource(int $collectionId, string $resourceType, string $resourceId): DataResponse {
146
-		try {
147
-			$collection = $this->getCollection($collectionId);
148
-		} catch (CollectionException $e) {
149
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
150
-		}
151
-
152
-		try {
153
-			$resource = $this->manager->getResourceForUser($resourceType, $resourceId, $this->userSession->getUser());
154
-		} catch (CollectionException $e) {
155
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
156
-		}
157
-
158
-		$collection->removeResource($resource);
159
-
160
-		return $this->respondCollection($collection);
161
-	}
162
-
163
-	/**
164
-	 * @NoAdminRequired
165
-	 *
166
-	 * @param string $resourceType
167
-	 * @param string $resourceId
168
-	 * @return DataResponse
169
-	 */
170
-	public function getCollectionsByResource(string $resourceType, string $resourceId): DataResponse {
171
-		try {
172
-			$resource = $this->manager->getResourceForUser($resourceType, $resourceId, $this->userSession->getUser());
173
-		} catch (ResourceException $e) {
174
-			$resource = $this->manager->createResource($resourceType, $resourceId);
175
-		}
176
-
177
-		if (!$resource->canAccess($this->userSession->getUser())) {
178
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
179
-		}
180
-
181
-		return new DataResponse($this->prepareCollections($resource->getCollections()));
182
-	}
183
-
184
-	/**
185
-	 * @NoAdminRequired
186
-	 *
187
-	 * @param string $baseResourceType
188
-	 * @param string $baseResourceId
189
-	 * @param string $name
190
-	 * @return DataResponse
191
-	 */
192
-	public function createCollectionOnResource(string $baseResourceType, string $baseResourceId, string $name): DataResponse {
193
-		if (!isset($name[0]) || isset($name[64])) {
194
-			return new DataResponse([], Http::STATUS_BAD_REQUEST);
195
-		}
196
-
197
-		try {
198
-			$resource = $this->manager->createResource($baseResourceType, $baseResourceId);
199
-		} catch (CollectionException $e) {
200
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
201
-		}
202
-
203
-		if (!$resource->canAccess($this->userSession->getUser())) {
204
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
205
-		}
206
-
207
-		$collection = $this->manager->newCollection($name);
208
-		$collection->addResource($resource);
209
-
210
-		return $this->respondCollection($collection);
211
-	}
212
-
213
-	/**
214
-	 * @NoAdminRequired
215
-	 *
216
-	 * @param int $collectionId
217
-	 * @param string $collectionName
218
-	 * @return DataResponse
219
-	 */
220
-	public function renameCollection(int $collectionId, string $collectionName): DataResponse {
221
-		try {
222
-			$collection = $this->getCollection($collectionId);
223
-		} catch (CollectionException $exception) {
224
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
225
-		}
226
-
227
-		$collection->setName($collectionName);
228
-
229
-		return $this->respondCollection($collection);
230
-	}
231
-
232
-	protected function respondCollection(ICollection $collection): DataResponse {
233
-		try {
234
-			return new DataResponse($this->prepareCollection($collection));
235
-		} catch (CollectionException $e) {
236
-			return new DataResponse([], Http::STATUS_NOT_FOUND);
237
-		} catch (Exception $e) {
238
-			$this->logger->logException($e);
239
-			return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR);
240
-		}
241
-	}
242
-
243
-	protected function prepareCollections(array $collections): array {
244
-		$result = [];
245
-
246
-		foreach ($collections as $collection) {
247
-			try {
248
-				$result[] = $this->prepareCollection($collection);
249
-			} catch (CollectionException $e) {
250
-			} catch (Exception $e) {
251
-				$this->logger->logException($e);
252
-			}
253
-		}
254
-
255
-		return $result;
256
-	}
257
-
258
-	protected function prepareCollection(ICollection $collection): array {
259
-		if (!$collection->canAccess($this->userSession->getUser())) {
260
-			throw new CollectionException('Can not access collection');
261
-		}
262
-
263
-		return [
264
-			'id' => $collection->getId(),
265
-			'name' => $collection->getName(),
266
-			'resources' => $this->prepareResources($collection->getResources()),
267
-		];
268
-	}
269
-
270
-	protected function prepareResources(array $resources): ?array {
271
-		$result = [];
272
-
273
-		foreach ($resources as $resource) {
274
-			try {
275
-				$result[] = $this->prepareResource($resource);
276
-			} catch (ResourceException $e) {
277
-			} catch (Exception $e) {
278
-				$this->logger->logException($e);
279
-			}
280
-		}
281
-
282
-		return $result;
283
-	}
284
-
285
-	protected function prepareResource(IResource $resource): array {
286
-		if (!$resource->canAccess($this->userSession->getUser())) {
287
-			throw new ResourceException('Can not access resource');
288
-		}
289
-
290
-		return $resource->getRichObject();
291
-	}
40
+    /** @var IManager */
41
+    private $manager;
42
+    /** @var IUserSession */
43
+    private $userSession;
44
+    /** @var ILogger */
45
+    private $logger;
46
+
47
+    public function __construct(
48
+        string $appName,
49
+        IRequest $request,
50
+        IManager $manager,
51
+        IUserSession $userSession,
52
+        ILogger $logger
53
+    ) {
54
+        parent::__construct($appName, $request);
55
+
56
+        $this->manager = $manager;
57
+        $this->userSession = $userSession;
58
+        $this->logger = $logger;
59
+    }
60
+
61
+    /**
62
+     * @param int $collectionId
63
+     * @return ICollection
64
+     * @throws CollectionException when the collection was not found for the user
65
+     */
66
+    protected function getCollection(int $collectionId): ICollection {
67
+        $collection = $this->manager->getCollectionForUser($collectionId, $this->userSession->getUser());
68
+
69
+        if (!$collection->canAccess($this->userSession->getUser())) {
70
+            throw new CollectionException('Not found');
71
+        }
72
+
73
+        return $collection;
74
+    }
75
+
76
+    /**
77
+     * @NoAdminRequired
78
+     *
79
+     * @param int $collectionId
80
+     * @return DataResponse
81
+     */
82
+    public function listCollection(int $collectionId): DataResponse {
83
+        try {
84
+            $collection = $this->getCollection($collectionId);
85
+        } catch (CollectionException $e) {
86
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
87
+        }
88
+
89
+        return $this->respondCollection($collection);
90
+    }
91
+
92
+    /**
93
+     * @NoAdminRequired
94
+     *
95
+     * @param string $filter
96
+     * @return DataResponse
97
+     */
98
+    public function searchCollections(string $filter): DataResponse {
99
+        try {
100
+            $collections = $this->manager->searchCollections($this->userSession->getUser(), $filter);
101
+        } catch (CollectionException $e) {
102
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
103
+        }
104
+
105
+        return new DataResponse($this->prepareCollections($collections));
106
+    }
107
+
108
+    /**
109
+     * @NoAdminRequired
110
+     *
111
+     * @param int $collectionId
112
+     * @param string $resourceType
113
+     * @param string $resourceId
114
+     * @return DataResponse
115
+     */
116
+    public function addResource(int $collectionId, string $resourceType, string $resourceId): DataResponse {
117
+        try {
118
+            $collection = $this->getCollection($collectionId);
119
+        } catch (CollectionException $e) {
120
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
121
+        }
122
+
123
+        $resource = $this->manager->createResource($resourceType, $resourceId);
124
+
125
+        if (!$resource->canAccess($this->userSession->getUser())) {
126
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
127
+        }
128
+
129
+        try {
130
+            $collection->addResource($resource);
131
+        } catch (ResourceException $e) {
132
+        }
133
+
134
+        return $this->respondCollection($collection);
135
+    }
136
+
137
+    /**
138
+     * @NoAdminRequired
139
+     *
140
+     * @param int $collectionId
141
+     * @param string $resourceType
142
+     * @param string $resourceId
143
+     * @return DataResponse
144
+     */
145
+    public function removeResource(int $collectionId, string $resourceType, string $resourceId): DataResponse {
146
+        try {
147
+            $collection = $this->getCollection($collectionId);
148
+        } catch (CollectionException $e) {
149
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
150
+        }
151
+
152
+        try {
153
+            $resource = $this->manager->getResourceForUser($resourceType, $resourceId, $this->userSession->getUser());
154
+        } catch (CollectionException $e) {
155
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
156
+        }
157
+
158
+        $collection->removeResource($resource);
159
+
160
+        return $this->respondCollection($collection);
161
+    }
162
+
163
+    /**
164
+     * @NoAdminRequired
165
+     *
166
+     * @param string $resourceType
167
+     * @param string $resourceId
168
+     * @return DataResponse
169
+     */
170
+    public function getCollectionsByResource(string $resourceType, string $resourceId): DataResponse {
171
+        try {
172
+            $resource = $this->manager->getResourceForUser($resourceType, $resourceId, $this->userSession->getUser());
173
+        } catch (ResourceException $e) {
174
+            $resource = $this->manager->createResource($resourceType, $resourceId);
175
+        }
176
+
177
+        if (!$resource->canAccess($this->userSession->getUser())) {
178
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
179
+        }
180
+
181
+        return new DataResponse($this->prepareCollections($resource->getCollections()));
182
+    }
183
+
184
+    /**
185
+     * @NoAdminRequired
186
+     *
187
+     * @param string $baseResourceType
188
+     * @param string $baseResourceId
189
+     * @param string $name
190
+     * @return DataResponse
191
+     */
192
+    public function createCollectionOnResource(string $baseResourceType, string $baseResourceId, string $name): DataResponse {
193
+        if (!isset($name[0]) || isset($name[64])) {
194
+            return new DataResponse([], Http::STATUS_BAD_REQUEST);
195
+        }
196
+
197
+        try {
198
+            $resource = $this->manager->createResource($baseResourceType, $baseResourceId);
199
+        } catch (CollectionException $e) {
200
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
201
+        }
202
+
203
+        if (!$resource->canAccess($this->userSession->getUser())) {
204
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
205
+        }
206
+
207
+        $collection = $this->manager->newCollection($name);
208
+        $collection->addResource($resource);
209
+
210
+        return $this->respondCollection($collection);
211
+    }
212
+
213
+    /**
214
+     * @NoAdminRequired
215
+     *
216
+     * @param int $collectionId
217
+     * @param string $collectionName
218
+     * @return DataResponse
219
+     */
220
+    public function renameCollection(int $collectionId, string $collectionName): DataResponse {
221
+        try {
222
+            $collection = $this->getCollection($collectionId);
223
+        } catch (CollectionException $exception) {
224
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
225
+        }
226
+
227
+        $collection->setName($collectionName);
228
+
229
+        return $this->respondCollection($collection);
230
+    }
231
+
232
+    protected function respondCollection(ICollection $collection): DataResponse {
233
+        try {
234
+            return new DataResponse($this->prepareCollection($collection));
235
+        } catch (CollectionException $e) {
236
+            return new DataResponse([], Http::STATUS_NOT_FOUND);
237
+        } catch (Exception $e) {
238
+            $this->logger->logException($e);
239
+            return new DataResponse([], Http::STATUS_INTERNAL_SERVER_ERROR);
240
+        }
241
+    }
242
+
243
+    protected function prepareCollections(array $collections): array {
244
+        $result = [];
245
+
246
+        foreach ($collections as $collection) {
247
+            try {
248
+                $result[] = $this->prepareCollection($collection);
249
+            } catch (CollectionException $e) {
250
+            } catch (Exception $e) {
251
+                $this->logger->logException($e);
252
+            }
253
+        }
254
+
255
+        return $result;
256
+    }
257
+
258
+    protected function prepareCollection(ICollection $collection): array {
259
+        if (!$collection->canAccess($this->userSession->getUser())) {
260
+            throw new CollectionException('Can not access collection');
261
+        }
262
+
263
+        return [
264
+            'id' => $collection->getId(),
265
+            'name' => $collection->getName(),
266
+            'resources' => $this->prepareResources($collection->getResources()),
267
+        ];
268
+    }
269
+
270
+    protected function prepareResources(array $resources): ?array {
271
+        $result = [];
272
+
273
+        foreach ($resources as $resource) {
274
+            try {
275
+                $result[] = $this->prepareResource($resource);
276
+            } catch (ResourceException $e) {
277
+            } catch (Exception $e) {
278
+                $this->logger->logException($e);
279
+            }
280
+        }
281
+
282
+        return $result;
283
+    }
284
+
285
+    protected function prepareResource(IResource $resource): array {
286
+        if (!$resource->canAccess($this->userSession->getUser())) {
287
+            throw new ResourceException('Can not access resource');
288
+        }
289
+
290
+        return $resource->getRichObject();
291
+    }
292 292
 }
Please login to merge, or discard this patch.