Completed
Pull Request — master (#70)
by Joas
01:35
created

Manager::removeNotifications()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 0
cts 16
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 13
nc 1
nop 1
crap 2
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, Joas Schilling <[email protected]>
4
 *
5
 * @author Joas Schilling <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\AnnouncementCenter;
25
26
use OCP\BackgroundJob\IJobList;
27
use OCP\Comments\ICommentsManager;
28
use OCP\DB\QueryBuilder\IQueryBuilder;
29
use OCP\IConfig;
30
use OCP\IDBConnection;
31
use OCP\IGroupManager;
32
use OCP\Notification\IManager as INotificationManager;
33
use OCP\IUser;
34
use OCP\IUserSession;
35
36
class Manager {
37
38
	/** @var IConfig */
39
	protected $config;
40
41
	/** @var IDBConnection */
42
	protected $connection;
43
44
	/** @var IGroupManager */
45
	protected $groupManager;
46
47
	/** @var INotificationManager */
48
	protected $notificationManager;
49
50
	/** @var ICommentsManager */
51
	protected $commentsManager;
52
53
	/** @var IJobList */
54
	protected $jobList;
55
56
	/** @var IUserSession */
57
	protected $userSession;
58
59
	/**
60
	 * @param IConfig $config
61
	 * @param IDBConnection $connection
62
	 * @param IGroupManager $groupManager
63
	 * @param INotificationManager $notificationManager
64
	 * @param ICommentsManager $commentsManager
65
	 * @param IJobList $jobList
66
	 * @param IUserSession $userSession
67
	 */
68 7
	public function __construct(IConfig $config,
69
								IDBConnection $connection,
70
								IGroupManager $groupManager,
71
								INotificationManager $notificationManager,
72
								ICommentsManager $commentsManager,
73
								IJobList $jobList,
74
								IUserSession $userSession) {
75 7
		$this->config = $config;
76 7
		$this->connection = $connection;
77 7
		$this->groupManager = $groupManager;
78 7
		$this->notificationManager = $notificationManager;
79 7
		$this->commentsManager = $commentsManager;
80 7
		$this->jobList = $jobList;
81 7
		$this->userSession = $userSession;
82 7
	}
83
84
	/**
85
	 * @param string $subject
86
	 * @param string $message
87
	 * @param string $user
88
	 * @param int $time
89
	 * @param string[] $groups
90
	 * @param bool $comments
91
	 * @return array
92
	 * @throws \InvalidArgumentException when the subject is empty or invalid
93
	 */
94
	public function announce($subject, $message, $user, $time, array $groups, $comments) {
95
		$subject = trim($subject);
96
		$message = trim($message);
97
		if (isset($subject[512])) {
98
			throw new \InvalidArgumentException('Invalid subject', 1);
99
		}
100
101
		if ($subject === '') {
102
			throw new \InvalidArgumentException('Invalid subject', 2);
103
		}
104
105
		$queryBuilder = $this->connection->getQueryBuilder();
106
		$queryBuilder->insert('announcements')
107
			->values([
108
				'announcement_time' => $queryBuilder->createNamedParameter($time),
109
				'announcement_user' => $queryBuilder->createNamedParameter($user),
110
				'announcement_subject' => $queryBuilder->createNamedParameter($subject),
111
				'announcement_message' => $queryBuilder->createNamedParameter($message),
112
				'allow_comments' => $queryBuilder->createNamedParameter((int) $comments),
113
			]);
114
		$queryBuilder->execute();
115
116
		$id = $queryBuilder->getLastInsertId();
117
118
		$addedGroups = 0;
119
		foreach ($groups as $group) {
120
			if ($this->groupManager->groupExists($group)) {
121
				$this->addGroupLink((int) $id, $group);
122
				$addedGroups++;
123
			}
124
		}
125
126
		if ($addedGroups === 0) {
127
			$this->addGroupLink((int) $id, 'everyone');
128
		}
129
130
		return $this->getAnnouncement($id, true, true);
131
	}
132
133
	/**
134
	 * @param int $announcementId
135
	 * @param string $group
136
	 */
137
	protected function addGroupLink($announcementId, $group) {
138
		$query = $this->connection->getQueryBuilder();
139
		$query->insert('announcements_groups')
140
			->values([
141
				'announcement_id' => $query->createNamedParameter($announcementId),
142
				'gid' => $query->createNamedParameter($group),
143
			]);
144
		$query->execute();
145
	}
146
147
	/**
148
	 * @param int $id
149
	 */
150
	public function delete($id) {
151
		// Delete notifications
152
		$notification = $this->notificationManager->createNotification();
153
		$notification->setApp('announcementcenter')
154
			->setObject('announcement', $id);
155
		$this->notificationManager->markProcessed($notification);
156
157
		// Delete comments
158
		$this->commentsManager->deleteCommentsAtObject('announcement', (string) $id);
159
160
		$query = $this->connection->getQueryBuilder();
161
		$query->delete('announcements')
162
			->where($query->expr()->eq('announcement_id', $query->createNamedParameter((int) $id)));
163
		$query->execute();
164
165
		$query = $this->connection->getQueryBuilder();
166
		$query->delete('announcements_groups')
167
			->where($query->expr()->eq('announcement_id', $query->createNamedParameter((int) $id)));
168
		$query->execute();
169
	}
170
171
	/**
172
	 * @param int $id
173
	 * @param bool $parseStrings
174
	 * @param bool $ignorePermissions
175
	 * @param bool $returnGroups
176
	 * @return array
177
	 * @throws \InvalidArgumentException when the id is invalid
178
	 */
179
	public function getAnnouncement($id, $parseStrings = true, $ignorePermissions = false, $returnGroups = true) {
180
		if (!$ignorePermissions) {
181
			$user = $this->userSession->getUser();
182 View Code Duplication
			if ($user instanceof IUser) {
0 ignored issues
show
Bug introduced by
The class OCP\IUser does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
183
				$userGroups = $this->groupManager->getUserGroupIds($user);
184
				$userGroups[] = 'everyone';
185
			} else {
186
				$userGroups = ['everyone'];
187
			}
188
			$isInAdminGroups = array_intersect($this->getAdminGroups(), $userGroups);
189
190
			if (empty($isInAdminGroups)) {
191
				$query = $this->connection->getQueryBuilder();
192
				$query->select('*')
193
					->from('announcements_groups')
194
					->where($query->expr()->eq('announcement_id', $query->createNamedParameter((int) $id)))
195
					->andWhere($query->expr()->in('gid', $query->createNamedParameter($userGroups, IQueryBuilder::PARAM_STR_ARRAY)))
196
					->setMaxResults(1);
197
				$result = $query->execute();
198
				$entry = $result->fetch();
199
				$result->closeCursor();
200
201
				if (!$entry) {
202
					throw new \InvalidArgumentException('Invalid ID');
203
				}
204
			}
205
		}
206
207
		$queryBuilder = $this->connection->getQueryBuilder();
208
		$query = $queryBuilder->select('*')
209
			->from('announcements')
210
			->where($queryBuilder->expr()->eq('announcement_id', $queryBuilder->createParameter('id')))
211
			->setParameter('id', (int) $id);
212
		$result = $query->execute();
213
		$row = $result->fetch();
214
		$result->closeCursor();
215
216
		if ($row === false) {
217
			throw new \InvalidArgumentException('Invalid ID');
218
		}
219
220
		$groups = null;
221
		if ($returnGroups && ($ignorePermissions || !empty($isInAdminGroups))) {
222
			$groups = $this->getGroups((int) $id);
223
		}
224
225
		$announcement = [
226
			'id'		=> (int) $row['announcement_id'],
227
			'author'	=> $row['announcement_user'],
228
			'time'		=> (int) $row['announcement_time'],
229
			'subject'	=> $parseStrings ? $this->parseSubject($row['announcement_subject']) : $row['announcement_subject'],
230
			'message'	=> $parseStrings ? $this->parseMessage($row['announcement_message']) : $row['announcement_message'],
231
			'groups'	=> $groups,
232
			'comments'	=> $row['allow_comments'] ? 0 : false,
233
		];
234
235
		if (!empty($isInAdminGroups)) {
236
			$announcement['notifications'] = $this->hasNotifications((int) $id);
237
		}
238
239
		return $announcement;
240
	}
241
242
	/**
243
	 * @param int $limit
244
	 * @param int $offset
245
	 * @param bool $parseStrings
246
	 * @return array
247
	 */
248
	public function getAnnouncements($limit = 15, $offset = 0, $parseStrings = true) {
249
		$query = $this->connection->getQueryBuilder();
250
		$query->select('a.*')
251
			->from('announcements', 'a')
252
			->orderBy('a.announcement_time', 'DESC')
253
			->groupBy('a.announcement_id')
254
			->setMaxResults($limit);
255
256
		$user = $this->userSession->getUser();
257 View Code Duplication
		if ($user instanceof IUser) {
0 ignored issues
show
Bug introduced by
The class OCP\IUser does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
258
			$userGroups = $this->groupManager->getUserGroupIds($user);
259
			$userGroups[] = 'everyone';
260
		} else {
261
			$userGroups = ['everyone'];
262
		}
263
264
		$isInAdminGroups = array_intersect($this->getAdminGroups(), $userGroups);
265
		if (empty($isInAdminGroups)) {
266
			$query->leftJoin('a', 'announcements_groups', 'ag', $query->expr()->eq(
267
					'a.announcement_id', 'ag.announcement_id'
268
				))
269
				->andWhere($query->expr()->in('ag.gid', $query->createNamedParameter($userGroups, IQueryBuilder::PARAM_STR_ARRAY)));
270
		}
271
272
		if ($offset > 0) {
273
			$query->andWhere($query->expr()->lt('a.announcement_id', $query->createNamedParameter($offset, IQueryBuilder::PARAM_INT)));
274
		}
275
276
		$result = $query->execute();
277
278
		$announcements = [];
279
		while ($row = $result->fetch()) {
280
			$id = (int) $row['announcement_id'];
281
			$announcements[$id] = [
282
				'id'		=> $id,
283
				'author'	=> $row['announcement_user'],
284
				'time'		=> (int) $row['announcement_time'],
285
				'subject'	=> $parseStrings ? $this->parseSubject($row['announcement_subject']) : $row['announcement_subject'],
286
				'message'	=> $parseStrings ? $this->parseMessage($row['announcement_message']) : $row['announcement_message'],
287
				'groups'	=> null,
288
				'comments'	=> $row['allow_comments'] ? $this->getNumberOfComments($id) : false,
289
			];
290
291
			if (!empty($isInAdminGroups)) {
292
				$announcements[$id]['notifications'] = $this->hasNotifications($id);
293
			}
294
		}
295
		$result->closeCursor();
296
297
		if (!empty($isInAdminGroups)) {
298
			$allGroups = $this->getGroups(array_keys($announcements));
299
			foreach ($allGroups as $id => $groups) {
300
				$announcements[$id]['groups'] = $groups;
301
			}
302
		}
303
304
		return $announcements;
305
	}
306
307
	/**
308
	 * Return the groups (or string everyone) which have access to the announcement(s)
309
	 *
310
	 * @param int|int[] $ids
311
	 * @return string[]|array[]
312
	 */
313
	public function getGroups($ids) {
314
		$returnSingleResult = false;
315
		if (is_int($ids)) {
316
			$ids = [$ids];
317
			$returnSingleResult = true;
318
		}
319
320
		$query = $this->connection->getQueryBuilder();
321
		$query->select('*')
322
			->from('announcements_groups')
323
			->where($query->expr()->in('announcement_id', $query->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)));
324
		$result = $query->execute();
325
326
		$groups = [];
327
		while ($row = $result->fetch()) {
328
			if (!isset($groups[(int) $row['announcement_id']])) {
329
				$groups[(int) $row['announcement_id']] = [];
330
			}
331
			$groups[(int) $row['announcement_id']][] = $row['gid'];
332
		}
333
		$result->closeCursor();
334
335
		return $returnSingleResult ? (array) array_pop($groups) : $groups;
336
	}
337
338
	/**
339
	 * @param int $id
340
	 */
341
	public function markNotificationRead($id) {
342
		$user = $this->userSession->getUser();
343
344
		if ($user instanceof IUser) {
0 ignored issues
show
Bug introduced by
The class OCP\IUser does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
345
			$notification = $this->notificationManager->createNotification();
346
			$notification->setApp('announcementcenter')
347
				->setUser($user->getUID())
348
				->setObject('announcement', $id);
349
			$this->notificationManager->markProcessed($notification);
350
		}
351
	}
352
353
	/**
354
	 * @param int $id
355
	 * @return int
356
	 */
357
	protected function getNumberOfComments($id) {
358
		return $this->commentsManager->getNumberOfCommentsForObject('announcement', (string) $id);
359
	}
360
361
	/**
362
	 * @param int $id
363
	 * @return bool
364
	 */
365
	protected function hasNotifications($id) {
366
		$hasJob = $this->jobList->has('OCA\AnnouncementCenter\BackgroundJob', [
367
			'id' => $id,
368
			'activities' => true,
369
			'notifications' => true,
370
		]);
371
372
		$hasJob = $hasJob || $this->jobList->has('OCA\AnnouncementCenter\BackgroundJob', [
373
			'id' => $id,
374
			'activities' => false,
375
			'notifications' => true,
376
		]);
377
378
		if ($hasJob) {
379
			return true;
380
		}
381
382
		$notification = $this->notificationManager->createNotification();
383
		$notification->setApp('announcementcenter')
384
			->setObject('announcement', $id);
385
		return $this->notificationManager->getCount($notification) > 0;
386
	}
387
388
	/**
389
	 * @param int $id
390
	 */
391
	public function removeNotifications($id) {
392
		$this->jobList->remove('OCA\AnnouncementCenter\BackgroundJob', [
393
			'id' => $id,
394
			'activities' => true,
395
			'notifications' => true,
396
		]);
397
398
		$this->jobList->remove('OCA\AnnouncementCenter\BackgroundJob', [
399
			'id' => $id,
400
			'activities' => false,
401
			'notifications' => true,
402
		]);
403
404
		$notification = $this->notificationManager->createNotification();
405
		$notification->setApp('announcementcenter')
406
			->setObject('announcement', $id);
407
		$this->notificationManager->markProcessed($notification);
408
	}
409
410
	/**
411
	 * @param string $message
412
	 * @return string
413
	 */
414
	protected function parseMessage($message) {
415
		return str_replace("\n", '<br />', str_replace(['<', '>'], ['&lt;', '&gt;'], $message));
416
	}
417
418
	/**
419
	 * @param string $subject
420
	 * @return string
421
	 */
422
	protected function parseSubject($subject) {
423
		return str_replace("\n", ' ', str_replace(['<', '>'], ['&lt;', '&gt;'], $subject));
424
	}
425
426
	/**
427
	 * Check if the user is in the admin group
428
	 * @return bool
429
	 */
430
	public function checkIsAdmin() {
431
		$user = $this->userSession->getUser();
432
433
		if ($user instanceof IUser) {
0 ignored issues
show
Bug introduced by
The class OCP\IUser does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
434
			$groups = $this->getAdminGroups();
435
			foreach ($groups as $group) {
436
				if ($this->groupManager->isInGroup($user->getUID(), $group)) {
437
					return true;
438
				}
439
			}
440
		}
441
442
		return false;
443
	}
444
445
	protected function getAdminGroups() {
446
		$adminGroups = $this->config->getAppValue('announcementcenter', 'admin_groups', '["admin"]');
447
		$adminGroups = json_decode($adminGroups, true);
448
		return $adminGroups;
449
	}
450
}
451