diff --git a/Converter.php b/Converter.php index f32ce2c..30fb324 100644 --- a/Converter.php +++ b/Converter.php @@ -114,9 +114,12 @@ public function needRecompile($from, $to) public function checkDestinationDir($basePath, $file) { - $distDir = dirname($basePath . '/' . $file); - if (!is_dir($distDir)) { - mkdir($distDir, $this->destinationDirPerms, true); + $dstDir = dirname($basePath . '/' . $file); + if (!is_dir($dstDir)) { + mkdir($dstDir, $this->destinationDirPerms, true); + $assetManager = \Yii::$app->assetManager; + if ($assetManager->dirMode) + @chmod($dstDir, $assetManager->dirMode); } } } diff --git a/Less.php b/Less.php index 62326fa..e248f5f 100644 --- a/Less.php +++ b/Less.php @@ -3,10 +3,40 @@ use Yii; use yii\caching\FileCache; +use yii\base\Event; class Less extends Parser { - public $auto = false; + /** Name of the event that will be sent right before a compile. It will include filenames and the compiler instance */ + const EVENT_BEFORE_COMPILE = 'beforeCompile'; + + /** @var bool true to automatically try to determine what to compile using the file cache manager */ + public $auto = false; + + /** @var bool true to compress the output */ + public $compressed = false; + + /** @var bool If true, adjust urls to be relative, false means don't touch */ + public $relativeUrls = true; + + /** + * Set of variables to register and that will be available in the less files. + * Note: The value should be in less format (strings are double quoted etc) + * eg "variables" => ['some-variable' => '"variable quoted content"'] + * + * On top of these 2 others will be added: + * - published-url: Full url of the file currently being compiled + * - published-base-url: Base Url of the assets folder + * + * @var array + */ + public $variables = []; + + /** + * Temporary runtime data so the event handlers can access it + * @var array + */ + public $runtime = null; /** * Parse a Less file to CSS @@ -14,6 +44,33 @@ class Less extends Parser public function parse($src, $dst, $options) { $this->auto = isset($options['auto']) ? $options['auto'] : $this->auto; + + $variables = $this->variables; + $assetManager = Yii::$app->assetManager; + + // Final url of the file being compiled + $assetUrl = substr($dst, strpos($assetManager->basePath, $assetManager->baseUrl)); + $variables['published-url'] = '"' . $assetUrl . '"'; + + // Root for the published folder + $variables['published-base-url'] = '"/' . implode('/', array_slice(explode('/', ltrim($assetUrl, '/')), 0, 2)) . '"'; + + $less = new \lessc(); + $less->setVariables($variables); + + // Compressed setting + if ($this->compressed) { + $less->setFormatter('compressed'); + } + \Less_Parser::$default_options['compress'] = $this->compressed; + \Less_Parser::$default_options['relativeUrls'] = $this->relativeUrls; + + // Send out pre-compile event + $event = new \yii\base\Event(); + $this->runtime = ['sourceFile' => $src, 'destinationFile' => $dst, 'compiler' => $less]; + $event->sender = $this; + Event::trigger($this, self::EVENT_BEFORE_COMPILE, $event); + try { if ($this->auto) { /* @var FileCache $cacheMgr */ @@ -24,7 +81,6 @@ public function parse($src, $dst, $options) if ($cache === false || (@filemtime($dst) < @filemtime($src))) { $cache = $src; } - $less = new \lessc(); $newCache = $less->cachedCompile($cache); if (!is_array($cache) || ($newCache["updated"] > $cache["updated"])) { @@ -32,11 +88,16 @@ public function parse($src, $dst, $options) file_put_contents($dst, $newCache['compiled']); } } else { - $less = new \lessc(); $less->compileFile($src, $dst); } - } catch (Exception $e) { - throw new Exception(__CLASS__ . ': Failed to compile less file : ' . $e->getMessage() . '.'); + + // If needed, respect the users configuration + if ($assetManager->fileMode !== null) + @chmod($dst, $assetManager->fileMode); + + unset($this->less); + } catch (\Exception $e) { + throw new \Exception(__CLASS__ . ': Failed to compile less file : ' . $e->getMessage() . '.'); } } } \ No newline at end of file