Completed
Push — master ( bcf587...5a9224 )
by Morris
19:50 queued 04:43
created

ThemingController::updateStylesheet()   B

Complexity

Conditions 9
Paths 9

Size

Total Lines 56
Code Lines 36

Duplication

Lines 40
Ratio 71.43 %

Importance

Changes 0
Metric Value
cc 9
eloc 36
c 0
b 0
f 0
nc 9
nop 2
dl 40
loc 56
rs 7.1584

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016 Bjoern Schiessle <[email protected]>
4
 * @copyright Copyright (c) 2016 Lukas Reschke <[email protected]>
5
 *
6
 * @author Bjoern Schiessle <[email protected]>
7
 * @author Julius Haertl <[email protected]>
8
 * @author Lukas Reschke <[email protected]>
9
 * @author oparoz <[email protected]>
10
 *
11
 * @license GNU AGPL version 3 or any later version
12
 *
13
 * This program is free software: you can redistribute it and/or modify
14
 * it under the terms of the GNU Affero General Public License as
15
 * published by the Free Software Foundation, either version 3 of the
16
 * License, or (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU Affero General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU Affero General Public License
24
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25
 *
26
 */
27
28
namespace OCA\Theming\Controller;
29
30
use OC\Files\AppData\Factory;
31
use OC\Template\SCSSCacher;
32
use OCA\Theming\ThemingDefaults;
33
use OCP\AppFramework\Controller;
34
use OCP\AppFramework\Http;
35
use OCP\AppFramework\Http\DataDownloadResponse;
36
use OCP\AppFramework\Http\FileDisplayResponse;
37
use OCP\AppFramework\Http\DataResponse;
38
use OCP\AppFramework\Http\NotFoundResponse;
39
use OCP\AppFramework\Utility\ITimeFactory;
40
use OCP\Files\File;
41
use OCP\Files\IAppData;
42
use OCP\Files\NotFoundException;
43
use OCP\IConfig;
44
use OCP\IL10N;
45
use OCP\ILogger;
46
use OCP\IRequest;
47
use OCA\Theming\Util;
48
use OCP\ITempManager;
49
use OCP\IURLGenerator;
50
51
/**
52
 * Class ThemingController
53
 *
54
 * handle ajax requests to update the theme
55
 *
56
 * @package OCA\Theming\Controller
57
 */
58
class ThemingController extends Controller {
59
	/** @var ThemingDefaults */
60
	private $themingDefaults;
61
	/** @var Util */
62
	private $util;
63
	/** @var ITimeFactory */
64
	private $timeFactory;
65
	/** @var IL10N */
66
	private $l10n;
67
	/** @var IConfig */
68
	private $config;
69
	/** @var ITempManager */
70
	private $tempManager;
71
	/** @var IAppData */
72
	private $appData;
73
	/** @var SCSSCacher */
74
	private $scssCacher;
75
76
	/**
77
	 * ThemingController constructor.
78
	 *
79
	 * @param string $appName
80
	 * @param IRequest $request
81
	 * @param IConfig $config
82
	 * @param ThemingDefaults $themingDefaults
83
	 * @param Util $util
84
	 * @param ITimeFactory $timeFactory
85
	 * @param IL10N $l
86
	 * @param ITempManager $tempManager
87
	 * @param IAppData $appData
88
	 * @param SCSSCacher $scssCacher
89
	 */
90 View Code Duplication
	public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91
		$appName,
92
		IRequest $request,
93
		IConfig $config,
94
		ThemingDefaults $themingDefaults,
95
		Util $util,
96
		ITimeFactory $timeFactory,
97
		IL10N $l,
98
		ITempManager $tempManager,
99
		IAppData $appData,
100
		SCSSCacher $scssCacher
101
	) {
102
		parent::__construct($appName, $request);
103
104
		$this->themingDefaults = $themingDefaults;
105
		$this->util = $util;
106
		$this->timeFactory = $timeFactory;
107
		$this->l10n = $l;
108
		$this->config = $config;
109
		$this->tempManager = $tempManager;
110
		$this->appData = $appData;
111
		$this->scssCacher = $scssCacher;
112
	}
113
114
	/**
115
	 * @param string $setting
116
	 * @param string $value
117
	 * @return DataResponse
118
	 * @internal param string $color
119
	 */
120
	public function updateStylesheet($setting, $value) {
121
		$value = trim($value);
122
		switch ($setting) {
123 View Code Duplication
			case 'name':
124
				if (strlen($value) > 250) {
125
					return new DataResponse([
126
						'data' => [
127
							'message' => $this->l10n->t('The given name is too long'),
128
						],
129
						'status' => 'error'
130
					]);
131
				}
132
				break;
133 View Code Duplication
			case 'url':
134
				if (strlen($value) > 500) {
135
					return new DataResponse([
136
						'data' => [
137
							'message' => $this->l10n->t('The given web address is too long'),
138
						],
139
						'status' => 'error'
140
					]);
141
				}
142
				break;
143 View Code Duplication
			case 'slogan':
144
				if (strlen($value) > 500) {
145
					return new DataResponse([
146
						'data' => [
147
							'message' => $this->l10n->t('The given slogan is too long'),
148
						],
149
						'status' => 'error'
150
					]);
151
				}
152
				break;
153 View Code Duplication
			case 'color':
154
				if (!preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $value)) {
155
					return new DataResponse([
156
						'data' => [
157
							'message' => $this->l10n->t('The given color is invalid'),
158
						],
159
						'status' => 'error'
160
					]);
161
				}
162
				break;
163
		}
164
165
		$this->themingDefaults->set($setting, $value);
166
		return new DataResponse(
167
			[
168
				'data' =>
169
					[
170
						'message' => $this->l10n->t('Saved')
171
					],
172
				'status' => 'success'
173
			]
174
		);
175
	}
176
177
	/**
178
	 * Update the logos and background image
179
	 *
180
	 * @return DataResponse
181
	 */
182
	public function updateLogo() {
183
		$newLogo = $this->request->getUploadedFile('uploadlogo');
184
		$newBackgroundLogo = $this->request->getUploadedFile('upload-login-background');
185 View Code Duplication
		if (empty($newLogo) && empty($newBackgroundLogo)) {
186
			return new DataResponse(
187
				[
188
					'data' => [
189
						'message' => $this->l10n->t('No file uploaded')
190
					]
191
				],
192
				Http::STATUS_UNPROCESSABLE_ENTITY
193
			);
194
		}
195
196
		$name = '';
197
		try {
198
			$folder = $this->appData->getFolder('images');
199
		} catch (NotFoundException $e) {
200
			$folder = $this->appData->newFolder('images');
201
		}
202
203
		if (!empty($newLogo)) {
204
			$target = $folder->newFile('logo');
205
			$target->putContent(file_get_contents($newLogo['tmp_name'], 'r'));
206
			$this->themingDefaults->set('logoMime', $newLogo['type']);
207
			$name = $newLogo['name'];
208
		}
209
		if (!empty($newBackgroundLogo)) {
210
			$target = $folder->newFile('background');
211
			$image = @imagecreatefromstring(file_get_contents($newBackgroundLogo['tmp_name'], 'r'));
212
			if ($image === false) {
213
				return new DataResponse(
214
					[
215
						'data' => [
216
							'message' => $this->l10n->t('Unsupported image type'),
217
						],
218
						'status' => 'failure',
219
					],
220
					Http::STATUS_UNPROCESSABLE_ENTITY
221
				);
222
			}
223
224
			// Optimize the image since some people may upload images that will be
225
			// either to big or are not progressive rendering.
226
			$tmpFile = $this->tempManager->getTemporaryFile();
227
			if (function_exists('imagescale')) {
228
				// FIXME: Once PHP 5.5.0 is a requirement the above check can be removed
229
				// Workaround for https://bugs.php.net/bug.php?id=65171
230
				$newHeight = imagesy($image) / (imagesx($image) / 1920);
231
				$image = imagescale($image, 1920, $newHeight);
232
			}
233
			imageinterlace($image, 1);
234
			imagejpeg($image, $tmpFile, 75);
235
			imagedestroy($image);
236
237
			$target->putContent(file_get_contents($tmpFile, 'r'));
238
			$this->themingDefaults->set('backgroundMime', $newBackgroundLogo['type']);
239
			$name = $newBackgroundLogo['name'];
240
		}
241
242
		return new DataResponse(
243
			[
244
				'data' =>
245
					[
246
						'name' => $name,
247
						'message' => $this->l10n->t('Saved')
248
					],
249
				'status' => 'success'
250
			]
251
		);
252
	}
253
254
	/**
255
	 * Revert setting to default value
256
	 *
257
	 * @param string $setting setting which should be reverted
258
	 * @return DataResponse
259
	 */
260
	public function undo($setting) {
261
		$value = $this->themingDefaults->undo($setting);
262
		return new DataResponse(
263
			[
264
				'data' =>
265
					[
266
						'value' => $value,
267
						'message' => $this->l10n->t('Saved')
268
					],
269
				'status' => 'success'
270
			]
271
		);
272
	}
273
274
	/**
275
	 * @PublicPage
276
	 * @NoCSRFRequired
277
	 *
278
	 * @return FileDisplayResponse|NotFoundResponse
279
	 */
280 View Code Duplication
	public function getLogo() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
281
		try {
282
			/** @var File $file */
283
			$file = $this->appData->getFolder('images')->getFile('logo');
284
		} catch (NotFoundException $e) {
285
			return new NotFoundResponse();
286
		}
287
288
		$response = new FileDisplayResponse($file);
289
		$response->cacheFor(3600);
290
		$expires = new \DateTime();
291
		$expires->setTimestamp($this->timeFactory->getTime());
292
		$expires->add(new \DateInterval('PT24H'));
293
		$response->addHeader('Expires', $expires->format(\DateTime::RFC2822));
294
		$response->addHeader('Pragma', 'cache');
295
		$response->addHeader('Content-Type', $this->config->getAppValue($this->appName, 'logoMime', ''));
296
		return $response;
297
	}
298
299
	/**
300
	 * @PublicPage
301
	 * @NoCSRFRequired
302
	 *
303
	 * @return FileDisplayResponse|NotFoundResponse
304
	 */
305 View Code Duplication
	public function getLoginBackground() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
306
		try {
307
			/** @var File $file */
308
			$file = $this->appData->getFolder('images')->getFile('background');
309
		} catch (NotFoundException $e) {
310
			return new NotFoundResponse();
311
		}
312
313
		$response = new FileDisplayResponse($file);
314
		$response->cacheFor(3600);
315
		$expires = new \DateTime();
316
		$expires->setTimestamp($this->timeFactory->getTime());
317
		$expires->add(new \DateInterval('PT24H'));
318
		$response->addHeader('Expires', $expires->format(\DateTime::RFC2822));
319
		$response->addHeader('Pragma', 'cache');
320
		$response->addHeader('Content-Type', $this->config->getAppValue($this->appName, 'backgroundMime', ''));
321
		return $response;
322
	}
323
324
	/**
325
	 * @NoCSRFRequired
326
	 * @PublicPage
327
	 *
328
	 * @return FileDisplayResponse|NotFoundResponse
329
	 */
330
	public function getStylesheet() {
331
		$appPath = substr(\OC::$server->getAppManager()->getAppPath('theming'), strlen(\OC::$SERVERROOT) + 1);
332
		/* SCSSCacher is required here
333
		 * We cannot rely on automatic caching done by \OC_Util::addStyle,
334
		 * since we need to add the cacheBuster value to the url
335
		 */
336
		$cssCached = $this->scssCacher->process(\OC::$SERVERROOT, $appPath . '/css/theming.scss', 'theming');
337
		if(!$cssCached) {
338
			return new NotFoundResponse();
339
		}
340
341
		try {
342
			$cssFile = $this->scssCacher->getCachedCSS('theming', 'theming.css');
343
			$response = new FileDisplayResponse($cssFile, Http::STATUS_OK, ['Content-Type' => 'text/css']);
344
			$response->cacheFor(86400);
345
			$expires = new \DateTime();
346
			$expires->setTimestamp($this->timeFactory->getTime());
347
			$expires->add(new \DateInterval('PT24H'));
348
			$response->addHeader('Expires', $expires->format(\DateTime::RFC1123));
349
			$response->addHeader('Pragma', 'cache');
350
			return $response;
351
		} catch (NotFoundException $e) {
352
			return new NotFoundResponse();
353
		}
354
	}
355
356
	/**
357
	 * @NoCSRFRequired
358
	 * @PublicPage
359
	 *
360
	 * @return DataDownloadResponse
361
	 */
362
	public function getJavascript() {
363
		$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
364
		$responseJS = '(function() {
365
	OCA.Theming = {
366
		name: ' . json_encode($this->themingDefaults->getName()) . ',
367
		url: ' . json_encode($this->themingDefaults->getBaseUrl()) . ',
368
		slogan: ' . json_encode($this->themingDefaults->getSlogan()) . ',
369
		color: ' . json_encode($this->themingDefaults->getColorPrimary()) . ',
370
		inverted: ' . json_encode($this->util->invertTextColor($this->themingDefaults->getColorPrimary())) . ',
371
		cacheBuster: ' . json_encode($cacheBusterValue) . '
372
	};
373
})();';
374
		$response = new DataDownloadResponse($responseJS, 'javascript', 'text/javascript');
375
		$response->addHeader('Expires', date(\DateTime::RFC2822, $this->timeFactory->getTime()));
376
		$response->addHeader('Pragma', 'cache');
377
		$response->cacheFor(3600);
378
		return $response;
379
	}
380
}
381