Completed
Pull Request — master (#44)
by Joas
02:28
created

EventHandler   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 0
dl 0
loc 110
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A handle() 0 15 3
C evaluateMentions() 0 27 7
A instantiateNotification() 0 14 1
A extractMentions() 0 9 4
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016 Arthur Schiwon <[email protected]>
4
 * @copyright Copyright (c) 2016 Joas Schilling <[email protected]>
5
 *
6
 * @author Arthur Schiwon <[email protected]>
7
 * @author Joas Schilling <[email protected]>
8
 *
9
 * @license GNU AGPL version 3 or any later version
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
26
namespace OCA\AnnouncementCenter\Comments;
27
28
29
use OCP\Comments\CommentsEvent;
30
use OCP\Comments\IComment;
31
use OCP\Comments\ICommentsEventHandler;
32
use OCP\IURLGenerator;
33
use OCP\IUserManager;
34
use OCP\Notification\IManager as INotificationManager;
35
use OCP\Notification\INotification;
36
37
class EventHandler implements ICommentsEventHandler {
38
39
	/** @var IUserManager */
40
	protected $userManager;
41
	/** @var INotificationManager */
42
	protected $notificationManager;
43
	/** @var IURLGenerator */
44
	protected $urlGenerator;
45
46
	/**
47
	 * EventHandler constructor.
48
	 *
49
	 * @param IUserManager $userManager
50
	 * @param INotificationManager $notificationManager
51
	 * @param IURLGenerator $urlGenerator
52
	 */
53
	public function __construct(IUserManager $userManager, INotificationManager $notificationManager, IURLGenerator $urlGenerator) {
54
		$this->userManager = $userManager;
55
		$this->notificationManager = $notificationManager;
56
		$this->urlGenerator = $urlGenerator;
57
	}
58
59
	/**
60
	 * @param CommentsEvent $event
61
	 * @since 9.2.0
62
	 */
63
	public function handle(CommentsEvent $event) {
64
		if ($event->getComment()->getObjectType() !== 'announcement') {
65
			return;
66
		}
67
68
		$eventType = $event->getEvent();
69
		if (in_array($eventType, [
70
			CommentsEvent::EVENT_ADD,
71
			CommentsEvent::EVENT_PRE_UPDATE,
72
			CommentsEvent::EVENT_UPDATE,
73
			CommentsEvent::EVENT_DELETE,
74
		])) {
75
			$this->evaluateMentions($event);
76
		}
77
	}
78
79
	/**
80
	 * @param CommentsEvent $event
81
	 */
82
	public function evaluateMentions(CommentsEvent $event) {
83
		$comment = $event->getComment();
84
		$mentions = $this->extractMentions($comment->getMessage());
85
		if (empty($mentions)) {
86
			// no one to notify
87
			return;
88
		}
89
90
		$notification = $this->instantiateNotification($comment);
91
92
		foreach ($mentions as $mention) {
93
			$user = substr($mention, 1); // @username → username
94
			if( ($comment->getActorType() === 'users' && $user === $comment->getActorId())
95
				|| !$this->userManager->userExists($user)
96
			) {
97
				// do not notify unknown users or yourself
98
				continue;
99
			}
100
101
			$notification->setUser($user);
102
			if (in_array($event->getEvent(), [CommentsEvent::EVENT_DELETE, CommentsEvent::EVENT_PRE_UPDATE])) {
103
				$this->notificationManager->markProcessed($notification);
104
			} else {
105
				$this->notificationManager->notify($notification);
106
			}
107
		}
108
	}
109
110
	/**
111
	 * creates a notification instance and fills it with comment data
112
	 *
113
	 * @param IComment $comment
114
	 * @return INotification
115
	 */
116
	public function instantiateNotification(IComment $comment) {
117
		$notification = $this->notificationManager->createNotification();
118
		$notification
119
			->setApp('announcementcenter')
120
			->setObject('comment', $comment->getId())
121
			->setSubject('mention', [$comment->getObjectType(), $comment->getObjectId()])
122
			->setDateTime($comment->getCreationDateTime())
123
			->setLink($this->urlGenerator->linkToRouteAbsolute(
124
				'announcementcenter.page.followComment',
125
					['id' => $comment->getId()]
126
			));
127
128
		return $notification;
129
	}
130
131
	/**
132
	 * extracts @-mentions out of a message body.
133
	 *
134
	 * @param string $message
135
	 * @return string[] containing the mentions, e.g. ['@alice', '@bob']
136
	 */
137
	public function extractMentions($message) {
138
		$ok = preg_match_all('/\B@[a-z0-9_\-@\.\']+/i', $message, $mentions);
139
140
		if (!$ok || !isset($mentions[0]) || !is_array($mentions[0])) {
141
			return [];
142
		}
143
144
		return array_unique($mentions[0]);
145
	}
146
}
147