Completed
Push — master ( dfbc21...f148e3 )
by John
64:33 queued 45:49
created

AccessibilityController   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 163
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
dl 0
loc 163
rs 10
c 0
b 0
f 0
wmc 9
lcom 1
cbo 8

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 22 1
B getCss() 0 54 5
A getUserValues() 0 6 1
A filterOutRule() 0 3 1
A rebaseUrls() 0 6 1
1
<?php
2
declare (strict_types = 1);
3
/**
4
 * @copyright Copyright (c) 2018 John Molakvoæ (skjnldsv) <[email protected]>
5
 *
6
 * @license GNU AGPL version 3 or any later version
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as
10
 * published by the Free Software Foundation, either version 3 of the
11
 * License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
23
namespace OCA\Accessibility\Controller;
24
25
use Leafo\ScssPhp\Compiler;
26
use Leafo\ScssPhp\Exception\ParserException;
27
use Leafo\ScssPhp\Formatter\Crunched;
28
use OCP\AppFramework\Controller;
29
use OCP\AppFramework\Http;
30
use OCP\AppFramework\Http\DataDisplayResponse;
31
use OCP\AppFramework\Utility\ITimeFactory;
32
use OCP\App\IAppManager;
33
use OCP\IConfig;
34
use OCP\ILogger;
35
use OCP\IRequest;
36
use OCP\IURLGenerator;
37
use OCP\IUserManager;
38
use OCP\IUserSession;
39
40
class AccessibilityController extends Controller {
41
42
	/** @var string */
43
	protected $appName;
44
45
	/** @var string */
46
	protected $serverRoot;
47
48
	/** @var IConfig */
49
	private $config;
50
51
	/** @var IUserManager */
52
	private $userManager;
53
54
	/** @var ILogger */
55
	private $logger;
56
57
	/** @var IURLGenerator */
58
	private $urlGenerator;
59
60
	/** @var ITimeFactory */
61
	protected $timeFactory;
62
63
	/** @var IUserSession */
64
	private $userSession;
65
66
	/** @var IAppManager */
67
	private $appManager;
68
69
	/**
70
	 * Account constructor.
71
	 *
72
	 * @param string $appName
73
	 * @param IRequest $request
74
	 * @param IConfig $config
75
	 * @param IUserManager $userManager
76
	 * @param ILogger $logger
77
	 * @param IURLGenerator $urlGenerator
78
	 * @param ITimeFactory $timeFactory
79
	 * @param IUserSession $userSession
80
	 * @param IAppManager $appManager
81
	 */
82
	public function __construct(string $appName,
83
								IRequest $request,
84
								IConfig $config,
85
								IUserManager $userManager,
86
								ILogger $logger,
87
								IURLGenerator $urlGenerator,
88
								ITimeFactory $timeFactory,
89
								IUserSession $userSession,
90
								IAppManager $appManager) {
91
		parent::__construct($appName, $request);
92
		$this->appName      = $appName;
93
		$this->config       = $config;
94
		$this->userManager  = $userManager;
95
		$this->logger       = $logger;
96
		$this->urlGenerator = $urlGenerator;
97
		$this->timeFactory  = $timeFactory;
98
		$this->userSession  = $userSession;
99
		$this->appManager   = $appManager;
100
101
		$this->serverRoot = \OC::$SERVERROOT;
102
		$this->appRoot    = $this->appManager->getAppPath($this->appName);
0 ignored issues
show
Bug introduced by
The property appRoot does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
103
	}
104
105
	/**
106
	 * @NoAdminRequired
107
	 * @NoCSRFRequired
108
	 *
109
	 * @return DataDisplayResponse
110
	 */
111
	public function getCss(): DataDisplayResponse {
112
		$css        = '';
113
		$imports    = '';
114
		$userValues = $this->getUserValues();
115
116
		foreach ($userValues as $key => $scssFile) {
117
			if ($scssFile !== false) {
118
				$imports .= '@import "' . $scssFile . '";';
119
			}
120
		}
121
122
		if ($imports !== '') {
123
			$scss = new Compiler();
124
			$scss->setImportPaths([
125
				$this->appRoot . '/css/',
126
				$this->serverRoot . '/core/css/'
127
			]);
128
129
			// Continue after throw
130
			$scss->setIgnoreErrors(true);
131
			$scss->setFormatter(Crunched::class);
132
133
			// Import theme, variables and compile css4 variables
134
			try {
135
				$css .= $scss->compile(
136
					$imports .
137
					'@import "variables.scss";' .
138
					'@import "css-variables.scss";'
139
				);
140
			} catch (ParserException $e) {
0 ignored issues
show
Bug introduced by
The class Leafo\ScssPhp\Exception\ParserException 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...
141
				$this->logger->error($e->getMessage(), ['app' => 'core']);
142
			}
143
		}
144
145
		// We don't want to override vars with url since path is different
146
		$css = $this->filterOutRule('/--[a-z-:]+url\([^;]+\)/mi', $css);
147
148
		// Rebase all urls
149
		$appWebRoot = substr($this->appRoot, strlen($this->serverRoot) - strlen(\OC::$WEBROOT));
150
		$css = $this->rebaseUrls($css, $appWebRoot . '/css');
151
152
		$response = new DataDisplayResponse($css, Http::STATUS_OK, ['Content-Type' => 'text/css']);
153
154
		// Set cache control
155
		$ttl = 31536000;
156
		$response->addHeader('Cache-Control', 'max-age=' . $ttl . ', immutable');
157
		$expires = new \DateTime();
158
		$expires->setTimestamp($this->timeFactory->getTime());
159
		$expires->add(new \DateInterval('PT' . $ttl . 'S'));
160
		$response->addHeader('Expires', $expires->format(\DateTime::RFC1123));
161
		$response->addHeader('Pragma', 'cache');
162
163
		return $response;
164
	}
165
166
	/**
167
	 * Return an array with the user theme & font settings
168
	 *
169
	 * @return array
170
	 */
171
	private function getUserValues(): array{
172
		$userTheme = $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'theme', false);
173
		$userFont  = $this->config->getUserValue($this->userSession->getUser()->getUID(), $this->appName, 'font', false);
174
175
		return [$userTheme, $userFont];
176
	}
177
178
	/**
179
	 * Remove all matches from the $rule regex
180
	 *
181
	 * @param string $rule regex to match
182
	 * @param string $css string to parse
183
	 * @return string
184
	 */
185
	private function filterOutRule(string $rule, string $css): string {
186
		return preg_replace($rule, '', $css);
187
	}
188
189
	/**
190
	 * Add the correct uri prefix to make uri valid again
191
	 *
192
	 * @param string $css
193
	 * @param string $webDir
194
	 * @return string
195
	 */
196
	private function rebaseUrls(string $css, string $webDir): string {
197
		$re    = '/url\([\'"]([^\/][\.\w?=\/-]*)[\'"]\)/x';
198
		$subst = 'url(\'' . $webDir . '/$1\')';
199
200
		return preg_replace($re, $subst, $css);
201
	}
202
}
203