Handler::notificationFromRow()   B
last analyzed

Complexity

Conditions 8
Paths 24

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 8

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 34
ccs 24
cts 24
cp 1
rs 8.1315
cc 8
nc 24
nop 1
crap 8
1
<?php
2
/**
3
 * @author Joas Schilling <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2016, ownCloud, Inc.
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
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, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 *
20
 */
21
22
namespace OCA\Notifications;
23
24
25
use OCA\Notifications\Exceptions\NotificationNotFoundException;
26
use OCP\DB\QueryBuilder\IQueryBuilder;
27
use OCP\IDBConnection;
28
use OCP\Notification\IAction;
29
use OCP\Notification\IManager;
30
use OCP\Notification\INotification;
31
32
class Handler {
33
	/** @var IDBConnection */
34
	protected $connection;
35
36
	/** @var IManager */
37
	protected $manager;
38
39
	/**
40
	 * @param IDBConnection $connection
41
	 * @param IManager $manager
42
	 */
43 8
	public function __construct(IDBConnection $connection, IManager $manager) {
44 8
		$this->connection = $connection;
45 8
		$this->manager = $manager;
46 8
	}
47
48
	/**
49
	 * Add a new notification to the database
50
	 *
51
	 * @param INotification $notification
52
	 * @return int
53
	 */
54 2
	public function add(INotification $notification): int {
55 2
		$sql = $this->connection->getQueryBuilder();
56 2
		$sql->insert('notifications');
57 2
		$this->sqlInsert($sql, $notification);
58 2
		$sql->execute();
59
60 2
		return $sql->getLastInsertId();
61
	}
62
63
	/**
64
	 * Count the notifications matching the given Notification
65
	 *
66
	 * @param INotification $notification
67
	 * @return int
68
	 */
69 2
	public function count(INotification $notification): int {
70 2
		$sql = $this->connection->getQueryBuilder();
71 2
		$sql->select($sql->createFunction('COUNT(*)'))
72 2
			->from('notifications');
73
74 2
		$this->sqlWhere($sql, $notification);
75
76 2
		$statement = $sql->execute();
77 2
		$count = (int) $statement->fetchColumn();
78 2
		$statement->closeCursor();
79
80 2
		return $count;
81
	}
82
83
	/**
84
	 * Delete the notifications matching the given Notification
85
	 *
86
	 * @param INotification $notification
87
	 */
88 2
	public function delete(INotification $notification) {
89 2
		$sql = $this->connection->getQueryBuilder();
90 2
		$sql->delete('notifications');
91 2
		$this->sqlWhere($sql, $notification);
92 2
		$sql->execute();
93 2
	}
94
95
	/**
96
	 * Delete the notification of a given user
97
	 *
98
	 * @param string $user
99
	 */
100
	public function deleteByUser(string $user) {
101
		$notification = $this->manager->createNotification();
102
		try {
103
			$notification->setUser($user);
104
		} catch (\InvalidArgumentException $e) {
105
			return;
106
		}
107
		$this->delete($notification);
108
	}
109
110
	/**
111
	 * Delete the notification matching the given id
112
	 *
113
	 * @param int $id
114
	 * @param string $user
115
	 */
116 1
	public function deleteById(int $id, string $user) {
117 1
		$sql = $this->connection->getQueryBuilder();
118 1
		$sql->delete('notifications')
119 1
			->where($sql->expr()->eq('notification_id', $sql->createNamedParameter($id)))
120 1
			->andWhere($sql->expr()->eq('user', $sql->createNamedParameter($user)));
121 1
		$sql->execute();
122 1
	}
123
124
	/**
125
	 * Get the notification matching the given id
126
	 *
127
	 * @param int $id
128
	 * @param string $user
129
	 * @return INotification
130
	 * @throws NotificationNotFoundException
131
	 */
132 1
	public function getById(int $id, string $user): INotification {
133 1
		$sql = $this->connection->getQueryBuilder();
134 1
		$sql->select('*')
135 1
			->from('notifications')
136 1
			->where($sql->expr()->eq('notification_id', $sql->createNamedParameter($id)))
137 1
			->andWhere($sql->expr()->eq('user', $sql->createNamedParameter($user)));
138 1
		$statement = $sql->execute();
139 1
		$row = $statement->fetch();
140 1
		$statement->closeCursor();
141
142 1
		if ($row === false) {
143 1
			throw new NotificationNotFoundException('No entry returned from database');
144
		}
145
146
		try {
147 1
			return $this->notificationFromRow($row);
148
		} catch (\InvalidArgumentException $e) {
149
			throw new NotificationNotFoundException('Could not create notification from database row');
150
		}
151
	}
152
153
	/**
154
	 * Return the notifications matching the given Notification
155
	 *
156
	 * @param INotification $notification
157
	 * @param int $limit
158
	 * @return array [notification_id => INotification]
159
	 */
160 2
	public function get(INotification $notification, $limit = 25): array {
161 2
		$sql = $this->connection->getQueryBuilder();
162 2
		$sql->select('*')
163 2
			->from('notifications')
164 2
			->orderBy('notification_id', 'DESC')
165 2
			->setMaxResults($limit);
166
167 2
		$this->sqlWhere($sql, $notification);
168 2
		$statement = $sql->execute();
169
170 2
		$notifications = [];
171 2
		while ($row = $statement->fetch()) {
172
			try {
173 2
				$notifications[(int)$row['notification_id']] = $this->notificationFromRow($row);
174
			} catch (\InvalidArgumentException $e) {
175
				continue;
176
			}
177
		}
178 2
		$statement->closeCursor();
179
180 2
		return $notifications;
181
	}
182
183
	/**
184
	 * Add where statements to a query builder matching the given notification
185
	 *
186
	 * @param IQueryBuilder $sql
187
	 * @param INotification $notification
188
	 */
189 2
	protected function sqlWhere(IQueryBuilder $sql, INotification $notification) {
190 2
		if ($notification->getApp() !== '') {
191 2
			$sql->andWhere($sql->expr()->eq('app', $sql->createNamedParameter($notification->getApp())));
192
		}
193
194 2
		if ($notification->getUser() !== '') {
195 2
			$sql->andWhere($sql->expr()->eq('user', $sql->createNamedParameter($notification->getUser())));
196
		}
197
198 2
		$timestamp = $notification->getDateTime()->getTimestamp();
199 2
		if ($timestamp !== 0) {
200 1
			$sql->andWhere($sql->expr()->eq('timestamp', $sql->createNamedParameter($timestamp)));
201
		}
202
203 2
		if ($notification->getObjectType() !== '') {
204 1
			$sql->andWhere($sql->expr()->eq('object_type', $sql->createNamedParameter($notification->getObjectType())));
205
		}
206
207 2
		if ($notification->getObjectId() !== '') {
208 1
			$sql->andWhere($sql->expr()->eq('object_id', $sql->createNamedParameter($notification->getObjectId())));
209
		}
210
211 2
		if ($notification->getSubject() !== '') {
212 1
			$sql->andWhere($sql->expr()->eq('subject', $sql->createNamedParameter($notification->getSubject())));
213
		}
214
215 2
		if ($notification->getMessage() !== '') {
216 1
			$sql->andWhere($sql->expr()->eq('message', $sql->createNamedParameter($notification->getMessage())));
217
		}
218
219 2
		if ($notification->getLink() !== '') {
220 1
			$sql->andWhere($sql->expr()->eq('link', $sql->createNamedParameter($notification->getLink())));
221
		}
222
223 2
		if ($notification->getIcon() !== '') {
224 1
			$sql->andWhere($sql->expr()->eq('icon', $sql->createNamedParameter($notification->getIcon())));
225
		}
226 2
	}
227
228
	/**
229
	 * Turn a notification into an input statement
230
	 *
231
	 * @param IQueryBuilder $sql
232
	 * @param INotification $notification
233
	 */
234 2
	protected function sqlInsert(IQueryBuilder $sql, INotification $notification) {
235 2
		$actions = [];
236 2
		foreach ($notification->getActions() as $action) {
237
			/** @var IAction $action */
238 2
			$actions[] = [
239 2
				'label' => $action->getLabel(),
240 2
				'link' => $action->getLink(),
241 2
				'type' => $action->getRequestType(),
242 2
				'primary' => $action->isPrimary(),
243
			];
244
		}
245
246 2
		$sql->setValue('app', $sql->createNamedParameter($notification->getApp()))
247 2
			->setValue('user', $sql->createNamedParameter($notification->getUser()))
248 2
			->setValue('timestamp', $sql->createNamedParameter($notification->getDateTime()->getTimestamp()))
249 2
			->setValue('object_type', $sql->createNamedParameter($notification->getObjectType()))
250 2
			->setValue('object_id', $sql->createNamedParameter($notification->getObjectId()))
251 2
			->setValue('subject', $sql->createNamedParameter($notification->getSubject()))
252 2
			->setValue('subject_parameters', $sql->createNamedParameter(json_encode($notification->getSubjectParameters())))
253 2
			->setValue('message', $sql->createNamedParameter($notification->getMessage()))
254 2
			->setValue('message_parameters', $sql->createNamedParameter(json_encode($notification->getMessageParameters())))
255 2
			->setValue('link', $sql->createNamedParameter($notification->getLink()))
256 2
			->setValue('icon', $sql->createNamedParameter($notification->getIcon()))
257 2
			->setValue('actions', $sql->createNamedParameter(json_encode($actions)));
258 2
	}
259
260
	/**
261
	 * Turn a database row into a INotification
262
	 *
263
	 * @param array $row
264
	 * @return INotification
265
	 * @throws \InvalidArgumentException
266
	 */
267 2
	protected function notificationFromRow(array $row): INotification {
268 2
		$dateTime = new \DateTime();
269 2
		$dateTime->setTimestamp((int) $row['timestamp']);
270
271 2
		$notification = $this->manager->createNotification();
272 2
		$notification->setApp($row['app'])
273 2
			->setUser($row['user'])
274 2
			->setDateTime($dateTime)
275 2
			->setObject($row['object_type'], $row['object_id'])
276 2
			->setSubject($row['subject'], (array) json_decode($row['subject_parameters'], true));
277
278 2
		if ($row['message'] !== '') {
279 2
			$notification->setMessage($row['message'], (array) json_decode($row['message_parameters'], true));
280
		}
281 2
		if ($row['link'] !== '' && $row['link'] !== null) {
282 2
			$notification->setLink($row['link']);
283
		}
284 2
		if ($row['icon'] !== '' && $row['icon'] !== null) {
285 2
			$notification->setIcon($row['icon']);
286
		}
287
288 2
		$actions = (array) json_decode($row['actions'], true);
289 2
		foreach ($actions as $actionData) {
290 2
			$action = $notification->createAction();
291 2
			$action->setLabel($actionData['label'])
292 2
				->setLink($actionData['link'], $actionData['type']);
293 2
			if (isset($actionData['primary'])) {
294 2
				$action->setPrimary($actionData['primary']);
295
			}
296 2
			$notification->addAction($action);
297
		}
298
299 2
		return $notification;
300
	}
301
}
302