Add theme to the stylesheet if set and ...
... revamp interface of LessCompiler and StyleSheet refs #10705
This commit is contained in:
parent
e7262b7d14
commit
1f467ecfaa
|
@ -15,7 +15,7 @@ if ($moduleName !== 'default') {
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<style>
|
<style>
|
||||||
<?= StyleSheet::compileForPdf() ?>
|
<?= StyleSheet::forPdf() ?>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -21,6 +21,7 @@ use Icinga\Web\Navigation\Navigation;
|
||||||
use Icinga\Web\Notification;
|
use Icinga\Web\Notification;
|
||||||
use Icinga\Web\Session;
|
use Icinga\Web\Session;
|
||||||
use Icinga\Web\Session\Session as BaseSession;
|
use Icinga\Web\Session\Session as BaseSession;
|
||||||
|
use Icinga\Web\StyleSheet;
|
||||||
use Icinga\Web\View;
|
use Icinga\Web\View;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,13 +35,6 @@ use Icinga\Web\View;
|
||||||
*/
|
*/
|
||||||
class Web extends EmbeddedWeb
|
class Web extends EmbeddedWeb
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* The name of the default theme
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
const DEFAULT_THEME = 'Icinga';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View object
|
* View object
|
||||||
*
|
*
|
||||||
|
@ -113,7 +107,7 @@ class Web extends EmbeddedWeb
|
||||||
*/
|
*/
|
||||||
public function getThemes()
|
public function getThemes()
|
||||||
{
|
{
|
||||||
$themes = array(static::DEFAULT_THEME);
|
$themes = array(StyleSheet::DEFAULT_THEME);
|
||||||
$applicationThemePath = $this->getBaseDir('public/css/themes');
|
$applicationThemePath = $this->getBaseDir('public/css/themes');
|
||||||
if (DirectoryIterator::isReadable($applicationThemePath)) {
|
if (DirectoryIterator::isReadable($applicationThemePath)) {
|
||||||
foreach (new DirectoryIterator($applicationThemePath, 'less') as $name => $theme) {
|
foreach (new DirectoryIterator($applicationThemePath, 'less') as $name => $theme) {
|
||||||
|
|
|
@ -61,7 +61,7 @@ if (in_array($path, $special)) {
|
||||||
Stylesheet::send();
|
Stylesheet::send();
|
||||||
exit;
|
exit;
|
||||||
case 'css/icinga.min.css':
|
case 'css/icinga.min.css':
|
||||||
Stylesheet::sendMinified();
|
Stylesheet::send(true);
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
case 'js/icinga.dev.js':
|
case 'js/icinga.dev.js':
|
||||||
|
|
|
@ -3,167 +3,167 @@
|
||||||
|
|
||||||
namespace Icinga\Web;
|
namespace Icinga\Web;
|
||||||
|
|
||||||
use Exception;
|
use Icinga\Application\Logger;
|
||||||
use RecursiveDirectoryIterator;
|
use RecursiveArrayIterator;
|
||||||
use RecursiveIteratorIterator;
|
use RecursiveIteratorIterator;
|
||||||
use RegexIterator;
|
|
||||||
use RecursiveRegexIterator;
|
|
||||||
use Icinga\Application\Icinga;
|
|
||||||
use lessc;
|
use lessc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Less compiler prints files or directories to stdout
|
* Compile LESS into CSS
|
||||||
|
*
|
||||||
|
* Comments will be removed always. lessc is messing them up.
|
||||||
*/
|
*/
|
||||||
class LessCompiler
|
class LessCompiler
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Collection of items: File or directories
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $items = array();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lessphp compiler
|
* lessphp compiler
|
||||||
*
|
*
|
||||||
* @var \lessc
|
* @var lessc
|
||||||
*/
|
*/
|
||||||
private $lessc;
|
protected $lessc;
|
||||||
|
|
||||||
private $source;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance
|
* Array of LESS files
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $lessFiles = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of module LESS files indexed by module names
|
||||||
|
*
|
||||||
|
* @var array[]
|
||||||
|
*/
|
||||||
|
protected $moduleLessFiles = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LESS source
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $source;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path of the LESS theme
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $theme;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new LESS compiler
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
require_once 'lessphp/lessc.inc.php';
|
require_once 'lessphp/lessc.inc.php';
|
||||||
$this->lessc = new lessc();
|
$this->lessc = new lessc();
|
||||||
|
// Discourage usage of import because we're caching based on an explicit list of LESS files to compile
|
||||||
|
$this->lessc->importDisabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable the extendend import functionality
|
* Add a Web 2 LESS file
|
||||||
|
*
|
||||||
|
* @param string $lessFile Path to the LESS file
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function disableExtendedImport()
|
public function addLessFile($lessFile)
|
||||||
{
|
{
|
||||||
$this->lessc->importDisabled = true;
|
$this->lessFiles[] = $lessFile;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a module LESS file
|
||||||
|
*
|
||||||
|
* @param string $moduleName Name of the module
|
||||||
|
* @param string $lessFile Path to the LESS file
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addModuleLessFile($moduleName, $lessFile)
|
||||||
|
{
|
||||||
|
if (! isset($this->moduleLessFiles[$moduleName])) {
|
||||||
|
$this->moduleLessFiles[$moduleName] = array();
|
||||||
|
}
|
||||||
|
$this->moduleLessFiles[$moduleName][] = $lessFile;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of LESS files added to the compiler
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getLessFiles()
|
||||||
|
{
|
||||||
|
$lessFiles = iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator(
|
||||||
|
$this->lessFiles + $this->moduleLessFiles
|
||||||
|
)));
|
||||||
|
if ($this->theme !== null) {
|
||||||
|
$lessFiles[] = $this->theme;
|
||||||
|
}
|
||||||
|
return $lessFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the path to the LESS theme
|
||||||
|
*
|
||||||
|
* @param string $theme Path to the LESS theme
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setTheme($theme)
|
||||||
|
{
|
||||||
|
Logger::debug($theme);
|
||||||
|
$this->theme = $theme;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instruct the compiler to minify CSS
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
public function compress()
|
public function compress()
|
||||||
{
|
{
|
||||||
$this->lessc->setPreserveComments(false);
|
|
||||||
$this->lessc->setFormatter('compressed');
|
$this->lessc->setFormatter('compressed');
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add usable style item to stack
|
* Render to CSS
|
||||||
*
|
*
|
||||||
* @param string $item File or directory
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function addItem($item)
|
public function render()
|
||||||
{
|
{
|
||||||
$this->items[] = $item;
|
foreach ($this->lessFiles as $lessFile) {
|
||||||
}
|
$this->source .= file_get_contents($lessFile);
|
||||||
|
|
||||||
public function addLoadedModules()
|
|
||||||
{
|
|
||||||
foreach (Icinga::app()->getModuleManager()->getLoadedModules() as $name => $module) {
|
|
||||||
$this->addModule($name, $module);
|
|
||||||
}
|
}
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addFile($filename)
|
$moduleCss = '';
|
||||||
{
|
foreach ($this->moduleLessFiles as $moduleName => $moduleLessFiles) {
|
||||||
$this->source .= "\n/* CSS: $filename */\n"
|
$moduleCss .= '.icinga-module.module-' . $moduleName . ' {';
|
||||||
. file_get_contents($filename)
|
foreach ($moduleLessFiles as $moduleLessFile) {
|
||||||
. "\n\n";
|
$moduleCss .= file_get_contents($moduleLessFile);
|
||||||
return $this;
|
}
|
||||||
}
|
$moduleCss .= '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
$moduleCss = preg_replace(
|
||||||
|
'/(\.icinga-module\.module-[^\s]+) (#layout\.[^\s]+)/m',
|
||||||
|
'\2 \1',
|
||||||
|
$moduleCss
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->source .= $moduleCss;
|
||||||
|
|
||||||
|
if ($this->theme !== null) {
|
||||||
|
$this->source .= file_get_contents($this->theme);
|
||||||
|
}
|
||||||
|
|
||||||
public function compile()
|
|
||||||
{
|
|
||||||
return $this->lessc->compile($this->source);
|
return $this->lessc->compile($this->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addModule($name, $module)
|
|
||||||
{
|
|
||||||
if ($module->hasCss()) {
|
|
||||||
$contents = array();
|
|
||||||
foreach ($module->getCssFiles() as $path) {
|
|
||||||
if (file_exists($path)) {
|
|
||||||
$contents[] = "/* CSS: modules/$name/$path */\n" . file_get_contents($path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->source .= ''
|
|
||||||
. '.icinga-module.module-'
|
|
||||||
. $name
|
|
||||||
. " {\n"
|
|
||||||
. join("\n\n", $contents)
|
|
||||||
. "}\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compile and print a single file
|
|
||||||
*
|
|
||||||
* @param string $file
|
|
||||||
*/
|
|
||||||
public function printFile($file)
|
|
||||||
{
|
|
||||||
$ext = pathinfo($file, PATHINFO_EXTENSION);
|
|
||||||
echo PHP_EOL. '/* CSS: ' . $file . ' */' . PHP_EOL;
|
|
||||||
|
|
||||||
if ($ext === 'css') {
|
|
||||||
readfile($file);
|
|
||||||
} elseif ($ext === 'less') {
|
|
||||||
try {
|
|
||||||
echo $this->lessc->compileFile($file);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
echo '/* ' . PHP_EOL . ' ===' . PHP_EOL;
|
|
||||||
echo ' Error in file ' . $file . PHP_EOL;
|
|
||||||
echo ' ' . $e->getMessage() . PHP_EOL . PHP_EOL;
|
|
||||||
echo ' ' . 'This file was dropped cause of errors.' . PHP_EOL;
|
|
||||||
echo ' ===' . PHP_EOL . '*/' . PHP_EOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo PHP_EOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compile and print a path content (recursive)
|
|
||||||
*
|
|
||||||
* @param string $path
|
|
||||||
*/
|
|
||||||
public function printPathRecursive($path)
|
|
||||||
{
|
|
||||||
$directoryInterator = new RecursiveDirectoryIterator($path);
|
|
||||||
$iterator = new RecursiveIteratorIterator($directoryInterator);
|
|
||||||
$filteredIterator = new RegexIterator($iterator, '/\.(css|less)$/', RecursiveRegexIterator::GET_MATCH);
|
|
||||||
foreach ($filteredIterator as $file => $extension) {
|
|
||||||
$this->printFile($file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compile and print the whole item stack
|
|
||||||
*/
|
|
||||||
public function printStack()
|
|
||||||
{
|
|
||||||
foreach ($this->items as $item) {
|
|
||||||
if (is_dir($item)) {
|
|
||||||
$this->printPathRecursive($item);
|
|
||||||
} elseif (is_file($item)) {
|
|
||||||
$this->printFile($item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,28 @@
|
||||||
|
|
||||||
namespace Icinga\Web;
|
namespace Icinga\Web;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
use Icinga\Web\FileCache;
|
use Icinga\Application\Logger;
|
||||||
use Icinga\Web\LessCompiler;
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send CSS for Web 2 and all loaded modules to the client
|
||||||
|
*/
|
||||||
class StyleSheet
|
class StyleSheet
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The name of the default theme
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const DEFAULT_THEME = 'Icinga';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of core LESS files Web 2 sends to the client
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
protected static $lessFiles = array(
|
protected static $lessFiles = array(
|
||||||
'../application/fonts/fontello-ifont/css/ifont-embedded.css',
|
'../application/fonts/fontello-ifont/css/ifont-embedded.css',
|
||||||
'css/vendor/normalize.css',
|
'css/vendor/normalize.css',
|
||||||
|
@ -40,89 +56,176 @@ class StyleSheet
|
||||||
'css/icinga/compat.less'
|
'css/icinga/compat.less'
|
||||||
);
|
);
|
||||||
|
|
||||||
public static function compileForPdf()
|
/**
|
||||||
{
|
* Application instance
|
||||||
self::checkPhp();
|
*
|
||||||
$less = new LessCompiler();
|
* @var \Icinga\Application\EmbeddedWeb
|
||||||
$basedir = Icinga::app()->getBootstrapDirectory();
|
*/
|
||||||
foreach (self::$lessFiles as $file) {
|
protected $app;
|
||||||
$less->addFile($basedir . '/' . $file);
|
|
||||||
}
|
|
||||||
$less->addLoadedModules();
|
|
||||||
$less->addFile($basedir . '/css/pdf/pdfprint.less');
|
|
||||||
return $less->compile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendMinified()
|
/**
|
||||||
{
|
* Less compiler
|
||||||
self::send(true);
|
*
|
||||||
}
|
* @var LessCompiler
|
||||||
|
*/
|
||||||
|
protected $lessCompiler;
|
||||||
|
|
||||||
protected static function fixModuleLayoutCss($css)
|
/**
|
||||||
{
|
* Path to the public directory
|
||||||
return preg_replace(
|
*
|
||||||
'/(\.icinga-module\.module-[^\s]+) (#layout\.[^\s]+)/m',
|
* @var string
|
||||||
'\2 \1',
|
*/
|
||||||
$css
|
protected $pubPath;
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function checkPhp()
|
/**
|
||||||
|
* Create the StyleSheet
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
{
|
{
|
||||||
// PHP had a rather conservative PCRE backtrack limit unless 5.3.7
|
// PHP had a rather conservative PCRE backtrack limit unless 5.3.7
|
||||||
if (version_compare(PHP_VERSION, '5.3.7') <= 0) {
|
if (version_compare(PHP_VERSION, '5.3.7') <= 0) {
|
||||||
ini_set('pcre.backtrack_limit', 1000000);
|
ini_set('pcre.backtrack_limit', 1000000);
|
||||||
}
|
}
|
||||||
|
$app = Icinga::app();
|
||||||
|
$this->app = $app;
|
||||||
|
$this->lessCompiler = new LessCompiler();
|
||||||
|
$this->pubPath = $app->getBootstrapDirectory();
|
||||||
|
$this->collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function send($minified = false)
|
/**
|
||||||
|
* Collect Web 2 and module LESS files and add them to the LESS compiler
|
||||||
|
*/
|
||||||
|
protected function collect()
|
||||||
{
|
{
|
||||||
self::checkPhp();
|
foreach (self::$lessFiles as $lessFile) {
|
||||||
$app = Icinga::app();
|
$this->lessCompiler->addLessFile($this->pubPath . '/' . $lessFile);
|
||||||
$basedir = $app->getBootstrapDirectory();
|
|
||||||
foreach (self::$lessFiles as $file) {
|
|
||||||
$lessFiles[] = $basedir . '/' . $file;
|
|
||||||
}
|
}
|
||||||
$files = $lessFiles;
|
|
||||||
foreach ($app->getModuleManager()->getLoadedModules() as $name => $module) {
|
$mm = $this->app->getModuleManager();
|
||||||
|
|
||||||
|
foreach ($mm->getLoadedModules() as $moduleName => $module) {
|
||||||
if ($module->hasCss()) {
|
if ($module->hasCss()) {
|
||||||
foreach ($module->getCssFiles() as $path) {
|
foreach ($module->getCssFiles() as $lessFilePath) {
|
||||||
if (file_exists($path)) {
|
$this->lessCompiler->addModuleLessFile($moduleName, $lessFilePath);
|
||||||
$files[] = $path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($etag = FileCache::etagMatchesFiles($files)) {
|
$themingConfig = $this->app->getConfig()->getSection('theming');
|
||||||
header("HTTP/1.1 304 Not Modified");
|
$defaultTheme = $themingConfig->get('default', self::DEFAULT_THEME);
|
||||||
return;
|
$theme = null;
|
||||||
|
|
||||||
|
if ((bool) $themingConfig->get('disabled', false)) {
|
||||||
|
if ($defaultTheme !== self::DEFAULT_THEME) {
|
||||||
|
$theme = $defaultTheme;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$etag = FileCache::etagForFiles($files);
|
if (($userTheme = $this->app->getRequest()->getCookie('theme', $defaultTheme))
|
||||||
|
&& $userTheme !== $defaultTheme
|
||||||
|
) {
|
||||||
|
$theme = $userTheme;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
header('Cache-Control: public');
|
|
||||||
header('ETag: "' . $etag . '"');
|
|
||||||
header('Content-Type: text/css');
|
|
||||||
|
|
||||||
$min = $minified ? '.min' : '';
|
if ($theme) {
|
||||||
$cacheFile = 'icinga-' . $etag . $min . '.css';
|
if (($pos = strpos($theme, '/')) !== false) {
|
||||||
$cache = FileCache::instance();
|
$moduleName = substr($theme, 0, $pos);
|
||||||
if ($cache->has($cacheFile)) {
|
$theme = substr($theme, $pos + 1);
|
||||||
$cache->send($cacheFile);
|
if ($mm->hasLoaded($moduleName)) {
|
||||||
|
$module = $mm->getModule($moduleName);
|
||||||
|
$this->lessCompiler->setTheme($module->getCssDir() . '/themes/' . $theme . '.less');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->lessCompiler->setTheme($this->pubPath . '/css/themes/' . $theme . '.less');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the stylesheet for PDF export
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public static function forPdf()
|
||||||
|
{
|
||||||
|
$styleSheet = new self();
|
||||||
|
$styleSheet->lessCompiler->addLessFile($styleSheet->pubPath . '/css/pdf/pdfprint.less');
|
||||||
|
// TODO(el): Caching
|
||||||
|
return $styleSheet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the stylesheet
|
||||||
|
*
|
||||||
|
* @param bool $minified Whether to compress the stylesheet
|
||||||
|
*
|
||||||
|
* @return string CSS
|
||||||
|
*/
|
||||||
|
public function render($minified = false)
|
||||||
|
{
|
||||||
|
if ($minified) {
|
||||||
|
$this->lessCompiler->compress();
|
||||||
|
}
|
||||||
|
return $this->lessCompiler->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the stylesheet to the client
|
||||||
|
*
|
||||||
|
* Does not cache the stylesheet if the HTTP header Cache-Control or Pragma is set to no-cache.
|
||||||
|
*
|
||||||
|
* @param bool $minified Whether to compress the stylesheet
|
||||||
|
*/
|
||||||
|
public static function send($minified = false)
|
||||||
|
{
|
||||||
|
$styleSheet = new self();
|
||||||
|
|
||||||
|
$request = $styleSheet->app->getRequest();
|
||||||
|
$response = $styleSheet->app->getResponse();
|
||||||
|
|
||||||
|
$noCache = $request->getHeader('Cache-Control') === 'no-cache' || $request->getHeader('Pragma') === 'no-cache';
|
||||||
|
|
||||||
|
if (! $noCache && FileCache::etagMatchesFiles($styleSheet->lessCompiler->getLessFiles())) {
|
||||||
|
$response
|
||||||
|
->setHttpResponseCode(304)
|
||||||
|
->sendHeaders();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$less = new LessCompiler();
|
$etag = FileCache::etagForFiles($styleSheet->lessCompiler->getLessFiles());
|
||||||
$less->disableExtendedImport();
|
|
||||||
foreach ($lessFiles as $file) {
|
$response
|
||||||
$less->addFile($file);
|
->setHeader('Cache-Control', 'public', true)
|
||||||
|
->setHeader('ETag', $etag, true)
|
||||||
|
->setHeader('Content-Type', 'text/css', true);
|
||||||
|
|
||||||
|
$cacheFile = 'icinga-' . $etag . ($minified ? '.min' : '') . '.css';
|
||||||
|
$cache = FileCache::instance();
|
||||||
|
|
||||||
|
if (! $noCache && $cache->has($cacheFile)) {
|
||||||
|
$response->setBody($cache->get($cacheFile));
|
||||||
|
} else {
|
||||||
|
$css = $styleSheet->render($minified);
|
||||||
|
$response->setBody($css);
|
||||||
|
$cache->store($cacheFile, $css);
|
||||||
}
|
}
|
||||||
$less->addLoadedModules();
|
|
||||||
if ($minified) {
|
$response->sendResponse();
|
||||||
$less->compress();
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the stylesheet
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return $this->render();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Logger::error($e);
|
||||||
|
return IcingaException::describe($e);
|
||||||
}
|
}
|
||||||
$out = self::fixModuleLayoutCss($less->compile());
|
|
||||||
$cache->store($cacheFile, $out);
|
|
||||||
echo $out;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue