Completed
Push — master ( 3e14f2...b3a0de )
by Morris
15:06
created

IconController::getTouchIcon()   B

Complexity

Conditions 6
Paths 30

Size

Total Lines 30
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 24
nc 30
nop 1
dl 0
loc 30
rs 8.439
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016 Julius Haertl <[email protected]>
4
 *
5
 * @author Joas Schilling <[email protected]>
6
 * @author Julius Haertl <[email protected]>
7
 * @author Julius Härtl <[email protected]>
8
 *
9
 * @license GNU AGPL version 3 or any later version
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
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
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
namespace OCA\Theming\Controller;
26
27
use OC\IntegrityCheck\Helpers\FileAccessHelper;
28
use OCA\Theming\IconBuilder;
29
use OCA\Theming\ImageManager;
30
use OCA\Theming\ThemingDefaults;
31
use OCP\AppFramework\Controller;
32
use OCP\AppFramework\Http;
33
use OCP\AppFramework\Http\NotFoundResponse;
34
use OCP\AppFramework\Http\FileDisplayResponse;
35
use OCP\AppFramework\Http\DataDisplayResponse;
36
use OCP\AppFramework\Http\Response;
37
use OCP\AppFramework\Utility\ITimeFactory;
38
use OCP\Files\NotFoundException;
39
use OCP\IRequest;
40
41
class IconController extends Controller {
42
	/** @var ThemingDefaults */
43
	private $themingDefaults;
44
	/** @var ITimeFactory */
45
	private $timeFactory;
46
	/** @var IconBuilder */
47
	private $iconBuilder;
48
	/** @var ImageManager */
49
	private $imageManager;
50
	/** @var FileAccessHelper */
51
	private $fileAccessHelper;
52
53
	/**
54
	 * IconController constructor.
55
	 *
56
	 * @param string $appName
57
	 * @param IRequest $request
58
	 * @param ThemingDefaults $themingDefaults
59
	 * @param ITimeFactory $timeFactory
60
	 * @param IconBuilder $iconBuilder
61
	 * @param ImageManager $imageManager
62
	 * @param FileAccessHelper $fileAccessHelper
63
	 */
64
	public function __construct(
65
		$appName,
66
		IRequest $request,
67
		ThemingDefaults $themingDefaults,
68
		ITimeFactory $timeFactory,
69
		IconBuilder $iconBuilder,
70
		ImageManager $imageManager,
71
		FileAccessHelper $fileAccessHelper
72
	) {
73
		parent::__construct($appName, $request);
74
75
		$this->themingDefaults = $themingDefaults;
76
		$this->timeFactory = $timeFactory;
77
		$this->iconBuilder = $iconBuilder;
78
		$this->imageManager = $imageManager;
79
		$this->fileAccessHelper = $fileAccessHelper;
80
	}
81
82
	/**
83
	 * @PublicPage
84
	 * @NoCSRFRequired
85
	 *
86
	 * @param $app string app name
87
	 * @param $image string image file name (svg required)
88
	 * @return FileDisplayResponse|NotFoundResponse
89
	 * @throws \Exception
90
	 */
91
	public function getThemedIcon(string $app, string $image): Response {
92
		try {
93
			$iconFile = $this->imageManager->getCachedImage('icon-' . $app . '-' . str_replace('/', '_',$image));
94
		} catch (NotFoundException $exception) {
95
			$icon = $this->iconBuilder->colorSvg($app, $image);
96
			if ($icon === false || $icon === '') {
97
				return new NotFoundResponse();
98
			}
99
			$iconFile = $this->imageManager->setCachedImage('icon-' . $app . '-' . str_replace('/', '_',$image), $icon);
100
		}
101
		if ($iconFile !== false) {
102
			$response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/svg+xml']);
103
			$response->cacheFor(86400);
104
			$expires = new \DateTime();
105
			$expires->setTimestamp($this->timeFactory->getTime());
106
			$expires->add(new \DateInterval('PT24H'));
107
			$response->addHeader('Expires', $expires->format(\DateTime::RFC2822));
108
			$response->addHeader('Pragma', 'cache');
109
			return $response;
110
		}
111
112
		return new NotFoundResponse();
113
	}
114
115
	/**
116
	 * Return a 32x32 favicon as png
117
	 *
118
	 * @PublicPage
119
	 * @NoCSRFRequired
120
	 *
121
	 * @param $app string app name
122
	 * @return FileDisplayResponse|DataDisplayResponse
123
	 * @throws \Exception
124
	 */
125
	public function getFavicon(string $app = 'core'): Response {
126
		$response = null;
127
		$iconFile = null;
128
		try {
129
			$iconFile = $this->imageManager->getImage('favicon');
130
			$response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']);
131
		} catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
132
		}
133
		if ($iconFile === null && $this->themingDefaults->shouldReplaceIcons()) {
134
			try {
135
				$iconFile = $this->imageManager->getCachedImage('favIcon-' . $app);
136
			} catch (NotFoundException $exception) {
137
				$icon = $this->iconBuilder->getFavicon($app);
138
				$iconFile = $this->imageManager->setCachedImage('favIcon-' . $app, $icon);
0 ignored issues
show
Security Bug introduced by
It seems like $icon defined by $this->iconBuilder->getFavicon($app) on line 137 can also be of type false; however, OCA\Theming\ImageManager::setCachedImage() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
139
			}
140
			if ($iconFile !== false) {
141
				$response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']);
142
			}
143
		}
144
		if($response === null) {
145
			$fallbackLogo = \OC::$SERVERROOT . '/core/img/favicon.png';
146
			$response = new DataDisplayResponse($this->fileAccessHelper->file_get_contents($fallbackLogo), Http::STATUS_OK, ['Content-Type' => 'image/x-icon']);
0 ignored issues
show
Security Bug introduced by
It seems like $this->fileAccessHelper-...contents($fallbackLogo) targeting OC\IntegrityCheck\Helper...er::file_get_contents() can also be of type false; however, OCP\AppFramework\Http\Da...Response::__construct() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
147
		}
148
		$response->cacheFor(86400);
149
		$expires = new \DateTime();
150
		$expires->setTimestamp($this->timeFactory->getTime());
151
		$expires->add(new \DateInterval('PT24H'));
152
		$response->addHeader('Expires', $expires->format(\DateTime::RFC2822));
153
		$response->addHeader('Pragma', 'cache');
154
		return $response;
155
	}
156
157
	/**
158
	 * Return a 512x512 icon for touch devices
159
	 *
160
	 * @PublicPage
161
	 * @NoCSRFRequired
162
	 *
163
	 * @param $app string app name
164
	 * @return FileDisplayResponse|NotFoundResponse
165
	 * @throws \Exception
166
	 */
167
	public function getTouchIcon(string $app = 'core'): Response {
168
		$response = null;
169
		try {
170
			$iconFile = $this->imageManager->getImage('favicon');
171
			$response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/x-icon']);
172
		} catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
173
		}
174
		if ($this->themingDefaults->shouldReplaceIcons()) {
175
			try {
176
				$iconFile = $this->imageManager->getCachedImage('touchIcon-' . $app);
177
			} catch (NotFoundException $exception) {
178
				$icon = $this->iconBuilder->getTouchIcon($app);
179
				$iconFile = $this->imageManager->setCachedImage('touchIcon-' . $app, $icon);
0 ignored issues
show
Security Bug introduced by
It seems like $icon defined by $this->iconBuilder->getTouchIcon($app) on line 178 can also be of type false; however, OCA\Theming\ImageManager::setCachedImage() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
180
			}
181
			if ($iconFile !== false) {
182
				$response = new FileDisplayResponse($iconFile, Http::STATUS_OK, ['Content-Type' => 'image/png']);
183
			}
184
		}
185
		if($response === null) {
186
			$fallbackLogo = \OC::$SERVERROOT . '/core/img/favicon-touch.png';
187
			$response = new DataDisplayResponse($this->fileAccessHelper->file_get_contents($fallbackLogo), Http::STATUS_OK, ['Content-Type' => 'image/png']);
0 ignored issues
show
Security Bug introduced by
It seems like $this->fileAccessHelper-...contents($fallbackLogo) targeting OC\IntegrityCheck\Helper...er::file_get_contents() can also be of type false; however, OCP\AppFramework\Http\Da...Response::__construct() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
188
		}
189
		$response->cacheFor(86400);
190
		$expires = new \DateTime();
191
		$expires->setTimestamp($this->timeFactory->getTime());
192
		$expires->add(new \DateInterval('PT24H'));
193
		$response->addHeader('Expires', $expires->format(\DateTime::RFC2822));
194
		$response->addHeader('Pragma', 'cache');
195
		return $response;
196
	}
197
}
198