Completed
Push — master ( 8032e3...4751f1 )
by Morris
15:26
created

SvgController::getSvgFromApp()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 3
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
1
<?php
2
declare (strict_types = 1);
3
/**
4
 * @copyright Copyright (c) 2018, John Molakvoæ ([email protected])
5
 *
6
 * @author John Molakvoæ (skjnldsv) <[email protected]>
7
 *
8
 * @license GNU AGPL version 3 or any later version
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License as
12
 * published by the Free Software Foundation, either version 3 of the
13
 * License, or (at your option) any later version.
14
 *
15
 * This program 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 License
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 */
24
25
namespace OC\Core\Controller;
26
27
use OCP\AppFramework\Controller;
28
use OCP\AppFramework\Http;
29
use OCP\AppFramework\Http\DataDisplayResponse;
30
use OCP\AppFramework\Http\NotFoundResponse;
31
use OCP\AppFramework\Utility\ITimeFactory;
32
use OCP\Files\NotFoundException;
33
use OCP\App\IAppManager;
34
use OCP\IRequest;
35
36
class SvgController extends Controller {
37
38
	/** @var string */
39
	protected $serverRoot;
40
41
	/** @var ITimeFactory */
42
	protected $timeFactory;
43
44
	/** @var IAppManager */
45
	protected $appManager;
46
47
	public function __construct(string $appName,
48
								IRequest $request,
49
								ITimeFactory $timeFactory,
50
								IAppManager $appManager) {
51
		parent::__construct($appName, $request);
52
53
		$this->serverRoot  = \OC::$SERVERROOT;
54
		$this->timeFactory = $timeFactory;
55
		$this->appManager = $appManager;
56
	}
57
58
	/**
59
	 * @NoAdminRequired
60
	 * @NoCSRFRequired
61
	 *
62
	 * Generate svg from filename with the requested color
63
	 *
64
	 * @param string $folder
65
	 * @param string $fileName
66
	 * @param string $color
67
	 * @return DataDisplayResponse|NotFoundResponse
68
	 */
69
	public function getSvgFromCore(string $folder, string $fileName, string $color = 'ffffff') {
70
		$path = $this->serverRoot . "/core/img/$folder/$fileName.svg";
71
		return $this->getSvg($path, $color, $fileName);
72
	}
73
74
	/**
75
	 * @NoAdminRequired
76
	 * @NoCSRFRequired
77
	 *
78
	 * Generate svg from filename with the requested color
79
	 *
80
	 * @param string $app
81
	 * @param string $fileName
82
	 * @param string $color
83
	 * @return DataDisplayResponse|NotFoundResponse
84
	 */
85
	public function getSvgFromApp(string $app, string $fileName, string $color = 'ffffff') {
86
87
		if ($app === 'settings') {
88
			$path = $this->serverRoot . "/settings/img/$fileName.svg";
89
			return $this->getSvg($path, $color, $fileName);
90
		}
91
92
		$appRootPath = $this->appManager->getAppPath($app);
93
		$appPath = substr($appRootPath, strlen($this->serverRoot));
94
		
95
		if (!$appPath) {
96
			return new NotFoundResponse();
97
		}
98
		$path = $this->serverRoot . $appPath ."/img/$fileName.svg";
99
		return $this->getSvg($path, $color, $fileName);
100
	}
101
102
103
	/**
104
	 * Generate svg from filename with the requested color
105
	 *
106
	 * @param string $path
107
	 * @param string $color
108
	 * @return DataDisplayResponse|NotFoundResponse
109
	 */
110
	private function getSvg(string $path, string $color, string $fileName) {
111
		if (!file_exists($path)) {
112
			return new NotFoundResponse();
113
		}
114
115
		$svg = file_get_contents($path);
116
117
		if (is_null($svg)) {
118
			return new NotFoundResponse();
119
		}
120
121
		// add fill (fill is not present on black elements)
122
		$fillRe = '/<((circle|rect|path)((?!fill)[a-z0-9 =".\-#():;])+)\/>/mi';
123
124
		$svg = preg_replace($fillRe, '<$1 fill="#' . $color . '"/>', $svg);
125
126
		// replace any fill or stroke colors
127
		$svg = preg_replace('/stroke="#([a-z0-9]{3,6})"/mi', 'stroke="#' . $color . '"', $svg);
128
		$svg = preg_replace('/fill="#([a-z0-9]{3,6})"/mi', 'fill="#' . $color . '"', $svg);
129
130
		$response = new DataDisplayResponse($svg, Http::STATUS_OK, ['Content-Type' => 'image/svg+xml']);
131
132
		// Set cache control
133
		$ttl = 31536000;
134
		$response->cacheFor($ttl);
135
		$response->addHeader('Content-Disposition', 'inline; filename="' . $fileName . '.svg"');
136
		$expires = new \DateTime();
137
		$expires->setTimestamp($this->timeFactory->getTime());
138
		$expires->add(new \DateInterval('PT' . $ttl . 'S'));
139
		$response->addHeader('Expires', $expires->format(\DateTime::RFC1123));
140
		$response->addHeader('Pragma', 'cache');
141
142
		return $response;
143
	}
144
}