Completed
Pull Request — master (#113)
by Joas
05:01
created

Handler::getById()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3.0261

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 12
cts 14
cp 0.8571
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 15
nc 3
nop 2
crap 3.0261
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 matching the given id
97
	 *
98
	 * @param int $id
99
	 * @param string $user
100
	 */
101 1
	public function deleteById(int $id, string $user) {
102 1
		$sql = $this->connection->getQueryBuilder();
103 1
		$sql->delete('notifications')
104 1
			->where($sql->expr()->eq('notification_id', $sql->createNamedParameter($id)))
105 1
			->andWhere($sql->expr()->eq('user', $sql->createNamedParameter($user)));
106 1
		$sql->execute();
107 1
	}
108
109
	/**
110
	 * Get the notification matching the given id
111
	 *
112
	 * @param int $id
113
	 * @param string $user
114
	 * @return INotification
115
	 * @throws NotificationNotFoundException
116
	 */
117 1
	public function getById(int $id, string $user): INotification {
118 1
		$sql = $this->connection->getQueryBuilder();
119 1
		$sql->select('*')
120 1
			->from('notifications')
121 1
			->where($sql->expr()->eq('notification_id', $sql->createNamedParameter($id)))
122 1
			->andWhere($sql->expr()->eq('user', $sql->createNamedParameter($user)));
123 1
		$statement = $sql->execute();
124 1
		$row = $statement->fetch();
125 1
		$statement->closeCursor();
126
127 1
		if ($row === false) {
128 1
			throw new NotificationNotFoundException('No entry returned from database');
129
		}
130
131
		try {
132 1
			return $this->notificationFromRow($row);
133
		} catch (\InvalidArgumentException $e) {
134
			throw new NotificationNotFoundException('Could not create notification from database row');
135
		}
136
	}
137
138
	/**
139
	 * Return the notifications matching the given Notification
140
	 *
141
	 * @param INotification $notification
142
	 * @param int $limit
143
	 * @return array [notification_id => INotification]
144
	 */
145 2
	public function get(INotification $notification, $limit = 25): array {
146 2
		$sql = $this->connection->getQueryBuilder();
147 2
		$sql->select('*')
148 2
			->from('notifications')
149 2
			->orderBy('notification_id', 'DESC')
150 2
			->setMaxResults($limit);
151
152 2
		$this->sqlWhere($sql, $notification);
153 2
		$statement = $sql->execute();
154
155 2
		$notifications = [];
156 2
		while ($row = $statement->fetch()) {
157
			try {
158 2
				$notifications[(int)$row['notification_id']] = $this->notificationFromRow($row);
159
			} catch (\InvalidArgumentException $e) {
160
				continue;
161
			}
162
		}
163 2
		$statement->closeCursor();
164
165 2
		return $notifications;
166
	}
167
168
	/**
169
	 * Add where statements to a query builder matching the given notification
170
	 *
171
	 * @param IQueryBuilder $sql
172
	 * @param INotification $notification
173
	 */
174 2
	protected function sqlWhere(IQueryBuilder $sql, INotification $notification) {
175 2
		if ($notification->getApp() !== '') {
176 2
			$sql->andWhere($sql->expr()->eq('app', $sql->createNamedParameter($notification->getApp())));
177
		}
178
179 2
		if ($notification->getUser() !== '') {
180 2
			$sql->andWhere($sql->expr()->eq('user', $sql->createNamedParameter($notification->getUser())));
181
		}
182
183 2
		$timestamp = $notification->getDateTime()->getTimestamp();
184 2
		if ($timestamp !== 0) {
185 1
			$sql->andWhere($sql->expr()->eq('timestamp', $sql->createNamedParameter($timestamp)));
186
		}
187
188 2
		if ($notification->getObjectType() !== '') {
189 1
			$sql->andWhere($sql->expr()->eq('object_type', $sql->createNamedParameter($notification->getObjectType())));
190
		}
191
192 2
		if ($notification->getObjectId() !== '') {
193 1
			$sql->andWhere($sql->expr()->eq('object_id', $sql->createNamedParameter($notification->getObjectId())));
194
		}
195
196 2
		if ($notification->getSubject() !== '') {
197 1
			$sql->andWhere($sql->expr()->eq('subject', $sql->createNamedParameter($notification->getSubject())));
198
		}
199
200 2
		if ($notification->getMessage() !== '') {
201 1
			$sql->andWhere($sql->expr()->eq('message', $sql->createNamedParameter($notification->getMessage())));
202
		}
203
204 2
		if ($notification->getLink() !== '') {
205 1
			$sql->andWhere($sql->expr()->eq('link', $sql->createNamedParameter($notification->getLink())));
206
		}
207
208 2
		if ($notification->getIcon() !== '') {
209 1
			$sql->andWhere($sql->expr()->eq('icon', $sql->createNamedParameter($notification->getIcon())));
210
		}
211 2
	}
212
213
	/**
214
	 * Turn a notification into an input statement
215
	 *
216
	 * @param IQueryBuilder $sql
217
	 * @param INotification $notification
218
	 */
219 2
	protected function sqlInsert(IQueryBuilder $sql, INotification $notification) {
220 2
		$actions = [];
221 2
		foreach ($notification->getActions() as $action) {
222
			/** @var IAction $action */
223 2
			$actions[] = [
224 2
				'label' => $action->getLabel(),
225 2
				'link' => $action->getLink(),
226 2
				'type' => $action->getRequestType(),
227 2
				'primary' => $action->isPrimary(),
228
			];
229
		}
230
231 2
		$sql->setValue('app', $sql->createNamedParameter($notification->getApp()))
232 2
			->setValue('user', $sql->createNamedParameter($notification->getUser()))
233 2
			->setValue('timestamp', $sql->createNamedParameter($notification->getDateTime()->getTimestamp()))
234 2
			->setValue('object_type', $sql->createNamedParameter($notification->getObjectType()))
235 2
			->setValue('object_id', $sql->createNamedParameter($notification->getObjectId()))
236 2
			->setValue('subject', $sql->createNamedParameter($notification->getSubject()))
237 2
			->setValue('subject_parameters', $sql->createNamedParameter(json_encode($notification->getSubjectParameters())))
238 2
			->setValue('message', $sql->createNamedParameter($notification->getMessage()))
239 2
			->setValue('message_parameters', $sql->createNamedParameter(json_encode($notification->getMessageParameters())))
240 2
			->setValue('link', $sql->createNamedParameter($notification->getLink()))
241 2
			->setValue('icon', $sql->createNamedParameter($notification->getIcon()))
242 2
			->setValue('actions', $sql->createNamedParameter(json_encode($actions)));
243 2
	}
244
245
	/**
246
	 * Turn a database row into a INotification
247
	 *
248
	 * @param array $row
249
	 * @return INotification
250
	 * @throws \InvalidArgumentException
251
	 */
252 2
	protected function notificationFromRow(array $row): INotification {
253 2
		$dateTime = new \DateTime();
254 2
		$dateTime->setTimestamp((int) $row['timestamp']);
255
256 2
		$notification = $this->manager->createNotification();
257 2
		$notification->setApp($row['app'])
258 2
			->setUser($row['user'])
259 2
			->setDateTime($dateTime)
260 2
			->setObject($row['object_type'], $row['object_id'])
261 2
			->setSubject($row['subject'], (array) json_decode($row['subject_parameters'], true));
262
263 2
		if ($row['message'] !== '') {
264 2
			$notification->setMessage($row['message'], (array) json_decode($row['message_parameters'], true));
265
		}
266 2
		if ($row['link'] !== '' && $row['link'] !== null) {
267 2
			$notification->setLink($row['link']);
268
		}
269 2
		if ($row['icon'] !== '' && $row['icon'] !== null) {
270 2
			$notification->setIcon($row['icon']);
271
		}
272
273 2
		$actions = (array) json_decode($row['actions'], true);
274 2
		foreach ($actions as $actionData) {
275 2
			$action = $notification->createAction();
276 2
			$action->setLabel($actionData['label'])
277 2
				->setLink($actionData['link'], $actionData['type']);
278 2
			if (isset($actionData['primary'])) {
279 2
				$action->setPrimary($actionData['primary']);
280
			}
281 2
			$notification->addAction($action);
282
		}
283
284 2
		return $notification;
285
	}
286
}
287