Completed
Pull Request — master (#8078)
by Julius
14:35
created
apps/theming/lib/ThemingDefaults.php 2 patches
Indentation   +329 added lines, -329 removed lines patch added patch discarded remove patch
@@ -44,333 +44,333 @@
 block discarded – undo
44 44
 
45 45
 class ThemingDefaults extends \OC_Defaults {
46 46
 
47
-	/** @var IConfig */
48
-	private $config;
49
-	/** @var IL10N */
50
-	private $l;
51
-	/** @var IURLGenerator */
52
-	private $urlGenerator;
53
-	/** @var IAppData */
54
-	private $appData;
55
-	/** @var ICacheFactory */
56
-	private $cacheFactory;
57
-	/** @var Util */
58
-	private $util;
59
-	/** @var IAppManager */
60
-	private $appManager;
61
-	/** @var string */
62
-	private $name;
63
-	/** @var string */
64
-	private $title;
65
-	/** @var string */
66
-	private $entity;
67
-	/** @var string */
68
-	private $url;
69
-	/** @var string */
70
-	private $slogan;
71
-	/** @var string */
72
-	private $color;
73
-
74
-	/** @var string */
75
-	private $iTunesAppId;
76
-	/** @var string */
77
-	private $iOSClientUrl;
78
-	/** @var string */
79
-	private $AndroidClientUrl;
80
-
81
-	/**
82
-	 * ThemingDefaults constructor.
83
-	 *
84
-	 * @param IConfig $config
85
-	 * @param IL10N $l
86
-	 * @param IURLGenerator $urlGenerator
87
-	 * @param \OC_Defaults $defaults
88
-	 * @param IAppData $appData
89
-	 * @param ICacheFactory $cacheFactory
90
-	 * @param Util $util
91
-	 * @param IAppManager $appManager
92
-	 */
93
-	public function __construct(IConfig $config,
94
-								IL10N $l,
95
-								IURLGenerator $urlGenerator,
96
-								IAppData $appData,
97
-								ICacheFactory $cacheFactory,
98
-								Util $util,
99
-								IAppManager $appManager
100
-	) {
101
-		parent::__construct();
102
-		$this->config = $config;
103
-		$this->l = $l;
104
-		$this->urlGenerator = $urlGenerator;
105
-		$this->appData = $appData;
106
-		$this->cacheFactory = $cacheFactory;
107
-		$this->util = $util;
108
-		$this->appManager = $appManager;
109
-
110
-		$this->name = parent::getName();
111
-		$this->title = parent::getTitle();
112
-		$this->entity = parent::getEntity();
113
-		$this->url = parent::getBaseUrl();
114
-		$this->slogan = parent::getSlogan();
115
-		$this->color = parent::getColorPrimary();
116
-		$this->iTunesAppId = parent::getiTunesAppId();
117
-		$this->iOSClientUrl = parent::getiOSClientUrl();
118
-		$this->AndroidClientUrl = parent::getAndroidClientUrl();
119
-	}
120
-
121
-	public function getName() {
122
-		return strip_tags($this->config->getAppValue('theming', 'name', $this->name));
123
-	}
124
-
125
-	public function getHTMLName() {
126
-		return $this->config->getAppValue('theming', 'name', $this->name);
127
-	}
128
-
129
-	public function getTitle() {
130
-		return strip_tags($this->config->getAppValue('theming', 'name', $this->title));
131
-	}
132
-
133
-	public function getEntity() {
134
-		return strip_tags($this->config->getAppValue('theming', 'name', $this->entity));
135
-	}
136
-
137
-	public function getBaseUrl() {
138
-		return $this->config->getAppValue('theming', 'url', $this->url);
139
-	}
140
-
141
-	public function getSlogan() {
142
-		return \OCP\Util::sanitizeHTML($this->config->getAppValue('theming', 'slogan', $this->slogan));
143
-	}
144
-
145
-	public function getShortFooter() {
146
-		$slogan = $this->getSlogan();
147
-		$footer = '<a href="'. $this->getBaseUrl() . '" target="_blank"' .
148
-			' rel="noreferrer noopener">' .$this->getEntity() . '</a>'.
149
-			($slogan !== '' ? ' – ' . $slogan : '');
150
-
151
-		return $footer;
152
-	}
153
-
154
-	/**
155
-	 * Color that is used for the header as well as for mail headers
156
-	 *
157
-	 * @return string
158
-	 */
159
-	public function getColorPrimary() {
160
-		return $this->config->getAppValue('theming', 'color', $this->color);
161
-	}
162
-
163
-	/**
164
-	 * Themed logo url
165
-	 *
166
-	 * @param bool $useSvg Whether to point to the SVG image or a fallback
167
-	 * @return string
168
-	 */
169
-	public function getLogo($useSvg = true) {
170
-		$logo = $this->config->getAppValue('theming', 'logoMime', false);
171
-
172
-		$logoExists = true;
173
-		try {
174
-			$this->appData->getFolder('images')->getFile('logo');
175
-		} catch (\Exception $e) {
176
-			$logoExists = false;
177
-		}
178
-
179
-		$cacheBusterCounter = $this->config->getAppValue('theming', 'cachebuster', '0');
180
-
181
-		if(!$logo || !$logoExists) {
182
-			if($useSvg) {
183
-				$logo = $this->urlGenerator->imagePath('core', 'logo.svg');
184
-			} else {
185
-				$logo = $this->urlGenerator->imagePath('core', 'logo.png');
186
-			}
187
-			return $logo . '?v=' . $cacheBusterCounter;
188
-		}
189
-
190
-		return $this->urlGenerator->linkToRoute('theming.Theming.getLogo') . '?v=' . $cacheBusterCounter;
191
-	}
192
-
193
-	/**
194
-	 * Themed background image url
195
-	 *
196
-	 * @return string
197
-	 */
198
-	public function getBackground() {
199
-		$cacheBusterCounter = $this->config->getAppValue('theming', 'cachebuster', '0');
200
-
201
-		if($this->util->isBackgroundThemed()) {
202
-			return $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground') . '?v=' . $cacheBusterCounter;
203
-		}
204
-
205
-		return $this->urlGenerator->imagePath('core','background.png') . '?v=' . $cacheBusterCounter;
206
-	}
207
-
208
-	/**
209
-	 * @return string
210
-	 */
211
-	public function getiTunesAppId() {
212
-		return $this->config->getAppValue('theming', 'iTunesAppId', $this->iTunesAppId);
213
-	}
214
-
215
-	/**
216
-	 * @return string
217
-	 */
218
-	public function getiOSClientUrl() {
219
-		return $this->config->getAppValue('theming', 'iOSClientUrl', $this->iOSClientUrl);
220
-	}
221
-
222
-	/**
223
-	 * @return string
224
-	 */
225
-	public function getAndroidClientUrl() {
226
-		return $this->config->getAppValue('theming', 'AndroidClientUrl', $this->AndroidClientUrl);
227
-	}
228
-
229
-
230
-	/**
231
-	 * @return array scss variables to overwrite
232
-	 */
233
-	public function getScssVariables() {
234
-		$cache = $this->cacheFactory->createDistributed('theming');
235
-		if ($value = $cache->get('getScssVariables')) {
236
-			return $value;
237
-		}
238
-
239
-		$variables = [
240
-			'theming-cachebuster' => "'" . $this->config->getAppValue('theming', 'cachebuster', '0') . "'",
241
-			'theming-logo-mime' => "'" . $this->config->getAppValue('theming', 'logoMime', '') . "'",
242
-			'theming-background-mime' => "'" . $this->config->getAppValue('theming', 'backgroundMime', '') . "'"
243
-		];
244
-
245
-		$variables['image-logo'] = "'".$this->getLogo()."'";
246
-		$variables['image-login-background'] = "'".$this->getBackground()."'";
247
-		$variables['image-login-plain'] = 'false';
248
-
249
-		if ($this->config->getAppValue('theming', 'color', null) !== null) {
250
-			$variables['color-primary'] = $this->getColorPrimary();
251
-			$variables['color-primary-text'] = $this->getTextColorPrimary();
252
-			$variables['color-primary-element'] = $this->util->elementColor($this->getColorPrimary());
253
-		}
254
-
255
-		if ($this->config->getAppValue('theming', 'backgroundMime', null) === 'backgroundColor') {
256
-			$variables['image-login-plain'] = 'true';
257
-		}
258
-		$cache->set('getScssVariables', $variables);
259
-		return $variables;
260
-	}
261
-
262
-	/**
263
-	 * Check if the image should be replaced by the theming app
264
-	 * and return the new image location then
265
-	 *
266
-	 * @param string $app name of the app
267
-	 * @param string $image filename of the image
268
-	 * @return bool|string false if image should not replaced, otherwise the location of the image
269
-	 */
270
-	public function replaceImagePath($app, $image) {
271
-		if($app==='') {
272
-			$app = 'core';
273
-		}
274
-		$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
275
-
276
-		if ($image === 'favicon.ico' && $this->shouldReplaceIcons()) {
277
-			return $this->urlGenerator->linkToRoute('theming.Icon.getFavicon', ['app' => $app]) . '?v=' . $cacheBusterValue;
278
-		}
279
-		if ($image === 'favicon-touch.png' && $this->shouldReplaceIcons()) {
280
-			return $this->urlGenerator->linkToRoute('theming.Icon.getTouchIcon', ['app' => $app]) . '?v=' . $cacheBusterValue;
281
-		}
282
-		if ($image === 'manifest.json') {
283
-			try {
284
-				$appPath = $this->appManager->getAppPath($app);
285
-				if (file_exists($appPath . '/img/manifest.json')) {
286
-					return false;
287
-				}
288
-			} catch (AppPathNotFoundException $e) {}
289
-			return $this->urlGenerator->linkToRoute('theming.Theming.getManifest') . '?v=' . $cacheBusterValue;
290
-		}
291
-		return false;
292
-	}
293
-
294
-	/**
295
-	 * Check if Imagemagick is enabled and if SVG is supported
296
-	 * otherwise we can't render custom icons
297
-	 *
298
-	 * @return bool
299
-	 */
300
-	public function shouldReplaceIcons() {
301
-		$cache = $this->cacheFactory->createDistributed('theming');
302
-		if($value = $cache->get('shouldReplaceIcons')) {
303
-			return (bool)$value;
304
-		}
305
-		$value = false;
306
-		if(extension_loaded('imagick')) {
307
-			$checkImagick = new \Imagick();
308
-			if (count($checkImagick->queryFormats('SVG')) >= 1) {
309
-				$value = true;
310
-			}
311
-			$checkImagick->clear();
312
-		}
313
-		$cache->set('shouldReplaceIcons', $value);
314
-		return $value;
315
-	}
316
-
317
-	/**
318
-	 * Increases the cache buster key
319
-	 */
320
-	private function increaseCacheBuster() {
321
-		$cacheBusterKey = $this->config->getAppValue('theming', 'cachebuster', '0');
322
-		$this->config->setAppValue('theming', 'cachebuster', (int)$cacheBusterKey+1);
323
-		$this->cacheFactory->createDistributed('theming')->clear('getScssVariables');
324
-	}
325
-
326
-	/**
327
-	 * Update setting in the database
328
-	 *
329
-	 * @param string $setting
330
-	 * @param string $value
331
-	 */
332
-	public function set($setting, $value) {
333
-		$this->config->setAppValue('theming', $setting, $value);
334
-		$this->increaseCacheBuster();
335
-	}
336
-
337
-	/**
338
-	 * Revert settings to the default value
339
-	 *
340
-	 * @param string $setting setting which should be reverted
341
-	 * @return string default value
342
-	 */
343
-	public function undo($setting) {
344
-		$this->config->deleteAppValue('theming', $setting);
345
-		$this->increaseCacheBuster();
346
-
347
-		switch ($setting) {
348
-			case 'name':
349
-				$returnValue = $this->getEntity();
350
-				break;
351
-			case 'url':
352
-				$returnValue = $this->getBaseUrl();
353
-				break;
354
-			case 'slogan':
355
-				$returnValue = $this->getSlogan();
356
-				break;
357
-			case 'color':
358
-				$returnValue = $this->getColorPrimary();
359
-				break;
360
-			default:
361
-				$returnValue = '';
362
-				break;
363
-		}
364
-
365
-		return $returnValue;
366
-	}
367
-
368
-	/**
369
-	 * Color of text in the header and primary buttons
370
-	 *
371
-	 * @return string
372
-	 */
373
-	public function getTextColorPrimary() {
374
-		return $this->util->invertTextColor($this->getColorPrimary()) ? '#000000' : '#ffffff';
375
-	}
47
+    /** @var IConfig */
48
+    private $config;
49
+    /** @var IL10N */
50
+    private $l;
51
+    /** @var IURLGenerator */
52
+    private $urlGenerator;
53
+    /** @var IAppData */
54
+    private $appData;
55
+    /** @var ICacheFactory */
56
+    private $cacheFactory;
57
+    /** @var Util */
58
+    private $util;
59
+    /** @var IAppManager */
60
+    private $appManager;
61
+    /** @var string */
62
+    private $name;
63
+    /** @var string */
64
+    private $title;
65
+    /** @var string */
66
+    private $entity;
67
+    /** @var string */
68
+    private $url;
69
+    /** @var string */
70
+    private $slogan;
71
+    /** @var string */
72
+    private $color;
73
+
74
+    /** @var string */
75
+    private $iTunesAppId;
76
+    /** @var string */
77
+    private $iOSClientUrl;
78
+    /** @var string */
79
+    private $AndroidClientUrl;
80
+
81
+    /**
82
+     * ThemingDefaults constructor.
83
+     *
84
+     * @param IConfig $config
85
+     * @param IL10N $l
86
+     * @param IURLGenerator $urlGenerator
87
+     * @param \OC_Defaults $defaults
88
+     * @param IAppData $appData
89
+     * @param ICacheFactory $cacheFactory
90
+     * @param Util $util
91
+     * @param IAppManager $appManager
92
+     */
93
+    public function __construct(IConfig $config,
94
+                                IL10N $l,
95
+                                IURLGenerator $urlGenerator,
96
+                                IAppData $appData,
97
+                                ICacheFactory $cacheFactory,
98
+                                Util $util,
99
+                                IAppManager $appManager
100
+    ) {
101
+        parent::__construct();
102
+        $this->config = $config;
103
+        $this->l = $l;
104
+        $this->urlGenerator = $urlGenerator;
105
+        $this->appData = $appData;
106
+        $this->cacheFactory = $cacheFactory;
107
+        $this->util = $util;
108
+        $this->appManager = $appManager;
109
+
110
+        $this->name = parent::getName();
111
+        $this->title = parent::getTitle();
112
+        $this->entity = parent::getEntity();
113
+        $this->url = parent::getBaseUrl();
114
+        $this->slogan = parent::getSlogan();
115
+        $this->color = parent::getColorPrimary();
116
+        $this->iTunesAppId = parent::getiTunesAppId();
117
+        $this->iOSClientUrl = parent::getiOSClientUrl();
118
+        $this->AndroidClientUrl = parent::getAndroidClientUrl();
119
+    }
120
+
121
+    public function getName() {
122
+        return strip_tags($this->config->getAppValue('theming', 'name', $this->name));
123
+    }
124
+
125
+    public function getHTMLName() {
126
+        return $this->config->getAppValue('theming', 'name', $this->name);
127
+    }
128
+
129
+    public function getTitle() {
130
+        return strip_tags($this->config->getAppValue('theming', 'name', $this->title));
131
+    }
132
+
133
+    public function getEntity() {
134
+        return strip_tags($this->config->getAppValue('theming', 'name', $this->entity));
135
+    }
136
+
137
+    public function getBaseUrl() {
138
+        return $this->config->getAppValue('theming', 'url', $this->url);
139
+    }
140
+
141
+    public function getSlogan() {
142
+        return \OCP\Util::sanitizeHTML($this->config->getAppValue('theming', 'slogan', $this->slogan));
143
+    }
144
+
145
+    public function getShortFooter() {
146
+        $slogan = $this->getSlogan();
147
+        $footer = '<a href="'. $this->getBaseUrl() . '" target="_blank"' .
148
+            ' rel="noreferrer noopener">' .$this->getEntity() . '</a>'.
149
+            ($slogan !== '' ? ' – ' . $slogan : '');
150
+
151
+        return $footer;
152
+    }
153
+
154
+    /**
155
+     * Color that is used for the header as well as for mail headers
156
+     *
157
+     * @return string
158
+     */
159
+    public function getColorPrimary() {
160
+        return $this->config->getAppValue('theming', 'color', $this->color);
161
+    }
162
+
163
+    /**
164
+     * Themed logo url
165
+     *
166
+     * @param bool $useSvg Whether to point to the SVG image or a fallback
167
+     * @return string
168
+     */
169
+    public function getLogo($useSvg = true) {
170
+        $logo = $this->config->getAppValue('theming', 'logoMime', false);
171
+
172
+        $logoExists = true;
173
+        try {
174
+            $this->appData->getFolder('images')->getFile('logo');
175
+        } catch (\Exception $e) {
176
+            $logoExists = false;
177
+        }
178
+
179
+        $cacheBusterCounter = $this->config->getAppValue('theming', 'cachebuster', '0');
180
+
181
+        if(!$logo || !$logoExists) {
182
+            if($useSvg) {
183
+                $logo = $this->urlGenerator->imagePath('core', 'logo.svg');
184
+            } else {
185
+                $logo = $this->urlGenerator->imagePath('core', 'logo.png');
186
+            }
187
+            return $logo . '?v=' . $cacheBusterCounter;
188
+        }
189
+
190
+        return $this->urlGenerator->linkToRoute('theming.Theming.getLogo') . '?v=' . $cacheBusterCounter;
191
+    }
192
+
193
+    /**
194
+     * Themed background image url
195
+     *
196
+     * @return string
197
+     */
198
+    public function getBackground() {
199
+        $cacheBusterCounter = $this->config->getAppValue('theming', 'cachebuster', '0');
200
+
201
+        if($this->util->isBackgroundThemed()) {
202
+            return $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground') . '?v=' . $cacheBusterCounter;
203
+        }
204
+
205
+        return $this->urlGenerator->imagePath('core','background.png') . '?v=' . $cacheBusterCounter;
206
+    }
207
+
208
+    /**
209
+     * @return string
210
+     */
211
+    public function getiTunesAppId() {
212
+        return $this->config->getAppValue('theming', 'iTunesAppId', $this->iTunesAppId);
213
+    }
214
+
215
+    /**
216
+     * @return string
217
+     */
218
+    public function getiOSClientUrl() {
219
+        return $this->config->getAppValue('theming', 'iOSClientUrl', $this->iOSClientUrl);
220
+    }
221
+
222
+    /**
223
+     * @return string
224
+     */
225
+    public function getAndroidClientUrl() {
226
+        return $this->config->getAppValue('theming', 'AndroidClientUrl', $this->AndroidClientUrl);
227
+    }
228
+
229
+
230
+    /**
231
+     * @return array scss variables to overwrite
232
+     */
233
+    public function getScssVariables() {
234
+        $cache = $this->cacheFactory->createDistributed('theming');
235
+        if ($value = $cache->get('getScssVariables')) {
236
+            return $value;
237
+        }
238
+
239
+        $variables = [
240
+            'theming-cachebuster' => "'" . $this->config->getAppValue('theming', 'cachebuster', '0') . "'",
241
+            'theming-logo-mime' => "'" . $this->config->getAppValue('theming', 'logoMime', '') . "'",
242
+            'theming-background-mime' => "'" . $this->config->getAppValue('theming', 'backgroundMime', '') . "'"
243
+        ];
244
+
245
+        $variables['image-logo'] = "'".$this->getLogo()."'";
246
+        $variables['image-login-background'] = "'".$this->getBackground()."'";
247
+        $variables['image-login-plain'] = 'false';
248
+
249
+        if ($this->config->getAppValue('theming', 'color', null) !== null) {
250
+            $variables['color-primary'] = $this->getColorPrimary();
251
+            $variables['color-primary-text'] = $this->getTextColorPrimary();
252
+            $variables['color-primary-element'] = $this->util->elementColor($this->getColorPrimary());
253
+        }
254
+
255
+        if ($this->config->getAppValue('theming', 'backgroundMime', null) === 'backgroundColor') {
256
+            $variables['image-login-plain'] = 'true';
257
+        }
258
+        $cache->set('getScssVariables', $variables);
259
+        return $variables;
260
+    }
261
+
262
+    /**
263
+     * Check if the image should be replaced by the theming app
264
+     * and return the new image location then
265
+     *
266
+     * @param string $app name of the app
267
+     * @param string $image filename of the image
268
+     * @return bool|string false if image should not replaced, otherwise the location of the image
269
+     */
270
+    public function replaceImagePath($app, $image) {
271
+        if($app==='') {
272
+            $app = 'core';
273
+        }
274
+        $cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
275
+
276
+        if ($image === 'favicon.ico' && $this->shouldReplaceIcons()) {
277
+            return $this->urlGenerator->linkToRoute('theming.Icon.getFavicon', ['app' => $app]) . '?v=' . $cacheBusterValue;
278
+        }
279
+        if ($image === 'favicon-touch.png' && $this->shouldReplaceIcons()) {
280
+            return $this->urlGenerator->linkToRoute('theming.Icon.getTouchIcon', ['app' => $app]) . '?v=' . $cacheBusterValue;
281
+        }
282
+        if ($image === 'manifest.json') {
283
+            try {
284
+                $appPath = $this->appManager->getAppPath($app);
285
+                if (file_exists($appPath . '/img/manifest.json')) {
286
+                    return false;
287
+                }
288
+            } catch (AppPathNotFoundException $e) {}
289
+            return $this->urlGenerator->linkToRoute('theming.Theming.getManifest') . '?v=' . $cacheBusterValue;
290
+        }
291
+        return false;
292
+    }
293
+
294
+    /**
295
+     * Check if Imagemagick is enabled and if SVG is supported
296
+     * otherwise we can't render custom icons
297
+     *
298
+     * @return bool
299
+     */
300
+    public function shouldReplaceIcons() {
301
+        $cache = $this->cacheFactory->createDistributed('theming');
302
+        if($value = $cache->get('shouldReplaceIcons')) {
303
+            return (bool)$value;
304
+        }
305
+        $value = false;
306
+        if(extension_loaded('imagick')) {
307
+            $checkImagick = new \Imagick();
308
+            if (count($checkImagick->queryFormats('SVG')) >= 1) {
309
+                $value = true;
310
+            }
311
+            $checkImagick->clear();
312
+        }
313
+        $cache->set('shouldReplaceIcons', $value);
314
+        return $value;
315
+    }
316
+
317
+    /**
318
+     * Increases the cache buster key
319
+     */
320
+    private function increaseCacheBuster() {
321
+        $cacheBusterKey = $this->config->getAppValue('theming', 'cachebuster', '0');
322
+        $this->config->setAppValue('theming', 'cachebuster', (int)$cacheBusterKey+1);
323
+        $this->cacheFactory->createDistributed('theming')->clear('getScssVariables');
324
+    }
325
+
326
+    /**
327
+     * Update setting in the database
328
+     *
329
+     * @param string $setting
330
+     * @param string $value
331
+     */
332
+    public function set($setting, $value) {
333
+        $this->config->setAppValue('theming', $setting, $value);
334
+        $this->increaseCacheBuster();
335
+    }
336
+
337
+    /**
338
+     * Revert settings to the default value
339
+     *
340
+     * @param string $setting setting which should be reverted
341
+     * @return string default value
342
+     */
343
+    public function undo($setting) {
344
+        $this->config->deleteAppValue('theming', $setting);
345
+        $this->increaseCacheBuster();
346
+
347
+        switch ($setting) {
348
+            case 'name':
349
+                $returnValue = $this->getEntity();
350
+                break;
351
+            case 'url':
352
+                $returnValue = $this->getBaseUrl();
353
+                break;
354
+            case 'slogan':
355
+                $returnValue = $this->getSlogan();
356
+                break;
357
+            case 'color':
358
+                $returnValue = $this->getColorPrimary();
359
+                break;
360
+            default:
361
+                $returnValue = '';
362
+                break;
363
+        }
364
+
365
+        return $returnValue;
366
+    }
367
+
368
+    /**
369
+     * Color of text in the header and primary buttons
370
+     *
371
+     * @return string
372
+     */
373
+    public function getTextColorPrimary() {
374
+        return $this->util->invertTextColor($this->getColorPrimary()) ? '#000000' : '#ffffff';
375
+    }
376 376
 }
Please login to merge, or discard this patch.
Spacing   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -144,9 +144,9 @@  discard block
 block discarded – undo
144 144
 
145 145
 	public function getShortFooter() {
146 146
 		$slogan = $this->getSlogan();
147
-		$footer = '<a href="'. $this->getBaseUrl() . '" target="_blank"' .
148
-			' rel="noreferrer noopener">' .$this->getEntity() . '</a>'.
149
-			($slogan !== '' ? ' – ' . $slogan : '');
147
+		$footer = '<a href="'.$this->getBaseUrl().'" target="_blank"'.
148
+			' rel="noreferrer noopener">'.$this->getEntity().'</a>'.
149
+			($slogan !== '' ? ' – '.$slogan : '');
150 150
 
151 151
 		return $footer;
152 152
 	}
@@ -178,16 +178,16 @@  discard block
 block discarded – undo
178 178
 
179 179
 		$cacheBusterCounter = $this->config->getAppValue('theming', 'cachebuster', '0');
180 180
 
181
-		if(!$logo || !$logoExists) {
182
-			if($useSvg) {
181
+		if (!$logo || !$logoExists) {
182
+			if ($useSvg) {
183 183
 				$logo = $this->urlGenerator->imagePath('core', 'logo.svg');
184 184
 			} else {
185 185
 				$logo = $this->urlGenerator->imagePath('core', 'logo.png');
186 186
 			}
187
-			return $logo . '?v=' . $cacheBusterCounter;
187
+			return $logo.'?v='.$cacheBusterCounter;
188 188
 		}
189 189
 
190
-		return $this->urlGenerator->linkToRoute('theming.Theming.getLogo') . '?v=' . $cacheBusterCounter;
190
+		return $this->urlGenerator->linkToRoute('theming.Theming.getLogo').'?v='.$cacheBusterCounter;
191 191
 	}
192 192
 
193 193
 	/**
@@ -198,11 +198,11 @@  discard block
 block discarded – undo
198 198
 	public function getBackground() {
199 199
 		$cacheBusterCounter = $this->config->getAppValue('theming', 'cachebuster', '0');
200 200
 
201
-		if($this->util->isBackgroundThemed()) {
202
-			return $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground') . '?v=' . $cacheBusterCounter;
201
+		if ($this->util->isBackgroundThemed()) {
202
+			return $this->urlGenerator->linkToRoute('theming.Theming.getLoginBackground').'?v='.$cacheBusterCounter;
203 203
 		}
204 204
 
205
-		return $this->urlGenerator->imagePath('core','background.png') . '?v=' . $cacheBusterCounter;
205
+		return $this->urlGenerator->imagePath('core', 'background.png').'?v='.$cacheBusterCounter;
206 206
 	}
207 207
 
208 208
 	/**
@@ -237,9 +237,9 @@  discard block
 block discarded – undo
237 237
 		}
238 238
 
239 239
 		$variables = [
240
-			'theming-cachebuster' => "'" . $this->config->getAppValue('theming', 'cachebuster', '0') . "'",
241
-			'theming-logo-mime' => "'" . $this->config->getAppValue('theming', 'logoMime', '') . "'",
242
-			'theming-background-mime' => "'" . $this->config->getAppValue('theming', 'backgroundMime', '') . "'"
240
+			'theming-cachebuster' => "'".$this->config->getAppValue('theming', 'cachebuster', '0')."'",
241
+			'theming-logo-mime' => "'".$this->config->getAppValue('theming', 'logoMime', '')."'",
242
+			'theming-background-mime' => "'".$this->config->getAppValue('theming', 'backgroundMime', '')."'"
243 243
 		];
244 244
 
245 245
 		$variables['image-logo'] = "'".$this->getLogo()."'";
@@ -268,25 +268,25 @@  discard block
 block discarded – undo
268 268
 	 * @return bool|string false if image should not replaced, otherwise the location of the image
269 269
 	 */
270 270
 	public function replaceImagePath($app, $image) {
271
-		if($app==='') {
271
+		if ($app === '') {
272 272
 			$app = 'core';
273 273
 		}
274 274
 		$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
275 275
 
276 276
 		if ($image === 'favicon.ico' && $this->shouldReplaceIcons()) {
277
-			return $this->urlGenerator->linkToRoute('theming.Icon.getFavicon', ['app' => $app]) . '?v=' . $cacheBusterValue;
277
+			return $this->urlGenerator->linkToRoute('theming.Icon.getFavicon', ['app' => $app]).'?v='.$cacheBusterValue;
278 278
 		}
279 279
 		if ($image === 'favicon-touch.png' && $this->shouldReplaceIcons()) {
280
-			return $this->urlGenerator->linkToRoute('theming.Icon.getTouchIcon', ['app' => $app]) . '?v=' . $cacheBusterValue;
280
+			return $this->urlGenerator->linkToRoute('theming.Icon.getTouchIcon', ['app' => $app]).'?v='.$cacheBusterValue;
281 281
 		}
282 282
 		if ($image === 'manifest.json') {
283 283
 			try {
284 284
 				$appPath = $this->appManager->getAppPath($app);
285
-				if (file_exists($appPath . '/img/manifest.json')) {
285
+				if (file_exists($appPath.'/img/manifest.json')) {
286 286
 					return false;
287 287
 				}
288 288
 			} catch (AppPathNotFoundException $e) {}
289
-			return $this->urlGenerator->linkToRoute('theming.Theming.getManifest') . '?v=' . $cacheBusterValue;
289
+			return $this->urlGenerator->linkToRoute('theming.Theming.getManifest').'?v='.$cacheBusterValue;
290 290
 		}
291 291
 		return false;
292 292
 	}
@@ -299,11 +299,11 @@  discard block
 block discarded – undo
299 299
 	 */
300 300
 	public function shouldReplaceIcons() {
301 301
 		$cache = $this->cacheFactory->createDistributed('theming');
302
-		if($value = $cache->get('shouldReplaceIcons')) {
303
-			return (bool)$value;
302
+		if ($value = $cache->get('shouldReplaceIcons')) {
303
+			return (bool) $value;
304 304
 		}
305 305
 		$value = false;
306
-		if(extension_loaded('imagick')) {
306
+		if (extension_loaded('imagick')) {
307 307
 			$checkImagick = new \Imagick();
308 308
 			if (count($checkImagick->queryFormats('SVG')) >= 1) {
309 309
 				$value = true;
@@ -319,7 +319,7 @@  discard block
 block discarded – undo
319 319
 	 */
320 320
 	private function increaseCacheBuster() {
321 321
 		$cacheBusterKey = $this->config->getAppValue('theming', 'cachebuster', '0');
322
-		$this->config->setAppValue('theming', 'cachebuster', (int)$cacheBusterKey+1);
322
+		$this->config->setAppValue('theming', 'cachebuster', (int) $cacheBusterKey + 1);
323 323
 		$this->cacheFactory->createDistributed('theming')->clear('getScssVariables');
324 324
 	}
325 325
 
Please login to merge, or discard this patch.
lib/private/Template/SCSSCacher.php 2 patches
Indentation   +308 added lines, -308 removed lines patch added patch discarded remove patch
@@ -45,312 +45,312 @@
 block discarded – undo
45 45
 
46 46
 class SCSSCacher {
47 47
 
48
-	/** @var ILogger */
49
-	protected $logger;
50
-
51
-	/** @var IAppData */
52
-	protected $appData;
53
-
54
-	/** @var IURLGenerator */
55
-	protected $urlGenerator;
56
-
57
-	/** @var IConfig */
58
-	protected $config;
59
-
60
-	/** @var \OC_Defaults */
61
-	private $defaults;
62
-
63
-	/** @var string */
64
-	protected $serverRoot;
65
-
66
-	/** @var ICache */
67
-	protected $depsCache;
68
-
69
-	/** @var null|string */
70
-	private $injectedVariables;
71
-
72
-	/**
73
-	 * @param ILogger $logger
74
-	 * @param Factory $appDataFactory
75
-	 * @param IURLGenerator $urlGenerator
76
-	 * @param IConfig $config
77
-	 * @param \OC_Defaults $defaults
78
-	 * @param string $serverRoot
79
-	 * @param ICache $depsCache
80
-	 */
81
-	public function __construct(ILogger $logger,
82
-								Factory $appDataFactory,
83
-								IURLGenerator $urlGenerator,
84
-								IConfig $config,
85
-								\OC_Defaults $defaults,
86
-								$serverRoot,
87
-								ICache $depsCache) {
88
-		$this->logger = $logger;
89
-		$this->appData = $appDataFactory->get('css');
90
-		$this->urlGenerator = $urlGenerator;
91
-		$this->config = $config;
92
-		$this->defaults = $defaults;
93
-		$this->serverRoot = $serverRoot;
94
-		$this->depsCache = $depsCache;
95
-	}
96
-
97
-	/**
98
-	 * Process the caching process if needed
99
-	 *
100
-	 * @param string $root Root path to the nextcloud installation
101
-	 * @param string $file
102
-	 * @param string $app The app name
103
-	 * @return boolean
104
-	 * @throws NotPermittedException
105
-	 */
106
-	public function process(string $root, string $file, string $app): bool {
107
-		$path = explode('/', $root . '/' . $file);
108
-
109
-		$fileNameSCSS = array_pop($path);
110
-		$fileNameCSS = $this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileNameSCSS));
111
-
112
-		$path = implode('/', $path);
113
-		$webDir = $this->getWebDir($path, $app, $this->serverRoot, \OC::$WEBROOT);
114
-
115
-		try {
116
-			$folder = $this->appData->getFolder($app);
117
-		} catch(NotFoundException $e) {
118
-			// creating css appdata folder
119
-			$folder = $this->appData->newFolder($app);
120
-		}
121
-
122
-
123
-		if(!$this->variablesChanged() && $this->isCached($fileNameCSS, $folder)) {
124
-			return true;
125
-		}
126
-		return $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir);
127
-	}
128
-
129
-	/**
130
-	 * @param $appName
131
-	 * @param $fileName
132
-	 * @return ISimpleFile
133
-	 */
134
-	public function getCachedCSS(string $appName, string $fileName): ISimpleFile {
135
-		$folder = $this->appData->getFolder($appName);
136
-		return $folder->getFile($this->prependBaseurlPrefix($fileName));
137
-	}
138
-
139
-	/**
140
-	 * Check if the file is cached or not
141
-	 * @param string $fileNameCSS
142
-	 * @param ISimpleFolder $folder
143
-	 * @return boolean
144
-	 */
145
-	private function isCached(string $fileNameCSS, ISimpleFolder $folder) {
146
-		try {
147
-			$cachedFile = $folder->getFile($fileNameCSS);
148
-			if ($cachedFile->getSize() > 0) {
149
-				$depFileName = $fileNameCSS . '.deps';
150
-				$deps = $this->depsCache->get($folder->getName() . '-' . $depFileName);
151
-				if ($deps === null) {
152
-					$depFile = $folder->getFile($depFileName);
153
-					$deps = $depFile->getContent();
154
-					//Set to memcache for next run
155
-					$this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
156
-				}
157
-				$deps = json_decode($deps, true);
158
-
159
-				foreach ((array)$deps as $file=>$mtime) {
160
-					if (!file_exists($file) || filemtime($file) > $mtime) {
161
-						return false;
162
-					}
163
-				}
164
-				return true;
165
-			}
166
-			return false;
167
-		} catch(NotFoundException $e) {
168
-			return false;
169
-		}
170
-	}
171
-
172
-	/**
173
-	 * Check if the variables file has changed
174
-	 * @return bool
175
-	 */
176
-	private function variablesChanged(): bool {
177
-		$injectedVariables = $this->getInjectedVariables();
178
-		if($this->config->getAppValue('core', 'scss.variables') !== md5($injectedVariables)) {
179
-			$this->resetCache();
180
-			$this->config->setAppValue('core', 'scss.variables', md5($injectedVariables));
181
-			return true;
182
-		}
183
-		return false;
184
-	}
185
-
186
-	/**
187
-	 * Cache the file with AppData
188
-	 *
189
-	 * @param string $path
190
-	 * @param string $fileNameCSS
191
-	 * @param string $fileNameSCSS
192
-	 * @param ISimpleFolder $folder
193
-	 * @param string $webDir
194
-	 * @return boolean
195
-	 * @throws NotPermittedException
196
-	 */
197
-	private function cache(string $path, string $fileNameCSS, string $fileNameSCSS, ISimpleFolder $folder, string $webDir) {
198
-		$scss = new Compiler();
199
-		$scss->setImportPaths([
200
-			$path,
201
-			$this->serverRoot . '/core/css/',
202
-		]);
203
-		// Continue after throw
204
-		$scss->setIgnoreErrors(true);
205
-		if($this->config->getSystemValue('debug')) {
206
-			// Debug mode
207
-			$scss->setFormatter(Expanded::class);
208
-			$scss->setLineNumberStyle(Compiler::LINE_COMMENTS);
209
-		} else {
210
-			// Compression
211
-			$scss->setFormatter(Crunched::class);
212
-		}
213
-
214
-		try {
215
-			$cachedfile = $folder->getFile($fileNameCSS);
216
-		} catch(NotFoundException $e) {
217
-			$cachedfile = $folder->newFile($fileNameCSS);
218
-		}
219
-
220
-		$depFileName = $fileNameCSS . '.deps';
221
-		try {
222
-			$depFile = $folder->getFile($depFileName);
223
-		} catch (NotFoundException $e) {
224
-			$depFile = $folder->newFile($depFileName);
225
-		}
226
-
227
-		// Compile
228
-		try {
229
-			$compiledScss = $scss->compile(
230
-				'@import "variables.scss";' .
231
-				$this->getInjectedVariables() .
232
-				'@import "'.$fileNameSCSS.'";');
233
-		} catch(ParserException $e) {
234
-			$this->logger->error($e, ['app' => 'core']);
235
-			return false;
236
-		}
237
-
238
-		// Gzip file
239
-		try {
240
-			$gzipFile = $folder->getFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
241
-		} catch (NotFoundException $e) {
242
-			$gzipFile = $folder->newFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
243
-		}
244
-
245
-		try {
246
-			$data = $this->rebaseUrls($compiledScss, $webDir);
247
-			$cachedfile->putContent($data);
248
-			$deps = json_encode($scss->getParsedFiles());
249
-			$depFile->putContent($deps);
250
-			$this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
251
-			$gzipFile->putContent(gzencode($data, 9));
252
-			$this->logger->debug($webDir.'/'.$fileNameSCSS.' compiled and successfully cached', ['app' => 'core']);
253
-			return true;
254
-		} catch(NotPermittedException $e) {
255
-			return false;
256
-		}
257
-	}
258
-
259
-	/**
260
-	 * Reset scss cache by deleting all generated css files
261
-	 * We need to regenerate all files when variables change
262
-	 */
263
-	private function resetCache() {
264
-		$this->injectedVariables = null;
265
-		$appDirectory = $this->appData->getDirectoryListing();
266
-		if(empty($appDirectory)){
267
-			return;
268
-		}
269
-		foreach ($appDirectory as $folder) {
270
-			foreach ($folder->getDirectoryListing() as $file) {
271
-				if (substr($file->getName(), -3) === 'css' || substr($file->getName(), -4) === 'deps') {
272
-					$file->delete();
273
-				}
274
-			}
275
-		}
276
-	}
277
-
278
-	/**
279
-	 * @return string SCSS code for variables from OC_Defaults
280
-	 */
281
-	private function getInjectedVariables(): string {
282
-		if ($this->injectedVariables !== null) {
283
-			return $this->injectedVariables;
284
-		}
285
-		$variables = '';
286
-		foreach ($this->defaults->getScssVariables() as $key => $value) {
287
-			$variables .= '$' . $key . ': ' . $value . ';';
288
-		}
289
-
290
-		// check for valid variables / otherwise fall back to defaults
291
-		try {
292
-			$scss = new Compiler();
293
-			$scss->compile($variables);
294
-			$this->injectedVariables = $variables;
295
-		} catch (ParserException $e) {
296
-			$this->logger->error($e, ['app' => 'core']);
297
-		}
298
-
299
-		return $variables;
300
-	}
301
-
302
-	/**
303
-	 * Add the correct uri prefix to make uri valid again
304
-	 * @param string $css
305
-	 * @param string $webDir
306
-	 * @return string
307
-	 */
308
-	private function rebaseUrls(string $css, string $webDir): string {
309
-		$re = '/url\([\'"]([^\/][\.\w?=\/-]*)[\'"]\)/x';
310
-		$subst = 'url(\''.$webDir.'/$1\')';
311
-		return preg_replace($re, $subst, $css);
312
-	}
313
-
314
-	/**
315
-	 * Return the cached css file uri
316
-	 * @param string $appName the app name
317
-	 * @param string $fileName
318
-	 * @return string
319
-	 */
320
-	public function getCachedSCSS(string $appName, string $fileName): string {
321
-		$tmpfileLoc = explode('/', $fileName);
322
-		$fileName = array_pop($tmpfileLoc);
323
-		$fileName = $this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileName));
324
-
325
-		return substr($this->urlGenerator->linkToRoute('core.Css.getCss', ['fileName' => $fileName, 'appName' => $appName]), strlen(\OC::$WEBROOT) + 1);
326
-	}
327
-
328
-	/**
329
-	 * Prepend hashed base url to the css file
330
-	 * @param string$cssFile
331
-	 * @return string
332
-	 */
333
-	private function prependBaseurlPrefix(string $cssFile): string {
334
-		$frontendController = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
335
-		return substr(md5($this->urlGenerator->getBaseUrl() . $frontendController), 0, 8) . '-' . $cssFile;
336
-	}
337
-
338
-	/**
339
-	 * Get WebDir root
340
-	 * @param string $path the css file path
341
-	 * @param string $appName the app name
342
-	 * @param string $serverRoot the server root path
343
-	 * @param string $webRoot the nextcloud installation root path
344
-	 * @return string the webDir
345
-	 */
346
-	private function getWebDir(string $path, string $appName, string $serverRoot, string $webRoot): string {
347
-		// Detect if path is within server root AND if path is within an app path
348
-		if ( strpos($path, $serverRoot) === false && $appWebPath = \OC_App::getAppWebPath($appName)) {
349
-			// Get the file path within the app directory
350
-			$appDirectoryPath = explode($appName, $path)[1];
351
-			// Remove the webroot
352
-			return str_replace($webRoot, '', $appWebPath.$appDirectoryPath);
353
-		}
354
-		return $webRoot.substr($path, strlen($serverRoot));
355
-	}
48
+    /** @var ILogger */
49
+    protected $logger;
50
+
51
+    /** @var IAppData */
52
+    protected $appData;
53
+
54
+    /** @var IURLGenerator */
55
+    protected $urlGenerator;
56
+
57
+    /** @var IConfig */
58
+    protected $config;
59
+
60
+    /** @var \OC_Defaults */
61
+    private $defaults;
62
+
63
+    /** @var string */
64
+    protected $serverRoot;
65
+
66
+    /** @var ICache */
67
+    protected $depsCache;
68
+
69
+    /** @var null|string */
70
+    private $injectedVariables;
71
+
72
+    /**
73
+     * @param ILogger $logger
74
+     * @param Factory $appDataFactory
75
+     * @param IURLGenerator $urlGenerator
76
+     * @param IConfig $config
77
+     * @param \OC_Defaults $defaults
78
+     * @param string $serverRoot
79
+     * @param ICache $depsCache
80
+     */
81
+    public function __construct(ILogger $logger,
82
+                                Factory $appDataFactory,
83
+                                IURLGenerator $urlGenerator,
84
+                                IConfig $config,
85
+                                \OC_Defaults $defaults,
86
+                                $serverRoot,
87
+                                ICache $depsCache) {
88
+        $this->logger = $logger;
89
+        $this->appData = $appDataFactory->get('css');
90
+        $this->urlGenerator = $urlGenerator;
91
+        $this->config = $config;
92
+        $this->defaults = $defaults;
93
+        $this->serverRoot = $serverRoot;
94
+        $this->depsCache = $depsCache;
95
+    }
96
+
97
+    /**
98
+     * Process the caching process if needed
99
+     *
100
+     * @param string $root Root path to the nextcloud installation
101
+     * @param string $file
102
+     * @param string $app The app name
103
+     * @return boolean
104
+     * @throws NotPermittedException
105
+     */
106
+    public function process(string $root, string $file, string $app): bool {
107
+        $path = explode('/', $root . '/' . $file);
108
+
109
+        $fileNameSCSS = array_pop($path);
110
+        $fileNameCSS = $this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileNameSCSS));
111
+
112
+        $path = implode('/', $path);
113
+        $webDir = $this->getWebDir($path, $app, $this->serverRoot, \OC::$WEBROOT);
114
+
115
+        try {
116
+            $folder = $this->appData->getFolder($app);
117
+        } catch(NotFoundException $e) {
118
+            // creating css appdata folder
119
+            $folder = $this->appData->newFolder($app);
120
+        }
121
+
122
+
123
+        if(!$this->variablesChanged() && $this->isCached($fileNameCSS, $folder)) {
124
+            return true;
125
+        }
126
+        return $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir);
127
+    }
128
+
129
+    /**
130
+     * @param $appName
131
+     * @param $fileName
132
+     * @return ISimpleFile
133
+     */
134
+    public function getCachedCSS(string $appName, string $fileName): ISimpleFile {
135
+        $folder = $this->appData->getFolder($appName);
136
+        return $folder->getFile($this->prependBaseurlPrefix($fileName));
137
+    }
138
+
139
+    /**
140
+     * Check if the file is cached or not
141
+     * @param string $fileNameCSS
142
+     * @param ISimpleFolder $folder
143
+     * @return boolean
144
+     */
145
+    private function isCached(string $fileNameCSS, ISimpleFolder $folder) {
146
+        try {
147
+            $cachedFile = $folder->getFile($fileNameCSS);
148
+            if ($cachedFile->getSize() > 0) {
149
+                $depFileName = $fileNameCSS . '.deps';
150
+                $deps = $this->depsCache->get($folder->getName() . '-' . $depFileName);
151
+                if ($deps === null) {
152
+                    $depFile = $folder->getFile($depFileName);
153
+                    $deps = $depFile->getContent();
154
+                    //Set to memcache for next run
155
+                    $this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
156
+                }
157
+                $deps = json_decode($deps, true);
158
+
159
+                foreach ((array)$deps as $file=>$mtime) {
160
+                    if (!file_exists($file) || filemtime($file) > $mtime) {
161
+                        return false;
162
+                    }
163
+                }
164
+                return true;
165
+            }
166
+            return false;
167
+        } catch(NotFoundException $e) {
168
+            return false;
169
+        }
170
+    }
171
+
172
+    /**
173
+     * Check if the variables file has changed
174
+     * @return bool
175
+     */
176
+    private function variablesChanged(): bool {
177
+        $injectedVariables = $this->getInjectedVariables();
178
+        if($this->config->getAppValue('core', 'scss.variables') !== md5($injectedVariables)) {
179
+            $this->resetCache();
180
+            $this->config->setAppValue('core', 'scss.variables', md5($injectedVariables));
181
+            return true;
182
+        }
183
+        return false;
184
+    }
185
+
186
+    /**
187
+     * Cache the file with AppData
188
+     *
189
+     * @param string $path
190
+     * @param string $fileNameCSS
191
+     * @param string $fileNameSCSS
192
+     * @param ISimpleFolder $folder
193
+     * @param string $webDir
194
+     * @return boolean
195
+     * @throws NotPermittedException
196
+     */
197
+    private function cache(string $path, string $fileNameCSS, string $fileNameSCSS, ISimpleFolder $folder, string $webDir) {
198
+        $scss = new Compiler();
199
+        $scss->setImportPaths([
200
+            $path,
201
+            $this->serverRoot . '/core/css/',
202
+        ]);
203
+        // Continue after throw
204
+        $scss->setIgnoreErrors(true);
205
+        if($this->config->getSystemValue('debug')) {
206
+            // Debug mode
207
+            $scss->setFormatter(Expanded::class);
208
+            $scss->setLineNumberStyle(Compiler::LINE_COMMENTS);
209
+        } else {
210
+            // Compression
211
+            $scss->setFormatter(Crunched::class);
212
+        }
213
+
214
+        try {
215
+            $cachedfile = $folder->getFile($fileNameCSS);
216
+        } catch(NotFoundException $e) {
217
+            $cachedfile = $folder->newFile($fileNameCSS);
218
+        }
219
+
220
+        $depFileName = $fileNameCSS . '.deps';
221
+        try {
222
+            $depFile = $folder->getFile($depFileName);
223
+        } catch (NotFoundException $e) {
224
+            $depFile = $folder->newFile($depFileName);
225
+        }
226
+
227
+        // Compile
228
+        try {
229
+            $compiledScss = $scss->compile(
230
+                '@import "variables.scss";' .
231
+                $this->getInjectedVariables() .
232
+                '@import "'.$fileNameSCSS.'";');
233
+        } catch(ParserException $e) {
234
+            $this->logger->error($e, ['app' => 'core']);
235
+            return false;
236
+        }
237
+
238
+        // Gzip file
239
+        try {
240
+            $gzipFile = $folder->getFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
241
+        } catch (NotFoundException $e) {
242
+            $gzipFile = $folder->newFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
243
+        }
244
+
245
+        try {
246
+            $data = $this->rebaseUrls($compiledScss, $webDir);
247
+            $cachedfile->putContent($data);
248
+            $deps = json_encode($scss->getParsedFiles());
249
+            $depFile->putContent($deps);
250
+            $this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
251
+            $gzipFile->putContent(gzencode($data, 9));
252
+            $this->logger->debug($webDir.'/'.$fileNameSCSS.' compiled and successfully cached', ['app' => 'core']);
253
+            return true;
254
+        } catch(NotPermittedException $e) {
255
+            return false;
256
+        }
257
+    }
258
+
259
+    /**
260
+     * Reset scss cache by deleting all generated css files
261
+     * We need to regenerate all files when variables change
262
+     */
263
+    private function resetCache() {
264
+        $this->injectedVariables = null;
265
+        $appDirectory = $this->appData->getDirectoryListing();
266
+        if(empty($appDirectory)){
267
+            return;
268
+        }
269
+        foreach ($appDirectory as $folder) {
270
+            foreach ($folder->getDirectoryListing() as $file) {
271
+                if (substr($file->getName(), -3) === 'css' || substr($file->getName(), -4) === 'deps') {
272
+                    $file->delete();
273
+                }
274
+            }
275
+        }
276
+    }
277
+
278
+    /**
279
+     * @return string SCSS code for variables from OC_Defaults
280
+     */
281
+    private function getInjectedVariables(): string {
282
+        if ($this->injectedVariables !== null) {
283
+            return $this->injectedVariables;
284
+        }
285
+        $variables = '';
286
+        foreach ($this->defaults->getScssVariables() as $key => $value) {
287
+            $variables .= '$' . $key . ': ' . $value . ';';
288
+        }
289
+
290
+        // check for valid variables / otherwise fall back to defaults
291
+        try {
292
+            $scss = new Compiler();
293
+            $scss->compile($variables);
294
+            $this->injectedVariables = $variables;
295
+        } catch (ParserException $e) {
296
+            $this->logger->error($e, ['app' => 'core']);
297
+        }
298
+
299
+        return $variables;
300
+    }
301
+
302
+    /**
303
+     * Add the correct uri prefix to make uri valid again
304
+     * @param string $css
305
+     * @param string $webDir
306
+     * @return string
307
+     */
308
+    private function rebaseUrls(string $css, string $webDir): string {
309
+        $re = '/url\([\'"]([^\/][\.\w?=\/-]*)[\'"]\)/x';
310
+        $subst = 'url(\''.$webDir.'/$1\')';
311
+        return preg_replace($re, $subst, $css);
312
+    }
313
+
314
+    /**
315
+     * Return the cached css file uri
316
+     * @param string $appName the app name
317
+     * @param string $fileName
318
+     * @return string
319
+     */
320
+    public function getCachedSCSS(string $appName, string $fileName): string {
321
+        $tmpfileLoc = explode('/', $fileName);
322
+        $fileName = array_pop($tmpfileLoc);
323
+        $fileName = $this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileName));
324
+
325
+        return substr($this->urlGenerator->linkToRoute('core.Css.getCss', ['fileName' => $fileName, 'appName' => $appName]), strlen(\OC::$WEBROOT) + 1);
326
+    }
327
+
328
+    /**
329
+     * Prepend hashed base url to the css file
330
+     * @param string$cssFile
331
+     * @return string
332
+     */
333
+    private function prependBaseurlPrefix(string $cssFile): string {
334
+        $frontendController = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
335
+        return substr(md5($this->urlGenerator->getBaseUrl() . $frontendController), 0, 8) . '-' . $cssFile;
336
+    }
337
+
338
+    /**
339
+     * Get WebDir root
340
+     * @param string $path the css file path
341
+     * @param string $appName the app name
342
+     * @param string $serverRoot the server root path
343
+     * @param string $webRoot the nextcloud installation root path
344
+     * @return string the webDir
345
+     */
346
+    private function getWebDir(string $path, string $appName, string $serverRoot, string $webRoot): string {
347
+        // Detect if path is within server root AND if path is within an app path
348
+        if ( strpos($path, $serverRoot) === false && $appWebPath = \OC_App::getAppWebPath($appName)) {
349
+            // Get the file path within the app directory
350
+            $appDirectoryPath = explode($appName, $path)[1];
351
+            // Remove the webroot
352
+            return str_replace($webRoot, '', $appWebPath.$appDirectoryPath);
353
+        }
354
+        return $webRoot.substr($path, strlen($serverRoot));
355
+    }
356 356
 }
Please login to merge, or discard this patch.
Spacing   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -104,7 +104,7 @@  discard block
 block discarded – undo
104 104
 	 * @throws NotPermittedException
105 105
 	 */
106 106
 	public function process(string $root, string $file, string $app): bool {
107
-		$path = explode('/', $root . '/' . $file);
107
+		$path = explode('/', $root.'/'.$file);
108 108
 
109 109
 		$fileNameSCSS = array_pop($path);
110 110
 		$fileNameCSS = $this->prependBaseurlPrefix(str_replace('.scss', '.css', $fileNameSCSS));
@@ -114,13 +114,13 @@  discard block
 block discarded – undo
114 114
 
115 115
 		try {
116 116
 			$folder = $this->appData->getFolder($app);
117
-		} catch(NotFoundException $e) {
117
+		} catch (NotFoundException $e) {
118 118
 			// creating css appdata folder
119 119
 			$folder = $this->appData->newFolder($app);
120 120
 		}
121 121
 
122 122
 
123
-		if(!$this->variablesChanged() && $this->isCached($fileNameCSS, $folder)) {
123
+		if (!$this->variablesChanged() && $this->isCached($fileNameCSS, $folder)) {
124 124
 			return true;
125 125
 		}
126 126
 		return $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir);
@@ -146,17 +146,17 @@  discard block
 block discarded – undo
146 146
 		try {
147 147
 			$cachedFile = $folder->getFile($fileNameCSS);
148 148
 			if ($cachedFile->getSize() > 0) {
149
-				$depFileName = $fileNameCSS . '.deps';
150
-				$deps = $this->depsCache->get($folder->getName() . '-' . $depFileName);
149
+				$depFileName = $fileNameCSS.'.deps';
150
+				$deps = $this->depsCache->get($folder->getName().'-'.$depFileName);
151 151
 				if ($deps === null) {
152 152
 					$depFile = $folder->getFile($depFileName);
153 153
 					$deps = $depFile->getContent();
154 154
 					//Set to memcache for next run
155
-					$this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
155
+					$this->depsCache->set($folder->getName().'-'.$depFileName, $deps);
156 156
 				}
157 157
 				$deps = json_decode($deps, true);
158 158
 
159
-				foreach ((array)$deps as $file=>$mtime) {
159
+				foreach ((array) $deps as $file=>$mtime) {
160 160
 					if (!file_exists($file) || filemtime($file) > $mtime) {
161 161
 						return false;
162 162
 					}
@@ -164,7 +164,7 @@  discard block
 block discarded – undo
164 164
 				return true;
165 165
 			}
166 166
 			return false;
167
-		} catch(NotFoundException $e) {
167
+		} catch (NotFoundException $e) {
168 168
 			return false;
169 169
 		}
170 170
 	}
@@ -175,7 +175,7 @@  discard block
 block discarded – undo
175 175
 	 */
176 176
 	private function variablesChanged(): bool {
177 177
 		$injectedVariables = $this->getInjectedVariables();
178
-		if($this->config->getAppValue('core', 'scss.variables') !== md5($injectedVariables)) {
178
+		if ($this->config->getAppValue('core', 'scss.variables') !== md5($injectedVariables)) {
179 179
 			$this->resetCache();
180 180
 			$this->config->setAppValue('core', 'scss.variables', md5($injectedVariables));
181 181
 			return true;
@@ -198,11 +198,11 @@  discard block
 block discarded – undo
198 198
 		$scss = new Compiler();
199 199
 		$scss->setImportPaths([
200 200
 			$path,
201
-			$this->serverRoot . '/core/css/',
201
+			$this->serverRoot.'/core/css/',
202 202
 		]);
203 203
 		// Continue after throw
204 204
 		$scss->setIgnoreErrors(true);
205
-		if($this->config->getSystemValue('debug')) {
205
+		if ($this->config->getSystemValue('debug')) {
206 206
 			// Debug mode
207 207
 			$scss->setFormatter(Expanded::class);
208 208
 			$scss->setLineNumberStyle(Compiler::LINE_COMMENTS);
@@ -213,11 +213,11 @@  discard block
 block discarded – undo
213 213
 
214 214
 		try {
215 215
 			$cachedfile = $folder->getFile($fileNameCSS);
216
-		} catch(NotFoundException $e) {
216
+		} catch (NotFoundException $e) {
217 217
 			$cachedfile = $folder->newFile($fileNameCSS);
218 218
 		}
219 219
 
220
-		$depFileName = $fileNameCSS . '.deps';
220
+		$depFileName = $fileNameCSS.'.deps';
221 221
 		try {
222 222
 			$depFile = $folder->getFile($depFileName);
223 223
 		} catch (NotFoundException $e) {
@@ -227,19 +227,19 @@  discard block
 block discarded – undo
227 227
 		// Compile
228 228
 		try {
229 229
 			$compiledScss = $scss->compile(
230
-				'@import "variables.scss";' .
231
-				$this->getInjectedVariables() .
230
+				'@import "variables.scss";'.
231
+				$this->getInjectedVariables().
232 232
 				'@import "'.$fileNameSCSS.'";');
233
-		} catch(ParserException $e) {
233
+		} catch (ParserException $e) {
234 234
 			$this->logger->error($e, ['app' => 'core']);
235 235
 			return false;
236 236
 		}
237 237
 
238 238
 		// Gzip file
239 239
 		try {
240
-			$gzipFile = $folder->getFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
240
+			$gzipFile = $folder->getFile($fileNameCSS.'.gzip'); # Safari doesn't like .gz
241 241
 		} catch (NotFoundException $e) {
242
-			$gzipFile = $folder->newFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
242
+			$gzipFile = $folder->newFile($fileNameCSS.'.gzip'); # Safari doesn't like .gz
243 243
 		}
244 244
 
245 245
 		try {
@@ -247,11 +247,11 @@  discard block
 block discarded – undo
247 247
 			$cachedfile->putContent($data);
248 248
 			$deps = json_encode($scss->getParsedFiles());
249 249
 			$depFile->putContent($deps);
250
-			$this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
250
+			$this->depsCache->set($folder->getName().'-'.$depFileName, $deps);
251 251
 			$gzipFile->putContent(gzencode($data, 9));
252 252
 			$this->logger->debug($webDir.'/'.$fileNameSCSS.' compiled and successfully cached', ['app' => 'core']);
253 253
 			return true;
254
-		} catch(NotPermittedException $e) {
254
+		} catch (NotPermittedException $e) {
255 255
 			return false;
256 256
 		}
257 257
 	}
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
 	private function resetCache() {
264 264
 		$this->injectedVariables = null;
265 265
 		$appDirectory = $this->appData->getDirectoryListing();
266
-		if(empty($appDirectory)){
266
+		if (empty($appDirectory)) {
267 267
 			return;
268 268
 		}
269 269
 		foreach ($appDirectory as $folder) {
@@ -284,7 +284,7 @@  discard block
 block discarded – undo
284 284
 		}
285 285
 		$variables = '';
286 286
 		foreach ($this->defaults->getScssVariables() as $key => $value) {
287
-			$variables .= '$' . $key . ': ' . $value . ';';
287
+			$variables .= '$'.$key.': '.$value.';';
288 288
 		}
289 289
 
290 290
 		// check for valid variables / otherwise fall back to defaults
@@ -332,7 +332,7 @@  discard block
 block discarded – undo
332 332
 	 */
333 333
 	private function prependBaseurlPrefix(string $cssFile): string {
334 334
 		$frontendController = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
335
-		return substr(md5($this->urlGenerator->getBaseUrl() . $frontendController), 0, 8) . '-' . $cssFile;
335
+		return substr(md5($this->urlGenerator->getBaseUrl().$frontendController), 0, 8).'-'.$cssFile;
336 336
 	}
337 337
 
338 338
 	/**
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
 	 */
346 346
 	private function getWebDir(string $path, string $appName, string $serverRoot, string $webRoot): string {
347 347
 		// Detect if path is within server root AND if path is within an app path
348
-		if ( strpos($path, $serverRoot) === false && $appWebPath = \OC_App::getAppWebPath($appName)) {
348
+		if (strpos($path, $serverRoot) === false && $appWebPath = \OC_App::getAppWebPath($appName)) {
349 349
 			// Get the file path within the app directory
350 350
 			$appDirectoryPath = explode($appName, $path)[1];
351 351
 			// Remove the webroot
Please login to merge, or discard this patch.