Completed
Push — master ( f25d34...b91e75 )
by Morris
17:07
created

Manager::setPreparingPushNotification()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Joas Schilling <[email protected]>
6
 * @author Morris Jobke <[email protected]>
7
 * @author Roeland Jago Douma <[email protected]>
8
 *
9
 * @license AGPL-3.0
10
 *
11
 * This code is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License, version 3,
13
 * as published by the Free Software Foundation.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License, version 3,
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
22
 *
23
 */
24
25
namespace OC\Notification;
26
27
28
use OCP\Notification\IApp;
29
use OCP\Notification\IManager;
30
use OCP\Notification\INotification;
31
use OCP\Notification\INotifier;
32
use OCP\RichObjectStrings\IValidator;
33
34
class Manager implements IManager {
35
	/** @var IValidator */
36
	protected $validator;
37
38
	/** @var IApp[] */
39
	protected $apps;
40
41
	/** @var INotifier[] */
42
	protected $notifiers;
43
44
	/** @var array[] */
45
	protected $notifiersInfo;
46
47
	/** @var \Closure[] */
48
	protected $appsClosures;
49
50
	/** @var \Closure[] */
51
	protected $notifiersClosures;
52
53
	/** @var \Closure[] */
54
	protected $notifiersInfoClosures;
55
56
	/** @var bool */
57
	protected $preparingPushNotification;
58
59
	/**
60
	 * Manager constructor.
61
	 *
62
	 * @param IValidator $validator
63
	 */
64
	public function __construct(IValidator $validator) {
65
		$this->validator = $validator;
66
		$this->apps = [];
67
		$this->notifiers = [];
68
		$this->notifiersInfo = [];
69
		$this->appsClosures = [];
70
		$this->notifiersClosures = [];
71
		$this->notifiersInfoClosures = [];
72
		$this->preparingPushNotification = false;
73
	}
74
75
	/**
76
	 * @param \Closure $service The service must implement IApp, otherwise a
77
	 *                          \InvalidArgumentException is thrown later
78
	 * @since 8.2.0
79
	 */
80
	public function registerApp(\Closure $service) {
81
		$this->appsClosures[] = $service;
82
		$this->apps = [];
83
	}
84
85
	/**
86
	 * @param \Closure $service The service must implement INotifier, otherwise a
87
	 *                          \InvalidArgumentException is thrown later
88
	 * @param \Closure $info    An array with the keys 'id' and 'name' containing
89
	 *                          the app id and the app name
90
	 * @since 8.2.0 - Parameter $info was added in 9.0.0
91
	 */
92
	public function registerNotifier(\Closure $service, \Closure $info) {
93
		$this->notifiersClosures[] = $service;
94
		$this->notifiersInfoClosures[] = $info;
95
		$this->notifiers = [];
96
		$this->notifiersInfo = [];
97
	}
98
99
	/**
100
	 * @return IApp[]
101
	 */
102 View Code Duplication
	protected function getApps(): array {
103
		if (!empty($this->apps)) {
104
			return $this->apps;
105
		}
106
107
		$this->apps = [];
108
		foreach ($this->appsClosures as $closure) {
109
			$app = $closure();
110
			if (!($app instanceof IApp)) {
111
				throw new \InvalidArgumentException('The given notification app does not implement the IApp interface');
112
			}
113
			$this->apps[] = $app;
114
		}
115
116
		return $this->apps;
117
	}
118
119
	/**
120
	 * @return INotifier[]
121
	 */
122 View Code Duplication
	protected function getNotifiers(): array {
123
		if (!empty($this->notifiers)) {
124
			return $this->notifiers;
125
		}
126
127
		$this->notifiers = [];
128
		foreach ($this->notifiersClosures as $closure) {
129
			$notifier = $closure();
130
			if (!($notifier instanceof INotifier)) {
131
				throw new \InvalidArgumentException('The given notifier does not implement the INotifier interface');
132
			}
133
			$this->notifiers[] = $notifier;
134
		}
135
136
		return $this->notifiers;
137
	}
138
139
	/**
140
	 * @return array[]
141
	 */
142
	public function listNotifiers(): array {
143
		if (!empty($this->notifiersInfo)) {
144
			return $this->notifiersInfo;
145
		}
146
147
		$this->notifiersInfo = [];
148
		foreach ($this->notifiersInfoClosures as $closure) {
149
			$notifier = $closure();
150
			if (!\is_array($notifier) || \count($notifier) !== 2 || !isset($notifier['id'], $notifier['name'])) {
151
				throw new \InvalidArgumentException('The given notifier information is invalid');
152
			}
153
			if (isset($this->notifiersInfo[$notifier['id']])) {
154
				throw new \InvalidArgumentException('The given notifier ID ' . $notifier['id'] . ' is already in use');
155
			}
156
			$this->notifiersInfo[$notifier['id']] = $notifier['name'];
157
		}
158
159
		return $this->notifiersInfo;
160
	}
161
162
	/**
163
	 * @return INotification
164
	 * @since 8.2.0
165
	 */
166
	public function createNotification(): INotification {
167
		return new Notification($this->validator);
168
	}
169
170
	/**
171
	 * @return bool
172
	 * @since 8.2.0
173
	 */
174
	public function hasNotifiers(): bool {
175
		return !empty($this->notifiersClosures);
176
	}
177
178
	/**
179
	 * @param bool $preparingPushNotification
180
	 * @since 14.0.0
181
	 */
182
	public function setPreparingPushNotification($preparingPushNotification) {
183
		$this->preparingPushNotification = $preparingPushNotification;
184
	}
185
186
	/**
187
	 * @return bool
188
	 * @since 14.0.0
189
	 */
190
	public function isPreparingPushNotification(): bool {
191
		return $this->preparingPushNotification;
192
	}
193
194
	/**
195
	 * @param INotification $notification
196
	 * @throws \InvalidArgumentException When the notification is not valid
197
	 * @since 8.2.0
198
	 */
199
	public function notify(INotification $notification) {
200
		if (!$notification->isValid()) {
201
			throw new \InvalidArgumentException('The given notification is invalid');
202
		}
203
204
		$apps = $this->getApps();
205
206
		foreach ($apps as $app) {
207
			try {
208
				$app->notify($notification);
209
			} catch (\InvalidArgumentException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
210
			}
211
		}
212
	}
213
214
	/**
215
	 * @param INotification $notification
216
	 * @param string $languageCode The code of the language that should be used to prepare the notification
217
	 * @return INotification
218
	 * @throws \InvalidArgumentException When the notification was not prepared by a notifier
219
	 * @since 8.2.0
220
	 */
221
	public function prepare(INotification $notification, $languageCode): INotification {
222
		$notifiers = $this->getNotifiers();
223
224
		foreach ($notifiers as $notifier) {
225
			try {
226
				$notification = $notifier->prepare($notification, $languageCode);
227
			} catch (\InvalidArgumentException $e) {
228
				continue;
229
			}
230
231
			if (!($notification instanceof INotification) || !$notification->isValidParsed()) {
232
				throw new \InvalidArgumentException('The given notification has not been handled');
233
			}
234
		}
235
236
		if (!($notification instanceof INotification) || !$notification->isValidParsed()) {
237
			throw new \InvalidArgumentException('The given notification has not been handled');
238
		}
239
240
		return $notification;
241
	}
242
243
	/**
244
	 * @param INotification $notification
245
	 */
246
	public function markProcessed(INotification $notification) {
247
		$apps = $this->getApps();
248
249
		foreach ($apps as $app) {
250
			$app->markProcessed($notification);
251
		}
252
	}
253
254
	/**
255
	 * @param INotification $notification
256
	 * @return int
257
	 */
258
	public function getCount(INotification $notification): int {
259
		$apps = $this->getApps();
260
261
		$count = 0;
262
		foreach ($apps as $app) {
263
			$count += $app->getCount($notification);
264
		}
265
266
		return $count;
267
	}
268
}
269