Passed
Push — master ( 49415e...22ff60 )
by Morris
13:58 queued 10s
created

AvatarController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 10
dl 0
loc 20
rs 9.9666
c 0
b 0
f 0

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
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Christoph Wurst <[email protected]>
6
 * @author Daniel Kesselberg <[email protected]>
7
 * @author Joas Schilling <[email protected]>
8
 * @author John Molakvoæ (skjnldsv) <[email protected]>
9
 * @author Lukas Reschke <[email protected]>
10
 * @author Morris Jobke <[email protected]>
11
 * @author Roeland Jago Douma <[email protected]>
12
 * @author Thomas Müller <[email protected]>
13
 * @author Vincent Petry <[email protected]>
14
 *
15
 * @license AGPL-3.0
16
 *
17
 * This code is free software: you can redistribute it and/or modify
18
 * it under the terms of the GNU Affero General Public License, version 3,
19
 * as published by the Free Software Foundation.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
 * GNU Affero General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU Affero General Public License, version 3,
27
 * along with this program. If not, see <http://www.gnu.org/licenses/>
28
 *
29
 */
30
31
namespace OC\Core\Controller;
32
33
use OC\AppFramework\Utility\TimeFactory;
34
use OCP\AppFramework\Controller;
35
use OCP\AppFramework\Http;
36
use OCP\AppFramework\Http\DataDisplayResponse;
37
use OCP\AppFramework\Http\FileDisplayResponse;
38
use OCP\AppFramework\Http\JSONResponse;
39
use OCP\Files\File;
40
use OCP\Files\IRootFolder;
41
use OCP\IAvatarManager;
42
use OCP\ICache;
43
use OCP\IL10N;
44
use OCP\ILogger;
45
use OCP\IRequest;
46
use OCP\IUserManager;
47
use OCP\IUserSession;
48
49
/**
50
 * Class AvatarController
51
 *
52
 * @package OC\Core\Controller
53
 */
54
class AvatarController extends Controller {
55
56
	/** @var IAvatarManager */
57
	protected $avatarManager;
58
59
	/** @var ICache */
60
	protected $cache;
61
62
	/** @var IL10N */
63
	protected $l;
64
65
	/** @var IUserManager */
66
	protected $userManager;
67
68
	/** @var IUserSession */
69
	protected $userSession;
70
71
	/** @var IRootFolder */
72
	protected $rootFolder;
73
74
	/** @var ILogger */
75
	protected $logger;
76
77
	/** @var string */
78
	protected $userId;
79
80
	/** @var TimeFactory */
81
	protected $timeFactory;
82
83
	public function __construct($appName,
84
								IRequest $request,
85
								IAvatarManager $avatarManager,
86
								ICache $cache,
87
								IL10N $l10n,
88
								IUserManager $userManager,
89
								IRootFolder $rootFolder,
90
								ILogger $logger,
91
								$userId,
92
								TimeFactory $timeFactory) {
93
		parent::__construct($appName, $request);
94
95
		$this->avatarManager = $avatarManager;
96
		$this->cache = $cache;
97
		$this->l = $l10n;
98
		$this->userManager = $userManager;
99
		$this->rootFolder = $rootFolder;
100
		$this->logger = $logger;
101
		$this->userId = $userId;
102
		$this->timeFactory = $timeFactory;
103
	}
104
105
106
	/**
107
	 * @NoAdminRequired
108
	 * @NoCSRFRequired
109
	 * @NoSameSiteCookieRequired
110
	 * @PublicPage
111
	 *
112
	 * @param string $userId
113
	 * @param int $size
114
	 * @return JSONResponse|FileDisplayResponse
115
	 */
116
	public function getAvatar($userId, $size) {
117
		// min/max size
118
		if ($size > 2048) {
119
			$size = 2048;
120
		} elseif ($size <= 0) {
121
			$size = 64;
122
		}
123
124
		try {
125
			$avatar = $this->avatarManager->getAvatar($userId);
126
			$avatarFile = $avatar->getFile($size);
127
			$response = new FileDisplayResponse(
128
				$avatarFile,
129
				Http::STATUS_OK,
130
				['Content-Type' => $avatarFile->getMimeType(), 'X-NC-IsCustomAvatar' => (int)$avatar->isCustomAvatar()]
131
			);
132
		} catch (\Exception $e) {
133
			return new JSONResponse([], Http::STATUS_NOT_FOUND);
134
		}
135
136
		// Cache for 1 day
137
		$response->cacheFor(60*60*24);
138
		return $response;
139
	}
140
141
	/**
142
	 * @NoAdminRequired
143
	 *
144
	 * @param string $path
145
	 * @return JSONResponse
146
	 */
147
	public function postAvatar($path) {
148
		$files = $this->request->getUploadedFile('files');
149
150
		if (isset($path)) {
151
			$path = stripslashes($path);
152
			$userFolder = $this->rootFolder->getUserFolder($this->userId);
153
			/** @var File $node */
154
			$node = $userFolder->get($path);
155
			if (!($node instanceof File)) {
0 ignored issues
show
introduced by
$node is always a sub-type of OCP\Files\File.
Loading history...
156
				return new JSONResponse(['data' => ['message' => $this->l->t('Please select a file.')]]);
157
			}
158
			if ($node->getSize() > 20*1024*1024) {
159
				return new JSONResponse(
160
					['data' => ['message' => $this->l->t('File is too big')]],
161
					Http::STATUS_BAD_REQUEST
162
				);
163
			}
164
165
			if ($node->getMimeType() !== 'image/jpeg' && $node->getMimeType() !== 'image/png') {
166
				return new JSONResponse(
167
					['data' => ['message' => $this->l->t('The selected file is not an image.')]],
168
					Http::STATUS_BAD_REQUEST
169
				);
170
			}
171
172
			try {
173
				$content = $node->getContent();
174
			} catch (\OCP\Files\NotPermittedException $e) {
175
				return new JSONResponse(
176
					['data' => ['message' => $this->l->t('The selected file cannot be read.')]],
177
					Http::STATUS_BAD_REQUEST
178
				);
179
			}
180
		} elseif (!is_null($files)) {
0 ignored issues
show
introduced by
The condition is_null($files) is always false.
Loading history...
181
			if (
182
				$files['error'][0] === 0 &&
183
				 is_uploaded_file($files['tmp_name'][0]) &&
184
				!\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0])
185
			) {
186
				if ($files['size'][0] > 20*1024*1024) {
187
					return new JSONResponse(
188
						['data' => ['message' => $this->l->t('File is too big')]],
189
						Http::STATUS_BAD_REQUEST
190
					);
191
				}
192
				$this->cache->set('avatar_upload', file_get_contents($files['tmp_name'][0]), 7200);
193
				$content = $this->cache->get('avatar_upload');
194
				unlink($files['tmp_name'][0]);
195
			} else {
196
				return new JSONResponse(
197
					['data' => ['message' => $this->l->t('Invalid file provided')]],
198
					Http::STATUS_BAD_REQUEST
199
				);
200
			}
201
		} else {
202
			//Add imgfile
203
			return new JSONResponse(
204
				['data' => ['message' => $this->l->t('No image or file provided')]],
205
				Http::STATUS_BAD_REQUEST
206
			);
207
		}
208
209
		try {
210
			$image = new \OC_Image();
211
			$image->loadFromData($content);
212
			$image->readExif($content);
213
			$image->fixOrientation();
214
215
			if ($image->valid()) {
216
				$mimeType = $image->mimeType();
217
				if ($mimeType !== 'image/jpeg' && $mimeType !== 'image/png') {
218
					return new JSONResponse(
219
						['data' => ['message' => $this->l->t('Unknown filetype')]],
220
						Http::STATUS_OK
221
					);
222
				}
223
224
				$this->cache->set('tmpAvatar', $image->data(), 7200);
225
				return new JSONResponse(
226
					['data' => 'notsquare'],
227
					Http::STATUS_OK
228
				);
229
			} else {
230
				return new JSONResponse(
231
					['data' => ['message' => $this->l->t('Invalid image')]],
232
					Http::STATUS_OK
233
				);
234
			}
235
		} catch (\Exception $e) {
236
			$this->logger->logException($e, ['app' => 'core']);
237
			return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_OK);
238
		}
239
	}
240
241
	/**
242
	 * @NoAdminRequired
243
	 *
244
	 * @return JSONResponse
245
	 */
246
	public function deleteAvatar() {
247
		try {
248
			$avatar = $this->avatarManager->getAvatar($this->userId);
249
			$avatar->remove();
250
			return new JSONResponse();
251
		} catch (\Exception $e) {
252
			$this->logger->logException($e, ['app' => 'core']);
253
			return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_BAD_REQUEST);
254
		}
255
	}
256
257
	/**
258
	 * @NoAdminRequired
259
	 *
260
	 * @return JSONResponse|DataDisplayResponse
261
	 */
262
	public function getTmpAvatar() {
263
		$tmpAvatar = $this->cache->get('tmpAvatar');
264
		if (is_null($tmpAvatar)) {
265
			return new JSONResponse(['data' => [
266
				'message' => $this->l->t("No temporary profile picture available, try again")
267
			]],
268
									Http::STATUS_NOT_FOUND);
269
		}
270
271
		$image = new \OC_Image();
272
		$image->loadFromData($tmpAvatar);
273
274
		$resp = new DataDisplayResponse($image->data(),
275
				Http::STATUS_OK,
276
				['Content-Type' => $image->mimeType()]);
277
278
		$resp->setETag((string)crc32($image->data()));
279
		$resp->cacheFor(0);
280
		$resp->setLastModified(new \DateTime('now', new \DateTimeZone('GMT')));
281
		return $resp;
282
	}
283
284
	/**
285
	 * @NoAdminRequired
286
	 *
287
	 * @param array $crop
288
	 * @return JSONResponse
289
	 */
290
	public function postCroppedAvatar($crop) {
291
		if (is_null($crop)) {
0 ignored issues
show
introduced by
The condition is_null($crop) is always false.
Loading history...
292
			return new JSONResponse(['data' => ['message' => $this->l->t("No crop data provided")]],
293
									Http::STATUS_BAD_REQUEST);
294
		}
295
296
		if (!isset($crop['x'], $crop['y'], $crop['w'], $crop['h'])) {
297
			return new JSONResponse(['data' => ['message' => $this->l->t("No valid crop data provided")]],
298
									Http::STATUS_BAD_REQUEST);
299
		}
300
301
		$tmpAvatar = $this->cache->get('tmpAvatar');
302
		if (is_null($tmpAvatar)) {
303
			return new JSONResponse(['data' => [
304
				'message' => $this->l->t("No temporary profile picture available, try again")
305
			]],
306
									Http::STATUS_BAD_REQUEST);
307
		}
308
309
		$image = new \OC_Image();
310
		$image->loadFromData($tmpAvatar);
311
		$image->crop($crop['x'], $crop['y'], (int)round($crop['w']), (int)round($crop['h']));
312
		try {
313
			$avatar = $this->avatarManager->getAvatar($this->userId);
314
			$avatar->set($image);
315
			// Clean up
316
			$this->cache->remove('tmpAvatar');
317
			return new JSONResponse(['status' => 'success']);
318
		} catch (\OC\NotSquareException $e) {
319
			return new JSONResponse(['data' => ['message' => $this->l->t('Crop is not square')]],
320
									Http::STATUS_BAD_REQUEST);
321
		} catch (\Exception $e) {
322
			$this->logger->logException($e, ['app' => 'core']);
323
			return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_BAD_REQUEST);
324
		}
325
	}
326
}
327