/** * Get LESS compiler (if undefined, set it with path for @import directives) * * @param boolean $reset */ protected function getEnvironment($reset = false) { if ($reset === true || null === $this->lessc) { $this->lessc = new \lessc(); $this->lessc->addImportDir($this->getConfigFor('phr_template_dir')); } return $this->lessc; }
/** * {@inheritdoc} */ public function setImportPath($fullPath, $relPath = null) { $this->_initCompiler(); if (!FS::isDir($fullPath)) { throw new Exception('Undefined import path: ' . $fullPath); } $fullPath = FS::getRelative($fullPath, $this->_options->get('root_path')); $this->_compiler->addImportDir($fullPath); }
/** * Parse all the less files resolving the dependencies. * * @param array $variables * @throws Ai1ec_File_Not_Found_Exception|Exception * @throws Exception * @return string */ public function parse_less_files(array $variables = null) { // If no variables are passed, initialize from DB, config file, and // extension injections in one call. if (empty($variables)) { $variables = $this->get_saved_variables(false); } // convert the variables to key / value $variables = $this->convert_less_variables_for_parsing($variables); // Inject additional constants from extensions. $variables = apply_filters('ai1ec_less_constants', $variables); // Load the static variables defined in the theme's variables.less file. $this->load_static_theme_variables(); $loader = $this->_registry->get('theme.loader'); // Allow extensions to add their own LESS files. $this->files = apply_filters('ai1ec_less_files', $this->files); $this->files[] = 'override.less'; // Find out the active theme URL. $option = $this->_registry->get('model.option'); $theme = $option->get('ai1ec_current_theme'); $this->lessc->addImportDir($theme['theme_dir'] . DIRECTORY_SEPARATOR . 'less'); $import_dirs = array(); foreach ($this->files as $file) { $file_to_parse = null; try { // Get the filename following our fallback convention $file_to_parse = $loader->get_file($file); } catch (Ai1ec_Exception $e) { // We let child themes override styles of Vortex. // So there is no fallback for override and we can continue. if ($file !== 'override.less') { throw $e; } else { // It's an override, skip it. continue; } } // We prepend the unparsed variables.less file we got earlier. // We do this as we do not import that anymore in the less files. $this->unparsed_variable_file .= $file_to_parse->get_content(); // Set the import directories for the file. Includes current directory of // file as well as theme directory in core. This is important for // dependencies to be resolved correctly. $dir = dirname($file_to_parse->get_name()); if (!isset($import_dirs[$dir])) { $import_dirs[$dir] = true; $this->lessc->addImportDir($dir); } } $variables['fontdir'] = '~"' . $theme['theme_url'] . '/font"'; $variables['fontdir_default'] = '~"' . $this->default_theme_url . 'font"'; $variables['imgdir'] = '~"' . $theme['theme_url'] . '/img"'; $variables['imgdir_default'] = '~"' . $this->default_theme_url . 'img"'; try { $this->parsed_css = $this->lessc->parse($this->unparsed_variable_file, $variables); } catch (Exception $e) { throw $e; } return $this->parsed_css; }
/** * @param \AssetsBundle\AssetFile\AssetFile $oAssetFile * @return string */ public function filterAssetFile(\AssetsBundle\AssetFile\AssetFile $oAssetFile) { $oLessParser = new \lessc(); $oLessParser->addImportDir(getcwd()); $oLessParser->setAllowUrlRewrite(true); //Prevent time limit errors set_time_limit(0); return trim($oLessParser->compile($oAssetFile->getAssetFileContents())); }
public function filterLoad(AssetInterface $asset) { $root = $asset->getSourceRoot(); $path = $asset->getSourcePath(); $lc = new \lessc(); if ($root && $path) { $lc->importDir = dirname($root . '/' . $path); } foreach ($this->loadPaths as $loadPath) { $lc->addImportDir($loadPath); } $asset->setContent($lc->parse($asset->getContent(), $this->presets)); }
/** * Filters an asset just before it's dumped. * * @param AssetInterface $asset */ public function filterDump(AssetInterface $asset) { $compiler = new \lessc(); $this->dispatch(new LoadThemeVariables($variables = new Collection())); $compiler->setVariables($variables->all()); if ($dir = $asset->getSourceDirectory()) { $compiler->importDir = $dir; } foreach ($this->loadPaths as $loadPath) { $compiler->addImportDir($loadPath); } $asset->setContent($compiler->parse($this->parser->parse($asset->getContent()))); }
/** * @return lessc */ protected function _initProcessor() { // lazy load if (!class_exists('lessc')) { require_once dirname(__FILE__) . '/class.less.leafo.php'; } $less = new lessc(); if ($this->_isDebug()) { $formatter = new lessc_formatter_lessjs(); // configurate css view $formatter->openSingle = " { "; $formatter->closeSingle = "}\n"; $formatter->close = "}\n"; $formatter->indentChar = " "; $formatter->disableSingle = true; $formatter->breakSelectors = true; $formatter->assignSeparator = ": "; $formatter->selectorSeparator = ", "; } else { // compress mode $formatter = new lessc_formatter_compressed(); $formatter->closeSingle = "}\n"; $formatter->close = "}\n"; } // set formatter $less->setFormatter($formatter); $less->setPreserveComments(false); // add paths for imports $less->addImportDir($this->_tpl->lessFull); $less->addImportDir(JPATH_ROOT); // from php $less->setVariables(array('css' => str_replace($this->_tpl->baseurl, '', $this->_tpl->css), 'less' => str_replace($this->_tpl->baseurl, '', $this->_tpl->less), 'images' => str_replace($this->_tpl->baseurl, '', $this->_tpl->img), 'debug' => (int) $this->_isDebug())); // add custom functions $less->registerFunction('data-uri', array($this, 'lib_dataUri')); return $less; }
public function filterLoad(AssetInterface $asset) { $lc = new \lessc(); if ($dir = $asset->getSourceDirectory()) { $lc->importDir = $dir; } foreach ($this->loadPaths as $loadPath) { $lc->addImportDir($loadPath); } if ($this->formatter) { $lc->setFormatter($this->formatter); } if (null !== $this->preserveComments) { $lc->setPreserveComments($this->preserveComments); } $asset->setContent($lc->parse($asset->getContent(), $this->presets)); }
public function filterLoad(AssetInterface $asset) { $lc = new \lessc(); if ($dir = $asset->getSourceDirectory()) { $lc->importDir = $dir; } foreach ($this->loadPaths as $loadPath) { $lc->addImportDir($loadPath); } foreach ($this->customFunctions as $name => $callable) { $lc->registerFunction($name, $callable); } if ($this->formatter) { $lc->setFormatter($this->formatter); } if (null !== $this->preserveComments) { $lc->setPreserveComments($this->preserveComments); } if (method_exists($lc, 'setOptions') && count($this->options) > 0) { $lc->setOptions($this->options); } $asset->setContent($lc->parse($asset->getContent(), $this->presets)); }
/** * Compile less to css. Creates a cache-file of the last compiled less-file. * * This code is originally from the manual of lessphp. * * @param string $inputFile the filename of the less-file. * @param string $outputFile the filename of the css-file to be created. * @param array $config with configuration details. * * @return void */ function autoCompileLess($inputFile, $outputFile, $config) { $cacheFile = $inputFile . ".cache"; if (file_exists($cacheFile)) { $cache = unserialize(file_get_contents($cacheFile)); } else { $cache = $inputFile; } $less = new lessc(); // Add custom less functions if (isset($config['functions'])) { foreach ($config['functions'] as $key => $val) { $less->registerFunction($key, $val); } } // Add import dirs if (isset($config['imports'])) { foreach ($config['imports'] as $val) { $less->addImportDir($val); } } // Set output formatter if (isset($config['formatter'])) { $less->setFormatter($config['formatter']); } // Preserve comments if (isset($config['comments'])) { $less->setPreserveComments($config['comments']); } // Compile a new cache $newCache = $less->cachedCompile($cache); if (!is_array($cache) || $newCache["updated"] > $cache["updated"]) { file_put_contents($cacheFile, serialize($newCache)); file_put_contents($outputFile, $newCache['compiled']); } }
public function filterLoad(AssetInterface $asset) { $root = $asset->getSourceRoot(); $path = $asset->getSourcePath(); $lc = new \lessc(); if (basename(getcwd()) === 'public') { $lc->setVariable('__assetpath__', '"../"'); } else { $lc->setVariable('__assetpath__', '""'); } if ($root && $path) { $lc->importDir = dirname($root . '/' . $path); } foreach ($this->loadPaths as $loadPath) { $lc->addImportDir($loadPath); } if ($this->formatter) { $lc->setFormatter($this->formatter); } if (null !== $this->preserveComments) { $lc->setPreserveComments($this->preserveComments); } $asset->setContent($lc->parse($asset->getContent(), $this->presets)); }
/** * Lessify the stylesheet and return the href of the compiled file * * @param string $src Source URL of the file to be parsed * @param string $handle An identifier for the file used to create the file name in the cache * @return string URL of the compiled stylesheet */ public function parse_stylesheet($src, $handle) { // we only want to handle .less files if (!preg_match('/\\.less(\\.php)?$/', preg_replace('/\\?.*$/', '', $src))) { return $src; } // get file path from $src if (!strstr($src, '?')) { $src .= '?'; } // prevent non-existent index warning when using list() & explode() // Match the URL schemes between WP_CONTENT_URL and $src, // so the str_replace further down will work $src_scheme = parse_url($src, PHP_URL_SCHEME); $wp_content_url_scheme = parse_url(WP_CONTENT_URL, PHP_URL_SCHEME); if ($src_scheme != $wp_content_url_scheme) { $src = set_url_scheme($src, $wp_content_url_scheme); } list($less_path, $query_string) = explode('?', str_replace(WP_CONTENT_URL, WP_CONTENT_DIR, $src)); $cache = $this->get_cached_file_data($handle); // vars to pass into the compiler - default @themeurl var for image urls etc... $this->vars['themeurl'] = '~"' . get_stylesheet_directory_uri() . '"'; $this->vars['lessurl'] = '~"' . dirname($src) . '"'; $this->vars = apply_filters('less_vars', $this->vars, $handle); // The overall "version" of the LESS file is all it's vars, src etc. $less_version = md5(serialize(array($this->vars, $src))); /** * Give the ability to disable always compiling the LESS with lessc() * and instead just use the $vars and $version of the LESS file to * dictate whether the LESS should be (re)generated. * * This means we don't need to run everything through the lessc() compiler * on every page load. The tradeoff is making a change in a LESS file will not * necessarily cause a (re)generation, one would need to bump the $ver param * on wp_enqueue_script() to cause that. */ if (!get_option('wp_less_always_compile_less', true)) { if (!empty($cache['version']) && $cache['version'] === $less_version) { // restore query string it had if any $url = $cache['url'] . (!empty($query_string) ? "?{$query_string}" : ''); $url = set_url_scheme($url, $src_scheme); return add_query_arg('ver', $less_version, $url); } } // automatically regenerate files if source's modified time has changed or vars have changed try { // initialise the parser if (!class_exists('lessc')) { return $url; //wp_die( 'the lessphp library is missing, aborting, run composer update' ); } // If the cache or root path in it are invalid then regenerate if (empty($cache) || empty($cache['less']['root']) || !file_exists($cache['less']['root'])) { $cache = array('vars' => $this->vars, 'less' => $less_path); } if (empty($cache['url'])) { $cache['url'] = trailingslashit($this->get_cache_dir(false)) . "{$handle}.css"; } // less config $less = new lessc(); $less->setFormatter(apply_filters('less_compression', $this->compression)); $less->setPreserveComments(apply_filters('less_preserve_comments', $this->preserve_comments)); $less->setVariables($this->vars); // add directories to scan for imports $import_dirs = apply_filters('less_import_dirs', $this->import_dirs); if (!empty($import_dirs)) { foreach ((array) $import_dirs as $dir) { $less->addImportDir($dir); } } // register and unregister functions foreach ($this->registered_functions as $name => $callable) { $less->registerFunction($name, $callable); } foreach ($this->unregistered_functions as $name) { $less->unregisterFunction($name); } // allow devs to mess around with the less object configuration do_action_ref_array('lessc', array(&$less)); // $less->cachedCompile only checks for changed file modification times // if using the theme customiser (changed variables not files) then force a compile if ($this->vars !== $cache['vars']) { $force = true; } else { $force = false; } $force = apply_filters('less_force_compile', $force); $less_cache = $less->cachedCompile($cache['less'], $force); // if they have the same values but differing order, they wont match //sort( $cache['less'] ); //sort( $less_cache ); if (empty($cache) || empty($cache['less']['updated']) || md5($less_cache['compiled']) !== md5($cache['less']['compiled']) || $this->vars !== $cache['vars']) { // output css file name $css_path = trailingslashit($this->get_cache_dir()) . "{$handle}.css"; $cache = array('vars' => $this->vars, 'url' => trailingslashit($this->get_cache_dir(false)) . "{$handle}.css", 'version' => $less_version, 'less' => null); /** * If the option to not have LESS always compiled is set, * then we dont store the whole less_cache in the options table as it's * not needed because we only do a comparison based off $vars and $src * (which includes the $ver param). * * This saves space on the options table for high performance environments. */ if (get_option('wp_less_always_compile_less', true)) { $cache['less'] = $less_cache; } $payload = '<strong>Rebuilt stylesheet with handle: "' . $handle . '"</strong><br>'; if ($this->vars != $cache['vars']) { $payload .= '<em>Variables changed</em>'; $difference = array_merge(array_diff_assoc($cache['vars'], $this->vars), array_diff_assoc($this->vars, $cache['vars'])); $payload .= '<pre>' . print_r($difference, true) . '</pre>'; } else { if (empty($cache) || empty($cache['less']['updated'])) { $payload .= '<em>Empty cache or empty last update time</em>'; } else { if ($less_cache['updated'] > $cache['less']['updated']) { $payload .= '<em>Update times different</em>'; } else { $payload .= '<em><strong>Unknown! Contact the developers poste haste!!!!!!!</em><strong></em>'; } } } $payload .= '<br>src: <code>"' . $src . '"</code> css path: <code>"' . $css_path . '"</code> and cache path: <code>"' . $cache_path . '"</code> and scheme <code>"' . $src_scheme . '"</code>'; $this->add_message(array('time' => time(), 'payload' => $payload)); $this->save_parsed_css($css_path, $less_cache['compiled']); $this->update_cached_file_data($handle, $cache); } } catch (exception $ex) { $this->add_message(array('time' => time(), 'payload' => '<strong>Lessphp failure</strong> ' . $ex->GetMessage())); wp_die(wp_strip_all_tags($ex->getMessage())); } // restore query string it had if any $url = $cache['url'] . (!empty($query_string) ? "?{$query_string}" : ''); // restore original url scheme $url = set_url_scheme($url, $src_scheme); if (get_option('wp_less_always_compile_less', true)) { return add_query_arg('ver', $less_cache['updated'], $url); } return add_query_arg('ver', $less_version, $url); }
protected function compileLess($string, $path) { require_once WF_ADMINISTRATOR . '/classes/lessc.inc.php'; $less = new lessc(); // add file directory $less->addImportDir($path); // add joomla media folder $less->addImportDir(JPATH_SITE . 'media'); try { return $less->compile($string); } catch (Exception $e) { return "/* LESS file could not be compiled due to error - " . $e->getMessage() . " */"; } }
/** * Processing less file. * * @param $path * @param string $cacheFolder * @return null|string * @throws \Exception */ public function lessProcess($path, $cacheFolder = 'styles') { $output = null; $ext = pathinfo($path, PATHINFO_EXTENSION); if (!$ext) { $path .= '.less'; } $systemPath = $path; $segments = explode('/', $path); $lessFolder = ROOT . DS . 'webroot' . DS . 'less'; list($plugin, $path) = $this->_View->pluginSplit($path, false); $webRoot = ROOT . DS . 'webroot' . DS; $isPlugin = Plugin::loaded($plugin); $this->_imageFull = WWW_ROOT . DS . 'img' . DS; // Set data for plugin less. if ($plugin && $isPlugin) { $pluginPath = Plugin::path($plugin); $lessFolder = $pluginPath . 'webroot' . DS . 'less'; $webRootPlg = $pluginPath . 'webroot' . DS; $this->_type = 'plugin:' . $plugin; $this->_imageFull = $webRootPlg . 'img' . DS; } $lessFile = $lessFolder . DS . $path; // Set data for module less. if (strpos($segments[0], ':')) { list($type, $name) = explode(':', $segments[0]); if ($type == 'modules') { $modulePath = ROOT . DS . 'modules' . DS . $name . DS . 'assets' . DS; $lessFile = $modulePath . 'less' . DS . $segments[1]; $this->_type = 'modules:' . $name; $this->_imageFull = $modulePath . 'img' . DS; } } if (file_exists($lessFile)) { $less = new \lessc(); $fileHash = md5(serialize(md5_file($lessFile))); $cssFileName = $fileHash . '.css'; $less->registerFunction('url', array($this, 'lessPhpUrl')); $less->addImportDir(Plugin::path('Union/Core') . 'webroot' . DS . 'less' . DS); if (!DEBUG) { $formatter = new \lessc_formatter_compressed(); $less->setFormatter($formatter); $less->setPreserveComments(false); $cssFileName = $fileHash . '.min.css'; } $updateFile = false; try { $cssFile = $webRoot . 'cache' . DS . $cacheFolder . DS . $cssFileName; if (file_exists($cssFile)) { $cacheRes = fopen($cssFile, 'r'); $firstLine = fgets($cacheRes); fclose($cacheRes); if (!preg_match("#{$fileHash}#i", $firstLine)) { $updateFile = true; } } else { $updateFile = true; } $output = '/cache/' . $cacheFolder . '/' . $cssFileName; if ($this->_lessCompile) { $updateFile = true; } if ($updateFile) { $css = $less->compileFile($lessFile); $css = $this->_getLessFileComment($fileHash, $systemPath) . $css; $file = new File($cssFile, true); $file->write($css); $file->close(); } } catch (Exception $error) { die('<strong>' . __d('union_dev', 'Less Error:') . '</strong><br/><pre>' . $error->getMessage() . '</pre>'); } } return $output; }
/** * Lessify the stylesheet and return the href of the compiled file * * @param string $src Source URL of the file to be parsed * @param string $handle An identifier for the file used to create the file name in the cache * @return string URL of the compiled stylesheet */ public function parse_stylesheet($src, $handle) { // we only want to handle .less files if (!preg_match('/\\.less(\\.php)?$/', preg_replace('/\\?.*$/', '', $src))) { return $src; } // get file path from $src if (!strstr($src, '?')) { $src .= '?'; } // prevent non-existent index warning when using list() & explode() // Match the URL schemes between WP_CONTENT_URL and $src, // so the str_replace further down will work $src_scheme = parse_url($src, PHP_URL_SCHEME); $wp_content_url_scheme = parse_url(WP_CONTENT_URL, PHP_URL_SCHEME); if ($src_scheme != $wp_content_url_scheme) { $src = set_url_scheme($src, $wp_content_url_scheme); } list($less_path, $query_string) = explode('?', str_replace(WP_CONTENT_URL, WP_CONTENT_DIR, $src)); // output css file name $css_path = trailingslashit($this->get_cache_dir()) . "{$handle}.css"; // automatically regenerate files if source's modified time has changed or vars have changed try { // initialise the parser $less = new lessc(); // load the cache $cache_path = "{$css_path}.cache"; if (file_exists($cache_path)) { $cache = unserialize(file_get_contents($cache_path)); } // vars to pass into the compiler - default @themeurl var for image urls etc... $this->vars['themeurl'] = '~"' . get_stylesheet_directory_uri() . '"'; $this->vars['lessurl'] = '~"' . dirname($src) . '"'; $this->vars = apply_filters('less_vars', $this->vars, $handle); // If the cache or root path in it are invalid then regenerate if (empty($cache) || empty($cache['less']['root']) || !file_exists($cache['less']['root'])) { $cache = array('vars' => $this->vars, 'less' => $less_path); } // less config $less->setFormatter(apply_filters('less_compression', $this->compression)); $less->setPreserveComments(apply_filters('less_preserve_comments', $this->preserve_comments)); $less->setVariables($this->vars); // add directories to scan for imports $import_dirs = apply_filters('less_import_dirs', $this->import_dirs); if (!empty($import_dirs)) { foreach ((array) $import_dirs as $dir) { $less->addImportDir($dir); } } // register and unregister functions foreach ($this->registered_functions as $name => $callable) { $less->registerFunction($name, $callable); } foreach ($this->unregistered_functions as $name) { $less->unregisterFunction($name); } // allow devs to mess around with the less object configuration do_action_ref_array('lessc', array(&$less)); // $less->cachedCompile only checks for changed file modification times // if using the theme customiser (changed variables not files) then force a compile if ($this->vars !== $cache['vars']) { $force = true; } else { $force = false; } $less_cache = $less->cachedCompile($cache['less'], apply_filters('less_force_compile', $force)); if (empty($cache) || empty($cache['less']['updated']) || $less_cache['updated'] > $cache['less']['updated'] || $this->vars !== $cache['vars']) { file_put_contents($cache_path, serialize(array('vars' => $this->vars, 'less' => $less_cache))); file_put_contents($css_path, $less_cache['compiled']); } } catch (exception $ex) { wp_die($ex->getMessage()); } // restore query string it had if any $url = trailingslashit($this->get_cache_dir(false)) . "{$handle}.css" . (!empty($query_string) ? "?{$query_string}" : ''); // restore original url scheme $url = set_url_scheme($url, $src_scheme); return add_query_arg('ver', $less_cache['updated'], $url); }
/** * Compile LESS file to CSS and store in cache if necessary * * @param string $file LESS file to compile * @return integer Timestamp of the last compilation */ private function _compileLess($file) { $cacheFile = CACHE_DIR . DS . 'assets' . DS . md5($file) . ".less.cache"; $cache = is_file($cacheFile) ? unserialize(file_get_contents($cacheFile)) : $file; require_once FW_DIR . DS . "lib" . DS . 'vendor' . DS . "lessphp" . DS . "lessc.inc.php"; $less = new lessc(); $less->addImportDir(WWW_DIR); $less->addImportDir(dirname($file)); $compiled = $less->cachedCompile($cache); if (!is_array($cache) || $compiled["updated"] > $cache["updated"]) { file_put_contents($cacheFile, serialize($compiled)); return $compiled['updated']; } return $cache['updated']; }
/** * Compile a LESS file with our custom variables * * @param $string $less_file - 'style.less' * * @return string - the resulting CSS */ static function compile_less($less_file, $variables) { $variables = array_map(function ($var) { return stripslashes($var); }, $variables); // Load LESS compiler if loaded if (!class_exists('lessc')) { require dirname(__FILE__) . '/../lib/lessc.inc.php'; } $compiler = new lessc(); // Set to compressed mode unless SCRIPT_DEBUG is true if (!defined('JCLV_UNCOMPRESSED') || !JCLV_UNCOMPRESSED) { $compiler->setFormatter("compressed"); } $compiler->addImportDir(self::$less_dir); try { // Get the Less file and then replace variables.less with the update version $less = self::get_contents(self::$less_dir . $less_file); $less = self::replace_with_custom_variables($less, $variables); $css = $compiler->compile($less); $css = self::fix_urls($css); return $css; } catch (Exception $e) { return $less; } }
function mso_lessc($less_file = '', $css_file = '', $css_url = '', $use_cache = false, $use_mini = true, $use_mini_n = false) { if (is_array($less_file)) { $options = $less_file; // для красоты кода и чтобы не путаться $less_file = isset($options['less_file']) ? $options['less_file'] : ''; $css_file = isset($options['css_file']) ? $options['css_file'] : ''; $css_url = isset($options['css_url']) ? $options['css_url'] : ''; $use_cache = isset($options['use_cache']) ? $options['use_cache'] : false; $use_mini = isset($options['use_mini']) ? $options['use_mini'] : true; $use_mini_n = isset($options['use_mini_n']) ? $options['use_mini_n'] : false; } if (!$less_file or !$css_file) { return; } // не указаны файлы if ($use_cache) { if (file_exists($less_file) and file_exists($css_file)) { $flag_compiling = false; // флаг == true — требуется компиляция $t_css = filemtime($css_file); // время css-файла // смотрим все файлы каталога $CI =& get_instance(); // подключение CodeIgniter $CI->load->helper('file_helper'); // хелпер для работы с файлами $all_files_in_dirs = get_filenames(dirname($less_file), true); foreach ($all_files_in_dirs as $file) { if (substr(strrchr($file, '.'), 1) !== 'less') { continue; } // проверка расширения файла if (filemtime($file) > $t_css) { $flag_compiling = true; // нужна компиляция break; } } if (!$flag_compiling) { if ($css_url) { // в виде имени файла return NT . '<link rel="stylesheet" href="' . $css_url . '">'; } else { // в виде содержимого return file_get_contents($css_file); } } } } if (file_exists($less_file)) { $fc_all = file_get_contents($less_file); } else { return; } // нет файла, выходим // проверка на разрешение записывать css-файл if (file_exists($css_file) and !is_writable($css_file)) { // и что делать??? return tf('LESS: результирующий css-файл не имеет разрешений на запись.'); // die(tf('Нет возможности выполнить less-компиляцию: ') . $css_file); } if ($fc_all) { require_once getinfo('plugins_dir') . 'less_compiling/less/lessc.inc.php'; $compiler = new lessc(); // возможно есть php-файл для своих функций // строится как исходный + .php // пример http://leafo.net/lessphp/docs/#custom_functions if (file_exists($less_file . '.php')) { require_once $less_file . '.php'; } // это общие custom_functions // их набор зависит от версии LESSPHP if ($fn = mso_fe(getinfo('plugins_dir') . 'less_compiling/less/custom_functions.php')) { require $fn; } $compiler->addImportDir(dirname($less_file)); // новый 0.3.7 api $compiler->indentChar = "\t"; // для совметимости со старым вариантом — удалить в январе 2014!!! $fc_all = str_replace('@MSO_IMPORT_ALL_FONTS;', '@MSO_IMPORT_ALL(fonts);', $fc_all); $fc_all = str_replace('@MSO_IMPORT_ALL_MIXINS;', '@MSO_IMPORT_ALL(mixins);', $fc_all); $fc_all = str_replace('@MSO_IMPORT_ALL_BLOCKS;', '@MSO_IMPORT_ALL(blocks);', $fc_all); $fc_all = str_replace('@MSO_IMPORT_ALL_HELPERS;', '@MSO_IMPORT_ALL(helpers);', $fc_all); $fc_all = str_replace('@MSO_IMPORT_ALL_COMPONENTS;', '@MSO_IMPORT_ALL(components);', $fc_all); $fc_all = str_replace('@MSO_IMPORT_ALL_PLUGINS;', '@MSO_IMPORT_ALL(plugins);', $fc_all); $fc_all = str_replace('@MSO_IMPORT_ALL_TYPE;', '@MSO_IMPORT_ALL(type);', $fc_all); // универсальная конструкция: @MSO_IMPORT_ALL(каталог); $fc_all = preg_replace_callback('!(@MSO_IMPORT_ALL\\()(.*?)(\\);)!is', '_mso_less_import_all_callback', $fc_all); // в тексте исходного файла $fc_all может быть php-код ob_start(); eval('?>' . $fc_all . '<?php '); $fc_all = ob_get_contents(); ob_end_clean(); try { $out = $compiler->compile($fc_all); // новый 0.3.7 api } catch (Exception $ex) { $out = _mso_less_exception($ex->getMessage(), $fc_all); die($out); // рубим, ибо нефиг писать с ошибками } // сжатие кода if ($use_mini) { if ($use_mini_n) { $out = str_replace("\t", ' ', $out); $out = str_replace(array("\r\n", "\r", "\n", ' ', ' '), '', $out); } $out = str_replace("\n\t", '', $out); $out = str_replace("\n}", '}', $out); $out = str_replace('; ', ';', $out); $out = str_replace(';}', '}', $out); $out = str_replace(': ', ':', $out); $out = str_replace('{ ', '{', $out); $out = str_replace(' }', '}', $out); $out = str_replace(' {', '{', $out); $out = str_replace(', ', ',', $out); $out = str_replace(' > ', '>', $out); $out = str_replace('} ', '}', $out); $out = str_replace(' ', ' ', $out); } $fp = fopen($css_file, "w"); fwrite($fp, $out); fclose($fp); if ($css_url) { return NT . '<link rel="stylesheet" href="' . $css_url . '">'; // в виде имени файла } else { // в виде содержимого return $out; } } }