mirror of
https://github.com/Icinga/icingaweb2.git
synced 2026-06-11 09:31:31 -04:00
This reverts commit 7c58b3ced1.
Remove variable exports as they were never used in our modules or community
modules, and using this feature is discouraged.
235 lines
5.5 KiB
PHP
235 lines
5.5 KiB
PHP
<?php
|
|
|
|
// SPDX-FileCopyrightText: 2018 Icinga GmbH <https://icinga.com>
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
namespace Icinga\Web;
|
|
|
|
use Icinga\Application\Logger;
|
|
use Icinga\Less\Visitor;
|
|
use Less_Exception_Parser;
|
|
use Less_Parser;
|
|
use Less_Tree;
|
|
|
|
/**
|
|
* Compile LESS into CSS
|
|
*
|
|
* Comments will be removed always. lessc is messing them up.
|
|
*/
|
|
class LessCompiler
|
|
{
|
|
/**
|
|
* lessphp compiler
|
|
*
|
|
* @var Less_Parser
|
|
*/
|
|
protected $lessc;
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* Path of the LESS theme mode
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $themeMode;
|
|
|
|
/**
|
|
* Create a new LESS compiler
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->lessc = new Less_Parser(['plugins' => [new Visitor()]]);
|
|
}
|
|
|
|
/**
|
|
* Add a Web 2 LESS file
|
|
*
|
|
* @param string $lessFile Path to the LESS file
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function addLessFile($lessFile)
|
|
{
|
|
$this->lessFiles[] = realpath($lessFile);
|
|
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][] = realpath($lessFile);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get the list of LESS files added to the compiler
|
|
*
|
|
* @return string[]
|
|
*/
|
|
public function getLessFiles()
|
|
{
|
|
$lessFiles = $this->lessFiles;
|
|
|
|
foreach ($this->moduleLessFiles as $moduleLessFiles) {
|
|
$lessFiles = array_merge($lessFiles, $moduleLessFiles);
|
|
}
|
|
|
|
if ($this->theme !== null) {
|
|
$lessFiles[] = $this->theme;
|
|
}
|
|
|
|
if ($this->themeMode !== null) {
|
|
$lessFiles[] = $this->themeMode;
|
|
}
|
|
|
|
return $lessFiles;
|
|
}
|
|
|
|
/**
|
|
* Set the path to the LESS theme
|
|
*
|
|
* @param ?string $theme Path to the LESS theme
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function setTheme($theme)
|
|
{
|
|
if ($theme === null || (is_file($theme) && is_readable($theme))) {
|
|
$this->theme = $theme;
|
|
} else {
|
|
Logger::error('Can\t load theme %s. Make sure that the theme exists and is readable', $theme);
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set the path to the LESS theme mode
|
|
*
|
|
* @param string $themeMode Path to the LESS theme mode
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function setThemeMode($themeMode)
|
|
{
|
|
if (is_file($themeMode) && is_readable($themeMode)) {
|
|
$this->themeMode = $themeMode;
|
|
} else {
|
|
Logger::error('Can\t load theme mode %s. Make sure that the theme mode exists and is readable', $themeMode);
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Instruct the compiler to minify CSS
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function compress()
|
|
{
|
|
$this->lessc->setOption('compress', true);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Render to CSS
|
|
*
|
|
* @return string
|
|
*/
|
|
public function render()
|
|
{
|
|
foreach ($this->lessFiles as $lessFile) {
|
|
$this->source .= file_get_contents($lessFile);
|
|
}
|
|
|
|
$moduleCss = '';
|
|
foreach ($this->moduleLessFiles as $moduleName => $moduleLessFiles) {
|
|
$moduleCss .= '.icinga-module.module-' . $moduleName . ' {';
|
|
|
|
foreach ($moduleLessFiles as $moduleLessFile) {
|
|
$moduleCss .= file_get_contents($moduleLessFile);
|
|
}
|
|
$moduleCss .= '}';
|
|
}
|
|
|
|
$this->source .= $moduleCss;
|
|
|
|
if ($this->theme !== null) {
|
|
$this->source .= file_get_contents($this->theme);
|
|
}
|
|
|
|
if ($this->themeMode !== null) {
|
|
$this->source .= file_get_contents($this->themeMode);
|
|
}
|
|
|
|
try {
|
|
return preg_replace(
|
|
'/(\.icinga-module\.module-[^\s]+) (#layout\.[^\s]+)/m',
|
|
'\2 \1',
|
|
$this->lessc->parse($this->source)->getCss()
|
|
);
|
|
} catch (Less_Exception_Parser $e) {
|
|
$excerpt = substr($this->source, $e->index - 500, 1000);
|
|
|
|
$lines = [];
|
|
$found = false;
|
|
$pos = $e->index - 500;
|
|
foreach (explode("\n", $excerpt) as $i => $line) {
|
|
if ($i === 0) {
|
|
$pos += strlen($line);
|
|
$lines[] = '.. ' . $line;
|
|
} else {
|
|
$pos += strlen($line) + 1;
|
|
$sep = ' ';
|
|
if (! $found && $pos > $e->index) {
|
|
$found = true;
|
|
$sep = '!! ';
|
|
}
|
|
|
|
$lines[] = $sep . $line;
|
|
}
|
|
}
|
|
|
|
$lines[] = '..';
|
|
$excerpt = join("\n", $lines);
|
|
|
|
return sprintf("%s\n%s\n\n\n%s", $e->getMessage(), $e->getTraceAsString(), $excerpt);
|
|
}
|
|
}
|
|
}
|