diff --git a/module/VuFindConsole/src/VuFindConsole/Controller/UtilController.php b/module/VuFindConsole/src/VuFindConsole/Controller/UtilController.php index 93376f15d84fef8616cf7ecf8c7c0f6b3a940059..9362261dfd775261c4c409f5241416379b48bc75 100644 --- a/module/VuFindConsole/src/VuFindConsole/Controller/UtilController.php +++ b/module/VuFindConsole/src/VuFindConsole/Controller/UtilController.php @@ -456,6 +456,19 @@ class UtilController extends AbstractBase return $this->getSuccessResponse(); } + /** + * Compile CSS files from LESS. + * + * @return \Zend\Console\Response + */ + public function cssbuilderAction() + { + $argv = $this->consoleOpts->getRemainingArgs(); + $compiler = new \VuFindTheme\LessCompiler(); + $compiler->compile($argv); + return $this->getSuccessResponse(); + } + /** * Abstract delete method. * diff --git a/module/VuFindTheme/src/VuFindTheme/LessCompiler.php b/module/VuFindTheme/src/VuFindTheme/LessCompiler.php new file mode 100644 index 0000000000000000000000000000000000000000..fff9a18bc496a80d87f032ed260a033cd3a33541 --- /dev/null +++ b/module/VuFindTheme/src/VuFindTheme/LessCompiler.php @@ -0,0 +1,189 @@ +<?php +/** + * Class to compile LESS into CSS within a theme. + * + * PHP version 5 + * + * Copyright (C) Villanova University 2014. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @category VuFind2 + * @package Theme + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ +namespace VuFindTheme; +use \Zend\Console\Console; + +/** + * Class to compile LESS into CSS within a theme. + * + * @category VuFind2 + * @package Theme + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ +class LessCompiler +{ + /** + * Base path of VuFind. + * + * @var string + */ + protected $basePath; + + /** + * Fake base path used for generating absolute paths in CSS. + * + * @var string + */ + protected $fakePath = '/zzzz_basepath_zzzz/'; + + /** + * Constructor + */ + public function __construct() + { + $this->basePath = realpath(__DIR__ . '/../../../../'); + } + + /** + * Compile the scripts. + * + * @param array $themes Array of themes to process (empty for ALL themes). + * + * @return void + */ + public function compile(array $themes) + { + if (empty($themes)) { + $themes = $this->getAllThemes(); + } + + foreach ($themes as $theme) { + $this->processTheme($theme); + } + } + + /** + * Compile scripts for the specified theme. + * + * @param string $theme Theme name + * + * @return void + */ + protected function processTheme($theme) + { + $config = $this->basePath . '/themes/' . $theme . '/theme.config.php'; + if (!file_exists($config)) { + return; + } + $config = include($config); + if (!isset($config['less'])) { + Console::writeLine("No LESS in " . $theme); + return; + } + Console::writeLine("Processing " . $theme); + foreach ($config['less'] as $less) { + $this->compileFile($theme, $less); + } + } + + /** + * Compile a LESS file inside a theme. + * + * @param string $theme Theme containing file + * @param string $less Relative path to LESS file + * + * @return void + */ + protected function compileFile($theme, $less) + { + $finalOutDir = $this->basePath . '/themes/' . $theme . '/css/'; + list($fileName, ) = explode('.', $less); + $finalFile = $finalOutDir . $fileName . '.css'; + + Console::writeLine("\tcompiling '" . $less . "' into '" . $finalFile . "'"); + $start = microtime(true); + + $directories = array(); + $info = new ThemeInfo($this->basePath . '/themes', $theme); + foreach (array_keys($info->getThemeInfo()) as $curTheme) { + $directories["{$this->basePath}/themes/$curTheme/less/"] + = $this->fakePath . "themes/$curTheme/css/less"; + } + $lessDir = $this->basePath . '/themes/' . $theme . '/less/'; + $outDir = sys_get_temp_dir(); + $outFile = \Less_Cache::Regen( + array($lessDir . $less => $this->fakePath . "themes/$theme/css/less"), + array( + 'cache_dir' => $outDir, + 'cache_method' => false, + 'compress' => true, + 'import_dirs' => $directories + ) + ); + $css = file_get_contents($outDir . '/' . $outFile); + if (!is_dir(dirname($finalFile))) { + mkdir(dirname($finalFile)); + } + file_put_contents($finalFile, $this->makeRelative($css, $less)); + + Console::writeLine("\t\t" . (microtime(true)-$start) . ' sec'); + } + + /** + * Convert fake absolute paths to working relative paths. + * + * @param string $css Generated CSS + * @param string $less Relative LESS filename + * + * @return string + */ + protected function makeRelative($css, $less) + { + // Figure out how deep the LESS file is nested -- this will + // affect our relative path. + $depth = preg_match_all('|/|', $less, $matches); + $relPath = '../../../'; + for ($i = 0; $i < $depth; $i++) { + $relPath .= '/../'; + } + return str_replace($this->fakePath, $relPath, $css); + } + + /** + * Get a list of all available themes. + * + * @return array + */ + protected function getAllThemes() + { + $baseDir = $this->basePath . '/themes/'; + $dir = opendir($baseDir); + $list = array(); + while ($line = readdir($dir)) { + if (is_dir($baseDir . $line) + && file_exists($baseDir . $line . '/theme.config.php') + ) { + $list[] = $line; + } + } + closedir($dir); + return $list; + } +} \ No newline at end of file diff --git a/util/cssBuilder.php b/util/cssBuilder.php new file mode 100644 index 0000000000000000000000000000000000000000..a2cca7905e9246b20b6ba620654e50b93cb6327e --- /dev/null +++ b/util/cssBuilder.php @@ -0,0 +1,32 @@ +<?php +/** + * Compile CSS files from LESS. + * + * PHP version 5 + * + * Copyright (C) Villanova University 2014. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @category VuFind2 + * @package Utilities + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki Wiki + */ + +// Load the Zend framework -- this will automatically trigger the appropriate +// controller action based on directory and file names +define('CLI_DIR', __DIR__); // save directory name of current script +require_once __DIR__ . '/../public/index.php';