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

EventHandler::handle()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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