Completed
Pull Request — master (#265)
by Alexander
04:30
created

ViewController   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 265
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 0

Test Coverage

Coverage 87.61%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 265
ccs 99
cts 113
cp 0.8761
rs 10
c 2
b 0
f 0
wmc 19
lcom 2
cbo 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
B index() 0 54 7
B publicIndex() 0 31 3
A getTimezone() 0 11 2
A getTimezoneWithRegion() 0 3 1
A getTimezoneWithSubRegion() 0 3 1
A getTimezoneList() 0 7 1
A sendEmailPublicLink() 0 16 1
A sendEmail() 0 19 2
1
<?php
2
/**
3
 * Calendar App
4
 *
5
 * @author Georg Ehrke
6
 * @copyright 2016 Georg Ehrke <[email protected]>
7
 * @author Raghu Nayyar
8
 * @copyright 2016 Raghu Nayyar <[email protected]>
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
12
 * License as published by the Free Software Foundation; either
13
 * version 3 of the License, or any later version.
14
 *
15
 * This library 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
21
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 */
24
namespace OCA\Calendar\Controller;
25
26
use OCP\AppFramework\Controller;
27
use OCP\AppFramework\Http;
28
use OCP\AppFramework\Http\ContentSecurityPolicy;
29
use OCP\AppFramework\Http\DataDisplayResponse;
30
use OCP\AppFramework\Http\JSONResponse;
31
use OCP\AppFramework\Http\NotFoundResponse;
32
use OCP\AppFramework\Http\TemplateResponse;
33
use OCP\Defaults;
34
use OCP\IConfig;
35
use OCP\IL10N;
36
use OCP\IRequest;
37
use OCP\IUserSession;
38
use OCP\Mail\IMailer;
39
use OCP\IURLGenerator;
40
41
class ViewController extends Controller {
42
43
	/**
44
	 * @var IURLGenerator
45
	 */
46
	private $urlGenerator;
47
48
	/**
49
	 * @var IConfig
50
	 */
51
	private $config;
52
53
	/**
54
	 * @var IUserSession
55
	 */
56
	private $userSession;
57
58
	/**
59
	 * @var IMailer
60
	 */
61
	private $mailer;
62
63
	/**
64
	 * @var IL10N
65
	 */
66
	private $l10n;
67
68
	/**
69
	 * @var Defaults
70
	 */
71
	private $defaults;
72
73
	/**
74
	 * @param string $appName
75
	 * @param IRequest $request an instance of the request
76
	 * @param IUserSession $userSession
77
	 * @param IConfig $config
78
	 * @param IMailer $mailer
79
	 * @param IL10N $l10N
80
	 * @param Defaults $defaults
81
	 * @param IURLGenerator $urlGenerator
82
	 */
83 17
	public function __construct($appName, IRequest $request, IUserSession $userSession,
84
								IConfig $config, IMailer $mailer, IL10N $l10N,
85
								Defaults $defaults, IURLGenerator $urlGenerator) {
86 17
		parent::__construct($appName, $request);
87 17
		$this->config = $config;
88 17
		$this->userSession = $userSession;
89 17
		$this->mailer = $mailer;
90 17
		$this->l10n = $l10N;
91 17
		$this->defaults = $defaults;
92 17
		$this->urlGenerator = $urlGenerator;
93 17
	}
94
95
	/**
96
	 * @NoAdminRequired
97
	 * @NoCSRFRequired
98
	 *
99
	 * @return TemplateResponse
100
	 */
101 8
	public function index() {
102 8
		$runningOn = $this->config->getSystemValue('version');
103 8
		$runningOnNextcloud10OrLater = version_compare($runningOn, '9.1', '>=');
104
105 8
		$supportsClass = $runningOnNextcloud10OrLater;
106 8
		$assetPipelineBroken = !$runningOnNextcloud10OrLater;
107
108 8
		$isAssetPipelineEnabled = $this->config->getSystemValue('asset-pipeline.enabled', false);
109 8
		if ($isAssetPipelineEnabled && $assetPipelineBroken) {
110 2
			return new TemplateResponse('calendar', 'main-asset-pipeline-unsupported');
111
		}
112
113 6
		$user = $this->userSession->getUser();
114 6
		$userId = $user->getUID();
115 6
		$emailAddress = $user->getEMailAddress();
116
117 6
		$appVersion = $this->config->getAppValue($this->appName, 'installed_version');
118 6
		$initialView = $this->config->getUserValue($userId, $this->appName, 'currentView', null);
119 6
		$skipPopover = $this->config->getUserValue($userId, $this->appName, 'skipPopover', 'no');
120 6
		$weekNumbers = $this->config->getUserValue($userId, $this->appName, 'showWeekNr', 'no');
121 6
		$firstRun = $this->config->getUserValue($userId, $this->appName, 'firstRun', null);
122 6
		$defaultColor = $this->config->getAppValue('theming', 'color', '#0082C9');
123
124
		// the default view will be saved as soon as a user
125
		// opens the calendar app, therefore this is a good
126
		// indication if the calendar was used before
127 6
		if ($firstRun === null) {
128 2
			if ($initialView === null) {
129 1
				$firstRun = 'yes';
130 1
			} else {
131 1
				$this->config->setUserValue($userId, $this->appName, 'firstRun', 'no');
132 1
				$firstRun = 'no';
133
			}
134 2
		}
135
136 6
		if ($initialView === null) {
137 2
			$initialView = 'month';
138 2
		}
139
		
140 6
		$webCalWorkaround = $runningOnNextcloud10OrLater ? 'no' : 'yes';
141
142 6
		return new TemplateResponse('calendar', 'main', [
143 6
			'appVersion' => $appVersion,
144 6
			'initialView' => $initialView,
145 6
			'emailAddress' => $emailAddress,
146 6
			'skipPopover' => $skipPopover,
147 6
			'weekNumbers' => $weekNumbers,
148 6
			'firstRun' => $firstRun,
149 6
			'supportsClass' => $supportsClass,
150 6
			'defaultColor' => $defaultColor,
151 7
			'webCalWorkaround' => $webCalWorkaround,
152 6
			'isPublic' => false,
153 6
		]);
154
	}
155
156
	/**
157
	 * @PublicPage
158
	 * @NoCSRFRequired
159
	 *
160
	 * @return TemplateResponse
161
	 */
162 3
	public function publicIndex() {
163 3
		$runningOn = $this->config->getSystemValue('version');
164 3
		$runningOnServer91OrLater = version_compare($runningOn, '9.1', '>=');
165
166 3
		$supportsClass = $runningOnServer91OrLater;
167 3
		$assetPipelineBroken = !$runningOnServer91OrLater;
168
169 3
		$isAssetPipelineEnabled = $this->config->getSystemValue('asset-pipeline.enabled', false);
170 3
		if ($isAssetPipelineEnabled && $assetPipelineBroken) {
171
			return new TemplateResponse('calendar', 'main-asset-pipeline-unsupported');
172
		}
173
174 3
		$appVersion = $this->config->getAppValue($this->appName, 'installed_version');
175
176 3
		$response = new TemplateResponse('calendar', 'main', [
177 3
			'appVersion' => $appVersion,
178 3
			'initialView' => 'month',
179 3
			'emailAddress' => '',
180 3
			'supportsClass' => $supportsClass,
181 3
			'firstRun' => 'no',
182 3
			'isPublic' => true,
183 3
			'shareURL' => $this->request->getServerProtocol() . '://' . $this->request->getServerHost() . $this->request->getRequestUri(),
184 3
			'previewImage' => $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-touch.png')),
185 3
		], 'public');
186 3
		$response->addHeader('X-Frame-Options', 'ALLOW');
187 3
		$csp = new ContentSecurityPolicy();
188 3
		$csp->addAllowedScriptDomain('*');
189 3
		$response->setContentSecurityPolicy($csp);
190
191 3
		return $response;
192
	}
193
194
	/**
195
	 * @NoAdminRequired
196
	 *
197
	 * @param string $id
198
	 * @return NotFoundResponse|DataDisplayResponse
199
	 */
200 4
	public function getTimezone($id) {
201 4
		if (!in_array($id, $this->getTimezoneList())) {
202 2
			return new NotFoundResponse();
203
		}
204
205 2
		$tzData = file_get_contents(__DIR__ . '/../timezones/' . $id);
206
207 2
		return new DataDisplayResponse($tzData, Http::STATUS_OK, [
208 2
			'content-type' => 'text/calendar',
209 2
		]);
210
	}
211
212
213
	/**
214
	 * @NoAdminRequired
215
	 * @NoCSRFRequired
216
	 * @PublicPage
217
	 *
218
	 * @param $region
219
	 * @param $city
220
	 * @return DataDisplayResponse
221
	 */
222 2
	public function getTimezoneWithRegion($region, $city) {
223 2
		return $this->getTimezone($region . '-' . $city);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->getTimezone($region . '-' . $city); of type OCP\AppFramework\Http\No...ttp\DataDisplayResponse adds the type OCP\AppFramework\Http\NotFoundResponse to the return on line 223 which is incompatible with the return type documented by OCA\Calendar\Controller\...::getTimezoneWithRegion of type OCP\AppFramework\Http\DataDisplayResponse.
Loading history...
224
	}
225
226
227
	/**
228
	 * @NoAdminRequired
229
	 * @PublicPage
230
	 * @NoCSRFRequired
231
	 *
232
	 * @param $region
233
	 * @param $subregion
234
	 * @param $city
235
	 * @return DataDisplayResponse
236
	 */
237
	public function getTimezoneWithSubRegion($region, $subregion, $city) {
238
		return $this->getTimezone($region . '-' . $subregion . '-' . $city);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->getTimezone($regi...bregion . '-' . $city); of type OCP\AppFramework\Http\No...ttp\DataDisplayResponse adds the type OCP\AppFramework\Http\NotFoundResponse to the return on line 238 which is incompatible with the return type documented by OCA\Calendar\Controller\...etTimezoneWithSubRegion of type OCP\AppFramework\Http\DataDisplayResponse.
Loading history...
239
	}
240
241
242
	/**
243
	 * get a list of default timezones
244
	 *
245
	 * @return array
246
	 */
247 4
	private function getTimezoneList() {
248 4
		$allFiles = scandir(__DIR__ . '/../timezones/');
249
250 4
		return array_values(array_filter($allFiles, function($file) {
251 4
			return (substr($file, -4) === '.ics');
252 4
		}));
253
	}
254
255
	/**
256
	 * @param string $to
257
	 * @param string $url
258
	 * @param string $name
259
	 * @return JSONResponse
260
	 * @NoAdminRequired
261
	 */
262 2
	public function sendEmailPublicLink($to, $url, $name) {
263
264 2
		$user = $this->userSession->getUser();
265 2
		$username = $user->getDisplayName();
266
267 2
		$subject = $this->l10n->t('%s has published the calendar "%s"', [$username, $name]);
268
269 2
		$emailTemplateHTML = new TemplateResponse('calendar', 'mail.publication.html', ['subject' => $subject, 'username' => $username, 'calendarname' => $name, 'calendarurl' => $url, 'defaults' => $this->defaults], 'public');
270 2
		$bodyHTML = $emailTemplateHTML->render();
271 2
		$emailTemplateText = new TemplateResponse('calendar', 'mail.publication.text', ['subject' => $subject, 'username' => $username, 'calendarname' => $name, 'calendarurl' => $url], 'blank');
272 2
		$textBody = $emailTemplateText->render();
273
274 2
		$status = $this->sendEmail($to, $subject, $bodyHTML, $textBody);
275
276 2
		return new JSONResponse([], $status);
277
	}
278
279
	/**
280
	 * @param string $target
281
	 * @param string $subject
282
	 * @param string $body
283
	 * @param string $textBody
284
	 * @return int
285
	 */
286 2
	private function sendEmail($target, $subject, $body, $textBody) {
287 2
		if (!$this->mailer->validateMailAddress($target)) {
288 2
			return Http::STATUS_BAD_REQUEST;
289
		}
290
291
		$sendFromDomain = $this->config->getSystemValue('mail_domain', 'domain.org');
292
		$sendFromAddress = $this->config->getSystemValue('mail_from_address', 'nextcloud');
293
		$sendFrom = $sendFromAddress . '@' . $sendFromDomain;
294
295
		$message = $this->mailer->createMessage();
296
		$message->setSubject($subject);
297
		$message->setFrom([$sendFrom => $this->defaults->getName()]);
298
		$message->setTo([$target => 'Recipient']);
299
		$message->setPlainBody($textBody);
300
		$message->setHtmlBody($body);
301
		$this->mailer->send($message);
302
303
		return Http::STATUS_OK;
304
	}
305
}
306