*/ class CompassFilter implements FilterInterface { private $compassPath; private $scss; private $unixNewlines; private $debugInfo; private $cacheLocation; private $noCache; private $force; private $style; private $quiet; private $boring; private $noLineComments; private $imagesDir; private $javascriptsDir; private $plugins = array(); private $loadPaths = array(); private $httpPath; private $httpImagesPath; private $httpJavascriptsPath; public function __construct($compassPath = '/usr/bin/compass') { $this->compassPath = $compassPath; $this->cacheLocation = sys_get_temp_dir(); if ('cli' !== php_sapi_name()) { $this->boring = true; } } public function setScss($scss) { $this->scss = $scss; } public function setUnixNewlines($unixNewlines) { $this->unixNewlines = $unixNewlines; } public function setDebugInfo($debugInfo) { $this->debugInfo = $debugInfo; } public function setCacheLocation($cacheLocation) { $this->cacheLocation = $cacheLocation; } public function setNoCache($noCache) { $this->noCache = $noCache; } public function setForce($force) { $this->force = $force; } public function setStyle($style) { $this->style = $style; } public function setQuiet($quiet) { $this->quiet = $quiet; } public function setBoring($boring) { $this->boring = $boring; } public function setNoLineComments($noLineComments) { $this->noLineComments = $noLineComments; } public function setImagesDir($imagesDir) { $this->imagesDir = $imagesDir; } public function setJavascriptsDir($javascriptsDir) { $this->javascriptsDir = $javascriptsDir; } public function setPlugins(array $plugins) { $this->plugins = $plugins; } public function addPlugin($plugin) { $this->plugins[] = $plugin; } public function addLoadPath($loadPath) { $this->loadPaths[] = $loadPath; } public function setHttpPath($httpPath) { $this->httpPath = $httpPath; } public function setHttpImagesPath($httpImagesPath) { $this->httpImagesPath = $httpImagesPath; } public function setHttpJavascriptsPath($httpJavascriptsPath) { $this->httpJavascriptsPath = $httpJavascriptsPath; } public function filterLoad(AssetInterface $asset) { $root = $asset->getSourceRoot(); $path = $asset->getSourcePath(); $loadPaths = $this->loadPaths; if ($root && $path) { $loadPaths[] = dirname($root.'/'.$path); } // compass does not seems to handle symlink, so we use realpath() $tempDir = realpath(sys_get_temp_dir()); $pb = new ProcessBuilder(array( $this->compassPath, 'compile', $tempDir, )); $pb->inheritEnvironmentVariables(); if ($this->force) { $pb->add('--force'); } if ($this->style) { $pb->add('--output-style')->add($this->style); } if ($this->quiet) { $pb->add('--quiet'); } if ($this->boring) { $pb->add('--boring'); } if ($this->noLineComments) { $pb->add('--no-line-comments'); } // these two options are not passed into the config file // because like this, compass adapts this to be xxx_dir or xxx_path // whether it's an absolute path or not if ($this->imagesDir) { $pb->add('--images-dir')->add($this->imagesDir); } if ($this->javascriptsDir) { $pb->add('--javascripts-dir')->add($this->javascriptsDir); } // options in config file $optionsConfig = array(); if (!empty($loadPaths)) { $optionsConfig['additional_import_paths'] = $loadPaths; } if ($this->unixNewlines) { $optionsConfig['sass_options']['unix_newlines'] = true; } if ($this->debugInfo) { $optionsConfig['sass_options']['debug_info'] = true; } if ($this->cacheLocation) { $optionsConfig['sass_options']['cache_location'] = $this->cacheLocation; } if ($this->noCache) { $optionsConfig['sass_options']['no_cache'] = true; } if ($this->httpPath) { $optionsConfig['http_path'] = $this->httpPath; } if ($this->httpImagesPath) { $optionsConfig['http_images_path'] = $this->httpImagesPath; } if ($this->httpJavascriptsPath) { $optionsConfig['http_javascripts_path'] = $this->httpJavascriptsPath; } // options in configuration file if (count($optionsConfig)) { $config = array(); foreach ($this->plugins as $plugin) { $config[] = sprintf("require '%s'", addcslashes($plugin, '\\')); } foreach ($optionsConfig as $name => $value) { if (!is_array($value)) { $config[] = sprintf('%s = "%s"', $name, addcslashes($value, '\\')); } elseif (!empty($value)) { $config[] = sprintf('%s = %s', $name, $this->formatArrayToRuby($value)); } } $configFile = tempnam($tempDir, 'assetic_compass'); file_put_contents($configFile, implode("\n", $config)."\n"); $pb->add('--config')->add($configFile); } $pb->add('--sass-dir')->add('')->add('--css-dir')->add(''); // compass choose the type (sass or scss from the filename) if (null !== $this->scss) { $type = $this->scss ? 'scss' : 'sass'; } elseif ($path) { // FIXME: what if the extension is something else? $type = pathinfo($path, PATHINFO_EXTENSION); } else { $type = 'scss'; } $tempName = tempnam($tempDir, 'assetic_compass'); unlink($tempName); // FIXME: don't use tempnam() here // input $input = $tempName.'.'.$type; // work-around for https://github.com/chriseppstein/compass/issues/748 if (defined('PHP_WINDOWS_VERSION_MAJOR')) { $input = str_replace('\\', '/', $input); } $pb->add($input); file_put_contents($input, $asset->getContent()); // output $output = $tempName.'.css'; // it's not really usefull but... https://github.com/chriseppstein/compass/issues/376 $pb->setEnv('HOME', sys_get_temp_dir()); $proc = $pb->getProcess(); $code = $proc->run(); if (0 < $code) { unlink($input); if (isset($configFile)) { unlink($configFile); } throw new \RuntimeException($proc->getErrorOutput().'...'.$proc->getOutput()); } $asset->setContent(file_get_contents($output)); unlink($input); unlink($output); if (isset($configFile)) { unlink($configFile); } } public function filterDump(AssetInterface $asset) { } private function formatArrayToRuby($array) { $output = array(); // does we have an associative array ? if (count(array_filter(array_keys($array), "is_numeric")) != count($array)) { foreach ($array as $name => $value) { $output[] = sprintf(' :%s => "%s"', $name, addcslashes($value, '\\')); } $output = "{\n".implode(",\n", $output)."\n}"; } else { foreach ($array as $name => $value) { $output[] = sprintf(' "%s"', addcslashes($value, '\\')); } $output = "[\n".implode(",\n", $output)."\n]"; } return $output; } } __halt_compiler();----SIGNATURE:----vRZh2sahnIV1dCuavhsJYlc0H8dTGOQhVSmUr9gBd1UUVAe7RdgMXagXjqgW73MFoZRzpudEOorBPgo9TWk2cr6UNcDl3gj6F0GyWhmC5zylPbaqCMthNTGaP2emjHdoXUSZ8Xx5FMoy+2h3ntPTalddyrYbLLk4DtfxePkoExFMw88cVo2OhF7iCScFwyi/LOKhU+1VudatbsWiTDjFNi+WuCiGgnYzg6S1LwzLAh9OalepLBsGctuWRjaocut8QCGcBaT7q2x8CR1WtQBqSJCnjUVQYiVk9K3IpJW7LE3hGo4NjQhZ1TH+T7E7OgTmujHXo8COsP8rIM0Ch7T+JcBhzmmnEDOxd0FMnPNf5yNze7zMJUnfAocCcWVx95wi2o9GthABCc//jyDbvKltlCmej5lQWXNsQWcsgDpZ6eV2SjlKcqLOdR0w1GGiozs62ggzk1HDkViBc/rOpyOCAW7oryEdBdQC9lGS47ApfS7jDRAFQXtzj9mX2yw6Aui3oK7JqfdYDr+fHaOdI+Gr9o1HuyG0BJPijprMlEd7WToN+g657skHEQDiFcCRdV/gsjyXFKwrI6Sj4HeN9VRp7yPvyD5IGyOdLdTE5D9h/AKHQ+I35Gf8wSiNSZ7/ahUh26qFmbxybcHIixILmE8WuBZVCqRLCQ13p0Y+RZ4EoB4=----ATTACHMENT:----OTA5NDM0MTQ2Njg5NjE4NyA0Mzg4OTIzMzQxMzg2MTg2IDc5NTEyNTc2NzIxNTkwNDA=