Passed
Push — master ( 15f660...70a68e )
by Joas
15:16 queued 13s
created
lib/private/SystemTag/SystemTagManager.php 2 patches
Indentation   +387 added lines, -387 removed lines patch added patch discarded remove patch
@@ -45,391 +45,391 @@
 block discarded – undo
45 45
  * Manager class for system tags
46 46
  */
47 47
 class SystemTagManager implements ISystemTagManager {
48
-	public const TAG_TABLE = 'systemtag';
49
-	public const TAG_GROUP_TABLE = 'systemtag_group';
50
-
51
-	/** @var IDBConnection */
52
-	protected $connection;
53
-
54
-	/** @var EventDispatcherInterface */
55
-	protected $dispatcher;
56
-
57
-	/** @var IGroupManager */
58
-	protected $groupManager;
59
-
60
-	/**
61
-	 * Prepared query for selecting tags directly
62
-	 *
63
-	 * @var \OCP\DB\QueryBuilder\IQueryBuilder
64
-	 */
65
-	private $selectTagQuery;
66
-
67
-	/**
68
-	 * Constructor.
69
-	 *
70
-	 * @param IDBConnection $connection database connection
71
-	 * @param IGroupManager $groupManager
72
-	 * @param EventDispatcherInterface $dispatcher
73
-	 */
74
-	public function __construct(
75
-		IDBConnection $connection,
76
-		IGroupManager $groupManager,
77
-		EventDispatcherInterface $dispatcher
78
-	) {
79
-		$this->connection = $connection;
80
-		$this->groupManager = $groupManager;
81
-		$this->dispatcher = $dispatcher;
82
-
83
-		$query = $this->connection->getQueryBuilder();
84
-		$this->selectTagQuery = $query->select('*')
85
-			->from(self::TAG_TABLE)
86
-			->where($query->expr()->eq('name', $query->createParameter('name')))
87
-			->andWhere($query->expr()->eq('visibility', $query->createParameter('visibility')))
88
-			->andWhere($query->expr()->eq('editable', $query->createParameter('editable')));
89
-	}
90
-
91
-	/**
92
-	 * {@inheritdoc}
93
-	 */
94
-	public function getTagsByIds($tagIds): array {
95
-		if (!\is_array($tagIds)) {
96
-			$tagIds = [$tagIds];
97
-		}
98
-
99
-		$tags = [];
100
-
101
-		// note: not all databases will fail if it's a string or starts with a number
102
-		foreach ($tagIds as $tagId) {
103
-			if (!is_numeric($tagId)) {
104
-				throw new \InvalidArgumentException('Tag id must be integer');
105
-			}
106
-		}
107
-
108
-		$query = $this->connection->getQueryBuilder();
109
-		$query->select('*')
110
-			->from(self::TAG_TABLE)
111
-			->where($query->expr()->in('id', $query->createParameter('tagids')))
112
-			->addOrderBy('name', 'ASC')
113
-			->addOrderBy('visibility', 'ASC')
114
-			->addOrderBy('editable', 'ASC')
115
-			->setParameter('tagids', $tagIds, IQueryBuilder::PARAM_INT_ARRAY);
116
-
117
-		$result = $query->execute();
118
-		while ($row = $result->fetch()) {
119
-			$tags[$row['id']] = $this->createSystemTagFromRow($row);
120
-		}
121
-
122
-		$result->closeCursor();
123
-
124
-		if (\count($tags) !== \count($tagIds)) {
125
-			throw new TagNotFoundException(
126
-				'Tag id(s) not found', 0, null, array_diff($tagIds, array_keys($tags))
127
-			);
128
-		}
129
-
130
-		return $tags;
131
-	}
132
-
133
-	/**
134
-	 * {@inheritdoc}
135
-	 */
136
-	public function getAllTags($visibilityFilter = null, $nameSearchPattern = null): array {
137
-		$tags = [];
138
-
139
-		$query = $this->connection->getQueryBuilder();
140
-		$query->select('*')
141
-			->from(self::TAG_TABLE);
142
-
143
-		if (!\is_null($visibilityFilter)) {
144
-			$query->andWhere($query->expr()->eq('visibility', $query->createNamedParameter((int)$visibilityFilter)));
145
-		}
146
-
147
-		if (!empty($nameSearchPattern)) {
148
-			$query->andWhere(
149
-				$query->expr()->like(
150
-					'name',
151
-					$query->createNamedParameter('%' . $this->connection->escapeLikeParameter($nameSearchPattern). '%')
152
-				)
153
-			);
154
-		}
155
-
156
-		$query
157
-			->addOrderBy('name', 'ASC')
158
-			->addOrderBy('visibility', 'ASC')
159
-			->addOrderBy('editable', 'ASC');
160
-
161
-		$result = $query->execute();
162
-		while ($row = $result->fetch()) {
163
-			$tags[$row['id']] = $this->createSystemTagFromRow($row);
164
-		}
165
-
166
-		$result->closeCursor();
167
-
168
-		return $tags;
169
-	}
170
-
171
-	/**
172
-	 * {@inheritdoc}
173
-	 */
174
-	public function getTag(string $tagName, bool $userVisible, bool $userAssignable): ISystemTag {
175
-		$result = $this->selectTagQuery
176
-			->setParameter('name', $tagName)
177
-			->setParameter('visibility', $userVisible ? 1 : 0)
178
-			->setParameter('editable', $userAssignable ? 1 : 0)
179
-			->execute();
180
-
181
-		$row = $result->fetch();
182
-		$result->closeCursor();
183
-		if (!$row) {
184
-			throw new TagNotFoundException(
185
-				'Tag ("' . $tagName . '", '. $userVisible . ', ' . $userAssignable . ') does not exist'
186
-			);
187
-		}
188
-
189
-		return $this->createSystemTagFromRow($row);
190
-	}
191
-
192
-	/**
193
-	 * {@inheritdoc}
194
-	 */
195
-	public function createTag(string $tagName, bool $userVisible, bool $userAssignable): ISystemTag {
196
-		// Length of name column is 64
197
-		$truncatedTagName = substr($tagName, 0, 64);
198
-		$query = $this->connection->getQueryBuilder();
199
-		$query->insert(self::TAG_TABLE)
200
-			->values([
201
-				'name' => $query->createNamedParameter($truncatedTagName),
202
-				'visibility' => $query->createNamedParameter($userVisible ? 1 : 0),
203
-				'editable' => $query->createNamedParameter($userAssignable ? 1 : 0),
204
-			]);
205
-
206
-		try {
207
-			$query->execute();
208
-		} catch (UniqueConstraintViolationException $e) {
209
-			throw new TagAlreadyExistsException(
210
-				'Tag ("' . $truncatedTagName . '", '. $userVisible . ', ' . $userAssignable . ') already exists',
211
-				0,
212
-				$e
213
-			);
214
-		}
215
-
216
-		$tagId = $query->getLastInsertId();
217
-
218
-		$tag = new SystemTag(
219
-			(string)$tagId,
220
-			$truncatedTagName,
221
-			$userVisible,
222
-			$userAssignable
223
-		);
224
-
225
-		$this->dispatcher->dispatch(ManagerEvent::EVENT_CREATE, new ManagerEvent(
226
-			ManagerEvent::EVENT_CREATE, $tag
227
-		));
228
-
229
-		return $tag;
230
-	}
231
-
232
-	/**
233
-	 * {@inheritdoc}
234
-	 */
235
-	public function updateTag(string $tagId, string $newName, bool $userVisible, bool $userAssignable) {
236
-		try {
237
-			$tags = $this->getTagsByIds($tagId);
238
-		} catch (TagNotFoundException $e) {
239
-			throw new TagNotFoundException(
240
-				'Tag does not exist', 0, null, [$tagId]
241
-			);
242
-		}
243
-
244
-		$beforeUpdate = array_shift($tags);
245
-		$afterUpdate = new SystemTag(
246
-			$tagId,
247
-			$newName,
248
-			$userVisible,
249
-			$userAssignable
250
-		);
251
-
252
-		$query = $this->connection->getQueryBuilder();
253
-		$query->update(self::TAG_TABLE)
254
-			->set('name', $query->createParameter('name'))
255
-			->set('visibility', $query->createParameter('visibility'))
256
-			->set('editable', $query->createParameter('editable'))
257
-			->where($query->expr()->eq('id', $query->createParameter('tagid')))
258
-			->setParameter('name', $newName)
259
-			->setParameter('visibility', $userVisible ? 1 : 0)
260
-			->setParameter('editable', $userAssignable ? 1 : 0)
261
-			->setParameter('tagid', $tagId);
262
-
263
-		try {
264
-			if ($query->execute() === 0) {
265
-				throw new TagNotFoundException(
266
-					'Tag does not exist', 0, null, [$tagId]
267
-				);
268
-			}
269
-		} catch (UniqueConstraintViolationException $e) {
270
-			throw new TagAlreadyExistsException(
271
-				'Tag ("' . $newName . '", '. $userVisible . ', ' . $userAssignable . ') already exists',
272
-				0,
273
-				$e
274
-			);
275
-		}
276
-
277
-		$this->dispatcher->dispatch(ManagerEvent::EVENT_UPDATE, new ManagerEvent(
278
-			ManagerEvent::EVENT_UPDATE, $afterUpdate, $beforeUpdate
279
-		));
280
-	}
281
-
282
-	/**
283
-	 * {@inheritdoc}
284
-	 */
285
-	public function deleteTags($tagIds) {
286
-		if (!\is_array($tagIds)) {
287
-			$tagIds = [$tagIds];
288
-		}
289
-
290
-		$tagNotFoundException = null;
291
-		$tags = [];
292
-		try {
293
-			$tags = $this->getTagsByIds($tagIds);
294
-		} catch (TagNotFoundException $e) {
295
-			$tagNotFoundException = $e;
296
-
297
-			// Get existing tag objects for the hooks later
298
-			$existingTags = array_diff($tagIds, $tagNotFoundException->getMissingTags());
299
-			if (!empty($existingTags)) {
300
-				try {
301
-					$tags = $this->getTagsByIds($existingTags);
302
-				} catch (TagNotFoundException $e) {
303
-					// Ignore further errors...
304
-				}
305
-			}
306
-		}
307
-
308
-		// delete relationships first
309
-		$query = $this->connection->getQueryBuilder();
310
-		$query->delete(SystemTagObjectMapper::RELATION_TABLE)
311
-			->where($query->expr()->in('systemtagid', $query->createParameter('tagids')))
312
-			->setParameter('tagids', $tagIds, IQueryBuilder::PARAM_INT_ARRAY)
313
-			->execute();
314
-
315
-		$query = $this->connection->getQueryBuilder();
316
-		$query->delete(self::TAG_TABLE)
317
-			->where($query->expr()->in('id', $query->createParameter('tagids')))
318
-			->setParameter('tagids', $tagIds, IQueryBuilder::PARAM_INT_ARRAY)
319
-			->execute();
320
-
321
-		foreach ($tags as $tag) {
322
-			$this->dispatcher->dispatch(ManagerEvent::EVENT_DELETE, new ManagerEvent(
323
-				ManagerEvent::EVENT_DELETE, $tag
324
-			));
325
-		}
326
-
327
-		if ($tagNotFoundException !== null) {
328
-			throw new TagNotFoundException(
329
-				'Tag id(s) not found', 0, $tagNotFoundException, $tagNotFoundException->getMissingTags()
330
-			);
331
-		}
332
-	}
333
-
334
-	/**
335
-	 * {@inheritdoc}
336
-	 */
337
-	public function canUserAssignTag(ISystemTag $tag, IUser $user): bool {
338
-		// early check to avoid unneeded group lookups
339
-		if ($tag->isUserAssignable() && $tag->isUserVisible()) {
340
-			return true;
341
-		}
342
-
343
-		if ($this->groupManager->isAdmin($user->getUID())) {
344
-			return true;
345
-		}
346
-
347
-		if (!$tag->isUserVisible()) {
348
-			return false;
349
-		}
350
-
351
-		$groupIds = $this->groupManager->getUserGroupIds($user);
352
-		if (!empty($groupIds)) {
353
-			$matchingGroups = array_intersect($groupIds, $this->getTagGroups($tag));
354
-			if (!empty($matchingGroups)) {
355
-				return true;
356
-			}
357
-		}
358
-
359
-		return false;
360
-	}
361
-
362
-	/**
363
-	 * {@inheritdoc}
364
-	 */
365
-	public function canUserSeeTag(ISystemTag $tag, IUser $user): bool {
366
-		if ($tag->isUserVisible()) {
367
-			return true;
368
-		}
369
-
370
-		if ($this->groupManager->isAdmin($user->getUID())) {
371
-			return true;
372
-		}
373
-
374
-		return false;
375
-	}
376
-
377
-	private function createSystemTagFromRow($row) {
378
-		return new SystemTag((string)$row['id'], $row['name'], (bool)$row['visibility'], (bool)$row['editable']);
379
-	}
380
-
381
-	/**
382
-	 * {@inheritdoc}
383
-	 */
384
-	public function setTagGroups(ISystemTag $tag, array $groupIds) {
385
-		// delete relationships first
386
-		$this->connection->beginTransaction();
387
-		try {
388
-			$query = $this->connection->getQueryBuilder();
389
-			$query->delete(self::TAG_GROUP_TABLE)
390
-				->where($query->expr()->eq('systemtagid', $query->createNamedParameter($tag->getId())))
391
-				->execute();
392
-
393
-			// add each group id
394
-			$query = $this->connection->getQueryBuilder();
395
-			$query->insert(self::TAG_GROUP_TABLE)
396
-				->values([
397
-					'systemtagid' => $query->createNamedParameter($tag->getId()),
398
-					'gid' => $query->createParameter('gid'),
399
-				]);
400
-			foreach ($groupIds as $groupId) {
401
-				if ($groupId === '') {
402
-					continue;
403
-				}
404
-				$query->setParameter('gid', $groupId);
405
-				$query->execute();
406
-			}
407
-
408
-			$this->connection->commit();
409
-		} catch (\Exception $e) {
410
-			$this->connection->rollBack();
411
-			throw $e;
412
-		}
413
-	}
414
-
415
-	/**
416
-	 * {@inheritdoc}
417
-	 */
418
-	public function getTagGroups(ISystemTag $tag): array {
419
-		$groupIds = [];
420
-		$query = $this->connection->getQueryBuilder();
421
-		$query->select('gid')
422
-			->from(self::TAG_GROUP_TABLE)
423
-			->where($query->expr()->eq('systemtagid', $query->createNamedParameter($tag->getId())))
424
-			->orderBy('gid');
425
-
426
-		$result = $query->execute();
427
-		while ($row = $result->fetch()) {
428
-			$groupIds[] = $row['gid'];
429
-		}
430
-
431
-		$result->closeCursor();
432
-
433
-		return $groupIds;
434
-	}
48
+    public const TAG_TABLE = 'systemtag';
49
+    public const TAG_GROUP_TABLE = 'systemtag_group';
50
+
51
+    /** @var IDBConnection */
52
+    protected $connection;
53
+
54
+    /** @var EventDispatcherInterface */
55
+    protected $dispatcher;
56
+
57
+    /** @var IGroupManager */
58
+    protected $groupManager;
59
+
60
+    /**
61
+     * Prepared query for selecting tags directly
62
+     *
63
+     * @var \OCP\DB\QueryBuilder\IQueryBuilder
64
+     */
65
+    private $selectTagQuery;
66
+
67
+    /**
68
+     * Constructor.
69
+     *
70
+     * @param IDBConnection $connection database connection
71
+     * @param IGroupManager $groupManager
72
+     * @param EventDispatcherInterface $dispatcher
73
+     */
74
+    public function __construct(
75
+        IDBConnection $connection,
76
+        IGroupManager $groupManager,
77
+        EventDispatcherInterface $dispatcher
78
+    ) {
79
+        $this->connection = $connection;
80
+        $this->groupManager = $groupManager;
81
+        $this->dispatcher = $dispatcher;
82
+
83
+        $query = $this->connection->getQueryBuilder();
84
+        $this->selectTagQuery = $query->select('*')
85
+            ->from(self::TAG_TABLE)
86
+            ->where($query->expr()->eq('name', $query->createParameter('name')))
87
+            ->andWhere($query->expr()->eq('visibility', $query->createParameter('visibility')))
88
+            ->andWhere($query->expr()->eq('editable', $query->createParameter('editable')));
89
+    }
90
+
91
+    /**
92
+     * {@inheritdoc}
93
+     */
94
+    public function getTagsByIds($tagIds): array {
95
+        if (!\is_array($tagIds)) {
96
+            $tagIds = [$tagIds];
97
+        }
98
+
99
+        $tags = [];
100
+
101
+        // note: not all databases will fail if it's a string or starts with a number
102
+        foreach ($tagIds as $tagId) {
103
+            if (!is_numeric($tagId)) {
104
+                throw new \InvalidArgumentException('Tag id must be integer');
105
+            }
106
+        }
107
+
108
+        $query = $this->connection->getQueryBuilder();
109
+        $query->select('*')
110
+            ->from(self::TAG_TABLE)
111
+            ->where($query->expr()->in('id', $query->createParameter('tagids')))
112
+            ->addOrderBy('name', 'ASC')
113
+            ->addOrderBy('visibility', 'ASC')
114
+            ->addOrderBy('editable', 'ASC')
115
+            ->setParameter('tagids', $tagIds, IQueryBuilder::PARAM_INT_ARRAY);
116
+
117
+        $result = $query->execute();
118
+        while ($row = $result->fetch()) {
119
+            $tags[$row['id']] = $this->createSystemTagFromRow($row);
120
+        }
121
+
122
+        $result->closeCursor();
123
+
124
+        if (\count($tags) !== \count($tagIds)) {
125
+            throw new TagNotFoundException(
126
+                'Tag id(s) not found', 0, null, array_diff($tagIds, array_keys($tags))
127
+            );
128
+        }
129
+
130
+        return $tags;
131
+    }
132
+
133
+    /**
134
+     * {@inheritdoc}
135
+     */
136
+    public function getAllTags($visibilityFilter = null, $nameSearchPattern = null): array {
137
+        $tags = [];
138
+
139
+        $query = $this->connection->getQueryBuilder();
140
+        $query->select('*')
141
+            ->from(self::TAG_TABLE);
142
+
143
+        if (!\is_null($visibilityFilter)) {
144
+            $query->andWhere($query->expr()->eq('visibility', $query->createNamedParameter((int)$visibilityFilter)));
145
+        }
146
+
147
+        if (!empty($nameSearchPattern)) {
148
+            $query->andWhere(
149
+                $query->expr()->like(
150
+                    'name',
151
+                    $query->createNamedParameter('%' . $this->connection->escapeLikeParameter($nameSearchPattern). '%')
152
+                )
153
+            );
154
+        }
155
+
156
+        $query
157
+            ->addOrderBy('name', 'ASC')
158
+            ->addOrderBy('visibility', 'ASC')
159
+            ->addOrderBy('editable', 'ASC');
160
+
161
+        $result = $query->execute();
162
+        while ($row = $result->fetch()) {
163
+            $tags[$row['id']] = $this->createSystemTagFromRow($row);
164
+        }
165
+
166
+        $result->closeCursor();
167
+
168
+        return $tags;
169
+    }
170
+
171
+    /**
172
+     * {@inheritdoc}
173
+     */
174
+    public function getTag(string $tagName, bool $userVisible, bool $userAssignable): ISystemTag {
175
+        $result = $this->selectTagQuery
176
+            ->setParameter('name', $tagName)
177
+            ->setParameter('visibility', $userVisible ? 1 : 0)
178
+            ->setParameter('editable', $userAssignable ? 1 : 0)
179
+            ->execute();
180
+
181
+        $row = $result->fetch();
182
+        $result->closeCursor();
183
+        if (!$row) {
184
+            throw new TagNotFoundException(
185
+                'Tag ("' . $tagName . '", '. $userVisible . ', ' . $userAssignable . ') does not exist'
186
+            );
187
+        }
188
+
189
+        return $this->createSystemTagFromRow($row);
190
+    }
191
+
192
+    /**
193
+     * {@inheritdoc}
194
+     */
195
+    public function createTag(string $tagName, bool $userVisible, bool $userAssignable): ISystemTag {
196
+        // Length of name column is 64
197
+        $truncatedTagName = substr($tagName, 0, 64);
198
+        $query = $this->connection->getQueryBuilder();
199
+        $query->insert(self::TAG_TABLE)
200
+            ->values([
201
+                'name' => $query->createNamedParameter($truncatedTagName),
202
+                'visibility' => $query->createNamedParameter($userVisible ? 1 : 0),
203
+                'editable' => $query->createNamedParameter($userAssignable ? 1 : 0),
204
+            ]);
205
+
206
+        try {
207
+            $query->execute();
208
+        } catch (UniqueConstraintViolationException $e) {
209
+            throw new TagAlreadyExistsException(
210
+                'Tag ("' . $truncatedTagName . '", '. $userVisible . ', ' . $userAssignable . ') already exists',
211
+                0,
212
+                $e
213
+            );
214
+        }
215
+
216
+        $tagId = $query->getLastInsertId();
217
+
218
+        $tag = new SystemTag(
219
+            (string)$tagId,
220
+            $truncatedTagName,
221
+            $userVisible,
222
+            $userAssignable
223
+        );
224
+
225
+        $this->dispatcher->dispatch(ManagerEvent::EVENT_CREATE, new ManagerEvent(
226
+            ManagerEvent::EVENT_CREATE, $tag
227
+        ));
228
+
229
+        return $tag;
230
+    }
231
+
232
+    /**
233
+     * {@inheritdoc}
234
+     */
235
+    public function updateTag(string $tagId, string $newName, bool $userVisible, bool $userAssignable) {
236
+        try {
237
+            $tags = $this->getTagsByIds($tagId);
238
+        } catch (TagNotFoundException $e) {
239
+            throw new TagNotFoundException(
240
+                'Tag does not exist', 0, null, [$tagId]
241
+            );
242
+        }
243
+
244
+        $beforeUpdate = array_shift($tags);
245
+        $afterUpdate = new SystemTag(
246
+            $tagId,
247
+            $newName,
248
+            $userVisible,
249
+            $userAssignable
250
+        );
251
+
252
+        $query = $this->connection->getQueryBuilder();
253
+        $query->update(self::TAG_TABLE)
254
+            ->set('name', $query->createParameter('name'))
255
+            ->set('visibility', $query->createParameter('visibility'))
256
+            ->set('editable', $query->createParameter('editable'))
257
+            ->where($query->expr()->eq('id', $query->createParameter('tagid')))
258
+            ->setParameter('name', $newName)
259
+            ->setParameter('visibility', $userVisible ? 1 : 0)
260
+            ->setParameter('editable', $userAssignable ? 1 : 0)
261
+            ->setParameter('tagid', $tagId);
262
+
263
+        try {
264
+            if ($query->execute() === 0) {
265
+                throw new TagNotFoundException(
266
+                    'Tag does not exist', 0, null, [$tagId]
267
+                );
268
+            }
269
+        } catch (UniqueConstraintViolationException $e) {
270
+            throw new TagAlreadyExistsException(
271
+                'Tag ("' . $newName . '", '. $userVisible . ', ' . $userAssignable . ') already exists',
272
+                0,
273
+                $e
274
+            );
275
+        }
276
+
277
+        $this->dispatcher->dispatch(ManagerEvent::EVENT_UPDATE, new ManagerEvent(
278
+            ManagerEvent::EVENT_UPDATE, $afterUpdate, $beforeUpdate
279
+        ));
280
+    }
281
+
282
+    /**
283
+     * {@inheritdoc}
284
+     */
285
+    public function deleteTags($tagIds) {
286
+        if (!\is_array($tagIds)) {
287
+            $tagIds = [$tagIds];
288
+        }
289
+
290
+        $tagNotFoundException = null;
291
+        $tags = [];
292
+        try {
293
+            $tags = $this->getTagsByIds($tagIds);
294
+        } catch (TagNotFoundException $e) {
295
+            $tagNotFoundException = $e;
296
+
297
+            // Get existing tag objects for the hooks later
298
+            $existingTags = array_diff($tagIds, $tagNotFoundException->getMissingTags());
299
+            if (!empty($existingTags)) {
300
+                try {
301
+                    $tags = $this->getTagsByIds($existingTags);
302
+                } catch (TagNotFoundException $e) {
303
+                    // Ignore further errors...
304
+                }
305
+            }
306
+        }
307
+
308
+        // delete relationships first
309
+        $query = $this->connection->getQueryBuilder();
310
+        $query->delete(SystemTagObjectMapper::RELATION_TABLE)
311
+            ->where($query->expr()->in('systemtagid', $query->createParameter('tagids')))
312
+            ->setParameter('tagids', $tagIds, IQueryBuilder::PARAM_INT_ARRAY)
313
+            ->execute();
314
+
315
+        $query = $this->connection->getQueryBuilder();
316
+        $query->delete(self::TAG_TABLE)
317
+            ->where($query->expr()->in('id', $query->createParameter('tagids')))
318
+            ->setParameter('tagids', $tagIds, IQueryBuilder::PARAM_INT_ARRAY)
319
+            ->execute();
320
+
321
+        foreach ($tags as $tag) {
322
+            $this->dispatcher->dispatch(ManagerEvent::EVENT_DELETE, new ManagerEvent(
323
+                ManagerEvent::EVENT_DELETE, $tag
324
+            ));
325
+        }
326
+
327
+        if ($tagNotFoundException !== null) {
328
+            throw new TagNotFoundException(
329
+                'Tag id(s) not found', 0, $tagNotFoundException, $tagNotFoundException->getMissingTags()
330
+            );
331
+        }
332
+    }
333
+
334
+    /**
335
+     * {@inheritdoc}
336
+     */
337
+    public function canUserAssignTag(ISystemTag $tag, IUser $user): bool {
338
+        // early check to avoid unneeded group lookups
339
+        if ($tag->isUserAssignable() && $tag->isUserVisible()) {
340
+            return true;
341
+        }
342
+
343
+        if ($this->groupManager->isAdmin($user->getUID())) {
344
+            return true;
345
+        }
346
+
347
+        if (!$tag->isUserVisible()) {
348
+            return false;
349
+        }
350
+
351
+        $groupIds = $this->groupManager->getUserGroupIds($user);
352
+        if (!empty($groupIds)) {
353
+            $matchingGroups = array_intersect($groupIds, $this->getTagGroups($tag));
354
+            if (!empty($matchingGroups)) {
355
+                return true;
356
+            }
357
+        }
358
+
359
+        return false;
360
+    }
361
+
362
+    /**
363
+     * {@inheritdoc}
364
+     */
365
+    public function canUserSeeTag(ISystemTag $tag, IUser $user): bool {
366
+        if ($tag->isUserVisible()) {
367
+            return true;
368
+        }
369
+
370
+        if ($this->groupManager->isAdmin($user->getUID())) {
371
+            return true;
372
+        }
373
+
374
+        return false;
375
+    }
376
+
377
+    private function createSystemTagFromRow($row) {
378
+        return new SystemTag((string)$row['id'], $row['name'], (bool)$row['visibility'], (bool)$row['editable']);
379
+    }
380
+
381
+    /**
382
+     * {@inheritdoc}
383
+     */
384
+    public function setTagGroups(ISystemTag $tag, array $groupIds) {
385
+        // delete relationships first
386
+        $this->connection->beginTransaction();
387
+        try {
388
+            $query = $this->connection->getQueryBuilder();
389
+            $query->delete(self::TAG_GROUP_TABLE)
390
+                ->where($query->expr()->eq('systemtagid', $query->createNamedParameter($tag->getId())))
391
+                ->execute();
392
+
393
+            // add each group id
394
+            $query = $this->connection->getQueryBuilder();
395
+            $query->insert(self::TAG_GROUP_TABLE)
396
+                ->values([
397
+                    'systemtagid' => $query->createNamedParameter($tag->getId()),
398
+                    'gid' => $query->createParameter('gid'),
399
+                ]);
400
+            foreach ($groupIds as $groupId) {
401
+                if ($groupId === '') {
402
+                    continue;
403
+                }
404
+                $query->setParameter('gid', $groupId);
405
+                $query->execute();
406
+            }
407
+
408
+            $this->connection->commit();
409
+        } catch (\Exception $e) {
410
+            $this->connection->rollBack();
411
+            throw $e;
412
+        }
413
+    }
414
+
415
+    /**
416
+     * {@inheritdoc}
417
+     */
418
+    public function getTagGroups(ISystemTag $tag): array {
419
+        $groupIds = [];
420
+        $query = $this->connection->getQueryBuilder();
421
+        $query->select('gid')
422
+            ->from(self::TAG_GROUP_TABLE)
423
+            ->where($query->expr()->eq('systemtagid', $query->createNamedParameter($tag->getId())))
424
+            ->orderBy('gid');
425
+
426
+        $result = $query->execute();
427
+        while ($row = $result->fetch()) {
428
+            $groupIds[] = $row['gid'];
429
+        }
430
+
431
+        $result->closeCursor();
432
+
433
+        return $groupIds;
434
+    }
435 435
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -141,14 +141,14 @@  discard block
 block discarded – undo
141 141
 			->from(self::TAG_TABLE);
142 142
 
143 143
 		if (!\is_null($visibilityFilter)) {
144
-			$query->andWhere($query->expr()->eq('visibility', $query->createNamedParameter((int)$visibilityFilter)));
144
+			$query->andWhere($query->expr()->eq('visibility', $query->createNamedParameter((int) $visibilityFilter)));
145 145
 		}
146 146
 
147 147
 		if (!empty($nameSearchPattern)) {
148 148
 			$query->andWhere(
149 149
 				$query->expr()->like(
150 150
 					'name',
151
-					$query->createNamedParameter('%' . $this->connection->escapeLikeParameter($nameSearchPattern). '%')
151
+					$query->createNamedParameter('%'.$this->connection->escapeLikeParameter($nameSearchPattern).'%')
152 152
 				)
153 153
 			);
154 154
 		}
@@ -182,7 +182,7 @@  discard block
 block discarded – undo
182 182
 		$result->closeCursor();
183 183
 		if (!$row) {
184 184
 			throw new TagNotFoundException(
185
-				'Tag ("' . $tagName . '", '. $userVisible . ', ' . $userAssignable . ') does not exist'
185
+				'Tag ("'.$tagName.'", '.$userVisible.', '.$userAssignable.') does not exist'
186 186
 			);
187 187
 		}
188 188
 
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
 			$query->execute();
208 208
 		} catch (UniqueConstraintViolationException $e) {
209 209
 			throw new TagAlreadyExistsException(
210
-				'Tag ("' . $truncatedTagName . '", '. $userVisible . ', ' . $userAssignable . ') already exists',
210
+				'Tag ("'.$truncatedTagName.'", '.$userVisible.', '.$userAssignable.') already exists',
211 211
 				0,
212 212
 				$e
213 213
 			);
@@ -216,7 +216,7 @@  discard block
 block discarded – undo
216 216
 		$tagId = $query->getLastInsertId();
217 217
 
218 218
 		$tag = new SystemTag(
219
-			(string)$tagId,
219
+			(string) $tagId,
220 220
 			$truncatedTagName,
221 221
 			$userVisible,
222 222
 			$userAssignable
@@ -268,7 +268,7 @@  discard block
 block discarded – undo
268 268
 			}
269 269
 		} catch (UniqueConstraintViolationException $e) {
270 270
 			throw new TagAlreadyExistsException(
271
-				'Tag ("' . $newName . '", '. $userVisible . ', ' . $userAssignable . ') already exists',
271
+				'Tag ("'.$newName.'", '.$userVisible.', '.$userAssignable.') already exists',
272 272
 				0,
273 273
 				$e
274 274
 			);
@@ -375,7 +375,7 @@  discard block
 block discarded – undo
375 375
 	}
376 376
 
377 377
 	private function createSystemTagFromRow($row) {
378
-		return new SystemTag((string)$row['id'], $row['name'], (bool)$row['visibility'], (bool)$row['editable']);
378
+		return new SystemTag((string) $row['id'], $row['name'], (bool) $row['visibility'], (bool) $row['editable']);
379 379
 	}
380 380
 
381 381
 	/**
Please login to merge, or discard this patch.