Completed
Pull Request — master (#1523)
by
unknown
07:15
created

AccountsController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 23
ccs 10
cts 10
cp 1
rs 9.0856
cc 1
eloc 21
nc 1
nop 11
crap 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 * @author Christoph Wurst <[email protected]>
4
 * @author Christoph Wurst <[email protected]>
5
 * @author Jan-Christoph Borchardt <[email protected]>
6
 * @author Lukas Reschke <[email protected]>
7
 * @author Robin McCorkell <[email protected]>
8
 * @author Thomas Müller <[email protected]>
9
 *
10
 * ownCloud - Mail
11
 *
12
 * This code is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License, version 3,
14
 * as published by the Free Software Foundation.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License, version 3,
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
23
 *
24
 */
25
26
namespace OCA\Mail\Controller;
27
28
use Exception;
29
use Horde_Exception;
30
use Horde_Imap_Client;
31
use OCA\Mail\Account;
32
use OCA\Mail\Db\MailAccount;
33
use OCA\Mail\Model\Message;
34
use OCA\Mail\Model\ReplyMessage;
35
use OCA\Mail\Service\AccountService;
36
use OCA\Mail\Service\AutoCompletion\AddressCollector;
37
use OCA\Mail\Service\AutoConfig\AutoConfig;
38
use OCA\Mail\Service\Logger;
39
use OCA\Mail\Service\UnifiedAccount;
40
use OCP\AppFramework\Controller;
41
use OCP\AppFramework\Db\DoesNotExistException;
42
use OCP\AppFramework\Http;
43
use OCP\AppFramework\Http\JSONResponse;
44
use OCP\AppFramework\Http\Response;
45
use OCP\Files\File;
46
use OCP\Files\Folder;
47
use OCP\IL10N;
48
use OCP\IRequest;
49
use OCP\Security\ICrypto;
50
use OCA\Mail\Service\AliasesService;
51
52
class AccountsController extends Controller {
53
54
	/** @var AccountService */
55
	private $accountService;
56
57
	/** @var string */
58
	private $currentUserId;
59
60
	/** @var AutoConfig */
61
	private $autoConfig;
62
63
	/** @var Folder */
64
	private $userFolder;
65
66
	/** @var Logger */
67
	private $logger;
68
69
	/** @var IL10N */
70
	private $l10n;
71
72
	/** @var ICrypto */
73
	private $crypto;
74
75
	/** @var AddressCollector  */
76
	private $addressCollector;
77
78
	private $aliasesService;
79
80
	/**
81
	 * @param string $appName
82
	 * @param IRequest $request
83
	 * @param AccountService $accountService
84
	 * @param $UserId
85
	 * @param $userFolder
86
	 * @param AutoConfig $autoConfig
87
	 * @param Logger $logger
88 15
	 * @param IL10N $l10n
89
	 * @param ICrypto $crypto
90
	 */
91
	public function __construct($appName,
92
		IRequest $request,
93
		AccountService $accountService,
94
		$UserId,
95
		$userFolder,
96
		AutoConfig $autoConfig,
97
		Logger $logger,
98
		IL10N $l10n,
99 15
		ICrypto $crypto,
100 15
		AddressCollector $addressCollector,
101 15
		AliasesService $aliasesService
102 15
	) {
103 15
		parent::__construct($appName, $request);
104 15
		$this->accountService = $accountService;
105 15
		$this->currentUserId = $UserId;
106 15
		$this->userFolder = $userFolder;
107 15
		$this->autoConfig = $autoConfig;
108 15
		$this->logger = $logger;
109
		$this->l10n = $l10n;
110
		$this->crypto = $crypto;
111
		$this->addressCollector = $addressCollector;
112
		$this->aliasesService = $aliasesService;
113
	}
114
115
	/**
116 1
	 * @NoAdminRequired
117 1
	 * @NoCSRFRequired
118
	 *
119 1
	 * @return JSONResponse
120 1
	 */
121 1
	public function index() {
122 1
		$mailAccounts = $this->accountService->findByUserId($this->currentUserId);
123
124 1
		$json = [];
125
		foreach ($mailAccounts as $mailAccount) {
126
			$json[] = $mailAccount->getConfiguration();
127
		}
128
		foreach ($json as $key => $mailAccount) {
129
			$json[$key]['aliases'] = $this->aliasesService->findAll($mailAccount['accountId'], $this->currentUserId);
130
		}
131
		return new JSONResponse($json);
132
	}
133 2
134
	/**
135 2
	 * @NoAdminRequired
136
	 *
137 2
	 * @param int $accountId
138 1
	 * @return JSONResponse
139 1
	 */
140
	public function show($accountId) {
141
		try {
142
			$account = $this->accountService->find($this->currentUserId, $accountId);
143
144
			return new JSONResponse($account->getConfiguration());
145
		} catch (DoesNotExistException $e) {
0 ignored issues
show
Bug introduced by
The class OCP\AppFramework\Db\DoesNotExistException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
146
			return new JSONResponse([], 404);
147
		}
148
	}
149
150
	/**
151
	 * @NoAdminRequired
152
	 */
153
	public function update() {
154
		$response = new Response();
155
		$response->setStatus(Http::STATUS_NOT_IMPLEMENTED);
156
		return $response;
157
	}
158 2
159
	/**
160 2
	 * @NoAdminRequired
161
	 *
162 1
	 * @param int $accountId
163 1
	 * @return JSONResponse
164 1
	 */
165
	public function destroy($accountId) {
166
		try {
167
			$this->accountService->delete($this->currentUserId, $accountId);
168
169
			return new JSONResponse();
170
		} catch (DoesNotExistException $e) {
0 ignored issues
show
Bug introduced by
The class OCP\AppFramework\Db\DoesNotExistException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
171
			return new JSONResponse();
172
		}
173
	}
174
175
	/**
176
	 * @NoAdminRequired
177
	 *
178
	 * @param string $accountName
179
	 * @param string $emailAddress
180
	 * @param string $password
181
	 * @param string $imapHost
182
	 * @param int $imapPort
183
	 * @param string $imapSslMode
184
	 * @param string $imapUser
185
	 * @param string $imapPassword
186
	 * @param string $smtpHost
187 2
	 * @param int $smtpPort
188
	 * @param string $smtpSslMode
189
	 * @param string $smtpUser
190
	 * @param string $smtpPassword
191
	 * @param bool $autoDetect
192 2
	 * @return JSONResponse
193 2
	 */
194 2
	public function create($accountName, $emailAddress, $password,
195 2
		$imapHost, $imapPort, $imapSslMode, $imapUser, $imapPassword,
196
		$smtpHost, $smtpPort, $smtpSslMode, $smtpUser, $smtpPassword,
197
		$autoDetect) {
198
		try {
199
			if ($autoDetect) {
200
				$this->logger->info('setting up auto detected account');
201
				$newAccount = $this->autoConfig->createAutoDetected($emailAddress, $password, $accountName);
202
			} else {
203
				$this->logger->info('Setting up manually configured account');
204
				$newAccount = new MailAccount([
205
					'accountName'  => $accountName,
206
					'emailAddress' => $emailAddress,
207
					'imapHost'     => $imapHost,
208
					'imapPort'     => $imapPort,
209
					'imapSslMode'  => $imapSslMode,
210
					'imapUser'     => $imapUser,
211
					'imapPassword' => $imapPassword,
212
					'smtpHost'     => $smtpHost,
213
					'smtpPort'     => $smtpPort,
214
					'smtpSslMode'  => $smtpSslMode,
215
					'smtpUser'     => $smtpUser,
216
					'smtpPassword' => $smtpPassword
217
				]);
218
				$newAccount->setUserId($this->currentUserId);
219
				$newAccount->setInboundPassword(
220
					$this->crypto->encrypt(
221
						$newAccount->getInboundPassword()
222
					)
223
				);
224
				$newAccount->setOutboundPassword(
225
					$this->crypto->encrypt(
226
						$newAccount->getOutboundPassword()
227
					)
228 2
				);
229 1
230 1
				$a = new Account($newAccount);
231 1
				$this->logger->debug('Connecting to account {account}', ['account' => $newAccount->getEmail()]);
232 1
				$a->testConnectivity();
233 1
			}
234
235 1
			if ($newAccount) {
236
				$this->accountService->save($newAccount);
237
				$this->logger->debug("account created " . $newAccount->getId());
238
				return new JSONResponse(
239
					['data' => ['id' => $newAccount->getId()]],
240
					Http::STATUS_CREATED);
241
			}
242 1
		} catch (Exception $ex) {
243 1
			$this->logger->error('Creating account failed: ' . $ex->getMessage());
244 1
			return new JSONResponse(
245 1
				array('message' => $this->l10n->t('Creating account failed: ') . $ex->getMessage()),
246
				HTTP::STATUS_BAD_REQUEST);
247
		}
248
249
		$this->logger->info('Auto detect failed');
250
		return new JSONResponse(
251
			array('message' => $this->l10n->t('Auto detect failed. Please use manual mode.')),
252
			HTTP::STATUS_BAD_REQUEST);
253
	}
254
255
	/**
256
	 * @NoAdminRequired
257
	 *
258
	 * @param int $accountId
259
	 * @param string $folderId
260
	 * @param string $subject
261
	 * @param string $body
262
	 * @param string $to
263 4
	 * @param string $cc
264
	 * @param string $bcc
265 4
	 * @param int $draftUID
266 4
	 * @param string $messageId
267 2
	 * @param mixed $attachments
268 2
	 * @return JSONResponse
269 4
	 */
270
	public function send($accountId, $folderId, $subject, $body, $to, $cc,
271
		$bcc, $draftUID, $messageId, $attachments, $aliasId) {
272
		$account = $this->accountService->find($this->currentUserId, $accountId);
273
		$alias = $aliasId ? $this->aliasesService->find($aliasId, $this->currentUserId) : null;
274
		if ($account instanceof UnifiedAccount) {
275
			list($account, $folderId, $messageId) = $account->resolve($messageId);
276 4
		}
277 4
		if (!$account instanceof Account) {
278
			return new JSONResponse(
279 2
				['message' => 'Invalid account'],
280
				Http::STATUS_BAD_REQUEST
281 2
			);
282 2
		}
283
284 2
		$mailbox = null;
285
		if (!is_null($folderId) && !is_null($messageId)) {
286
			// Reply
287
			$message = $account->newReplyMessage();
288 2
289
			$mailbox = $account->getMailbox(base64_decode($folderId));
290
			$repliedMessage = $mailbox->getMessage($messageId);
291 2
292
			if (is_null($subject)) {
293
				// No subject set – use the original one
294 2
				$message->setSubject($repliedMessage->getSubject());
295
			} else {
296
				$message->setSubject($subject);
297 2
			}
298 2
299
			if (is_null($to)) {
300 2
				$message->setTo(Message::parseAddressList($repliedMessage->getToList()));
0 ignored issues
show
Documentation introduced by
$repliedMessage->getToList() is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
301 2
			} else {
302 2
				$message->setTo(Message::parseAddressList($to));
303
			}
304
305 4
			$message->setRepliedMessage($repliedMessage);
306 4
		} else {
307 4
			// New message
308 4
			$message = $account->newMessage();
309
			$message->setTo(Message::parseAddressList($to));
310 4
			$message->setSubject($subject ? : '');
311 4
		}
312 4
313 4
		$message->setName($alias ? $alias->name : $account->getName());
314 4
		$message->setFrom($alias ? $alias->alias : $account->getEMailAddress());
315 4
		$message->setCC(Message::parseAddressList($cc));
316 4
		$message->setBcc(Message::parseAddressList($bcc));
317 4
		$message->setContent($body);
318 4
319 4
		if (is_array($attachments)) {
320 4
			foreach($attachments as $attachment) {
321
				$fileName = $attachment['fileName'];
322
				if ($this->userFolder->nodeExists($fileName)) {
323 4
					$f = $this->userFolder->get($fileName);
324
					if ($f instanceof File) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\File does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
325
						$message->addAttachmentFromFiles($f);
326 4
					}
327 2
				}
328 2
			}
329
		}
330
331
		try {
332 4
			$account->sendMessage($message, $draftUID);
333 4
334 4
			// in case of reply we flag the message as answered
335 1
			if ($message instanceof ReplyMessage) {
336
				$mailbox->setMessageFlag($messageId, Horde_Imap_Client::FLAG_ANSWERED, true);
337 4
			}
338
339
			// Collect mail addresses
340
			try {
341
				$addresses = array_merge($message->getToList(), $message->getCCList(), $message->getBCCList());
342
				$this->addressCollector->addAddresses($addresses);
343
			} catch (Exception $e) {
344
				$this->logger->error("Error while collecting mail addresses: " . $e->getMessage());
345 4
			}
346
		} catch (Horde_Exception $ex) {
0 ignored issues
show
Bug introduced by
The class Horde_Exception does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
347
			$this->logger->error('Sending mail failed: ' . $ex->getMessage());
348
			return new JSONResponse(
349
				array('message' => $ex->getMessage()),
350
				Http::STATUS_INTERNAL_SERVER_ERROR
351
			);
352
		}
353
354
		return new JSONResponse();
355
	}
356
357
	/**
358
	 * @NoAdminRequired
359
	 * 
360
	 * @param int $accountId
361 4
	 * @param string $subject
362 4
	 * @param string $body
363 2
	 * @param string $to
364 2
	 * @param string $cc
365 2
	 * @param string $bcc
366
	 * @param int $uid
367
	 * @param string $messageId
368 4
	 * @return JSONResponse
369 4
	 */
370 2
	public function draft($accountId, $subject, $body, $to, $cc, $bcc, $uid, $messageId) {
371 2
		if (is_null($uid)) {
372 4
			$this->logger->info("Saving a new draft in account <$accountId>");
373
		} else {
374
			$this->logger->info("Updating draft <$uid> in account <$accountId>");
375
		}
376
377
		$account = $this->accountService->find($this->currentUserId, $accountId);
378
		if ($account instanceof UnifiedAccount) {
379 4
			list($account) = $account->resolve($messageId);
380 4
		}
381 4
		if (!$account instanceof Account) {
382 4
			return new JSONResponse(
383 4
				array('message' => 'Invalid account'),
384 4
				Http::STATUS_BAD_REQUEST
385 4
			);
386
		}
387
388
		$message = $account->newMessage();
389 4
		$message->setTo(Message::parseAddressList($to));
390 4
		$message->setSubject($subject ? : '');
391
		$message->setFrom($account->getEMailAddress());
392
		$message->setCC(Message::parseAddressList($cc));
393
		$message->setBcc(Message::parseAddressList($bcc));
394
		$message->setContent($body);
395
396
		// create transport and save message
397
		try {
398
			$newUID = $account->saveDraft($message, $uid);
399
		} catch (Horde_Exception $ex) {
0 ignored issues
show
Bug introduced by
The class Horde_Exception does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
400 4
			$this->logger->error('Saving draft failed: ' . $ex->getMessage());
401
			return new JSONResponse(
402 4
				[
403
					'message' => $ex->getMessage()
404
				],
405
				Http::STATUS_INTERNAL_SERVER_ERROR
406
			);
407
		}
408
409
		return new JSONResponse([
410
			'uid' => $newUID
411
		]);
412
	}
413
414
}
415