]> source.dussan.org Git - nextcloud-server.git/commitdiff
Cache and compile base
authorJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
Tue, 8 Nov 2016 12:36:35 +0000 (13:36 +0100)
committerRoeland Jago Douma <roeland@famdouma.nl>
Fri, 6 Jan 2017 08:42:13 +0000 (09:42 +0100)
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
lib/private/Template/CSSResourceLocator.php [changed mode: 0644->0755]
lib/private/Template/ResourceLocator.php [changed mode: 0644->0755]
lib/private/Template/SCSSCacher.php [new file with mode: 0755]

old mode 100644 (file)
new mode 100755 (executable)
index ffeaf76..353555a
@@ -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')
                ) {
old mode 100644 (file)
new mode 100755 (executable)
index 420317d..37360a9
@@ -106,6 +106,33 @@ abstract class ResourceLocator {
                return false;
        }
 
+       /**
+        * 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
         *
diff --git a/lib/private/Template/SCSSCacher.php b/lib/private/Template/SCSSCacher.php
new file mode 100755 (executable)
index 0000000..c53257d
--- /dev/null
@@ -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;
+       }
+}