summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2016-11-08 13:36:35 +0100
committerRoeland Jago Douma <roeland@famdouma.nl>2017-01-06 09:42:13 +0100
commit31f75e50b67050c09368805ef911569bcaceeeeb (patch)
tree939a533a6974bc49a0e3060d162c197ddc0aa13a
parent460ef39b18222dab5452b3dd50a6753060ba3de1 (diff)
downloadnextcloud-server-31f75e50b67050c09368805ef911569bcaceeeeb.tar.gz
nextcloud-server-31f75e50b67050c09368805ef911569bcaceeeeb.zip
Cache and compile base
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
-rwxr-xr-x[-rw-r--r--]lib/private/Template/CSSResourceLocator.php2
-rwxr-xr-x[-rw-r--r--]lib/private/Template/ResourceLocator.php27
-rwxr-xr-xlib/private/Template/SCSSCacher.php110
3 files changed, 139 insertions, 0 deletions
diff --git a/lib/private/Template/CSSResourceLocator.php b/lib/private/Template/CSSResourceLocator.php
index ffeaf765ff5..353555a6811 100644..100755
--- a/lib/private/Template/CSSResourceLocator.php
+++ b/lib/private/Template/CSSResourceLocator.php
@@ -32,6 +32,8 @@ class CSSResourceLocator extends ResourceLocator {
public function doFind($style) {
if (strpos($style, '3rdparty') === 0
&& $this->appendIfExist($this->thirdpartyroot, $style.'.css')
+ || $this->cacheAndAppendScssIfExist($this->serverroot, $style.'.scss')
+ || $this->cacheAndAppendScssIfExist($this->serverroot, 'core/'.$style.'.scss')
|| $this->appendIfExist($this->serverroot, $style.'.css')
|| $this->appendIfExist($this->serverroot, 'core/'.$style.'.css')
) {
diff --git a/lib/private/Template/ResourceLocator.php b/lib/private/Template/ResourceLocator.php
index 420317d27ac..37360a98d91 100644..100755
--- a/lib/private/Template/ResourceLocator.php
+++ b/lib/private/Template/ResourceLocator.php
@@ -107,6 +107,33 @@ abstract class ResourceLocator {
}
/**
+ * cache and append the scss $file if exist at $root
+ *
+ * @param string $root path to check
+ * @param string $file the filename
+ * @param string|null $webRoot base for path, default map $root to $webRoot
+ * @return bool True if the resource was found and cached, false otherwise
+ */
+ protected function cacheAndAppendScssIfExist($root, $file, $webRoot = null) {
+ if (is_file($root.'/'.$file)) {
+ $scssCache = new \OC\Template\SCSSCacher(
+ $this->logger,
+ $root,
+ $file);
+
+ if($scssCache->process()) {
+ $this->append($root, $scssCache->getCachedSCSS(), $webRoot, false);
+ $this->logger->debug($root.'/'.$file.' compiled and successfully cached', ['app' => 'SCSSPHP']);
+ return true;
+ } else {
+ $this->logger->error('Failed to compile and/or save '.$root.'/'.$file, ['app' => 'SCSSPHP']);
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
* append the $file resource at $root
*
* @param string $root path to check
diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php
new file mode 100755
index 00000000000..c53257d1a0f
--- /dev/null
+++ b/lib/private/Template/SCSSCacher.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016, John Molakvoæ (skjnldsv@protonmail.com)
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Template;
+
+use Leafo\ScssPhp\Compiler;
+use Leafo\ScssPhp\Exception\ParserException;
+
+class SCSSCacher {
+
+ protected $root;
+ protected $file;
+ protected $fileName;
+ protected $fileLoc;
+ protected $fileCache;
+ protected $rootCssLoc;
+
+ /** Cache folder from serverroot */
+ private $scssCache = "assets";
+
+
+ /** @var \OCP\ILogger */
+ protected $logger;
+
+ /**
+ * @param \OCP\ILogger $logger
+ * @param string $root
+ * @param string $file
+ */
+ public function __construct(\OCP\ILogger $logger, $root, $file) {
+ $this->logger = $logger;
+ $this->root = $root;
+ $this->file = explode('/', $root.'/'.$file);
+
+ $this->fileName = array_pop($this->file);
+ $this->fileLoc = implode('/', $this->file);
+ $this->fileCache = str_replace('.scss', '.css', $this->scssCache.'/'.$this->fileName);
+
+ // base uri to css file
+ $this->rootCssLoc = explode('/', $file);
+ array_pop($this->rootCssLoc);
+ $this->rootCssLoc = implode('/', $this->rootCssLoc);
+ }
+
+ public function process() {
+
+ if($this->is_cached($this->root.'/'.$this->fileCache, $this->fileLoc.'/'.$this->fileName)) {
+ return true;
+ } else {
+ return $this->cache();
+ }
+ return false;
+ }
+
+ private function is_cached($in, $out) {
+ if (! is_file($out) || filemtime($in) > filemtime($out)) {
+ return true;
+ }
+ return false;
+ }
+
+ private function cache() {
+ $scss = new Compiler();
+ $scss->setImportPaths($this->fileLoc);
+
+ if(\OC::$server->getSystemConfig()->getValue('debug')) {
+ // Debug mode
+ $scss->setFormatter('Leafo\ScssPhp\Formatter\Expanded');
+ $scss->setLineNumberStyle(Compiler::LINE_COMMENTS);
+ } else {
+ $scss->setFormatter('Leafo\ScssPhp\Formatter\Crunched');
+ }
+
+ try {
+ $compiledScss = $scss->compile('@import "'.$this->fileName.'";');
+ } catch(ParserException $e) {
+ $this->logger->error($e, ['app' => 'SCSSPHP']);
+ return false;
+ }
+ return file_put_contents($this->fileCache, $this->rebaseUrls($compiledScss));
+ }
+
+ private function rebaseUrls($css) {
+ $re = '/url\([\'"](.*)[\'"]\)/x';
+ $subst = 'url(\'../'.$this->rootCssLoc.'/$1\')';
+ return preg_replace($re, $subst, $css);
+ }
+
+ public function getCachedSCSS() {
+ return $this->fileCache;
+ }
+}