Completed
Push — master ( 5b39c6...1db93e )
by Lukas
47s
created
lib/private/Template/SCSSCacher.php 1 patch
Indentation   +258 added lines, -258 removed lines patch added patch discarded remove patch
@@ -38,262 +38,262 @@
 block discarded – undo
38 38
 
39 39
 class SCSSCacher {
40 40
 
41
-	/** @var ILogger */
42
-	protected $logger;
43
-
44
-	/** @var IAppData */
45
-	protected $appData;
46
-
47
-	/** @var IURLGenerator */
48
-	protected $urlGenerator;
49
-
50
-	/** @var IConfig */
51
-	protected $config;
52
-
53
-	/** @var string */
54
-	protected $serverRoot;
55
-
56
-	/** @var ICache */
57
-	protected $depsCache;
58
-
59
-	/**
60
-	 * @param ILogger $logger
61
-	 * @param Factory $appDataFactory
62
-	 * @param IURLGenerator $urlGenerator
63
-	 * @param IConfig $config
64
-	 * @param \OC_Defaults $defaults
65
-	 * @param string $serverRoot
66
-	 * @param ICache $depsCache
67
-	 */
68
-	public function __construct(ILogger $logger,
69
-								Factory $appDataFactory,
70
-								IURLGenerator $urlGenerator,
71
-								IConfig $config,
72
-								\OC_Defaults $defaults,
73
-								$serverRoot,
74
-								ICache $depsCache) {
75
-		$this->logger = $logger;
76
-		$this->appData = $appDataFactory->get('css');
77
-		$this->urlGenerator = $urlGenerator;
78
-		$this->config = $config;
79
-		$this->defaults = $defaults;
80
-		$this->serverRoot = $serverRoot;
81
-		$this->depsCache = $depsCache;
82
-	}
83
-
84
-	/**
85
-	 * Process the caching process if needed
86
-	 * @param string $root Root path to the nextcloud installation
87
-	 * @param string $file
88
-	 * @param string $app The app name
89
-	 * @return boolean
90
-	 */
91
-	public function process($root, $file, $app) {
92
-		$path = explode('/', $root . '/' . $file);
93
-
94
-		$fileNameSCSS = array_pop($path);
95
-		$fileNameCSS = str_replace('.scss', '.css', $fileNameSCSS);
96
-
97
-		$path = implode('/', $path);
98
-
99
-		$webDir = substr($path, strlen($this->serverRoot)+1);
100
-
101
-		try {
102
-			$folder = $this->appData->getFolder($app);
103
-		} catch(NotFoundException $e) {
104
-			// creating css appdata folder
105
-			$folder = $this->appData->newFolder($app);
106
-		}
107
-
108
-
109
-		if(!$this->variablesChanged() && $this->isCached($fileNameCSS, $folder)) {
110
-			return true;
111
-		}
112
-		return $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir);
113
-	}
114
-
115
-	/**
116
-	 * @param $appName
117
-	 * @param $fileName
118
-	 * @return ISimpleFile
119
-	 */
120
-	public function getCachedCSS($appName, $fileName) {
121
-		$folder = $this->appData->getFolder($appName);
122
-		return $folder->getFile($fileName);
123
-	}
124
-
125
-	/**
126
-	 * Check if the file is cached or not
127
-	 * @param string $fileNameCSS
128
-	 * @param ISimpleFolder $folder
129
-	 * @return boolean
130
-	 */
131
-	private function isCached($fileNameCSS, ISimpleFolder $folder) {
132
-		try {
133
-			$cachedFile = $folder->getFile($fileNameCSS);
134
-			if ($cachedFile->getSize() > 0) {
135
-				$depFileName = $fileNameCSS . '.deps';
136
-				$deps = $this->depsCache->get($folder->getName() . '-' . $depFileName);
137
-				if ($deps === null) {
138
-					$depFile = $folder->getFile($depFileName);
139
-					$deps = $depFile->getContent();
140
-					//Set to memcache for next run
141
-					$this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
142
-				}
143
-				$deps = json_decode($deps, true);
144
-
145
-				foreach ($deps as $file=>$mtime) {
146
-					if (!file_exists($file) || filemtime($file) > $mtime) {
147
-						return false;
148
-					}
149
-				}
150
-			}
151
-			return true;
152
-		} catch(NotFoundException $e) {
153
-			return false;
154
-		}
155
-	}
156
-
157
-	/**
158
-	 * Check if the variables file has changed
159
-	 * @return bool
160
-	 */
161
-	private function variablesChanged() {
162
-		$injectedVariables = $this->getInjectedVariables();
163
-		if($this->config->getAppValue('core', 'scss.variables') !== md5($injectedVariables)) {
164
-			$this->resetCache();
165
-			$this->config->setAppValue('core', 'scss.variables', md5($injectedVariables));
166
-			return true;
167
-		}
168
-		return false;
169
-	}
170
-
171
-	/**
172
-	 * Cache the file with AppData
173
-	 * @param string $path
174
-	 * @param string $fileNameCSS
175
-	 * @param string $fileNameSCSS
176
-	 * @param ISimpleFolder $folder
177
-	 * @param string $webDir
178
-	 * @return boolean
179
-	 */
180
-	private function cache($path, $fileNameCSS, $fileNameSCSS, ISimpleFolder $folder, $webDir) {
181
-		$scss = new Compiler();
182
-		$scss->setImportPaths([
183
-			$path,
184
-			\OC::$SERVERROOT . '/core/css/',
185
-		]);
186
-		if($this->config->getSystemValue('debug')) {
187
-			// Debug mode
188
-			$scss->setFormatter(Expanded::class);
189
-			$scss->setLineNumberStyle(Compiler::LINE_COMMENTS);
190
-		} else {
191
-			// Compression
192
-			$scss->setFormatter(Crunched::class);
193
-		}
194
-
195
-		try {
196
-			$cachedfile = $folder->getFile($fileNameCSS);
197
-		} catch(NotFoundException $e) {
198
-			$cachedfile = $folder->newFile($fileNameCSS);
199
-		}
200
-
201
-		$depFileName = $fileNameCSS . '.deps';
202
-		try {
203
-			$depFile = $folder->getFile($depFileName);
204
-		} catch (NotFoundException $e) {
205
-			$depFile = $folder->newFile($depFileName);
206
-		}
207
-
208
-		// Compile
209
-		try {
210
-			$compiledScss = $scss->compile(
211
-				'@import "variables.scss";' .
212
-				$this->getInjectedVariables() .
213
-				'@import "'.$fileNameSCSS.'";');
214
-		} catch(ParserException $e) {
215
-			$this->logger->error($e, ['app' => 'core']);
216
-			return false;
217
-		}
218
-
219
-		// Gzip file
220
-		try {
221
-			$gzipFile = $folder->getFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
222
-		} catch (NotFoundException $e) {
223
-			$gzipFile = $folder->newFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
224
-		}
225
-
226
-		try {
227
-			$data = $this->rebaseUrls($compiledScss, $webDir);
228
-			$cachedfile->putContent($data);
229
-			$deps = json_encode($scss->getParsedFiles());
230
-			$depFile->putContent($deps);
231
-			$this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
232
-			$gzipFile->putContent(gzencode($data, 9));
233
-			$this->logger->debug($webDir.'/'.$fileNameSCSS.' compiled and successfully cached', ['app' => 'core']);
234
-			return true;
235
-		} catch(NotPermittedException $e) {
236
-			return false;
237
-		}
238
-	}
239
-
240
-	/**
241
-	 * Reset scss cache by deleting all generated css files
242
-	 * We need to regenerate all files when variables change
243
-	 */
244
-	private function resetCache() {
245
-		$appDirectory = $this->appData->getDirectoryListing();
246
-		if(empty($appDirectory)){
247
-			return;
248
-		}
249
-		foreach ($appDirectory as $folder) {
250
-			foreach ($folder->getDirectoryListing() as $file) {
251
-				if (substr($file->getName(), -3) === "css" || substr($file->getName(), -4) === "deps") {
252
-					$file->delete();
253
-				}
254
-			}
255
-		}
256
-	}
257
-
258
-	/**
259
-	 * @return string SCSS code for variables from OC_Defaults
260
-	 */
261
-	private function getInjectedVariables() {
262
-		$variables = '';
263
-		foreach ($this->defaults->getScssVariables() as $key => $value) {
264
-			$variables .= '$' . $key . ': ' . $value . ';';
265
-		}
266
-		return $variables;
267
-	}
268
-
269
-	/**
270
-	 * Add the correct uri prefix to make uri valid again
271
-	 * @param string $css
272
-	 * @param string $webDir
273
-	 * @return string
274
-	 */
275
-	private function rebaseUrls($css, $webDir) {
276
-		$re = '/url\([\'"]([\.\w?=\/-]*)[\'"]\)/x';
277
-		// OC\Route\Router:75
278
-		if(($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) {
279
-			$subst = 'url(\'../../'.$webDir.'/$1\')';	
280
-		} else {
281
-			$subst = 'url(\'../../../'.$webDir.'/$1\')';
282
-		}
283
-		return preg_replace($re, $subst, $css);
284
-	}
285
-
286
-	/**
287
-	 * Return the cached css file uri
288
-	 * @param string $appName the app name
289
-	 * @param string $fileName
290
-	 * @return string
291
-	 */
292
-	public function getCachedSCSS($appName, $fileName) {
293
-		$tmpfileLoc = explode('/', $fileName);
294
-		$fileName = array_pop($tmpfileLoc);
295
-		$fileName = str_replace('.scss', '.css', $fileName);
296
-
297
-		return substr($this->urlGenerator->linkToRoute('core.Css.getCss', array('fileName' => $fileName, 'appName' => $appName)), strlen(\OC::$WEBROOT) + 1);
298
-	}
41
+    /** @var ILogger */
42
+    protected $logger;
43
+
44
+    /** @var IAppData */
45
+    protected $appData;
46
+
47
+    /** @var IURLGenerator */
48
+    protected $urlGenerator;
49
+
50
+    /** @var IConfig */
51
+    protected $config;
52
+
53
+    /** @var string */
54
+    protected $serverRoot;
55
+
56
+    /** @var ICache */
57
+    protected $depsCache;
58
+
59
+    /**
60
+     * @param ILogger $logger
61
+     * @param Factory $appDataFactory
62
+     * @param IURLGenerator $urlGenerator
63
+     * @param IConfig $config
64
+     * @param \OC_Defaults $defaults
65
+     * @param string $serverRoot
66
+     * @param ICache $depsCache
67
+     */
68
+    public function __construct(ILogger $logger,
69
+                                Factory $appDataFactory,
70
+                                IURLGenerator $urlGenerator,
71
+                                IConfig $config,
72
+                                \OC_Defaults $defaults,
73
+                                $serverRoot,
74
+                                ICache $depsCache) {
75
+        $this->logger = $logger;
76
+        $this->appData = $appDataFactory->get('css');
77
+        $this->urlGenerator = $urlGenerator;
78
+        $this->config = $config;
79
+        $this->defaults = $defaults;
80
+        $this->serverRoot = $serverRoot;
81
+        $this->depsCache = $depsCache;
82
+    }
83
+
84
+    /**
85
+     * Process the caching process if needed
86
+     * @param string $root Root path to the nextcloud installation
87
+     * @param string $file
88
+     * @param string $app The app name
89
+     * @return boolean
90
+     */
91
+    public function process($root, $file, $app) {
92
+        $path = explode('/', $root . '/' . $file);
93
+
94
+        $fileNameSCSS = array_pop($path);
95
+        $fileNameCSS = str_replace('.scss', '.css', $fileNameSCSS);
96
+
97
+        $path = implode('/', $path);
98
+
99
+        $webDir = substr($path, strlen($this->serverRoot)+1);
100
+
101
+        try {
102
+            $folder = $this->appData->getFolder($app);
103
+        } catch(NotFoundException $e) {
104
+            // creating css appdata folder
105
+            $folder = $this->appData->newFolder($app);
106
+        }
107
+
108
+
109
+        if(!$this->variablesChanged() && $this->isCached($fileNameCSS, $folder)) {
110
+            return true;
111
+        }
112
+        return $this->cache($path, $fileNameCSS, $fileNameSCSS, $folder, $webDir);
113
+    }
114
+
115
+    /**
116
+     * @param $appName
117
+     * @param $fileName
118
+     * @return ISimpleFile
119
+     */
120
+    public function getCachedCSS($appName, $fileName) {
121
+        $folder = $this->appData->getFolder($appName);
122
+        return $folder->getFile($fileName);
123
+    }
124
+
125
+    /**
126
+     * Check if the file is cached or not
127
+     * @param string $fileNameCSS
128
+     * @param ISimpleFolder $folder
129
+     * @return boolean
130
+     */
131
+    private function isCached($fileNameCSS, ISimpleFolder $folder) {
132
+        try {
133
+            $cachedFile = $folder->getFile($fileNameCSS);
134
+            if ($cachedFile->getSize() > 0) {
135
+                $depFileName = $fileNameCSS . '.deps';
136
+                $deps = $this->depsCache->get($folder->getName() . '-' . $depFileName);
137
+                if ($deps === null) {
138
+                    $depFile = $folder->getFile($depFileName);
139
+                    $deps = $depFile->getContent();
140
+                    //Set to memcache for next run
141
+                    $this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
142
+                }
143
+                $deps = json_decode($deps, true);
144
+
145
+                foreach ($deps as $file=>$mtime) {
146
+                    if (!file_exists($file) || filemtime($file) > $mtime) {
147
+                        return false;
148
+                    }
149
+                }
150
+            }
151
+            return true;
152
+        } catch(NotFoundException $e) {
153
+            return false;
154
+        }
155
+    }
156
+
157
+    /**
158
+     * Check if the variables file has changed
159
+     * @return bool
160
+     */
161
+    private function variablesChanged() {
162
+        $injectedVariables = $this->getInjectedVariables();
163
+        if($this->config->getAppValue('core', 'scss.variables') !== md5($injectedVariables)) {
164
+            $this->resetCache();
165
+            $this->config->setAppValue('core', 'scss.variables', md5($injectedVariables));
166
+            return true;
167
+        }
168
+        return false;
169
+    }
170
+
171
+    /**
172
+     * Cache the file with AppData
173
+     * @param string $path
174
+     * @param string $fileNameCSS
175
+     * @param string $fileNameSCSS
176
+     * @param ISimpleFolder $folder
177
+     * @param string $webDir
178
+     * @return boolean
179
+     */
180
+    private function cache($path, $fileNameCSS, $fileNameSCSS, ISimpleFolder $folder, $webDir) {
181
+        $scss = new Compiler();
182
+        $scss->setImportPaths([
183
+            $path,
184
+            \OC::$SERVERROOT . '/core/css/',
185
+        ]);
186
+        if($this->config->getSystemValue('debug')) {
187
+            // Debug mode
188
+            $scss->setFormatter(Expanded::class);
189
+            $scss->setLineNumberStyle(Compiler::LINE_COMMENTS);
190
+        } else {
191
+            // Compression
192
+            $scss->setFormatter(Crunched::class);
193
+        }
194
+
195
+        try {
196
+            $cachedfile = $folder->getFile($fileNameCSS);
197
+        } catch(NotFoundException $e) {
198
+            $cachedfile = $folder->newFile($fileNameCSS);
199
+        }
200
+
201
+        $depFileName = $fileNameCSS . '.deps';
202
+        try {
203
+            $depFile = $folder->getFile($depFileName);
204
+        } catch (NotFoundException $e) {
205
+            $depFile = $folder->newFile($depFileName);
206
+        }
207
+
208
+        // Compile
209
+        try {
210
+            $compiledScss = $scss->compile(
211
+                '@import "variables.scss";' .
212
+                $this->getInjectedVariables() .
213
+                '@import "'.$fileNameSCSS.'";');
214
+        } catch(ParserException $e) {
215
+            $this->logger->error($e, ['app' => 'core']);
216
+            return false;
217
+        }
218
+
219
+        // Gzip file
220
+        try {
221
+            $gzipFile = $folder->getFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
222
+        } catch (NotFoundException $e) {
223
+            $gzipFile = $folder->newFile($fileNameCSS . '.gzip'); # Safari doesn't like .gz
224
+        }
225
+
226
+        try {
227
+            $data = $this->rebaseUrls($compiledScss, $webDir);
228
+            $cachedfile->putContent($data);
229
+            $deps = json_encode($scss->getParsedFiles());
230
+            $depFile->putContent($deps);
231
+            $this->depsCache->set($folder->getName() . '-' . $depFileName, $deps);
232
+            $gzipFile->putContent(gzencode($data, 9));
233
+            $this->logger->debug($webDir.'/'.$fileNameSCSS.' compiled and successfully cached', ['app' => 'core']);
234
+            return true;
235
+        } catch(NotPermittedException $e) {
236
+            return false;
237
+        }
238
+    }
239
+
240
+    /**
241
+     * Reset scss cache by deleting all generated css files
242
+     * We need to regenerate all files when variables change
243
+     */
244
+    private function resetCache() {
245
+        $appDirectory = $this->appData->getDirectoryListing();
246
+        if(empty($appDirectory)){
247
+            return;
248
+        }
249
+        foreach ($appDirectory as $folder) {
250
+            foreach ($folder->getDirectoryListing() as $file) {
251
+                if (substr($file->getName(), -3) === "css" || substr($file->getName(), -4) === "deps") {
252
+                    $file->delete();
253
+                }
254
+            }
255
+        }
256
+    }
257
+
258
+    /**
259
+     * @return string SCSS code for variables from OC_Defaults
260
+     */
261
+    private function getInjectedVariables() {
262
+        $variables = '';
263
+        foreach ($this->defaults->getScssVariables() as $key => $value) {
264
+            $variables .= '$' . $key . ': ' . $value . ';';
265
+        }
266
+        return $variables;
267
+    }
268
+
269
+    /**
270
+     * Add the correct uri prefix to make uri valid again
271
+     * @param string $css
272
+     * @param string $webDir
273
+     * @return string
274
+     */
275
+    private function rebaseUrls($css, $webDir) {
276
+        $re = '/url\([\'"]([\.\w?=\/-]*)[\'"]\)/x';
277
+        // OC\Route\Router:75
278
+        if(($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) {
279
+            $subst = 'url(\'../../'.$webDir.'/$1\')';	
280
+        } else {
281
+            $subst = 'url(\'../../../'.$webDir.'/$1\')';
282
+        }
283
+        return preg_replace($re, $subst, $css);
284
+    }
285
+
286
+    /**
287
+     * Return the cached css file uri
288
+     * @param string $appName the app name
289
+     * @param string $fileName
290
+     * @return string
291
+     */
292
+    public function getCachedSCSS($appName, $fileName) {
293
+        $tmpfileLoc = explode('/', $fileName);
294
+        $fileName = array_pop($tmpfileLoc);
295
+        $fileName = str_replace('.scss', '.css', $fileName);
296
+
297
+        return substr($this->urlGenerator->linkToRoute('core.Css.getCss', array('fileName' => $fileName, 'appName' => $appName)), strlen(\OC::$WEBROOT) + 1);
298
+    }
299 299
 }
Please login to merge, or discard this patch.