* @since 2.0 */ class AssetConverter extends Component implements AssetConverterInterface { /** * @var array the commands that are used to perform the asset conversion. * The keys are the asset file extension names, and the values are the corresponding * target script types (either "css" or "js") and the commands used for the conversion. */ public $commands = [ 'less' => ['css', 'lessc {from} {to}'], 'scss' => ['css', 'sass {from} {to}'], 'sass' => ['css', 'sass {from} {to}'], 'styl' => ['js', 'stylus < {from} > {to}'], ]; /** * Converts a given asset file into a CSS or JS file. * @param string $asset the asset file path, relative to $basePath * @param string $basePath the directory the $asset is relative to. * @return string the converted asset file path, relative to $basePath. */ public function convert($asset, $basePath) { $pos = strrpos($asset, '.'); if ($pos !== false) { $ext = substr($asset, $pos + 1); if (isset($this->commands[$ext])) { list ($ext, $command) = $this->commands[$ext]; $result = substr($asset, 0, $pos + 1) . $ext; if (@filemtime("$basePath/$result") < filemtime("$basePath/$asset")) { $output = []; $command = strtr($command, [ '{from}' => escapeshellarg("$basePath/$asset"), '{to}' => escapeshellarg("$basePath/$result"), ]); exec($command, $output); Yii::trace("Converted $asset into $result: " . implode("\n", $output), __METHOD__); } return $result; } } return $asset; } }